ia64/xen-unstable

changeset 5974:f242de2e5a3c

Move copy+patched files to linux-xen directory.

Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author adsharma@xuni-t01.sc.intel.com
date Tue Aug 02 16:25:11 2005 -0800 (2005-08-02)
parents e2127f19861b
children 0380b4cc3c1a
files xen/arch/ia64/Makefile xen/arch/ia64/Rules.mk xen/arch/ia64/linux-xen/efi.c xen/arch/ia64/linux-xen/entry.S xen/arch/ia64/linux-xen/entry.h xen/arch/ia64/linux-xen/head.S xen/arch/ia64/linux-xen/irq_ia64.c xen/arch/ia64/linux-xen/mm_contig.c xen/arch/ia64/linux-xen/pal.S xen/arch/ia64/linux-xen/setup.c xen/arch/ia64/linux-xen/time.c xen/arch/ia64/linux-xen/tlb.c xen/arch/ia64/linux-xen/unaligned.c xen/include/asm-ia64/linux-xen/asm/gcc_intrin.h xen/include/asm-ia64/linux-xen/asm/hpsim_ssc.h xen/include/asm-ia64/linux-xen/asm/ia64regs.h xen/include/asm-ia64/linux-xen/asm/io.h xen/include/asm-ia64/linux-xen/asm/kregs.h xen/include/asm-ia64/linux-xen/asm/mca_asm.h xen/include/asm-ia64/linux-xen/asm/page.h xen/include/asm-ia64/linux-xen/asm/pal.h xen/include/asm-ia64/linux-xen/asm/pgalloc.h xen/include/asm-ia64/linux-xen/asm/processor.h xen/include/asm-ia64/linux-xen/asm/ptrace.h xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h xen/include/asm-ia64/linux-xen/asm/system.h xen/include/asm-ia64/linux-xen/asm/types.h xen/include/asm-ia64/linux-xen/asm/uaccess.h xen/include/asm-ia64/linux-xen/linux/cpumask.h xen/include/asm-ia64/linux-xen/linux/hardirq.h xen/include/asm-ia64/linux-xen/linux/interrupt.h
line diff
     1.1 --- a/xen/arch/ia64/Makefile	Tue Aug 02 15:59:09 2005 -0800
     1.2 +++ b/xen/arch/ia64/Makefile	Tue Aug 02 16:25:11 2005 -0800
     1.3 @@ -1,6 +1,6 @@
     1.4  include $(BASEDIR)/Rules.mk
     1.5  
     1.6 -VPATH = linux
     1.7 +VPATH = linux linux-xen
     1.8  
     1.9  # libs-y	+= arch/ia64/lib/lib.a
    1.10  
     2.1 --- a/xen/arch/ia64/Rules.mk	Tue Aug 02 15:59:09 2005 -0800
     2.2 +++ b/xen/arch/ia64/Rules.mk	Tue Aug 02 16:25:11 2005 -0800
     2.3 @@ -6,8 +6,11 @@ ifneq ($(COMPILE_ARCH),$(TARGET_ARCH))
     2.4  CROSS_COMPILE ?= /usr/local/sp_env/v2.2.5/i686/bin/ia64-unknown-linux-
     2.5  endif
     2.6  AFLAGS  += -D__ASSEMBLY__
     2.7 -CPPFLAGS  += -I$(BASEDIR)/include -I$(BASEDIR)/include/asm-ia64 \
     2.8 -             -I$(BASEDIR)/include/asm-ia64/linux -I$(BASEDIR)/arch/ia64/linux
     2.9 +CPPFLAGS  += -I$(BASEDIR)/include -I$(BASEDIR)/include/asm-ia64 	\
    2.10 +             -I$(BASEDIR)/include/asm-ia64/linux 			\
    2.11 +	     -I$(BASEDIR)/include/asm-ia64/linux-xen 			\
    2.12 +             -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
    2.13 +
    2.14  CFLAGS  := -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
    2.15  #CFLAGS  += -O3		# -O3 over-inlines making debugging tough!
    2.16  CFLAGS  += -O2		# but no optimization causes compile errors!
    2.17 @@ -15,7 +18,9 @@ CFLAGS  += -O2		# but no optimization ca
    2.18  CFLAGS  += -iwithprefix include -Wall
    2.19  CFLAGS  += -fomit-frame-pointer -I$(BASEDIR)/include -D__KERNEL__
    2.20  CFLAGS  += -I$(BASEDIR)/include/asm-ia64 -I$(BASEDIR)/include/asm-ia64/linux \
    2.21 -           -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64
    2.22 +           -I$(BASEDIR)/include/asm-ia64/linux 				\
    2.23 +           -I$(BASEDIR)/include/asm-ia64/linux-xen 			\
    2.24 +           -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
    2.25  CFLAGS  += -Wno-pointer-arith -Wredundant-decls
    2.26  CFLAGS  += -DIA64 -DXEN -DLINUX_2_6
    2.27  CFLAGS	+= -ffixed-r13 -mfixed-range=f12-f15,f32-f127
     3.1 --- a/xen/arch/ia64/efi.c	Tue Aug 02 15:59:09 2005 -0800
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,866 +0,0 @@
     3.4 -/*
     3.5 - * Extensible Firmware Interface
     3.6 - *
     3.7 - * Based on Extensible Firmware Interface Specification version 0.9 April 30, 1999
     3.8 - *
     3.9 - * Copyright (C) 1999 VA Linux Systems
    3.10 - * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    3.11 - * Copyright (C) 1999-2003 Hewlett-Packard Co.
    3.12 - *	David Mosberger-Tang <davidm@hpl.hp.com>
    3.13 - *	Stephane Eranian <eranian@hpl.hp.com>
    3.14 - *
    3.15 - * All EFI Runtime Services are not implemented yet as EFI only
    3.16 - * supports physical mode addressing on SoftSDV. This is to be fixed
    3.17 - * in a future version.  --drummond 1999-07-20
    3.18 - *
    3.19 - * Implemented EFI runtime services and virtual mode calls.  --davidm
    3.20 - *
    3.21 - * Goutham Rao: <goutham.rao@intel.com>
    3.22 - *	Skip non-WB memory and ignore empty memory ranges.
    3.23 - */
    3.24 -#include <linux/config.h>
    3.25 -#include <linux/module.h>
    3.26 -#include <linux/kernel.h>
    3.27 -#include <linux/init.h>
    3.28 -#include <linux/types.h>
    3.29 -#include <linux/time.h>
    3.30 -#include <linux/efi.h>
    3.31 -
    3.32 -#include <asm/io.h>
    3.33 -#include <asm/kregs.h>
    3.34 -#include <asm/meminit.h>
    3.35 -#include <asm/pgtable.h>
    3.36 -#include <asm/processor.h>
    3.37 -#include <asm/mca.h>
    3.38 -
    3.39 -#define EFI_DEBUG	0
    3.40 -
    3.41 -extern efi_status_t efi_call_phys (void *, ...);
    3.42 -
    3.43 -struct efi efi;
    3.44 -EXPORT_SYMBOL(efi);
    3.45 -static efi_runtime_services_t *runtime;
    3.46 -static unsigned long mem_limit = ~0UL, max_addr = ~0UL;
    3.47 -
    3.48 -#define efi_call_virt(f, args...)	(*(f))(args)
    3.49 -
    3.50 -#define STUB_GET_TIME(prefix, adjust_arg)							  \
    3.51 -static efi_status_t										  \
    3.52 -prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc)						  \
    3.53 -{												  \
    3.54 -	struct ia64_fpreg fr[6];								  \
    3.55 -	efi_time_cap_t *atc = NULL;								  \
    3.56 -	efi_status_t ret;									  \
    3.57 -												  \
    3.58 -	if (tc)											  \
    3.59 -		atc = adjust_arg(tc);								  \
    3.60 -	ia64_save_scratch_fpregs(fr);								  \
    3.61 -	ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), atc); \
    3.62 -	ia64_load_scratch_fpregs(fr);								  \
    3.63 -	return ret;										  \
    3.64 -}
    3.65 -
    3.66 -#define STUB_SET_TIME(prefix, adjust_arg)							\
    3.67 -static efi_status_t										\
    3.68 -prefix##_set_time (efi_time_t *tm)								\
    3.69 -{												\
    3.70 -	struct ia64_fpreg fr[6];								\
    3.71 -	efi_status_t ret;									\
    3.72 -												\
    3.73 -	ia64_save_scratch_fpregs(fr);								\
    3.74 -	ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm));	\
    3.75 -	ia64_load_scratch_fpregs(fr);								\
    3.76 -	return ret;										\
    3.77 -}
    3.78 -
    3.79 -#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg)						\
    3.80 -static efi_status_t										\
    3.81 -prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)		\
    3.82 -{												\
    3.83 -	struct ia64_fpreg fr[6];								\
    3.84 -	efi_status_t ret;									\
    3.85 -												\
    3.86 -	ia64_save_scratch_fpregs(fr);								\
    3.87 -	ret = efi_call_##prefix((efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time),	\
    3.88 -				adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm));	\
    3.89 -	ia64_load_scratch_fpregs(fr);								\
    3.90 -	return ret;										\
    3.91 -}
    3.92 -
    3.93 -#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg)						\
    3.94 -static efi_status_t										\
    3.95 -prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)					\
    3.96 -{												\
    3.97 -	struct ia64_fpreg fr[6];								\
    3.98 -	efi_time_t *atm = NULL;									\
    3.99 -	efi_status_t ret;									\
   3.100 -												\
   3.101 -	if (tm)											\
   3.102 -		atm = adjust_arg(tm);								\
   3.103 -	ia64_save_scratch_fpregs(fr);								\
   3.104 -	ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time),	\
   3.105 -				enabled, atm);							\
   3.106 -	ia64_load_scratch_fpregs(fr);								\
   3.107 -	return ret;										\
   3.108 -}
   3.109 -
   3.110 -#define STUB_GET_VARIABLE(prefix, adjust_arg)						\
   3.111 -static efi_status_t									\
   3.112 -prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,		\
   3.113 -		       unsigned long *data_size, void *data)				\
   3.114 -{											\
   3.115 -	struct ia64_fpreg fr[6];							\
   3.116 -	u32 *aattr = NULL;									\
   3.117 -	efi_status_t ret;								\
   3.118 -											\
   3.119 -	if (attr)									\
   3.120 -		aattr = adjust_arg(attr);						\
   3.121 -	ia64_save_scratch_fpregs(fr);							\
   3.122 -	ret = efi_call_##prefix((efi_get_variable_t *) __va(runtime->get_variable),	\
   3.123 -				adjust_arg(name), adjust_arg(vendor), aattr,		\
   3.124 -				adjust_arg(data_size), adjust_arg(data));		\
   3.125 -	ia64_load_scratch_fpregs(fr);							\
   3.126 -	return ret;									\
   3.127 -}
   3.128 -
   3.129 -#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg)						\
   3.130 -static efi_status_t										\
   3.131 -prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor)	\
   3.132 -{												\
   3.133 -	struct ia64_fpreg fr[6];								\
   3.134 -	efi_status_t ret;									\
   3.135 -												\
   3.136 -	ia64_save_scratch_fpregs(fr);								\
   3.137 -	ret = efi_call_##prefix((efi_get_next_variable_t *) __va(runtime->get_next_variable),	\
   3.138 -				adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor));	\
   3.139 -	ia64_load_scratch_fpregs(fr);								\
   3.140 -	return ret;										\
   3.141 -}
   3.142 -
   3.143 -#define STUB_SET_VARIABLE(prefix, adjust_arg)						\
   3.144 -static efi_status_t									\
   3.145 -prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, unsigned long attr,	\
   3.146 -		       unsigned long data_size, void *data)				\
   3.147 -{											\
   3.148 -	struct ia64_fpreg fr[6];							\
   3.149 -	efi_status_t ret;								\
   3.150 -											\
   3.151 -	ia64_save_scratch_fpregs(fr);							\
   3.152 -	ret = efi_call_##prefix((efi_set_variable_t *) __va(runtime->set_variable),	\
   3.153 -				adjust_arg(name), adjust_arg(vendor), attr, data_size,	\
   3.154 -				adjust_arg(data));					\
   3.155 -	ia64_load_scratch_fpregs(fr);							\
   3.156 -	return ret;									\
   3.157 -}
   3.158 -
   3.159 -#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg)					\
   3.160 -static efi_status_t										\
   3.161 -prefix##_get_next_high_mono_count (u32 *count)							\
   3.162 -{												\
   3.163 -	struct ia64_fpreg fr[6];								\
   3.164 -	efi_status_t ret;									\
   3.165 -												\
   3.166 -	ia64_save_scratch_fpregs(fr);								\
   3.167 -	ret = efi_call_##prefix((efi_get_next_high_mono_count_t *)				\
   3.168 -				__va(runtime->get_next_high_mono_count), adjust_arg(count));	\
   3.169 -	ia64_load_scratch_fpregs(fr);								\
   3.170 -	return ret;										\
   3.171 -}
   3.172 -
   3.173 -#define STUB_RESET_SYSTEM(prefix, adjust_arg)					\
   3.174 -static void									\
   3.175 -prefix##_reset_system (int reset_type, efi_status_t status,			\
   3.176 -		       unsigned long data_size, efi_char16_t *data)		\
   3.177 -{										\
   3.178 -	struct ia64_fpreg fr[6];						\
   3.179 -	efi_char16_t *adata = NULL;						\
   3.180 -										\
   3.181 -	if (data)								\
   3.182 -		adata = adjust_arg(data);					\
   3.183 -										\
   3.184 -	ia64_save_scratch_fpregs(fr);						\
   3.185 -	efi_call_##prefix((efi_reset_system_t *) __va(runtime->reset_system),	\
   3.186 -			  reset_type, status, data_size, adata);		\
   3.187 -	/* should not return, but just in case... */				\
   3.188 -	ia64_load_scratch_fpregs(fr);						\
   3.189 -}
   3.190 -
   3.191 -#define phys_ptr(arg)	((__typeof__(arg)) ia64_tpa(arg))
   3.192 -
   3.193 -STUB_GET_TIME(phys, phys_ptr)
   3.194 -STUB_SET_TIME(phys, phys_ptr)
   3.195 -STUB_GET_WAKEUP_TIME(phys, phys_ptr)
   3.196 -STUB_SET_WAKEUP_TIME(phys, phys_ptr)
   3.197 -STUB_GET_VARIABLE(phys, phys_ptr)
   3.198 -STUB_GET_NEXT_VARIABLE(phys, phys_ptr)
   3.199 -STUB_SET_VARIABLE(phys, phys_ptr)
   3.200 -STUB_GET_NEXT_HIGH_MONO_COUNT(phys, phys_ptr)
   3.201 -STUB_RESET_SYSTEM(phys, phys_ptr)
   3.202 -
   3.203 -#define id(arg)	arg
   3.204 -
   3.205 -STUB_GET_TIME(virt, id)
   3.206 -STUB_SET_TIME(virt, id)
   3.207 -STUB_GET_WAKEUP_TIME(virt, id)
   3.208 -STUB_SET_WAKEUP_TIME(virt, id)
   3.209 -STUB_GET_VARIABLE(virt, id)
   3.210 -STUB_GET_NEXT_VARIABLE(virt, id)
   3.211 -STUB_SET_VARIABLE(virt, id)
   3.212 -STUB_GET_NEXT_HIGH_MONO_COUNT(virt, id)
   3.213 -STUB_RESET_SYSTEM(virt, id)
   3.214 -
   3.215 -void
   3.216 -efi_gettimeofday (struct timespec *ts)
   3.217 -{
   3.218 -	efi_time_t tm;
   3.219 -
   3.220 -	memset(ts, 0, sizeof(ts));
   3.221 -	if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS)
   3.222 -		return;
   3.223 -
   3.224 -	ts->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
   3.225 -	ts->tv_nsec = tm.nanosecond;
   3.226 -}
   3.227 -
   3.228 -static int
   3.229 -is_available_memory (efi_memory_desc_t *md)
   3.230 -{
   3.231 -	if (!(md->attribute & EFI_MEMORY_WB))
   3.232 -		return 0;
   3.233 -
   3.234 -	switch (md->type) {
   3.235 -	      case EFI_LOADER_CODE:
   3.236 -	      case EFI_LOADER_DATA:
   3.237 -	      case EFI_BOOT_SERVICES_CODE:
   3.238 -	      case EFI_BOOT_SERVICES_DATA:
   3.239 -	      case EFI_CONVENTIONAL_MEMORY:
   3.240 -		return 1;
   3.241 -	}
   3.242 -	return 0;
   3.243 -}
   3.244 -
   3.245 -/*
   3.246 - * Trim descriptor MD so its starts at address START_ADDR.  If the descriptor covers
   3.247 - * memory that is normally available to the kernel, issue a warning that some memory
   3.248 - * is being ignored.
   3.249 - */
   3.250 -static void
   3.251 -trim_bottom (efi_memory_desc_t *md, u64 start_addr)
   3.252 -{
   3.253 -	u64 num_skipped_pages;
   3.254 -
   3.255 -	if (md->phys_addr >= start_addr || !md->num_pages)
   3.256 -		return;
   3.257 -
   3.258 -	num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
   3.259 -	if (num_skipped_pages > md->num_pages)
   3.260 -		num_skipped_pages = md->num_pages;
   3.261 -
   3.262 -	if (is_available_memory(md))
   3.263 -		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
   3.264 -		       "at 0x%lx\n", __FUNCTION__,
   3.265 -		       (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
   3.266 -		       md->phys_addr, start_addr - IA64_GRANULE_SIZE);
   3.267 -	/*
   3.268 -	 * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
   3.269 -	 * descriptor list to become unsorted.  In such a case, md->num_pages will be
   3.270 -	 * zero, so the Right Thing will happen.
   3.271 -	 */
   3.272 -	md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
   3.273 -	md->num_pages -= num_skipped_pages;
   3.274 -}
   3.275 -
   3.276 -static void
   3.277 -trim_top (efi_memory_desc_t *md, u64 end_addr)
   3.278 -{
   3.279 -	u64 num_dropped_pages, md_end_addr;
   3.280 -
   3.281 -	md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   3.282 -
   3.283 -	if (md_end_addr <= end_addr || !md->num_pages)
   3.284 -		return;
   3.285 -
   3.286 -	num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
   3.287 -	if (num_dropped_pages > md->num_pages)
   3.288 -		num_dropped_pages = md->num_pages;
   3.289 -
   3.290 -	if (is_available_memory(md))
   3.291 -		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
   3.292 -		       "at 0x%lx\n", __FUNCTION__,
   3.293 -		       (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
   3.294 -		       md->phys_addr, end_addr);
   3.295 -	md->num_pages -= num_dropped_pages;
   3.296 -}
   3.297 -
   3.298 -/*
   3.299 - * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
   3.300 - * has memory that is available for OS use.
   3.301 - */
   3.302 -void
   3.303 -efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
   3.304 -{
   3.305 -	int prev_valid = 0;
   3.306 -	struct range {
   3.307 -		u64 start;
   3.308 -		u64 end;
   3.309 -	} prev, curr;
   3.310 -	void *efi_map_start, *efi_map_end, *p, *q;
   3.311 -	efi_memory_desc_t *md, *check_md;
   3.312 -	u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
   3.313 -	unsigned long total_mem = 0;
   3.314 -
   3.315 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.316 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.317 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.318 -
   3.319 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.320 -		md = p;
   3.321 -
   3.322 -		/* skip over non-WB memory descriptors; that's all we're interested in... */
   3.323 -		if (!(md->attribute & EFI_MEMORY_WB))
   3.324 -			continue;
   3.325 -
   3.326 -#ifdef XEN
   3.327 -// this works around a problem in the ski bootloader
   3.328 -{
   3.329 -		extern long running_on_sim;
   3.330 -		if (running_on_sim && md->type != EFI_CONVENTIONAL_MEMORY)
   3.331 -			continue;
   3.332 -}
   3.333 -// this is a temporary hack to avoid CONFIG_VIRTUAL_MEM_MAP
   3.334 -		if (md->phys_addr >= 0x100000000) continue;
   3.335 -#endif
   3.336 -		/*
   3.337 -		 * granule_addr is the base of md's first granule.
   3.338 -		 * [granule_addr - first_non_wb_addr) is guaranteed to
   3.339 -		 * be contiguous WB memory.
   3.340 -		 */
   3.341 -		granule_addr = GRANULEROUNDDOWN(md->phys_addr);
   3.342 -		first_non_wb_addr = max(first_non_wb_addr, granule_addr);
   3.343 -
   3.344 -		if (first_non_wb_addr < md->phys_addr) {
   3.345 -			trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
   3.346 -			granule_addr = GRANULEROUNDDOWN(md->phys_addr);
   3.347 -			first_non_wb_addr = max(first_non_wb_addr, granule_addr);
   3.348 -		}
   3.349 -
   3.350 -		for (q = p; q < efi_map_end; q += efi_desc_size) {
   3.351 -			check_md = q;
   3.352 -
   3.353 -			if ((check_md->attribute & EFI_MEMORY_WB) &&
   3.354 -			    (check_md->phys_addr == first_non_wb_addr))
   3.355 -				first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
   3.356 -			else
   3.357 -				break;		/* non-WB or hole */
   3.358 -		}
   3.359 -
   3.360 -		last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
   3.361 -		if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
   3.362 -			trim_top(md, last_granule_addr);
   3.363 -
   3.364 -		if (is_available_memory(md)) {
   3.365 -			if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
   3.366 -				if (md->phys_addr >= max_addr)
   3.367 -					continue;
   3.368 -				md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
   3.369 -				first_non_wb_addr = max_addr;
   3.370 -			}
   3.371 -
   3.372 -			if (total_mem >= mem_limit)
   3.373 -				continue;
   3.374 -
   3.375 -			if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
   3.376 -				unsigned long limit_addr = md->phys_addr;
   3.377 -
   3.378 -				limit_addr += mem_limit - total_mem;
   3.379 -				limit_addr = GRANULEROUNDDOWN(limit_addr);
   3.380 -
   3.381 -				if (md->phys_addr > limit_addr)
   3.382 -					continue;
   3.383 -
   3.384 -				md->num_pages = (limit_addr - md->phys_addr) >>
   3.385 -				                EFI_PAGE_SHIFT;
   3.386 -				first_non_wb_addr = max_addr = md->phys_addr +
   3.387 -				              (md->num_pages << EFI_PAGE_SHIFT);
   3.388 -			}
   3.389 -			total_mem += (md->num_pages << EFI_PAGE_SHIFT);
   3.390 -
   3.391 -			if (md->num_pages == 0)
   3.392 -				continue;
   3.393 -
   3.394 -			curr.start = PAGE_OFFSET + md->phys_addr;
   3.395 -			curr.end   = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
   3.396 -
   3.397 -			if (!prev_valid) {
   3.398 -				prev = curr;
   3.399 -				prev_valid = 1;
   3.400 -			} else {
   3.401 -				if (curr.start < prev.start)
   3.402 -					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
   3.403 -
   3.404 -				if (prev.end == curr.start) {
   3.405 -					/* merge two consecutive memory ranges */
   3.406 -					prev.end = curr.end;
   3.407 -				} else {
   3.408 -					start = PAGE_ALIGN(prev.start);
   3.409 -					end = prev.end & PAGE_MASK;
   3.410 -					if ((end > start) && (*callback)(start, end, arg) < 0)
   3.411 -						return;
   3.412 -					prev = curr;
   3.413 -				}
   3.414 -			}
   3.415 -		}
   3.416 -	}
   3.417 -	if (prev_valid) {
   3.418 -		start = PAGE_ALIGN(prev.start);
   3.419 -		end = prev.end & PAGE_MASK;
   3.420 -		if (end > start)
   3.421 -			(*callback)(start, end, arg);
   3.422 -	}
   3.423 -}
   3.424 -
   3.425 -/*
   3.426 - * Look for the PAL_CODE region reported by EFI and maps it using an
   3.427 - * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
   3.428 - * Abstraction Layer chapter 11 in ADAG
   3.429 - */
   3.430 -
   3.431 -void *
   3.432 -efi_get_pal_addr (void)
   3.433 -{
   3.434 -	void *efi_map_start, *efi_map_end, *p;
   3.435 -	efi_memory_desc_t *md;
   3.436 -	u64 efi_desc_size;
   3.437 -	int pal_code_count = 0;
   3.438 -	u64 vaddr, mask;
   3.439 -
   3.440 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.441 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.442 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.443 -
   3.444 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.445 -		md = p;
   3.446 -		if (md->type != EFI_PAL_CODE)
   3.447 -			continue;
   3.448 -
   3.449 -		if (++pal_code_count > 1) {
   3.450 -			printk(KERN_ERR "Too many EFI Pal Code memory ranges, dropped @ %lx\n",
   3.451 -			       md->phys_addr);
   3.452 -			continue;
   3.453 -		}
   3.454 -		/*
   3.455 -		 * The only ITLB entry in region 7 that is used is the one installed by
   3.456 -		 * __start().  That entry covers a 64MB range.
   3.457 -		 */
   3.458 -		mask  = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1);
   3.459 -		vaddr = PAGE_OFFSET + md->phys_addr;
   3.460 -
   3.461 -		/*
   3.462 -		 * We must check that the PAL mapping won't overlap with the kernel
   3.463 -		 * mapping.
   3.464 -		 *
   3.465 -		 * PAL code is guaranteed to be aligned on a power of 2 between 4k and
   3.466 -		 * 256KB and that only one ITR is needed to map it. This implies that the
   3.467 -		 * PAL code is always aligned on its size, i.e., the closest matching page
   3.468 -		 * size supported by the TLB. Therefore PAL code is guaranteed never to
   3.469 -		 * cross a 64MB unless it is bigger than 64MB (very unlikely!).  So for
   3.470 -		 * now the following test is enough to determine whether or not we need a
   3.471 -		 * dedicated ITR for the PAL code.
   3.472 -		 */
   3.473 -		if ((vaddr & mask) == (KERNEL_START & mask)) {
   3.474 -			printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
   3.475 -			       __FUNCTION__);
   3.476 -			continue;
   3.477 -		}
   3.478 -
   3.479 -		if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE)
   3.480 -			panic("Woah!  PAL code size bigger than a granule!");
   3.481 -
   3.482 -#if EFI_DEBUG
   3.483 -		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
   3.484 -
   3.485 -		printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
   3.486 -			smp_processor_id(), md->phys_addr,
   3.487 -			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   3.488 -			vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
   3.489 -#endif
   3.490 -		return __va(md->phys_addr);
   3.491 -	}
   3.492 -	printk(KERN_WARNING "%s: no PAL-code memory-descriptor found",
   3.493 -	       __FUNCTION__);
   3.494 -	return NULL;
   3.495 -}
   3.496 -
   3.497 -void
   3.498 -efi_map_pal_code (void)
   3.499 -{
   3.500 -	void *pal_vaddr = efi_get_pal_addr ();
   3.501 -	u64 psr;
   3.502 -
   3.503 -	if (!pal_vaddr)
   3.504 -		return;
   3.505 -
   3.506 -	/*
   3.507 -	 * Cannot write to CRx with PSR.ic=1
   3.508 -	 */
   3.509 -	psr = ia64_clear_ic();
   3.510 -	ia64_itr(0x1, IA64_TR_PALCODE, GRANULEROUNDDOWN((unsigned long) pal_vaddr),
   3.511 -		 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
   3.512 -		 IA64_GRANULE_SHIFT);
   3.513 -	ia64_set_psr(psr);		/* restore psr */
   3.514 -	ia64_srlz_i();
   3.515 -}
   3.516 -
   3.517 -void __init
   3.518 -efi_init (void)
   3.519 -{
   3.520 -	void *efi_map_start, *efi_map_end;
   3.521 -	efi_config_table_t *config_tables;
   3.522 -	efi_char16_t *c16;
   3.523 -	u64 efi_desc_size;
   3.524 -	char *cp, *end, vendor[100] = "unknown";
   3.525 -	extern char saved_command_line[];
   3.526 -	int i;
   3.527 -
   3.528 -	/* it's too early to be able to use the standard kernel command line support... */
   3.529 -	for (cp = saved_command_line; *cp; ) {
   3.530 -		if (memcmp(cp, "mem=", 4) == 0) {
   3.531 -			cp += 4;
   3.532 -			mem_limit = memparse(cp, &end);
   3.533 -			if (end != cp)
   3.534 -				break;
   3.535 -			cp = end;
   3.536 -		} else if (memcmp(cp, "max_addr=", 9) == 0) {
   3.537 -			cp += 9;
   3.538 -			max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
   3.539 -			if (end != cp)
   3.540 -				break;
   3.541 -			cp = end;
   3.542 -		} else {
   3.543 -			while (*cp != ' ' && *cp)
   3.544 -				++cp;
   3.545 -			while (*cp == ' ')
   3.546 -				++cp;
   3.547 -		}
   3.548 -	}
   3.549 -	if (max_addr != ~0UL)
   3.550 -		printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20);
   3.551 -
   3.552 -	efi.systab = __va(ia64_boot_param->efi_systab);
   3.553 -
   3.554 -	/*
   3.555 -	 * Verify the EFI Table
   3.556 -	 */
   3.557 -	if (efi.systab == NULL)
   3.558 -		panic("Woah! Can't find EFI system table.\n");
   3.559 -	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
   3.560 -		panic("Woah! EFI system table signature incorrect\n");
   3.561 -	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
   3.562 -		printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
   3.563 -		       "got %d.%02d, expected %d.%02d\n",
   3.564 -		       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
   3.565 -		       EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
   3.566 -
   3.567 -	config_tables = __va(efi.systab->tables);
   3.568 -
   3.569 -	/* Show what we know for posterity */
   3.570 -	c16 = __va(efi.systab->fw_vendor);
   3.571 -	if (c16) {
   3.572 -		for (i = 0;i < (int) sizeof(vendor) && *c16; ++i)
   3.573 -			vendor[i] = *c16++;
   3.574 -		vendor[i] = '\0';
   3.575 -	}
   3.576 -
   3.577 -	printk(KERN_INFO "EFI v%u.%.02u by %s:",
   3.578 -	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
   3.579 -
   3.580 -	for (i = 0; i < (int) efi.systab->nr_tables; i++) {
   3.581 -		if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
   3.582 -			efi.mps = __va(config_tables[i].table);
   3.583 -			printk(" MPS=0x%lx", config_tables[i].table);
   3.584 -		} else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
   3.585 -			efi.acpi20 = __va(config_tables[i].table);
   3.586 -			printk(" ACPI 2.0=0x%lx", config_tables[i].table);
   3.587 -		} else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
   3.588 -			efi.acpi = __va(config_tables[i].table);
   3.589 -			printk(" ACPI=0x%lx", config_tables[i].table);
   3.590 -		} else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
   3.591 -			efi.smbios = __va(config_tables[i].table);
   3.592 -			printk(" SMBIOS=0x%lx", config_tables[i].table);
   3.593 -		} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
   3.594 -			efi.sal_systab = __va(config_tables[i].table);
   3.595 -			printk(" SALsystab=0x%lx", config_tables[i].table);
   3.596 -		} else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
   3.597 -			efi.hcdp = __va(config_tables[i].table);
   3.598 -			printk(" HCDP=0x%lx", config_tables[i].table);
   3.599 -		}
   3.600 -	}
   3.601 -	printk("\n");
   3.602 -
   3.603 -	runtime = __va(efi.systab->runtime);
   3.604 -	efi.get_time = phys_get_time;
   3.605 -	efi.set_time = phys_set_time;
   3.606 -	efi.get_wakeup_time = phys_get_wakeup_time;
   3.607 -	efi.set_wakeup_time = phys_set_wakeup_time;
   3.608 -	efi.get_variable = phys_get_variable;
   3.609 -	efi.get_next_variable = phys_get_next_variable;
   3.610 -	efi.set_variable = phys_set_variable;
   3.611 -	efi.get_next_high_mono_count = phys_get_next_high_mono_count;
   3.612 -	efi.reset_system = phys_reset_system;
   3.613 -
   3.614 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.615 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.616 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.617 -
   3.618 -#if EFI_DEBUG
   3.619 -	/* print EFI memory map: */
   3.620 -	{
   3.621 -		efi_memory_desc_t *md;
   3.622 -		void *p;
   3.623 -
   3.624 -		for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
   3.625 -			md = p;
   3.626 -			printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
   3.627 -			       i, md->type, md->attribute, md->phys_addr,
   3.628 -			       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   3.629 -			       md->num_pages >> (20 - EFI_PAGE_SHIFT));
   3.630 -		}
   3.631 -	}
   3.632 -#endif
   3.633 -
   3.634 -	efi_map_pal_code();
   3.635 -	efi_enter_virtual_mode();
   3.636 -}
   3.637 -
   3.638 -void
   3.639 -efi_enter_virtual_mode (void)
   3.640 -{
   3.641 -	void *efi_map_start, *efi_map_end, *p;
   3.642 -	efi_memory_desc_t *md;
   3.643 -	efi_status_t status;
   3.644 -	u64 efi_desc_size;
   3.645 -
   3.646 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.647 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.648 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.649 -
   3.650 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.651 -		md = p;
   3.652 -		if (md->attribute & EFI_MEMORY_RUNTIME) {
   3.653 -			/*
   3.654 -			 * Some descriptors have multiple bits set, so the order of
   3.655 -			 * the tests is relevant.
   3.656 -			 */
   3.657 -			if (md->attribute & EFI_MEMORY_WB) {
   3.658 -				md->virt_addr = (u64) __va(md->phys_addr);
   3.659 -			} else if (md->attribute & EFI_MEMORY_UC) {
   3.660 -				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   3.661 -			} else if (md->attribute & EFI_MEMORY_WC) {
   3.662 -#if 0
   3.663 -				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
   3.664 -									   | _PAGE_D
   3.665 -									   | _PAGE_MA_WC
   3.666 -									   | _PAGE_PL_0
   3.667 -									   | _PAGE_AR_RW));
   3.668 -#else
   3.669 -				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
   3.670 -				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   3.671 -#endif
   3.672 -			} else if (md->attribute & EFI_MEMORY_WT) {
   3.673 -#if 0
   3.674 -				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
   3.675 -									   | _PAGE_D | _PAGE_MA_WT
   3.676 -									   | _PAGE_PL_0
   3.677 -									   | _PAGE_AR_RW));
   3.678 -#else
   3.679 -				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
   3.680 -				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   3.681 -#endif
   3.682 -			}
   3.683 -		}
   3.684 -	}
   3.685 -
   3.686 -	status = efi_call_phys(__va(runtime->set_virtual_address_map),
   3.687 -			       ia64_boot_param->efi_memmap_size,
   3.688 -			       efi_desc_size, ia64_boot_param->efi_memdesc_version,
   3.689 -			       ia64_boot_param->efi_memmap);
   3.690 -	if (status != EFI_SUCCESS) {
   3.691 -		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode "
   3.692 -		       "(status=%lu)\n", status);
   3.693 -		return;
   3.694 -	}
   3.695 -
   3.696 -	/*
   3.697 -	 * Now that EFI is in virtual mode, we call the EFI functions more efficiently:
   3.698 -	 */
   3.699 -	efi.get_time = virt_get_time;
   3.700 -	efi.set_time = virt_set_time;
   3.701 -	efi.get_wakeup_time = virt_get_wakeup_time;
   3.702 -	efi.set_wakeup_time = virt_set_wakeup_time;
   3.703 -	efi.get_variable = virt_get_variable;
   3.704 -	efi.get_next_variable = virt_get_next_variable;
   3.705 -	efi.set_variable = virt_set_variable;
   3.706 -	efi.get_next_high_mono_count = virt_get_next_high_mono_count;
   3.707 -	efi.reset_system = virt_reset_system;
   3.708 -}
   3.709 -
   3.710 -/*
   3.711 - * Walk the EFI memory map looking for the I/O port range.  There can only be one entry of
   3.712 - * this type, other I/O port ranges should be described via ACPI.
   3.713 - */
   3.714 -u64
   3.715 -efi_get_iobase (void)
   3.716 -{
   3.717 -	void *efi_map_start, *efi_map_end, *p;
   3.718 -	efi_memory_desc_t *md;
   3.719 -	u64 efi_desc_size;
   3.720 -
   3.721 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.722 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.723 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.724 -
   3.725 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.726 -		md = p;
   3.727 -		if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
   3.728 -			if (md->attribute & EFI_MEMORY_UC)
   3.729 -				return md->phys_addr;
   3.730 -		}
   3.731 -	}
   3.732 -	return 0;
   3.733 -}
   3.734 -
   3.735 -#ifdef XEN
   3.736 -// variation of efi_get_iobase which returns entire memory descriptor
   3.737 -efi_memory_desc_t *
   3.738 -efi_get_io_md (void)
   3.739 -{
   3.740 -	void *efi_map_start, *efi_map_end, *p;
   3.741 -	efi_memory_desc_t *md;
   3.742 -	u64 efi_desc_size;
   3.743 -
   3.744 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.745 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.746 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.747 -
   3.748 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.749 -		md = p;
   3.750 -		if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
   3.751 -			if (md->attribute & EFI_MEMORY_UC)
   3.752 -				return md;
   3.753 -		}
   3.754 -	}
   3.755 -	return 0;
   3.756 -}
   3.757 -#endif
   3.758 -
   3.759 -u32
   3.760 -efi_mem_type (unsigned long phys_addr)
   3.761 -{
   3.762 -	void *efi_map_start, *efi_map_end, *p;
   3.763 -	efi_memory_desc_t *md;
   3.764 -	u64 efi_desc_size;
   3.765 -
   3.766 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.767 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.768 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.769 -
   3.770 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.771 -		md = p;
   3.772 -
   3.773 -		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
   3.774 -			 return md->type;
   3.775 -	}
   3.776 -	return 0;
   3.777 -}
   3.778 -
   3.779 -u64
   3.780 -efi_mem_attributes (unsigned long phys_addr)
   3.781 -{
   3.782 -	void *efi_map_start, *efi_map_end, *p;
   3.783 -	efi_memory_desc_t *md;
   3.784 -	u64 efi_desc_size;
   3.785 -
   3.786 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.787 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.788 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.789 -
   3.790 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.791 -		md = p;
   3.792 -
   3.793 -		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
   3.794 -			return md->attribute;
   3.795 -	}
   3.796 -	return 0;
   3.797 -}
   3.798 -EXPORT_SYMBOL(efi_mem_attributes);
   3.799 -
   3.800 -int
   3.801 -valid_phys_addr_range (unsigned long phys_addr, unsigned long *size)
   3.802 -{
   3.803 -	void *efi_map_start, *efi_map_end, *p;
   3.804 -	efi_memory_desc_t *md;
   3.805 -	u64 efi_desc_size;
   3.806 -
   3.807 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   3.808 -	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   3.809 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   3.810 -
   3.811 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   3.812 -		md = p;
   3.813 -
   3.814 -		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) {
   3.815 -			if (!(md->attribute & EFI_MEMORY_WB))
   3.816 -				return 0;
   3.817 -
   3.818 -			if (*size > md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr)
   3.819 -				*size = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr;
   3.820 -			return 1;
   3.821 -		}
   3.822 -	}
   3.823 -	return 0;
   3.824 -}
   3.825 -
   3.826 -int __init
   3.827 -efi_uart_console_only(void)
   3.828 -{
   3.829 -	efi_status_t status;
   3.830 -	char *s, name[] = "ConOut";
   3.831 -	efi_guid_t guid = EFI_GLOBAL_VARIABLE_GUID;
   3.832 -	efi_char16_t *utf16, name_utf16[32];
   3.833 -	unsigned char data[1024];
   3.834 -	unsigned long size = sizeof(data);
   3.835 -	struct efi_generic_dev_path *hdr, *end_addr;
   3.836 -	int uart = 0;
   3.837 -
   3.838 -	/* Convert to UTF-16 */
   3.839 -	utf16 = name_utf16;
   3.840 -	s = name;
   3.841 -	while (*s)
   3.842 -		*utf16++ = *s++ & 0x7f;
   3.843 -	*utf16 = 0;
   3.844 -
   3.845 -	status = efi.get_variable(name_utf16, &guid, NULL, &size, data);
   3.846 -	if (status != EFI_SUCCESS) {
   3.847 -		printk(KERN_ERR "No EFI %s variable?\n", name);
   3.848 -		return 0;
   3.849 -	}
   3.850 -
   3.851 -	hdr = (struct efi_generic_dev_path *) data;
   3.852 -	end_addr = (struct efi_generic_dev_path *) ((u8 *) data + size);
   3.853 -	while (hdr < end_addr) {
   3.854 -		if (hdr->type == EFI_DEV_MSG &&
   3.855 -		    hdr->sub_type == EFI_DEV_MSG_UART)
   3.856 -			uart = 1;
   3.857 -		else if (hdr->type == EFI_DEV_END_PATH ||
   3.858 -			  hdr->type == EFI_DEV_END_PATH2) {
   3.859 -			if (!uart)
   3.860 -				return 0;
   3.861 -			if (hdr->sub_type == EFI_DEV_END_ENTIRE)
   3.862 -				return 1;
   3.863 -			uart = 0;
   3.864 -		}
   3.865 -		hdr = (struct efi_generic_dev_path *) ((u8 *) hdr + hdr->length);
   3.866 -	}
   3.867 -	printk(KERN_ERR "Malformed %s value\n", name);
   3.868 -	return 0;
   3.869 -}
     4.1 --- a/xen/arch/ia64/entry.S	Tue Aug 02 15:59:09 2005 -0800
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,1653 +0,0 @@
     4.4 -/*
     4.5 - * ia64/kernel/entry.S
     4.6 - *
     4.7 - * Kernel entry points.
     4.8 - *
     4.9 - * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
    4.10 - *	David Mosberger-Tang <davidm@hpl.hp.com>
    4.11 - * Copyright (C) 1999, 2002-2003
    4.12 - *	Asit Mallick <Asit.K.Mallick@intel.com>
    4.13 - * 	Don Dugger <Don.Dugger@intel.com>
    4.14 - *	Suresh Siddha <suresh.b.siddha@intel.com>
    4.15 - *	Fenghua Yu <fenghua.yu@intel.com>
    4.16 - * Copyright (C) 1999 VA Linux Systems
    4.17 - * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    4.18 - */
    4.19 -/*
    4.20 - * ia64_switch_to now places correct virtual mapping in in TR2 for
    4.21 - * kernel stack. This allows us to handle interrupts without changing
    4.22 - * to physical mode.
    4.23 - *
    4.24 - * Jonathan Nicklin	<nicklin@missioncriticallinux.com>
    4.25 - * Patrick O'Rourke	<orourke@missioncriticallinux.com>
    4.26 - * 11/07/2000
    4.27 - */
    4.28 -/*
    4.29 - * Global (preserved) predicate usage on syscall entry/exit path:
    4.30 - *
    4.31 - *	pKStk:		See entry.h.
    4.32 - *	pUStk:		See entry.h.
    4.33 - *	pSys:		See entry.h.
    4.34 - *	pNonSys:	!pSys
    4.35 - */
    4.36 -
    4.37 -#include <linux/config.h>
    4.38 -
    4.39 -#include <asm/asmmacro.h>
    4.40 -#include <asm/cache.h>
    4.41 -#include <asm/errno.h>
    4.42 -#include <asm/kregs.h>
    4.43 -#include <asm/offsets.h>
    4.44 -#include <asm/pgtable.h>
    4.45 -#include <asm/percpu.h>
    4.46 -#include <asm/processor.h>
    4.47 -#include <asm/thread_info.h>
    4.48 -#include <asm/unistd.h>
    4.49 -
    4.50 -#include "minstate.h"
    4.51 -
    4.52 -#ifndef XEN
    4.53 -	/*
    4.54 -	 * execve() is special because in case of success, we need to
    4.55 -	 * setup a null register window frame.
    4.56 -	 */
    4.57 -ENTRY(ia64_execve)
    4.58 -	/*
    4.59 -	 * Allocate 8 input registers since ptrace() may clobber them
    4.60 -	 */
    4.61 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
    4.62 -	alloc loc1=ar.pfs,8,2,4,0
    4.63 -	mov loc0=rp
    4.64 -	.body
    4.65 -	mov out0=in0			// filename
    4.66 -	;;				// stop bit between alloc and call
    4.67 -	mov out1=in1			// argv
    4.68 -	mov out2=in2			// envp
    4.69 -	add out3=16,sp			// regs
    4.70 -	br.call.sptk.many rp=sys_execve
    4.71 -.ret0:
    4.72 -#ifdef CONFIG_IA32_SUPPORT
    4.73 -	/*
    4.74 -	 * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers
    4.75 -	 * from pt_regs.
    4.76 -	 */
    4.77 -	adds r16=PT(CR_IPSR)+16,sp
    4.78 -	;;
    4.79 -	ld8 r16=[r16]
    4.80 -#endif
    4.81 -	cmp4.ge p6,p7=r8,r0
    4.82 -	mov ar.pfs=loc1			// restore ar.pfs
    4.83 -	sxt4 r8=r8			// return 64-bit result
    4.84 -	;;
    4.85 -	stf.spill [sp]=f0
    4.86 -(p6)	cmp.ne pKStk,pUStk=r0,r0	// a successful execve() lands us in user-mode...
    4.87 -	mov rp=loc0
    4.88 -(p6)	mov ar.pfs=r0			// clear ar.pfs on success
    4.89 -(p7)	br.ret.sptk.many rp
    4.90 -
    4.91 -	/*
    4.92 -	 * In theory, we'd have to zap this state only to prevent leaking of
    4.93 -	 * security sensitive state (e.g., if current->mm->dumpable is zero).  However,
    4.94 -	 * this executes in less than 20 cycles even on Itanium, so it's not worth
    4.95 -	 * optimizing for...).
    4.96 -	 */
    4.97 -	mov ar.unat=0; 		mov ar.lc=0
    4.98 -	mov r4=0;		mov f2=f0;		mov b1=r0
    4.99 -	mov r5=0;		mov f3=f0;		mov b2=r0
   4.100 -	mov r6=0;		mov f4=f0;		mov b3=r0
   4.101 -	mov r7=0;		mov f5=f0;		mov b4=r0
   4.102 -	ldf.fill f12=[sp];	mov f13=f0;		mov b5=r0
   4.103 -	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
   4.104 -	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
   4.105 -	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
   4.106 -	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
   4.107 -	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
   4.108 -	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
   4.109 -#ifdef CONFIG_IA32_SUPPORT
   4.110 -	tbit.nz p6,p0=r16, IA64_PSR_IS_BIT
   4.111 -	movl loc0=ia64_ret_from_ia32_execve
   4.112 -	;;
   4.113 -(p6)	mov rp=loc0
   4.114 -#endif
   4.115 -	br.ret.sptk.many rp
   4.116 -END(ia64_execve)
   4.117 -
   4.118 -/*
   4.119 - * sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 parent_tidptr, u64 child_tidptr,
   4.120 - *	      u64 tls)
   4.121 - */
   4.122 -GLOBAL_ENTRY(sys_clone2)
   4.123 -	/*
   4.124 -	 * Allocate 8 input registers since ptrace() may clobber them
   4.125 -	 */
   4.126 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
   4.127 -	alloc r16=ar.pfs,8,2,6,0
   4.128 -	DO_SAVE_SWITCH_STACK
   4.129 -	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
   4.130 -	mov loc0=rp
   4.131 -	mov loc1=r16				// save ar.pfs across do_fork
   4.132 -	.body
   4.133 -	mov out1=in1
   4.134 -	mov out3=in2
   4.135 -	tbit.nz p6,p0=in0,CLONE_SETTLS_BIT
   4.136 -	mov out4=in3	// parent_tidptr: valid only w/CLONE_PARENT_SETTID
   4.137 -	;;
   4.138 -(p6)	st8 [r2]=in5				// store TLS in r16 for copy_thread()
   4.139 -	mov out5=in4	// child_tidptr:  valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
   4.140 -	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
   4.141 -	mov out0=in0				// out0 = clone_flags
   4.142 -	br.call.sptk.many rp=do_fork
   4.143 -.ret1:	.restore sp
   4.144 -	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
   4.145 -	mov ar.pfs=loc1
   4.146 -	mov rp=loc0
   4.147 -	br.ret.sptk.many rp
   4.148 -END(sys_clone2)
   4.149 -
   4.150 -/*
   4.151 - * sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
   4.152 - *	Deprecated.  Use sys_clone2() instead.
   4.153 - */
   4.154 -GLOBAL_ENTRY(sys_clone)
   4.155 -	/*
   4.156 -	 * Allocate 8 input registers since ptrace() may clobber them
   4.157 -	 */
   4.158 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
   4.159 -	alloc r16=ar.pfs,8,2,6,0
   4.160 -	DO_SAVE_SWITCH_STACK
   4.161 -	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
   4.162 -	mov loc0=rp
   4.163 -	mov loc1=r16				// save ar.pfs across do_fork
   4.164 -	.body
   4.165 -	mov out1=in1
   4.166 -	mov out3=16				// stacksize (compensates for 16-byte scratch area)
   4.167 -	tbit.nz p6,p0=in0,CLONE_SETTLS_BIT
   4.168 -	mov out4=in2	// parent_tidptr: valid only w/CLONE_PARENT_SETTID
   4.169 -	;;
   4.170 -(p6)	st8 [r2]=in4				// store TLS in r13 (tp)
   4.171 -	mov out5=in3	// child_tidptr:  valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
   4.172 -	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
   4.173 -	mov out0=in0				// out0 = clone_flags
   4.174 -	br.call.sptk.many rp=do_fork
   4.175 -.ret2:	.restore sp
   4.176 -	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
   4.177 -	mov ar.pfs=loc1
   4.178 -	mov rp=loc0
   4.179 -	br.ret.sptk.many rp
   4.180 -END(sys_clone)
   4.181 -#endif /* !XEN */
   4.182 -
   4.183 -/*
   4.184 - * prev_task <- ia64_switch_to(struct task_struct *next)
   4.185 - *	With Ingo's new scheduler, interrupts are disabled when this routine gets
   4.186 - *	called.  The code starting at .map relies on this.  The rest of the code
   4.187 - *	doesn't care about the interrupt masking status.
   4.188 - */
   4.189 -GLOBAL_ENTRY(ia64_switch_to)
   4.190 -	.prologue
   4.191 -	alloc r16=ar.pfs,1,0,0,0
   4.192 -	DO_SAVE_SWITCH_STACK
   4.193 -	.body
   4.194 -
   4.195 -	adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
   4.196 -	movl r25=init_task
   4.197 -	mov r27=IA64_KR(CURRENT_STACK)
   4.198 -	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
   4.199 -#ifdef XEN
   4.200 -	dep r20=0,in0,60,4		// physical address of "next"
   4.201 -#else
   4.202 -	dep r20=0,in0,61,3		// physical address of "next"
   4.203 -#endif
   4.204 -	;;
   4.205 -	st8 [r22]=sp			// save kernel stack pointer of old task
   4.206 -	shr.u r26=r20,IA64_GRANULE_SHIFT
   4.207 -	cmp.eq p7,p6=r25,in0
   4.208 -	;;
   4.209 -	/*
   4.210 -	 * If we've already mapped this task's page, we can skip doing it again.
   4.211 -	 */
   4.212 -(p6)	cmp.eq p7,p6=r26,r27
   4.213 -(p6)	br.cond.dpnt .map
   4.214 -	;;
   4.215 -.done:
   4.216 -(p6)	ssm psr.ic			// if we had to map, reenable the psr.ic bit FIRST!!!
   4.217 -	;;
   4.218 -(p6)	srlz.d
   4.219 -	ld8 sp=[r21]			// load kernel stack pointer of new task
   4.220 -	mov IA64_KR(CURRENT)=in0	// update "current" application register
   4.221 -	mov r8=r13			// return pointer to previously running task
   4.222 -	mov r13=in0			// set "current" pointer
   4.223 -	;;
   4.224 -	DO_LOAD_SWITCH_STACK
   4.225 -
   4.226 -#ifdef CONFIG_SMP
   4.227 -	sync.i				// ensure "fc"s done by this CPU are visible on other CPUs
   4.228 -#endif
   4.229 -	br.ret.sptk.many rp		// boogie on out in new context
   4.230 -
   4.231 -.map:
   4.232 -#ifdef XEN
   4.233 -	// avoid overlapping with kernel TR
   4.234 -	movl r25=KERNEL_START
   4.235 -	dep  r23=0,in0,0,KERNEL_TR_PAGE_SHIFT
   4.236 -	;;
   4.237 -	cmp.eq p7,p0=r25,r23
   4.238 -	;;
   4.239 -(p7)	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
   4.240 -(p7)	br.cond.sptk .done
   4.241 -#endif
   4.242 -	rsm psr.ic			// interrupts (psr.i) are already disabled here
   4.243 -	movl r25=PAGE_KERNEL
   4.244 -	;;
   4.245 -	srlz.d
   4.246 -	or r23=r25,r20			// construct PA | page properties
   4.247 -	mov r25=IA64_GRANULE_SHIFT<<2
   4.248 -	;;
   4.249 -	mov cr.itir=r25
   4.250 -	mov cr.ifa=in0			// VA of next task...
   4.251 -	;;
   4.252 -	mov r25=IA64_TR_CURRENT_STACK
   4.253 -	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
   4.254 -	;;
   4.255 -	itr.d dtr[r25]=r23		// wire in new mapping...
   4.256 -	br.cond.sptk .done
   4.257 -END(ia64_switch_to)
   4.258 -
   4.259 -/*
   4.260 - * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
   4.261 - * means that we may get an interrupt with "sp" pointing to the new kernel stack while
   4.262 - * ar.bspstore is still pointing to the old kernel backing store area.  Since ar.rsc,
   4.263 - * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts, this is not a
   4.264 - * problem.  Also, we don't need to specify unwind information for preserved registers
   4.265 - * that are not modified in save_switch_stack as the right unwind information is already
   4.266 - * specified at the call-site of save_switch_stack.
   4.267 - */
   4.268 -
   4.269 -/*
   4.270 - * save_switch_stack:
   4.271 - *	- r16 holds ar.pfs
   4.272 - *	- b7 holds address to return to
   4.273 - *	- rp (b0) holds return address to save
   4.274 - */
   4.275 -GLOBAL_ENTRY(save_switch_stack)
   4.276 -	.prologue
   4.277 -	.altrp b7
   4.278 -	flushrs			// flush dirty regs to backing store (must be first in insn group)
   4.279 -	.save @priunat,r17
   4.280 -	mov r17=ar.unat		// preserve caller's
   4.281 -	.body
   4.282 -#ifdef CONFIG_ITANIUM
   4.283 -	adds r2=16+128,sp
   4.284 -	adds r3=16+64,sp
   4.285 -	adds r14=SW(R4)+16,sp
   4.286 -	;;
   4.287 -	st8.spill [r14]=r4,16		// spill r4
   4.288 -	lfetch.fault.excl.nt1 [r3],128
   4.289 -	;;
   4.290 -	lfetch.fault.excl.nt1 [r2],128
   4.291 -	lfetch.fault.excl.nt1 [r3],128
   4.292 -	;;
   4.293 -	lfetch.fault.excl [r2]
   4.294 -	lfetch.fault.excl [r3]
   4.295 -	adds r15=SW(R5)+16,sp
   4.296 -#else
   4.297 -	add r2=16+3*128,sp
   4.298 -	add r3=16,sp
   4.299 -	add r14=SW(R4)+16,sp
   4.300 -	;;
   4.301 -	st8.spill [r14]=r4,SW(R6)-SW(R4)	// spill r4 and prefetch offset 0x1c0
   4.302 -	lfetch.fault.excl.nt1 [r3],128	//		prefetch offset 0x010
   4.303 -	;;
   4.304 -	lfetch.fault.excl.nt1 [r3],128	//		prefetch offset 0x090
   4.305 -	lfetch.fault.excl.nt1 [r2],128	//		prefetch offset 0x190
   4.306 -	;;
   4.307 -	lfetch.fault.excl.nt1 [r3]	//		prefetch offset 0x110
   4.308 -	lfetch.fault.excl.nt1 [r2]	//		prefetch offset 0x210
   4.309 -	adds r15=SW(R5)+16,sp
   4.310 -#endif
   4.311 -	;;
   4.312 -	st8.spill [r15]=r5,SW(R7)-SW(R5)	// spill r5
   4.313 -	mov.m ar.rsc=0			// put RSE in mode: enforced lazy, little endian, pl 0
   4.314 -	add r2=SW(F2)+16,sp		// r2 = &sw->f2
   4.315 -	;;
   4.316 -	st8.spill [r14]=r6,SW(B0)-SW(R6)	// spill r6
   4.317 -	mov.m r18=ar.fpsr		// preserve fpsr
   4.318 -	add r3=SW(F3)+16,sp		// r3 = &sw->f3
   4.319 -	;;
   4.320 -	stf.spill [r2]=f2,32
   4.321 -	mov.m r19=ar.rnat
   4.322 -	mov r21=b0
   4.323 -
   4.324 -	stf.spill [r3]=f3,32
   4.325 -	st8.spill [r15]=r7,SW(B2)-SW(R7)	// spill r7
   4.326 -	mov r22=b1
   4.327 -	;;
   4.328 -	// since we're done with the spills, read and save ar.unat:
   4.329 -	mov.m r29=ar.unat
   4.330 -	mov.m r20=ar.bspstore
   4.331 -	mov r23=b2
   4.332 -	stf.spill [r2]=f4,32
   4.333 -	stf.spill [r3]=f5,32
   4.334 -	mov r24=b3
   4.335 -	;;
   4.336 -	st8 [r14]=r21,SW(B1)-SW(B0)		// save b0
   4.337 -	st8 [r15]=r23,SW(B3)-SW(B2)		// save b2
   4.338 -	mov r25=b4
   4.339 -	mov r26=b5
   4.340 -	;;
   4.341 -	st8 [r14]=r22,SW(B4)-SW(B1)		// save b1
   4.342 -	st8 [r15]=r24,SW(AR_PFS)-SW(B3)		// save b3
   4.343 -	mov r21=ar.lc		// I-unit
   4.344 -	stf.spill [r2]=f12,32
   4.345 -	stf.spill [r3]=f13,32
   4.346 -	;;
   4.347 -	st8 [r14]=r25,SW(B5)-SW(B4)		// save b4
   4.348 -	st8 [r15]=r16,SW(AR_LC)-SW(AR_PFS)	// save ar.pfs
   4.349 -	stf.spill [r2]=f14,32
   4.350 -	stf.spill [r3]=f15,32
   4.351 -	;;
   4.352 -	st8 [r14]=r26				// save b5
   4.353 -	st8 [r15]=r21				// save ar.lc
   4.354 -	stf.spill [r2]=f16,32
   4.355 -	stf.spill [r3]=f17,32
   4.356 -	;;
   4.357 -	stf.spill [r2]=f18,32
   4.358 -	stf.spill [r3]=f19,32
   4.359 -	;;
   4.360 -	stf.spill [r2]=f20,32
   4.361 -	stf.spill [r3]=f21,32
   4.362 -	;;
   4.363 -	stf.spill [r2]=f22,32
   4.364 -	stf.spill [r3]=f23,32
   4.365 -	;;
   4.366 -	stf.spill [r2]=f24,32
   4.367 -	stf.spill [r3]=f25,32
   4.368 -	;;
   4.369 -	stf.spill [r2]=f26,32
   4.370 -	stf.spill [r3]=f27,32
   4.371 -	;;
   4.372 -	stf.spill [r2]=f28,32
   4.373 -	stf.spill [r3]=f29,32
   4.374 -	;;
   4.375 -	stf.spill [r2]=f30,SW(AR_UNAT)-SW(F30)
   4.376 -	stf.spill [r3]=f31,SW(PR)-SW(F31)
   4.377 -	add r14=SW(CALLER_UNAT)+16,sp
   4.378 -	;;
   4.379 -	st8 [r2]=r29,SW(AR_RNAT)-SW(AR_UNAT)	// save ar.unat
   4.380 -	st8 [r14]=r17,SW(AR_FPSR)-SW(CALLER_UNAT) // save caller_unat
   4.381 -	mov r21=pr
   4.382 -	;;
   4.383 -	st8 [r2]=r19,SW(AR_BSPSTORE)-SW(AR_RNAT) // save ar.rnat
   4.384 -	st8 [r3]=r21				// save predicate registers
   4.385 -	;;
   4.386 -	st8 [r2]=r20				// save ar.bspstore
   4.387 -	st8 [r14]=r18				// save fpsr
   4.388 -	mov ar.rsc=3		// put RSE back into eager mode, pl 0
   4.389 -	br.cond.sptk.many b7
   4.390 -END(save_switch_stack)
   4.391 -
   4.392 -/*
   4.393 - * load_switch_stack:
   4.394 - *	- "invala" MUST be done at call site (normally in DO_LOAD_SWITCH_STACK)
   4.395 - *	- b7 holds address to return to
   4.396 - *	- must not touch r8-r11
   4.397 - */
   4.398 -#ifdef XEN
   4.399 -GLOBAL_ENTRY(load_switch_stack)
   4.400 -#else
   4.401 -ENTRY(load_switch_stack)
   4.402 -#endif
   4.403 -	.prologue
   4.404 -	.altrp b7
   4.405 -
   4.406 -	.body
   4.407 -	lfetch.fault.nt1 [sp]
   4.408 -	adds r2=SW(AR_BSPSTORE)+16,sp
   4.409 -	adds r3=SW(AR_UNAT)+16,sp
   4.410 -	mov ar.rsc=0						// put RSE into enforced lazy mode
   4.411 -	adds r14=SW(CALLER_UNAT)+16,sp
   4.412 -	adds r15=SW(AR_FPSR)+16,sp
   4.413 -	;;
   4.414 -	ld8 r27=[r2],(SW(B0)-SW(AR_BSPSTORE))	// bspstore
   4.415 -	ld8 r29=[r3],(SW(B1)-SW(AR_UNAT))	// unat
   4.416 -	;;
   4.417 -	ld8 r21=[r2],16		// restore b0
   4.418 -	ld8 r22=[r3],16		// restore b1
   4.419 -	;;
   4.420 -	ld8 r23=[r2],16		// restore b2
   4.421 -	ld8 r24=[r3],16		// restore b3
   4.422 -	;;
   4.423 -	ld8 r25=[r2],16		// restore b4
   4.424 -	ld8 r26=[r3],16		// restore b5
   4.425 -	;;
   4.426 -	ld8 r16=[r2],(SW(PR)-SW(AR_PFS))	// ar.pfs
   4.427 -	ld8 r17=[r3],(SW(AR_RNAT)-SW(AR_LC))	// ar.lc
   4.428 -	;;
   4.429 -	ld8 r28=[r2]		// restore pr
   4.430 -	ld8 r30=[r3]		// restore rnat
   4.431 -	;;
   4.432 -	ld8 r18=[r14],16	// restore caller's unat
   4.433 -	ld8 r19=[r15],24	// restore fpsr
   4.434 -	;;
   4.435 -	ldf.fill f2=[r14],32
   4.436 -	ldf.fill f3=[r15],32
   4.437 -	;;
   4.438 -	ldf.fill f4=[r14],32
   4.439 -	ldf.fill f5=[r15],32
   4.440 -	;;
   4.441 -	ldf.fill f12=[r14],32
   4.442 -	ldf.fill f13=[r15],32
   4.443 -	;;
   4.444 -	ldf.fill f14=[r14],32
   4.445 -	ldf.fill f15=[r15],32
   4.446 -	;;
   4.447 -	ldf.fill f16=[r14],32
   4.448 -	ldf.fill f17=[r15],32
   4.449 -	;;
   4.450 -	ldf.fill f18=[r14],32
   4.451 -	ldf.fill f19=[r15],32
   4.452 -	mov b0=r21
   4.453 -	;;
   4.454 -	ldf.fill f20=[r14],32
   4.455 -	ldf.fill f21=[r15],32
   4.456 -	mov b1=r22
   4.457 -	;;
   4.458 -	ldf.fill f22=[r14],32
   4.459 -	ldf.fill f23=[r15],32
   4.460 -	mov b2=r23
   4.461 -	;;
   4.462 -	mov ar.bspstore=r27
   4.463 -	mov ar.unat=r29		// establish unat holding the NaT bits for r4-r7
   4.464 -	mov b3=r24
   4.465 -	;;
   4.466 -	ldf.fill f24=[r14],32
   4.467 -	ldf.fill f25=[r15],32
   4.468 -	mov b4=r25
   4.469 -	;;
   4.470 -	ldf.fill f26=[r14],32
   4.471 -	ldf.fill f27=[r15],32
   4.472 -	mov b5=r26
   4.473 -	;;
   4.474 -	ldf.fill f28=[r14],32
   4.475 -	ldf.fill f29=[r15],32
   4.476 -	mov ar.pfs=r16
   4.477 -	;;
   4.478 -	ldf.fill f30=[r14],32
   4.479 -	ldf.fill f31=[r15],24
   4.480 -	mov ar.lc=r17
   4.481 -	;;
   4.482 -	ld8.fill r4=[r14],16
   4.483 -	ld8.fill r5=[r15],16
   4.484 -	mov pr=r28,-1
   4.485 -	;;
   4.486 -	ld8.fill r6=[r14],16
   4.487 -	ld8.fill r7=[r15],16
   4.488 -
   4.489 -	mov ar.unat=r18				// restore caller's unat
   4.490 -	mov ar.rnat=r30				// must restore after bspstore but before rsc!
   4.491 -	mov ar.fpsr=r19				// restore fpsr
   4.492 -	mov ar.rsc=3				// put RSE back into eager mode, pl 0
   4.493 -	br.cond.sptk.many b7
   4.494 -END(load_switch_stack)
   4.495 -
   4.496 -#ifndef XEN
   4.497 -GLOBAL_ENTRY(__ia64_syscall)
   4.498 -	.regstk 6,0,0,0
   4.499 -	mov r15=in5				// put syscall number in place
   4.500 -	break __BREAK_SYSCALL
   4.501 -	movl r2=errno
   4.502 -	cmp.eq p6,p7=-1,r10
   4.503 -	;;
   4.504 -(p6)	st4 [r2]=r8
   4.505 -(p6)	mov r8=-1
   4.506 -	br.ret.sptk.many rp
   4.507 -END(__ia64_syscall)
   4.508 -
   4.509 -GLOBAL_ENTRY(execve)
   4.510 -	mov r15=__NR_execve			// put syscall number in place
   4.511 -	break __BREAK_SYSCALL
   4.512 -	br.ret.sptk.many rp
   4.513 -END(execve)
   4.514 -
   4.515 -GLOBAL_ENTRY(clone)
   4.516 -	mov r15=__NR_clone			// put syscall number in place
   4.517 -	break __BREAK_SYSCALL
   4.518 -	br.ret.sptk.many rp
   4.519 -END(clone)
   4.520 -
   4.521 -	/*
   4.522 -	 * Invoke a system call, but do some tracing before and after the call.
   4.523 -	 * We MUST preserve the current register frame throughout this routine
   4.524 -	 * because some system calls (such as ia64_execve) directly
   4.525 -	 * manipulate ar.pfs.
   4.526 -	 */
   4.527 -GLOBAL_ENTRY(ia64_trace_syscall)
   4.528 -	PT_REGS_UNWIND_INFO(0)
   4.529 -	/*
   4.530 -	 * We need to preserve the scratch registers f6-f11 in case the system
   4.531 -	 * call is sigreturn.
   4.532 -	 */
   4.533 -	adds r16=PT(F6)+16,sp
   4.534 -	adds r17=PT(F7)+16,sp
   4.535 -	;;
   4.536 - 	stf.spill [r16]=f6,32
   4.537 - 	stf.spill [r17]=f7,32
   4.538 -	;;
   4.539 - 	stf.spill [r16]=f8,32
   4.540 - 	stf.spill [r17]=f9,32
   4.541 -	;;
   4.542 - 	stf.spill [r16]=f10
   4.543 - 	stf.spill [r17]=f11
   4.544 -	br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
   4.545 -	adds r16=PT(F6)+16,sp
   4.546 -	adds r17=PT(F7)+16,sp
   4.547 -	;;
   4.548 -	ldf.fill f6=[r16],32
   4.549 -	ldf.fill f7=[r17],32
   4.550 -	;;
   4.551 -	ldf.fill f8=[r16],32
   4.552 -	ldf.fill f9=[r17],32
   4.553 -	;;
   4.554 -	ldf.fill f10=[r16]
   4.555 -	ldf.fill f11=[r17]
   4.556 -	// the syscall number may have changed, so re-load it and re-calculate the
   4.557 -	// syscall entry-point:
   4.558 -	adds r15=PT(R15)+16,sp			// r15 = &pt_regs.r15 (syscall #)
   4.559 -	;;
   4.560 -	ld8 r15=[r15]
   4.561 -	mov r3=NR_syscalls - 1
   4.562 -	;;
   4.563 -	adds r15=-1024,r15
   4.564 -	movl r16=sys_call_table
   4.565 -	;;
   4.566 -	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
   4.567 -	cmp.leu p6,p7=r15,r3
   4.568 -	;;
   4.569 -(p6)	ld8 r20=[r20]				// load address of syscall entry point
   4.570 -(p7)	movl r20=sys_ni_syscall
   4.571 -	;;
   4.572 -	mov b6=r20
   4.573 -	br.call.sptk.many rp=b6			// do the syscall
   4.574 -.strace_check_retval:
   4.575 -	cmp.lt p6,p0=r8,r0			// syscall failed?
   4.576 -	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   4.577 -	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
   4.578 -	mov r10=0
   4.579 -(p6)	br.cond.sptk strace_error		// syscall failed ->
   4.580 -	;;					// avoid RAW on r10
   4.581 -.strace_save_retval:
   4.582 -.mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
   4.583 -.mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
   4.584 -	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
   4.585 -.ret3:	br.cond.sptk .work_pending_syscall_end
   4.586 -
   4.587 -strace_error:
   4.588 -	ld8 r3=[r2]				// load pt_regs.r8
   4.589 -	sub r9=0,r8				// negate return value to get errno value
   4.590 -	;;
   4.591 -	cmp.ne p6,p0=r3,r0			// is pt_regs.r8!=0?
   4.592 -	adds r3=16,r2				// r3=&pt_regs.r10
   4.593 -	;;
   4.594 -(p6)	mov r10=-1
   4.595 -(p6)	mov r8=r9
   4.596 -	br.cond.sptk .strace_save_retval
   4.597 -END(ia64_trace_syscall)
   4.598 -
   4.599 -	/*
   4.600 -	 * When traced and returning from sigreturn, we invoke syscall_trace but then
   4.601 -	 * go straight to ia64_leave_kernel rather than ia64_leave_syscall.
   4.602 -	 */
   4.603 -GLOBAL_ENTRY(ia64_strace_leave_kernel)
   4.604 -	PT_REGS_UNWIND_INFO(0)
   4.605 -{	/*
   4.606 -	 * Some versions of gas generate bad unwind info if the first instruction of a
   4.607 -	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
   4.608 -	 */
   4.609 -	nop.m 0
   4.610 -	nop.i 0
   4.611 -	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
   4.612 -}
   4.613 -.ret4:	br.cond.sptk ia64_leave_kernel
   4.614 -END(ia64_strace_leave_kernel)
   4.615 -#endif
   4.616 -
   4.617 -GLOBAL_ENTRY(ia64_ret_from_clone)
   4.618 -	PT_REGS_UNWIND_INFO(0)
   4.619 -{	/*
   4.620 -	 * Some versions of gas generate bad unwind info if the first instruction of a
   4.621 -	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
   4.622 -	 */
   4.623 -	nop.m 0
   4.624 -	nop.i 0
   4.625 -	/*
   4.626 -	 * We need to call schedule_tail() to complete the scheduling process.
   4.627 -	 * Called by ia64_switch_to() after do_fork()->copy_thread().  r8 contains the
   4.628 -	 * address of the previously executing task.
   4.629 -	 */
   4.630 -	br.call.sptk.many rp=ia64_invoke_schedule_tail
   4.631 -}
   4.632 -#ifdef XEN
   4.633 -	// new domains are cloned but not exec'ed so switch to user mode here
   4.634 -	cmp.ne pKStk,pUStk=r0,r0
   4.635 -#ifdef CONFIG_VTI
   4.636 -	br.cond.spnt ia64_leave_hypervisor
   4.637 -#else // CONFIG_VTI
   4.638 -	br.cond.spnt ia64_leave_kernel
   4.639 -#endif // CONFIG_VTI
   4.640 -#else
   4.641 -.ret8:
   4.642 -	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
   4.643 -	;;
   4.644 -	ld4 r2=[r2]
   4.645 -	;;
   4.646 -	mov r8=0
   4.647 -	and r2=_TIF_SYSCALL_TRACEAUDIT,r2
   4.648 -	;;
   4.649 -	cmp.ne p6,p0=r2,r0
   4.650 -(p6)	br.cond.spnt .strace_check_retval
   4.651 -#endif
   4.652 -	;;					// added stop bits to prevent r8 dependency
   4.653 -END(ia64_ret_from_clone)
   4.654 -	// fall through
   4.655 -GLOBAL_ENTRY(ia64_ret_from_syscall)
   4.656 -	PT_REGS_UNWIND_INFO(0)
   4.657 -	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
   4.658 -	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   4.659 -	mov r10=r0				// clear error indication in r10
   4.660 -(p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
   4.661 -END(ia64_ret_from_syscall)
   4.662 -	// fall through
   4.663 -/*
   4.664 - * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
   4.665 - *	need to switch to bank 0 and doesn't restore the scratch registers.
   4.666 - *	To avoid leaking kernel bits, the scratch registers are set to
   4.667 - *	the following known-to-be-safe values:
   4.668 - *
   4.669 - *		  r1: restored (global pointer)
   4.670 - *		  r2: cleared
   4.671 - *		  r3: 1 (when returning to user-level)
   4.672 - *	      r8-r11: restored (syscall return value(s))
   4.673 - *		 r12: restored (user-level stack pointer)
   4.674 - *		 r13: restored (user-level thread pointer)
   4.675 - *		 r14: cleared
   4.676 - *		 r15: restored (syscall #)
   4.677 - *	     r16-r17: cleared
   4.678 - *		 r18: user-level b6
   4.679 - *		 r19: cleared
   4.680 - *		 r20: user-level ar.fpsr
   4.681 - *		 r21: user-level b0
   4.682 - *		 r22: cleared
   4.683 - *		 r23: user-level ar.bspstore
   4.684 - *		 r24: user-level ar.rnat
   4.685 - *		 r25: user-level ar.unat
   4.686 - *		 r26: user-level ar.pfs
   4.687 - *		 r27: user-level ar.rsc
   4.688 - *		 r28: user-level ip
   4.689 - *		 r29: user-level psr
   4.690 - *		 r30: user-level cfm
   4.691 - *		 r31: user-level pr
   4.692 - *	      f6-f11: cleared
   4.693 - *		  pr: restored (user-level pr)
   4.694 - *		  b0: restored (user-level rp)
   4.695 - *	          b6: restored
   4.696 - *		  b7: cleared
   4.697 - *	     ar.unat: restored (user-level ar.unat)
   4.698 - *	      ar.pfs: restored (user-level ar.pfs)
   4.699 - *	      ar.rsc: restored (user-level ar.rsc)
   4.700 - *	     ar.rnat: restored (user-level ar.rnat)
   4.701 - *	 ar.bspstore: restored (user-level ar.bspstore)
   4.702 - *	     ar.fpsr: restored (user-level ar.fpsr)
   4.703 - *	      ar.ccv: cleared
   4.704 - *	      ar.csd: cleared
   4.705 - *	      ar.ssd: cleared
   4.706 - */
   4.707 -ENTRY(ia64_leave_syscall)
   4.708 -	PT_REGS_UNWIND_INFO(0)
   4.709 -	/*
   4.710 -	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
   4.711 -	 * user- or fsys-mode, hence we disable interrupts early on.
   4.712 -	 *
   4.713 -	 * p6 controls whether current_thread_info()->flags needs to be check for
   4.714 -	 * extra work.  We always check for extra work when returning to user-level.
   4.715 -	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
   4.716 -	 * is 0.  After extra work processing has been completed, execution
   4.717 -	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
   4.718 -	 * needs to be redone.
   4.719 -	 */
   4.720 -#ifdef CONFIG_PREEMPT
   4.721 -	rsm psr.i				// disable interrupts
   4.722 -	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
   4.723 -(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
   4.724 -	;;
   4.725 -	.pred.rel.mutex pUStk,pKStk
   4.726 -(pKStk) ld4 r21=[r20]			// r21 <- preempt_count
   4.727 -(pUStk)	mov r21=0			// r21 <- 0
   4.728 -	;;
   4.729 -	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
   4.730 -#else /* !CONFIG_PREEMPT */
   4.731 -(pUStk)	rsm psr.i
   4.732 -	cmp.eq pLvSys,p0=r0,r0		// pLvSys=1: leave from syscall
   4.733 -(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
   4.734 -#endif
   4.735 -.work_processed_syscall:
   4.736 -	adds r2=PT(LOADRS)+16,r12
   4.737 -	adds r3=PT(AR_BSPSTORE)+16,r12
   4.738 -#ifdef XEN
   4.739 -	;;
   4.740 -#else
   4.741 -	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
   4.742 -	;;
   4.743 -(p6)	ld4 r31=[r18]				// load current_thread_info()->flags
   4.744 -#endif
   4.745 -	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
   4.746 -	mov b7=r0		// clear b7
   4.747 -	;;
   4.748 -	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
   4.749 -	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
   4.750 -#ifndef XEN
   4.751 -(p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
   4.752 -#endif
   4.753 -	;;
   4.754 -	mov r16=ar.bsp				// M2  get existing backing store pointer
   4.755 -#ifndef XEN
   4.756 -(p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
   4.757 -(p6)	br.cond.spnt .work_pending_syscall
   4.758 -#endif
   4.759 -	;;
   4.760 -	// start restoring the state saved on the kernel stack (struct pt_regs):
   4.761 -	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
   4.762 -	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
   4.763 -	mov f6=f0		// clear f6
   4.764 -	;;
   4.765 -	invala			// M0|1 invalidate ALAT
   4.766 -	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
   4.767 -	mov f9=f0		// clear f9
   4.768 -
   4.769 -	ld8 r29=[r2],16		// load cr.ipsr
   4.770 -	ld8 r28=[r3],16			// load cr.iip
   4.771 -	mov f8=f0		// clear f8
   4.772 -	;;
   4.773 -	ld8 r30=[r2],16		// M0|1 load cr.ifs
   4.774 -	mov.m ar.ssd=r0		// M2 clear ar.ssd
   4.775 -	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
   4.776 -	;;
   4.777 -	ld8 r25=[r3],16		// M0|1 load ar.unat
   4.778 -	mov.m ar.csd=r0		// M2 clear ar.csd
   4.779 -	mov r22=r0		// clear r22
   4.780 -	;;
   4.781 -	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
   4.782 -(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
   4.783 -	mov f10=f0		// clear f10
   4.784 -	;;
   4.785 -	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
   4.786 -	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// load ar.rsc
   4.787 -	mov f11=f0		// clear f11
   4.788 -	;;
   4.789 -	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
   4.790 -	ld8 r31=[r3],PT(R1)-PT(PR)		// load predicates
   4.791 -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
   4.792 -	;;
   4.793 -	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
   4.794 -	ld8.fill r1=[r3],16	// load r1
   4.795 -(pUStk) mov r17=1
   4.796 -	;;
   4.797 -	srlz.d			// M0  ensure interruption collection is off
   4.798 -	ld8.fill r13=[r3],16
   4.799 -	mov f7=f0		// clear f7
   4.800 -	;;
   4.801 -	ld8.fill r12=[r2]	// restore r12 (sp)
   4.802 -	ld8.fill r15=[r3]	// restore r15
   4.803 -#ifdef XEN
   4.804 -	movl r3=THIS_CPU(ia64_phys_stacked_size_p8)
   4.805 -#else
   4.806 -	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
   4.807 -#endif
   4.808 -	;;
   4.809 -(pUStk)	ld4 r3=[r3]		// r3 = cpu_data->phys_stacked_size_p8
   4.810 -(pUStk) st1 [r14]=r17
   4.811 -	mov b6=r18		// I0  restore b6
   4.812 -	;;
   4.813 -	mov r14=r0		// clear r14
   4.814 -	shr.u r18=r19,16	// I0|1 get byte size of existing "dirty" partition
   4.815 -(pKStk) br.cond.dpnt.many skip_rbs_switch
   4.816 -
   4.817 -	mov.m ar.ccv=r0		// clear ar.ccv
   4.818 -(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
   4.819 -	br.cond.sptk.many rbs_switch
   4.820 -END(ia64_leave_syscall)
   4.821 -
   4.822 -#ifdef CONFIG_IA32_SUPPORT
   4.823 -GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
   4.824 -	PT_REGS_UNWIND_INFO(0)
   4.825 -	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   4.826 -	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
   4.827 -	;;
   4.828 -	.mem.offset 0,0
   4.829 -	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
   4.830 -	.mem.offset 8,0
   4.831 -	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
   4.832 -END(ia64_ret_from_ia32_execve_syscall)
   4.833 -	// fall through
   4.834 -#endif /* CONFIG_IA32_SUPPORT */
   4.835 -GLOBAL_ENTRY(ia64_leave_kernel)
   4.836 -	PT_REGS_UNWIND_INFO(0)
   4.837 -	/*
   4.838 -	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
   4.839 -	 * user- or fsys-mode, hence we disable interrupts early on.
   4.840 -	 *
   4.841 -	 * p6 controls whether current_thread_info()->flags needs to be check for
   4.842 -	 * extra work.  We always check for extra work when returning to user-level.
   4.843 -	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
   4.844 -	 * is 0.  After extra work processing has been completed, execution
   4.845 -	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
   4.846 -	 * needs to be redone.
   4.847 -	 */
   4.848 -#ifdef CONFIG_PREEMPT
   4.849 -	rsm psr.i				// disable interrupts
   4.850 -	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
   4.851 -(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
   4.852 -	;;
   4.853 -	.pred.rel.mutex pUStk,pKStk
   4.854 -(pKStk)	ld4 r21=[r20]			// r21 <- preempt_count
   4.855 -(pUStk)	mov r21=0			// r21 <- 0
   4.856 -	;;
   4.857 -	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
   4.858 -#else
   4.859 -(pUStk)	rsm psr.i
   4.860 -	cmp.eq p0,pLvSys=r0,r0		// pLvSys=0: leave from kernel
   4.861 -(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
   4.862 -#endif
   4.863 -.work_processed_kernel:
   4.864 -#ifdef XEN
   4.865 -	alloc loc0=ar.pfs,0,1,1,0
   4.866 -	adds out0=16,r12
   4.867 -	;;
   4.868 -(p6)	br.call.sptk.many b0=deliver_pending_interrupt
   4.869 -	mov ar.pfs=loc0
   4.870 -	mov r31=r0
   4.871 -#else
   4.872 -	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
   4.873 -	;;
   4.874 -(p6)	ld4 r31=[r17]				// load current_thread_info()->flags
   4.875 -#endif
   4.876 -	adds r21=PT(PR)+16,r12
   4.877 -	;;
   4.878 -
   4.879 -	lfetch [r21],PT(CR_IPSR)-PT(PR)
   4.880 -	adds r2=PT(B6)+16,r12
   4.881 -	adds r3=PT(R16)+16,r12
   4.882 -	;;
   4.883 -	lfetch [r21]
   4.884 -	ld8 r28=[r2],8		// load b6
   4.885 -	adds r29=PT(R24)+16,r12
   4.886 -
   4.887 -	ld8.fill r16=[r3]
   4.888 -	adds r30=PT(AR_CCV)+16,r12
   4.889 -(p6)	and r19=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
   4.890 -	;;
   4.891 -	adds r3=PT(AR_CSD)-PT(R16),r3
   4.892 -	ld8.fill r24=[r29]
   4.893 -	ld8 r15=[r30]		// load ar.ccv
   4.894 -(p6)	cmp4.ne.unc p6,p0=r19, r0		// any special work pending?
   4.895 -	;;
   4.896 -	ld8 r29=[r2],16		// load b7
   4.897 -	ld8 r30=[r3],16		// load ar.csd
   4.898 -#ifndef XEN
   4.899 -(p6)	br.cond.spnt .work_pending
   4.900 -#endif
   4.901 -	;;
   4.902 -	ld8 r31=[r2],16		// load ar.ssd
   4.903 -	ld8.fill r8=[r3],16
   4.904 -	;;
   4.905 -	ld8.fill r9=[r2],16
   4.906 -	ld8.fill r10=[r3],PT(R17)-PT(R10)
   4.907 -	;;
   4.908 -	ld8.fill r11=[r2],PT(R18)-PT(R11)
   4.909 -	ld8.fill r17=[r3],16
   4.910 -	;;
   4.911 -	ld8.fill r18=[r2],16
   4.912 -	ld8.fill r19=[r3],16
   4.913 -	;;
   4.914 -	ld8.fill r20=[r2],16
   4.915 -	ld8.fill r21=[r3],16
   4.916 -	mov ar.csd=r30
   4.917 -	mov ar.ssd=r31
   4.918 -	;;
   4.919 -	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
   4.920 -	invala			// invalidate ALAT
   4.921 -	;;
   4.922 -	ld8.fill r22=[r2],24
   4.923 -	ld8.fill r23=[r3],24
   4.924 -	mov b6=r28
   4.925 -	;;
   4.926 -	ld8.fill r25=[r2],16
   4.927 -	ld8.fill r26=[r3],16
   4.928 -	mov b7=r29
   4.929 -	;;
   4.930 -	ld8.fill r27=[r2],16
   4.931 -	ld8.fill r28=[r3],16
   4.932 -	;;
   4.933 -	ld8.fill r29=[r2],16
   4.934 -	ld8.fill r30=[r3],24
   4.935 -	;;
   4.936 -	ld8.fill r31=[r2],PT(F9)-PT(R31)
   4.937 -	adds r3=PT(F10)-PT(F6),r3
   4.938 -	;;
   4.939 -	ldf.fill f9=[r2],PT(F6)-PT(F9)
   4.940 -	ldf.fill f10=[r3],PT(F8)-PT(F10)
   4.941 -	;;
   4.942 -	ldf.fill f6=[r2],PT(F7)-PT(F6)
   4.943 -	;;
   4.944 -	ldf.fill f7=[r2],PT(F11)-PT(F7)
   4.945 -	ldf.fill f8=[r3],32
   4.946 -	;;
   4.947 -	srlz.i			// ensure interruption collection is off
   4.948 -	mov ar.ccv=r15
   4.949 -	;;
   4.950 -	ldf.fill f11=[r2]
   4.951 -	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
   4.952 -	;;
   4.953 -(pUStk)	mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
   4.954 -	adds r16=PT(CR_IPSR)+16,r12
   4.955 -	adds r17=PT(CR_IIP)+16,r12
   4.956 -
   4.957 -(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
   4.958 -	nop.i 0
   4.959 -	nop.i 0
   4.960 -	;;
   4.961 -	ld8 r29=[r16],16	// load cr.ipsr
   4.962 -	ld8 r28=[r17],16	// load cr.iip
   4.963 -	;;
   4.964 -	ld8 r30=[r16],16	// load cr.ifs
   4.965 -	ld8 r25=[r17],16	// load ar.unat
   4.966 -	;;
   4.967 -	ld8 r26=[r16],16	// load ar.pfs
   4.968 -	ld8 r27=[r17],16	// load ar.rsc
   4.969 -	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
   4.970 -	;;
   4.971 -	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
   4.972 -	ld8 r23=[r17],16	// load ar.bspstore (may be garbage)
   4.973 -	;;
   4.974 -	ld8 r31=[r16],16	// load predicates
   4.975 -	ld8 r21=[r17],16	// load b0
   4.976 -	;;
   4.977 -	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
   4.978 -	ld8.fill r1=[r17],16	// load r1
   4.979 -	;;
   4.980 -	ld8.fill r12=[r16],16
   4.981 -	ld8.fill r13=[r17],16
   4.982 -(pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
   4.983 -	;;
   4.984 -	ld8 r20=[r16],16	// ar.fpsr
   4.985 -	ld8.fill r15=[r17],16
   4.986 -	;;
   4.987 -	ld8.fill r14=[r16],16
   4.988 -	ld8.fill r2=[r17]
   4.989 -(pUStk)	mov r17=1
   4.990 -	;;
   4.991 -	ld8.fill r3=[r16]
   4.992 -(pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
   4.993 -	shr.u r18=r19,16	// get byte size of existing "dirty" partition
   4.994 -	;;
   4.995 -	mov r16=ar.bsp		// get existing backing store pointer
   4.996 -#ifdef XEN
   4.997 -	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
   4.998 -#else
   4.999 -	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
  4.1000 -#endif
  4.1001 -	;;
  4.1002 -	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
  4.1003 -(pKStk)	br.cond.dpnt skip_rbs_switch
  4.1004 -
  4.1005 -	/*
  4.1006 -	 * Restore user backing store.
  4.1007 -	 *
  4.1008 -	 * NOTE: alloc, loadrs, and cover can't be predicated.
  4.1009 -	 */
  4.1010 -(pNonSys) br.cond.dpnt dont_preserve_current_frame
  4.1011 -
  4.1012 -rbs_switch:
  4.1013 -	cover				// add current frame into dirty partition and set cr.ifs
  4.1014 -	;;
  4.1015 -	mov r19=ar.bsp			// get new backing store pointer
  4.1016 -	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
  4.1017 -	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
  4.1018 -	;;
  4.1019 -	sub r19=r19,r16			// calculate total byte size of dirty partition
  4.1020 -	add r18=64,r18			// don't force in0-in7 into memory...
  4.1021 -	;;
  4.1022 -	shl r19=r19,16			// shift size of dirty partition into loadrs position
  4.1023 -	;;
  4.1024 -dont_preserve_current_frame:
  4.1025 -	/*
  4.1026 -	 * To prevent leaking bits between the kernel and user-space,
  4.1027 -	 * we must clear the stacked registers in the "invalid" partition here.
  4.1028 -	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
  4.1029 -	 * 5 registers/cycle on McKinley).
  4.1030 -	 */
  4.1031 -#	define pRecurse	p6
  4.1032 -#	define pReturn	p7
  4.1033 -#ifdef CONFIG_ITANIUM
  4.1034 -#	define Nregs	10
  4.1035 -#else
  4.1036 -#	define Nregs	14
  4.1037 -#endif
  4.1038 -	alloc loc0=ar.pfs,2,Nregs-2,2,0
  4.1039 -	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
  4.1040 -	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
  4.1041 -	;;
  4.1042 -	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
  4.1043 -	shladd in0=loc1,3,r17
  4.1044 -	mov in1=0
  4.1045 -	;;
  4.1046 -	TEXT_ALIGN(32)
  4.1047 -rse_clear_invalid:
  4.1048 -#ifdef CONFIG_ITANIUM
  4.1049 -	// cycle 0
  4.1050 - { .mii
  4.1051 -	alloc loc0=ar.pfs,2,Nregs-2,2,0
  4.1052 -	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
  4.1053 -	add out0=-Nregs*8,in0
  4.1054 -}{ .mfb
  4.1055 -	add out1=1,in1			// increment recursion count
  4.1056 -	nop.f 0
  4.1057 -	nop.b 0				// can't do br.call here because of alloc (WAW on CFM)
  4.1058 -	;;
  4.1059 -}{ .mfi	// cycle 1
  4.1060 -	mov loc1=0
  4.1061 -	nop.f 0
  4.1062 -	mov loc2=0
  4.1063 -}{ .mib
  4.1064 -	mov loc3=0
  4.1065 -	mov loc4=0
  4.1066 -(pRecurse) br.call.sptk.many b0=rse_clear_invalid
  4.1067 -
  4.1068 -}{ .mfi	// cycle 2
  4.1069 -	mov loc5=0
  4.1070 -	nop.f 0
  4.1071 -	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
  4.1072 -}{ .mib
  4.1073 -	mov loc6=0
  4.1074 -	mov loc7=0
  4.1075 -(pReturn) br.ret.sptk.many b0
  4.1076 -}
  4.1077 -#else /* !CONFIG_ITANIUM */
  4.1078 -	alloc loc0=ar.pfs,2,Nregs-2,2,0
  4.1079 -	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
  4.1080 -	add out0=-Nregs*8,in0
  4.1081 -	add out1=1,in1			// increment recursion count
  4.1082 -	mov loc1=0
  4.1083 -	mov loc2=0
  4.1084 -	;;
  4.1085 -	mov loc3=0
  4.1086 -	mov loc4=0
  4.1087 -	mov loc5=0
  4.1088 -	mov loc6=0
  4.1089 -	mov loc7=0
  4.1090 -(pRecurse) br.call.sptk.few b0=rse_clear_invalid
  4.1091 -	;;
  4.1092 -	mov loc8=0
  4.1093 -	mov loc9=0
  4.1094 -	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
  4.1095 -	mov loc10=0
  4.1096 -	mov loc11=0
  4.1097 -(pReturn) br.ret.sptk.many b0
  4.1098 -#endif /* !CONFIG_ITANIUM */
  4.1099 -#	undef pRecurse
  4.1100 -#	undef pReturn
  4.1101 -	;;
  4.1102 -	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
  4.1103 -	;;
  4.1104 -	loadrs
  4.1105 -	;;
  4.1106 -skip_rbs_switch:
  4.1107 -	mov ar.unat=r25		// M2
  4.1108 -(pKStk)	extr.u r22=r22,21,1	// I0 extract current value of psr.pp from r22
  4.1109 -(pLvSys)mov r19=r0		// A  clear r19 for leave_syscall, no-op otherwise
  4.1110 -	;;
  4.1111 -(pUStk)	mov ar.bspstore=r23	// M2
  4.1112 -(pKStk)	dep r29=r22,r29,21,1	// I0 update ipsr.pp with psr.pp
  4.1113 -(pLvSys)mov r16=r0		// A  clear r16 for leave_syscall, no-op otherwise
  4.1114 -	;;
  4.1115 -	mov cr.ipsr=r29		// M2
  4.1116 -	mov ar.pfs=r26		// I0
  4.1117 -(pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
  4.1118 -
  4.1119 -(p9)	mov cr.ifs=r30		// M2
  4.1120 -	mov b0=r21		// I0
  4.1121 -(pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
  4.1122 -
  4.1123 -	mov ar.fpsr=r20		// M2
  4.1124 -	mov cr.iip=r28		// M2
  4.1125 -	nop 0
  4.1126 -	;;
  4.1127 -(pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
  4.1128 -	nop 0
  4.1129 -(pLvSys)mov r2=r0
  4.1130 -
  4.1131 -	mov ar.rsc=r27		// M2
  4.1132 -	mov pr=r31,-1		// I0
  4.1133 -	rfi			// B
  4.1134 -
  4.1135 -#ifndef XEN
  4.1136 -	/*
  4.1137 -	 * On entry:
  4.1138 -	 *	r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
  4.1139 -	 *	r31 = current->thread_info->flags
  4.1140 -	 * On exit:
  4.1141 -	 *	p6 = TRUE if work-pending-check needs to be redone
  4.1142 -	 */
  4.1143 -.work_pending_syscall:
  4.1144 -	add r2=-8,r2
  4.1145 -	add r3=-8,r3
  4.1146 -	;;
  4.1147 -	st8 [r2]=r8
  4.1148 -	st8 [r3]=r10
  4.1149 -.work_pending:
  4.1150 -	tbit.nz p6,p0=r31,TIF_SIGDELAYED		// signal delayed from  MCA/INIT/NMI/PMI context?
  4.1151 -(p6)	br.cond.sptk.few .sigdelayed
  4.1152 -	;;
  4.1153 -	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
  4.1154 -(p6)	br.cond.sptk.few .notify
  4.1155 -#ifdef CONFIG_PREEMPT
  4.1156 -(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
  4.1157 -	;;
  4.1158 -(pKStk) st4 [r20]=r21
  4.1159 -	ssm psr.i		// enable interrupts
  4.1160 -#endif
  4.1161 -	br.call.spnt.many rp=schedule
  4.1162 -.ret9:	cmp.eq p6,p0=r0,r0				// p6 <- 1
  4.1163 -	rsm psr.i		// disable interrupts
  4.1164 -	;;
  4.1165 -#ifdef CONFIG_PREEMPT
  4.1166 -(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
  4.1167 -	;;
  4.1168 -(pKStk)	st4 [r20]=r0		// preempt_count() <- 0
  4.1169 -#endif
  4.1170 -(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  4.1171 -	br.cond.sptk.many .work_processed_kernel	// re-check
  4.1172 -
  4.1173 -.notify:
  4.1174 -(pUStk)	br.call.spnt.many rp=notify_resume_user
  4.1175 -.ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
  4.1176 -(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  4.1177 -	br.cond.sptk.many .work_processed_kernel	// don't re-check
  4.1178 -
  4.1179 -// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
  4.1180 -// it could not be delivered.  Deliver it now.  The signal might be for us and
  4.1181 -// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
  4.1182 -// signal.
  4.1183 -
  4.1184 -.sigdelayed:
  4.1185 -	br.call.sptk.many rp=do_sigdelayed
  4.1186 -	cmp.eq p6,p0=r0,r0				// p6 <- 1, always re-check
  4.1187 -(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  4.1188 -	br.cond.sptk.many .work_processed_kernel	// re-check
  4.1189 -
  4.1190 -.work_pending_syscall_end:
  4.1191 -	adds r2=PT(R8)+16,r12
  4.1192 -	adds r3=PT(R10)+16,r12
  4.1193 -	;;
  4.1194 -	ld8 r8=[r2]
  4.1195 -	ld8 r10=[r3]
  4.1196 -	br.cond.sptk.many .work_processed_syscall	// re-check
  4.1197 -#endif
  4.1198 -
  4.1199 -END(ia64_leave_kernel)
  4.1200 -
  4.1201 -ENTRY(handle_syscall_error)
  4.1202 -	/*
  4.1203 -	 * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
  4.1204 -	 * lead us to mistake a negative return value as a failed syscall.  Those syscall
  4.1205 -	 * must deposit a non-zero value in pt_regs.r8 to indicate an error.  If
  4.1206 -	 * pt_regs.r8 is zero, we assume that the call completed successfully.
  4.1207 -	 */
  4.1208 -	PT_REGS_UNWIND_INFO(0)
  4.1209 -	ld8 r3=[r2]		// load pt_regs.r8
  4.1210 -	;;
  4.1211 -	cmp.eq p6,p7=r3,r0	// is pt_regs.r8==0?
  4.1212 -	;;
  4.1213 -(p7)	mov r10=-1
  4.1214 -(p7)	sub r8=0,r8		// negate return value to get errno
  4.1215 -	br.cond.sptk ia64_leave_syscall
  4.1216 -END(handle_syscall_error)
  4.1217 -
  4.1218 -	/*
  4.1219 -	 * Invoke schedule_tail(task) while preserving in0-in7, which may be needed
  4.1220 -	 * in case a system call gets restarted.
  4.1221 -	 */
  4.1222 -GLOBAL_ENTRY(ia64_invoke_schedule_tail)
  4.1223 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  4.1224 -	alloc loc1=ar.pfs,8,2,1,0
  4.1225 -	mov loc0=rp
  4.1226 -	mov out0=r8				// Address of previous task
  4.1227 -	;;
  4.1228 -	br.call.sptk.many rp=schedule_tail
  4.1229 -.ret11:	mov ar.pfs=loc1
  4.1230 -	mov rp=loc0
  4.1231 -	br.ret.sptk.many rp
  4.1232 -END(ia64_invoke_schedule_tail)
  4.1233 -
  4.1234 -#ifndef XEN
  4.1235 -	/*
  4.1236 -	 * Setup stack and call do_notify_resume_user().  Note that pSys and pNonSys need to
  4.1237 -	 * be set up by the caller.  We declare 8 input registers so the system call
  4.1238 -	 * args get preserved, in case we need to restart a system call.
  4.1239 -	 */
  4.1240 -ENTRY(notify_resume_user)
  4.1241 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  4.1242 -	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
  4.1243 -	mov r9=ar.unat
  4.1244 -	mov loc0=rp				// save return address
  4.1245 -	mov out0=0				// there is no "oldset"
  4.1246 -	adds out1=8,sp				// out1=&sigscratch->ar_pfs
  4.1247 -(pSys)	mov out2=1				// out2==1 => we're in a syscall
  4.1248 -	;;
  4.1249 -(pNonSys) mov out2=0				// out2==0 => not a syscall
  4.1250 -	.fframe 16
  4.1251 -	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
  4.1252 -	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
  4.1253 -	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
  4.1254 -	.body
  4.1255 -	br.call.sptk.many rp=do_notify_resume_user
  4.1256 -.ret15:	.restore sp
  4.1257 -	adds sp=16,sp				// pop scratch stack space
  4.1258 -	;;
  4.1259 -	ld8 r9=[sp]				// load new unat from sigscratch->scratch_unat
  4.1260 -	mov rp=loc0
  4.1261 -	;;
  4.1262 -	mov ar.unat=r9
  4.1263 -	mov ar.pfs=loc1
  4.1264 -	br.ret.sptk.many rp
  4.1265 -END(notify_resume_user)
  4.1266 -
  4.1267 -GLOBAL_ENTRY(sys_rt_sigsuspend)
  4.1268 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  4.1269 -	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
  4.1270 -	mov r9=ar.unat
  4.1271 -	mov loc0=rp				// save return address
  4.1272 -	mov out0=in0				// mask
  4.1273 -	mov out1=in1				// sigsetsize
  4.1274 -	adds out2=8,sp				// out2=&sigscratch->ar_pfs
  4.1275 -	;;
  4.1276 -	.fframe 16
  4.1277 -	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
  4.1278 -	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
  4.1279 -	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
  4.1280 -	.body
  4.1281 -	br.call.sptk.many rp=ia64_rt_sigsuspend
  4.1282 -.ret17:	.restore sp
  4.1283 -	adds sp=16,sp				// pop scratch stack space
  4.1284 -	;;
  4.1285 -	ld8 r9=[sp]				// load new unat from sw->caller_unat
  4.1286 -	mov rp=loc0
  4.1287 -	;;
  4.1288 -	mov ar.unat=r9
  4.1289 -	mov ar.pfs=loc1
  4.1290 -	br.ret.sptk.many rp
  4.1291 -END(sys_rt_sigsuspend)
  4.1292 -
  4.1293 -ENTRY(sys_rt_sigreturn)
  4.1294 -	PT_REGS_UNWIND_INFO(0)
  4.1295 -	/*
  4.1296 -	 * Allocate 8 input registers since ptrace() may clobber them
  4.1297 -	 */
  4.1298 -	alloc r2=ar.pfs,8,0,1,0
  4.1299 -	.prologue
  4.1300 -	PT_REGS_SAVES(16)
  4.1301 -	adds sp=-16,sp
  4.1302 -	.body
  4.1303 -	cmp.eq pNonSys,pSys=r0,r0		// sigreturn isn't a normal syscall...
  4.1304 -	;;
  4.1305 -	/*
  4.1306 -	 * leave_kernel() restores f6-f11 from pt_regs, but since the streamlined
  4.1307 -	 * syscall-entry path does not save them we save them here instead.  Note: we
  4.1308 -	 * don't need to save any other registers that are not saved by the stream-lined
  4.1309 -	 * syscall path, because restore_sigcontext() restores them.
  4.1310 -	 */
  4.1311 -	adds r16=PT(F6)+32,sp
  4.1312 -	adds r17=PT(F7)+32,sp
  4.1313 -	;;
  4.1314 - 	stf.spill [r16]=f6,32
  4.1315 - 	stf.spill [r17]=f7,32
  4.1316 -	;;
  4.1317 - 	stf.spill [r16]=f8,32
  4.1318 - 	stf.spill [r17]=f9,32
  4.1319 -	;;
  4.1320 - 	stf.spill [r16]=f10
  4.1321 - 	stf.spill [r17]=f11
  4.1322 -	adds out0=16,sp				// out0 = &sigscratch
  4.1323 -	br.call.sptk.many rp=ia64_rt_sigreturn
  4.1324 -.ret19:	.restore sp 0
  4.1325 -	adds sp=16,sp
  4.1326 -	;;
  4.1327 -	ld8 r9=[sp]				// load new ar.unat
  4.1328 -	mov.sptk b7=r8,ia64_leave_kernel
  4.1329 -	;;
  4.1330 -	mov ar.unat=r9
  4.1331 -	br.many b7
  4.1332 -END(sys_rt_sigreturn)
  4.1333 -#endif
  4.1334 -
  4.1335 -GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
  4.1336 -	.prologue
  4.1337 -	/*
  4.1338 -	 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
  4.1339 -	 */
  4.1340 -	mov r16=r0
  4.1341 -	DO_SAVE_SWITCH_STACK
  4.1342 -	br.call.sptk.many rp=ia64_handle_unaligned	// stack frame setup in ivt
  4.1343 -.ret21:	.body
  4.1344 -	DO_LOAD_SWITCH_STACK
  4.1345 -	br.cond.sptk.many rp				// goes to ia64_leave_kernel
  4.1346 -END(ia64_prepare_handle_unaligned)
  4.1347 -
  4.1348 -#ifndef XEN
  4.1349 -	//
  4.1350 -	// unw_init_running(void (*callback)(info, arg), void *arg)
  4.1351 -	//
  4.1352 -#	define EXTRA_FRAME_SIZE	((UNW_FRAME_INFO_SIZE+15)&~15)
  4.1353 -
  4.1354 -GLOBAL_ENTRY(unw_init_running)
  4.1355 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  4.1356 -	alloc loc1=ar.pfs,2,3,3,0
  4.1357 -	;;
  4.1358 -	ld8 loc2=[in0],8
  4.1359 -	mov loc0=rp
  4.1360 -	mov r16=loc1
  4.1361 -	DO_SAVE_SWITCH_STACK
  4.1362 -	.body
  4.1363 -
  4.1364 -	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  4.1365 -	.fframe IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE
  4.1366 -	SWITCH_STACK_SAVES(EXTRA_FRAME_SIZE)
  4.1367 -	adds sp=-EXTRA_FRAME_SIZE,sp
  4.1368 -	.body
  4.1369 -	;;
  4.1370 -	adds out0=16,sp				// &info
  4.1371 -	mov out1=r13				// current
  4.1372 -	adds out2=16+EXTRA_FRAME_SIZE,sp	// &switch_stack
  4.1373 -	br.call.sptk.many rp=unw_init_frame_info
  4.1374 -1:	adds out0=16,sp				// &info
  4.1375 -	mov b6=loc2
  4.1376 -	mov loc2=gp				// save gp across indirect function call
  4.1377 -	;;
  4.1378 -	ld8 gp=[in0]
  4.1379 -	mov out1=in1				// arg
  4.1380 -	br.call.sptk.many rp=b6			// invoke the callback function
  4.1381 -1:	mov gp=loc2				// restore gp
  4.1382 -
  4.1383 -	// For now, we don't allow changing registers from within
  4.1384 -	// unw_init_running; if we ever want to allow that, we'd
  4.1385 -	// have to do a load_switch_stack here:
  4.1386 -	.restore sp
  4.1387 -	adds sp=IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE,sp
  4.1388 -
  4.1389 -	mov ar.pfs=loc1
  4.1390 -	mov rp=loc0
  4.1391 -	br.ret.sptk.many rp
  4.1392 -END(unw_init_running)
  4.1393 -
  4.1394 -	.rodata
  4.1395 -	.align 8
  4.1396 -	.globl sys_call_table
  4.1397 -sys_call_table:
  4.1398 -	data8 sys_ni_syscall		//  This must be sys_ni_syscall!  See ivt.S.
  4.1399 -	data8 sys_exit				// 1025
  4.1400 -	data8 sys_read
  4.1401 -	data8 sys_write
  4.1402 -	data8 sys_open
  4.1403 -	data8 sys_close
  4.1404 -	data8 sys_creat				// 1030
  4.1405 -	data8 sys_link
  4.1406 -	data8 sys_unlink
  4.1407 -	data8 ia64_execve
  4.1408 -	data8 sys_chdir
  4.1409 -	data8 sys_fchdir			// 1035
  4.1410 -	data8 sys_utimes
  4.1411 -	data8 sys_mknod
  4.1412 -	data8 sys_chmod
  4.1413 -	data8 sys_chown
  4.1414 -	data8 sys_lseek				// 1040
  4.1415 -	data8 sys_getpid
  4.1416 -	data8 sys_getppid
  4.1417 -	data8 sys_mount
  4.1418 -	data8 sys_umount
  4.1419 -	data8 sys_setuid			// 1045
  4.1420 -	data8 sys_getuid
  4.1421 -	data8 sys_geteuid
  4.1422 -	data8 sys_ptrace
  4.1423 -	data8 sys_access
  4.1424 -	data8 sys_sync				// 1050
  4.1425 -	data8 sys_fsync
  4.1426 -	data8 sys_fdatasync
  4.1427 -	data8 sys_kill
  4.1428 -	data8 sys_rename
  4.1429 -	data8 sys_mkdir				// 1055
  4.1430 -	data8 sys_rmdir
  4.1431 -	data8 sys_dup
  4.1432 -	data8 sys_pipe
  4.1433 -	data8 sys_times
  4.1434 -	data8 ia64_brk				// 1060
  4.1435 -	data8 sys_setgid
  4.1436 -	data8 sys_getgid
  4.1437 -	data8 sys_getegid
  4.1438 -	data8 sys_acct
  4.1439 -	data8 sys_ioctl				// 1065
  4.1440 -	data8 sys_fcntl
  4.1441 -	data8 sys_umask
  4.1442 -	data8 sys_chroot
  4.1443 -	data8 sys_ustat
  4.1444 -	data8 sys_dup2				// 1070
  4.1445 -	data8 sys_setreuid
  4.1446 -	data8 sys_setregid
  4.1447 -	data8 sys_getresuid
  4.1448 -	data8 sys_setresuid
  4.1449 -	data8 sys_getresgid			// 1075
  4.1450 -	data8 sys_setresgid
  4.1451 -	data8 sys_getgroups
  4.1452 -	data8 sys_setgroups
  4.1453 -	data8 sys_getpgid
  4.1454 -	data8 sys_setpgid			// 1080
  4.1455 -	data8 sys_setsid
  4.1456 -	data8 sys_getsid
  4.1457 -	data8 sys_sethostname
  4.1458 -	data8 sys_setrlimit
  4.1459 -	data8 sys_getrlimit			// 1085
  4.1460 -	data8 sys_getrusage
  4.1461 -	data8 sys_gettimeofday
  4.1462 -	data8 sys_settimeofday
  4.1463 -	data8 sys_select
  4.1464 -	data8 sys_poll				// 1090
  4.1465 -	data8 sys_symlink
  4.1466 -	data8 sys_readlink
  4.1467 -	data8 sys_uselib
  4.1468 -	data8 sys_swapon
  4.1469 -	data8 sys_swapoff			// 1095
  4.1470 -	data8 sys_reboot
  4.1471 -	data8 sys_truncate
  4.1472 -	data8 sys_ftruncate
  4.1473 -	data8 sys_fchmod
  4.1474 -	data8 sys_fchown			// 1100
  4.1475 -	data8 ia64_getpriority
  4.1476 -	data8 sys_setpriority
  4.1477 -	data8 sys_statfs
  4.1478 -	data8 sys_fstatfs
  4.1479 -	data8 sys_gettid			// 1105
  4.1480 -	data8 sys_semget
  4.1481 -	data8 sys_semop
  4.1482 -	data8 sys_semctl
  4.1483 -	data8 sys_msgget
  4.1484 -	data8 sys_msgsnd			// 1110
  4.1485 -	data8 sys_msgrcv
  4.1486 -	data8 sys_msgctl
  4.1487 -	data8 sys_shmget
  4.1488 -	data8 ia64_shmat
  4.1489 -	data8 sys_shmdt				// 1115
  4.1490 -	data8 sys_shmctl
  4.1491 -	data8 sys_syslog
  4.1492 -	data8 sys_setitimer
  4.1493 -	data8 sys_getitimer
  4.1494 -	data8 sys_ni_syscall			// 1120		/* was: ia64_oldstat */
  4.1495 -	data8 sys_ni_syscall					/* was: ia64_oldlstat */
  4.1496 -	data8 sys_ni_syscall					/* was: ia64_oldfstat */
  4.1497 -	data8 sys_vhangup
  4.1498 -	data8 sys_lchown
  4.1499 -	data8 sys_remap_file_pages		// 1125
  4.1500 -	data8 sys_wait4
  4.1501 -	data8 sys_sysinfo
  4.1502 -	data8 sys_clone
  4.1503 -	data8 sys_setdomainname
  4.1504 -	data8 sys_newuname			// 1130
  4.1505 -	data8 sys_adjtimex
  4.1506 -	data8 sys_ni_syscall					/* was: ia64_create_module */
  4.1507 -	data8 sys_init_module
  4.1508 -	data8 sys_delete_module
  4.1509 -	data8 sys_ni_syscall			// 1135		/* was: sys_get_kernel_syms */
  4.1510 -	data8 sys_ni_syscall					/* was: sys_query_module */
  4.1511 -	data8 sys_quotactl
  4.1512 -	data8 sys_bdflush
  4.1513 -	data8 sys_sysfs
  4.1514 -	data8 sys_personality			// 1140
  4.1515 -	data8 sys_ni_syscall		// sys_afs_syscall
  4.1516 -	data8 sys_setfsuid
  4.1517 -	data8 sys_setfsgid
  4.1518 -	data8 sys_getdents
  4.1519 -	data8 sys_flock				// 1145
  4.1520 -	data8 sys_readv
  4.1521 -	data8 sys_writev
  4.1522 -	data8 sys_pread64
  4.1523 -	data8 sys_pwrite64
  4.1524 -	data8 sys_sysctl			// 1150
  4.1525 -	data8 sys_mmap
  4.1526 -	data8 sys_munmap
  4.1527 -	data8 sys_mlock
  4.1528 -	data8 sys_mlockall
  4.1529 -	data8 sys_mprotect			// 1155
  4.1530 -	data8 ia64_mremap
  4.1531 -	data8 sys_msync
  4.1532 -	data8 sys_munlock
  4.1533 -	data8 sys_munlockall
  4.1534 -	data8 sys_sched_getparam		// 1160
  4.1535 -	data8 sys_sched_setparam
  4.1536 -	data8 sys_sched_getscheduler
  4.1537 -	data8 sys_sched_setscheduler
  4.1538 -	data8 sys_sched_yield
  4.1539 -	data8 sys_sched_get_priority_max	// 1165
  4.1540 -	data8 sys_sched_get_priority_min
  4.1541 -	data8 sys_sched_rr_get_interval
  4.1542 -	data8 sys_nanosleep
  4.1543 -	data8 sys_nfsservctl
  4.1544 -	data8 sys_prctl				// 1170
  4.1545 -	data8 sys_getpagesize
  4.1546 -	data8 sys_mmap2
  4.1547 -	data8 sys_pciconfig_read
  4.1548 -	data8 sys_pciconfig_write
  4.1549 -	data8 sys_perfmonctl			// 1175
  4.1550 -	data8 sys_sigaltstack
  4.1551 -	data8 sys_rt_sigaction
  4.1552 -	data8 sys_rt_sigpending
  4.1553 -	data8 sys_rt_sigprocmask
  4.1554 -	data8 sys_rt_sigqueueinfo		// 1180
  4.1555 -	data8 sys_rt_sigreturn
  4.1556 -	data8 sys_rt_sigsuspend
  4.1557 -	data8 sys_rt_sigtimedwait
  4.1558 -	data8 sys_getcwd
  4.1559 -	data8 sys_capget			// 1185
  4.1560 -	data8 sys_capset
  4.1561 -	data8 sys_sendfile64
  4.1562 -	data8 sys_ni_syscall		// sys_getpmsg (STREAMS)
  4.1563 -	data8 sys_ni_syscall		// sys_putpmsg (STREAMS)
  4.1564 -	data8 sys_socket			// 1190
  4.1565 -	data8 sys_bind
  4.1566 -	data8 sys_connect
  4.1567 -	data8 sys_listen
  4.1568 -	data8 sys_accept
  4.1569 -	data8 sys_getsockname			// 1195
  4.1570 -	data8 sys_getpeername
  4.1571 -	data8 sys_socketpair
  4.1572 -	data8 sys_send
  4.1573 -	data8 sys_sendto
  4.1574 -	data8 sys_recv				// 1200
  4.1575 -	data8 sys_recvfrom
  4.1576 -	data8 sys_shutdown
  4.1577 -	data8 sys_setsockopt
  4.1578 -	data8 sys_getsockopt
  4.1579 -	data8 sys_sendmsg			// 1205
  4.1580 -	data8 sys_recvmsg
  4.1581 -	data8 sys_pivot_root
  4.1582 -	data8 sys_mincore
  4.1583 -	data8 sys_madvise
  4.1584 -	data8 sys_newstat			// 1210
  4.1585 -	data8 sys_newlstat
  4.1586 -	data8 sys_newfstat
  4.1587 -	data8 sys_clone2
  4.1588 -	data8 sys_getdents64
  4.1589 -	data8 sys_getunwind			// 1215
  4.1590 -	data8 sys_readahead
  4.1591 -	data8 sys_setxattr
  4.1592 -	data8 sys_lsetxattr
  4.1593 -	data8 sys_fsetxattr
  4.1594 -	data8 sys_getxattr			// 1220
  4.1595 -	data8 sys_lgetxattr
  4.1596 -	data8 sys_fgetxattr
  4.1597 -	data8 sys_listxattr
  4.1598 -	data8 sys_llistxattr
  4.1599 -	data8 sys_flistxattr			// 1225
  4.1600 -	data8 sys_removexattr
  4.1601 -	data8 sys_lremovexattr
  4.1602 -	data8 sys_fremovexattr
  4.1603 -	data8 sys_tkill
  4.1604 -	data8 sys_futex				// 1230
  4.1605 -	data8 sys_sched_setaffinity
  4.1606 -	data8 sys_sched_getaffinity
  4.1607 -	data8 sys_set_tid_address
  4.1608 -	data8 sys_fadvise64_64
  4.1609 -	data8 sys_tgkill 			// 1235
  4.1610 -	data8 sys_exit_group
  4.1611 -	data8 sys_lookup_dcookie
  4.1612 -	data8 sys_io_setup
  4.1613 -	data8 sys_io_destroy
  4.1614 -	data8 sys_io_getevents			// 1240
  4.1615 -	data8 sys_io_submit
  4.1616 -	data8 sys_io_cancel
  4.1617 -	data8 sys_epoll_create
  4.1618 -	data8 sys_epoll_ctl
  4.1619 -	data8 sys_epoll_wait			// 1245
  4.1620 -	data8 sys_restart_syscall
  4.1621 -	data8 sys_semtimedop
  4.1622 -	data8 sys_timer_create
  4.1623 -	data8 sys_timer_settime
  4.1624 -	data8 sys_timer_gettime			// 1250
  4.1625 -	data8 sys_timer_getoverrun
  4.1626 -	data8 sys_timer_delete
  4.1627 -	data8 sys_clock_settime
  4.1628 -	data8 sys_clock_gettime
  4.1629 -	data8 sys_clock_getres			// 1255
  4.1630 -	data8 sys_clock_nanosleep
  4.1631 -	data8 sys_fstatfs64
  4.1632 -	data8 sys_statfs64
  4.1633 -	data8 sys_mbind
  4.1634 -	data8 sys_get_mempolicy			// 1260
  4.1635 -	data8 sys_set_mempolicy
  4.1636 -	data8 sys_mq_open
  4.1637 -	data8 sys_mq_unlink
  4.1638 -	data8 sys_mq_timedsend
  4.1639 -	data8 sys_mq_timedreceive		// 1265
  4.1640 -	data8 sys_mq_notify
  4.1641 -	data8 sys_mq_getsetattr
  4.1642 -	data8 sys_ni_syscall			// reserved for kexec_load
  4.1643 -	data8 sys_ni_syscall			// reserved for vserver
  4.1644 -	data8 sys_waitid			// 1270
  4.1645 -	data8 sys_add_key
  4.1646 -	data8 sys_request_key
  4.1647 -	data8 sys_keyctl
  4.1648 -	data8 sys_ni_syscall
  4.1649 -	data8 sys_ni_syscall			// 1275
  4.1650 -	data8 sys_ni_syscall
  4.1651 -	data8 sys_ni_syscall
  4.1652 -	data8 sys_ni_syscall
  4.1653 -	data8 sys_ni_syscall
  4.1654 -
  4.1655 -	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
  4.1656 -#endif
     5.1 --- a/xen/arch/ia64/entry.h	Tue Aug 02 15:59:09 2005 -0800
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,97 +0,0 @@
     5.4 -#include <linux/config.h>
     5.5 -
     5.6 -/*
     5.7 - * Preserved registers that are shared between code in ivt.S and
     5.8 - * entry.S.  Be careful not to step on these!
     5.9 - */
    5.10 -#define PRED_LEAVE_SYSCALL	1 /* TRUE iff leave from syscall */
    5.11 -#define PRED_KERNEL_STACK	2 /* returning to kernel-stacks? */
    5.12 -#define PRED_USER_STACK		3 /* returning to user-stacks? */
    5.13 -#ifdef CONFIG_VTI
    5.14 -#define PRED_EMUL		2 /* Need to save r4-r7 for inst emulation */
    5.15 -#define PRED_NON_EMUL		3 /* No need to save r4-r7 for normal path */
    5.16 -#define PRED_BN0		6 /* Guest is in bank 0 */
    5.17 -#define PRED_BN1		7 /* Guest is in bank 1 */
    5.18 -#endif // CONFIG_VTI
    5.19 -#define PRED_SYSCALL		4 /* inside a system call? */
    5.20 -#define PRED_NON_SYSCALL	5 /* complement of PRED_SYSCALL */
    5.21 -
    5.22 -#ifdef __ASSEMBLY__
    5.23 -# define PASTE2(x,y)	x##y
    5.24 -# define PASTE(x,y)	PASTE2(x,y)
    5.25 -
    5.26 -# define pLvSys		PASTE(p,PRED_LEAVE_SYSCALL)
    5.27 -# define pKStk		PASTE(p,PRED_KERNEL_STACK)
    5.28 -# define pUStk		PASTE(p,PRED_USER_STACK)
    5.29 -#ifdef CONFIG_VTI
    5.30 -# define pEml		PASTE(p,PRED_EMUL)
    5.31 -# define pNonEml	PASTE(p,PRED_NON_EMUL)
    5.32 -# define pBN0		PASTE(p,PRED_BN0)
    5.33 -# define pBN1		PASTE(p,PRED_BN1)
    5.34 -#endif // CONFIG_VTI
    5.35 -# define pSys		PASTE(p,PRED_SYSCALL)
    5.36 -# define pNonSys	PASTE(p,PRED_NON_SYSCALL)
    5.37 -#endif
    5.38 -
    5.39 -#define PT(f)		(IA64_PT_REGS_##f##_OFFSET)
    5.40 -#define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
    5.41 -#ifdef CONFIG_VTI
    5.42 -#define VPD(f)      (VPD_##f##_START_OFFSET)
    5.43 -#endif // CONFIG_VTI
    5.44 -
    5.45 -#define PT_REGS_SAVES(off)			\
    5.46 -	.unwabi 3, 'i';				\
    5.47 -	.fframe IA64_PT_REGS_SIZE+16+(off);	\
    5.48 -	.spillsp rp, PT(CR_IIP)+16+(off);	\
    5.49 -	.spillsp ar.pfs, PT(CR_IFS)+16+(off);	\
    5.50 -	.spillsp ar.unat, PT(AR_UNAT)+16+(off);	\
    5.51 -	.spillsp ar.fpsr, PT(AR_FPSR)+16+(off);	\
    5.52 -	.spillsp pr, PT(PR)+16+(off);
    5.53 -
    5.54 -#define PT_REGS_UNWIND_INFO(off)		\
    5.55 -	.prologue;				\
    5.56 -	PT_REGS_SAVES(off);			\
    5.57 -	.body
    5.58 -
    5.59 -#define SWITCH_STACK_SAVES(off)							\
    5.60 -	.savesp ar.unat,SW(CALLER_UNAT)+16+(off);				\
    5.61 -	.savesp ar.fpsr,SW(AR_FPSR)+16+(off);					\
    5.62 -	.spillsp f2,SW(F2)+16+(off); .spillsp f3,SW(F3)+16+(off);		\
    5.63 -	.spillsp f4,SW(F4)+16+(off); .spillsp f5,SW(F5)+16+(off);		\
    5.64 -	.spillsp f16,SW(F16)+16+(off); .spillsp f17,SW(F17)+16+(off);		\
    5.65 -	.spillsp f18,SW(F18)+16+(off); .spillsp f19,SW(F19)+16+(off);		\
    5.66 -	.spillsp f20,SW(F20)+16+(off); .spillsp f21,SW(F21)+16+(off);		\
    5.67 -	.spillsp f22,SW(F22)+16+(off); .spillsp f23,SW(F23)+16+(off);		\
    5.68 -	.spillsp f24,SW(F24)+16+(off); .spillsp f25,SW(F25)+16+(off);		\
    5.69 -	.spillsp f26,SW(F26)+16+(off); .spillsp f27,SW(F27)+16+(off);		\
    5.70 -	.spillsp f28,SW(F28)+16+(off); .spillsp f29,SW(F29)+16+(off);		\
    5.71 -	.spillsp f30,SW(F30)+16+(off); .spillsp f31,SW(F31)+16+(off);		\
    5.72 -	.spillsp r4,SW(R4)+16+(off); .spillsp r5,SW(R5)+16+(off);		\
    5.73 -	.spillsp r6,SW(R6)+16+(off); .spillsp r7,SW(R7)+16+(off);		\
    5.74 -	.spillsp b0,SW(B0)+16+(off); .spillsp b1,SW(B1)+16+(off);		\
    5.75 -	.spillsp b2,SW(B2)+16+(off); .spillsp b3,SW(B3)+16+(off);		\
    5.76 -	.spillsp b4,SW(B4)+16+(off); .spillsp b5,SW(B5)+16+(off);		\
    5.77 -	.spillsp ar.pfs,SW(AR_PFS)+16+(off); .spillsp ar.lc,SW(AR_LC)+16+(off);	\
    5.78 -	.spillsp @priunat,SW(AR_UNAT)+16+(off);					\
    5.79 -	.spillsp ar.rnat,SW(AR_RNAT)+16+(off);					\
    5.80 -	.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off);				\
    5.81 -	.spillsp pr,SW(PR)+16+(off))
    5.82 -
    5.83 -#define DO_SAVE_SWITCH_STACK			\
    5.84 -	movl r28=1f;				\
    5.85 -	;;					\
    5.86 -	.fframe IA64_SWITCH_STACK_SIZE;		\
    5.87 -	adds sp=-IA64_SWITCH_STACK_SIZE,sp;	\
    5.88 -	mov.ret.sptk b7=r28,1f;			\
    5.89 -	SWITCH_STACK_SAVES(0);			\
    5.90 -	br.cond.sptk.many save_switch_stack;	\
    5.91 -1:
    5.92 -
    5.93 -#define DO_LOAD_SWITCH_STACK			\
    5.94 -	movl r28=1f;				\
    5.95 -	;;					\
    5.96 -	invala;					\
    5.97 -	mov.ret.sptk b7=r28,1f;			\
    5.98 -	br.cond.sptk.many load_switch_stack;	\
    5.99 -1:	.restore sp;				\
   5.100 -	adds sp=IA64_SWITCH_STACK_SIZE,sp
     6.1 --- a/xen/arch/ia64/head.S	Tue Aug 02 15:59:09 2005 -0800
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,1026 +0,0 @@
     6.4 -/*
     6.5 - * Here is where the ball gets rolling as far as the kernel is concerned.
     6.6 - * When control is transferred to _start, the bootload has already
     6.7 - * loaded us to the correct address.  All that's left to do here is
     6.8 - * to set up the kernel's global pointer and jump to the kernel
     6.9 - * entry point.
    6.10 - *
    6.11 - * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
    6.12 - *	David Mosberger-Tang <davidm@hpl.hp.com>
    6.13 - *	Stephane Eranian <eranian@hpl.hp.com>
    6.14 - * Copyright (C) 1999 VA Linux Systems
    6.15 - * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    6.16 - * Copyright (C) 1999 Intel Corp.
    6.17 - * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
    6.18 - * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
    6.19 - * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com>
    6.20 - *   -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
    6.21 - */
    6.22 -
    6.23 -#include <linux/config.h>
    6.24 -
    6.25 -#include <asm/asmmacro.h>
    6.26 -#include <asm/fpu.h>
    6.27 -#include <asm/kregs.h>
    6.28 -#include <asm/mmu_context.h>
    6.29 -#include <asm/offsets.h>
    6.30 -#include <asm/pal.h>
    6.31 -#include <asm/pgtable.h>
    6.32 -#include <asm/processor.h>
    6.33 -#include <asm/ptrace.h>
    6.34 -#include <asm/system.h>
    6.35 -
    6.36 -	.section __special_page_section,"ax"
    6.37 -
    6.38 -	.global empty_zero_page
    6.39 -empty_zero_page:
    6.40 -	.skip PAGE_SIZE
    6.41 -
    6.42 -	.global swapper_pg_dir
    6.43 -swapper_pg_dir:
    6.44 -	.skip PAGE_SIZE
    6.45 -
    6.46 -	.rodata
    6.47 -halt_msg:
    6.48 -	stringz "Halting kernel\n"
    6.49 -
    6.50 -	.text
    6.51 -
    6.52 -	.global start_ap
    6.53 -
    6.54 -	/*
    6.55 -	 * Start the kernel.  When the bootloader passes control to _start(), r28
    6.56 -	 * points to the address of the boot parameter area.  Execution reaches
    6.57 -	 * here in physical mode.
    6.58 -	 */
    6.59 -GLOBAL_ENTRY(_start)
    6.60 -start_ap:
    6.61 -	.prologue
    6.62 -	.save rp, r0		// terminate unwind chain with a NULL rp
    6.63 -	.body
    6.64 -
    6.65 -	rsm psr.i | psr.ic
    6.66 -	;;
    6.67 -	srlz.i
    6.68 -	;;
    6.69 -	/*
    6.70 -	 * Initialize kernel region registers:
    6.71 -	 *	rr[0]: VHPT enabled, page size = PAGE_SHIFT
    6.72 -	 *	rr[1]: VHPT enabled, page size = PAGE_SHIFT
    6.73 -	 *	rr[2]: VHPT enabled, page size = PAGE_SHIFT
    6.74 -	 *	rr[3]: VHPT enabled, page size = PAGE_SHIFT
    6.75 -	 *	rr[4]: VHPT enabled, page size = PAGE_SHIFT
    6.76 -	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT
    6.77 -	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
    6.78 -	 *	rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT
    6.79 -	 * We initialize all of them to prevent inadvertently assuming
    6.80 -	 * something about the state of address translation early in boot.
    6.81 -	 */
    6.82 -	movl r6=((ia64_rid(IA64_REGION_ID_KERNEL, (0<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.83 -	movl r7=(0<<61)
    6.84 -	movl r8=((ia64_rid(IA64_REGION_ID_KERNEL, (1<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.85 -	movl r9=(1<<61)
    6.86 -	movl r10=((ia64_rid(IA64_REGION_ID_KERNEL, (2<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.87 -	movl r11=(2<<61)
    6.88 -	movl r12=((ia64_rid(IA64_REGION_ID_KERNEL, (3<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.89 -	movl r13=(3<<61)
    6.90 -	movl r14=((ia64_rid(IA64_REGION_ID_KERNEL, (4<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.91 -	movl r15=(4<<61)
    6.92 -	movl r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
    6.93 -	movl r17=(5<<61)
    6.94 -	movl r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
    6.95 -	movl r19=(6<<61)
    6.96 -	movl r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
    6.97 -	movl r21=(7<<61)
    6.98 -	;;
    6.99 -	mov rr[r7]=r6
   6.100 -	mov rr[r9]=r8
   6.101 -	mov rr[r11]=r10
   6.102 -	mov rr[r13]=r12
   6.103 -	mov rr[r15]=r14
   6.104 -	mov rr[r17]=r16
   6.105 -	mov rr[r19]=r18
   6.106 -	mov rr[r21]=r20
   6.107 -	;;
   6.108 -	/*
   6.109 -	 * Now pin mappings into the TLB for kernel text and data
   6.110 -	 */
   6.111 -	mov r18=KERNEL_TR_PAGE_SHIFT<<2
   6.112 -	movl r17=KERNEL_START
   6.113 -	;;
   6.114 -	mov cr.itir=r18
   6.115 -	mov cr.ifa=r17
   6.116 -	mov r16=IA64_TR_KERNEL
   6.117 -	mov r3=ip
   6.118 -	movl r18=PAGE_KERNEL
   6.119 -	;;
   6.120 -	dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
   6.121 -	;;
   6.122 -	or r18=r2,r18
   6.123 -	;;
   6.124 -	srlz.i
   6.125 -	;;
   6.126 -	itr.i itr[r16]=r18
   6.127 -	;;
   6.128 -	itr.d dtr[r16]=r18
   6.129 -	;;
   6.130 -	srlz.i
   6.131 -
   6.132 -	/*
   6.133 -	 * Switch into virtual mode:
   6.134 -	 */
   6.135 -#ifdef CONFIG_VTI
   6.136 -	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH \
   6.137 -		  |IA64_PSR_DI)
   6.138 -#else // CONFIG_VTI
   6.139 -	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
   6.140 -		  |IA64_PSR_DI)
   6.141 -#endif // CONFIG_VTI
   6.142 -	;;
   6.143 -	mov cr.ipsr=r16
   6.144 -	movl r17=1f
   6.145 -	;;
   6.146 -	mov cr.iip=r17
   6.147 -	mov cr.ifs=r0
   6.148 -	;;
   6.149 -	rfi
   6.150 -	;;
   6.151 -1:	// now we are in virtual mode
   6.152 -
   6.153 -	// set IVT entry point---can't access I/O ports without it
   6.154 -#ifdef CONFIG_VTI
   6.155 -    movl r3=vmx_ia64_ivt
   6.156 -#else // CONFIG_VTI
   6.157 -	movl r3=ia64_ivt
   6.158 -#endif // CONFIG_VTI
   6.159 -	;;
   6.160 -	mov cr.iva=r3
   6.161 -	movl r2=FPSR_DEFAULT
   6.162 -	;;
   6.163 -	srlz.i
   6.164 -	movl gp=__gp
   6.165 -
   6.166 -	mov ar.fpsr=r2
   6.167 -	;;
   6.168 -
   6.169 -#define isAP	p2	// are we an Application Processor?
   6.170 -#define isBP	p3	// are we the Bootstrap Processor?
   6.171 -
   6.172 -#ifdef CONFIG_SMP
   6.173 -	/*
   6.174 -	 * Find the init_task for the currently booting CPU.  At poweron, and in
   6.175 -	 * UP mode, task_for_booting_cpu is NULL.
   6.176 -	 */
   6.177 -	movl r3=task_for_booting_cpu
   6.178 - 	;;
   6.179 -	ld8 r3=[r3]
   6.180 -	movl r2=init_task
   6.181 -	;;
   6.182 -	cmp.eq isBP,isAP=r3,r0
   6.183 -	;;
   6.184 -(isAP)	mov r2=r3
   6.185 -#else
   6.186 -	movl r2=init_task
   6.187 -	cmp.eq isBP,isAP=r0,r0
   6.188 -#endif
   6.189 -	;;
   6.190 -	tpa r3=r2		// r3 == phys addr of task struct
   6.191 -	mov r16=-1
   6.192 -(isBP)	br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it
   6.193 -
   6.194 -	// load mapping for stack (virtaddr in r2, physaddr in r3)
   6.195 -	rsm psr.ic
   6.196 -	movl r17=PAGE_KERNEL
   6.197 -	;;
   6.198 -	srlz.d
   6.199 -	dep r18=0,r3,0,12
   6.200 -	;;
   6.201 -	or r18=r17,r18
   6.202 -#ifdef XEN
   6.203 -	dep r2=-1,r3,60,4	// IMVA of task
   6.204 -#else
   6.205 -	dep r2=-1,r3,61,3	// IMVA of task
   6.206 -#endif
   6.207 -	;;
   6.208 -	mov r17=rr[r2]
   6.209 -	shr.u r16=r3,IA64_GRANULE_SHIFT
   6.210 -	;;
   6.211 -	dep r17=0,r17,8,24
   6.212 -	;;
   6.213 -	mov cr.itir=r17
   6.214 -	mov cr.ifa=r2
   6.215 -
   6.216 -	mov r19=IA64_TR_CURRENT_STACK
   6.217 -	;;
   6.218 -	itr.d dtr[r19]=r18
   6.219 -	;;
   6.220 -	ssm psr.ic
   6.221 -	srlz.d
   6.222 -  	;;
   6.223 -
   6.224 -.load_current:
   6.225 -	// load the "current" pointer (r13) and ar.k6 with the current task
   6.226 -#ifdef CONFIG_VTI
   6.227 -	mov r21=r2		// virtual address
   6.228 -	;;
   6.229 -	bsw.1
   6.230 -	;;
   6.231 -#else // CONFIG_VTI
   6.232 -	mov IA64_KR(CURRENT)=r2		// virtual address
   6.233 -	mov IA64_KR(CURRENT_STACK)=r16
   6.234 -#endif // CONFIG_VTI
   6.235 -	mov r13=r2
   6.236 -	/*
   6.237 -	 * Reserve space at the top of the stack for "struct pt_regs".  Kernel threads
   6.238 -	 * don't store interesting values in that structure, but the space still needs
   6.239 -	 * to be there because time-critical stuff such as the context switching can
   6.240 -	 * be implemented more efficiently (for example, __switch_to()
   6.241 -	 * always sets the psr.dfh bit of the task it is switching to).
   6.242 -	 */
   6.243 -	addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2
   6.244 -	addl r2=IA64_RBS_OFFSET,r2	// initialize the RSE
   6.245 -	mov ar.rsc=0		// place RSE in enforced lazy mode
   6.246 -	;;
   6.247 -	loadrs			// clear the dirty partition
   6.248 -	;;
   6.249 -	mov ar.bspstore=r2	// establish the new RSE stack
   6.250 -	;;
   6.251 -	mov ar.rsc=0x3		// place RSE in eager mode
   6.252 -
   6.253 -#ifdef XEN
   6.254 -(isBP)	dep r28=-1,r28,60,4	// make address virtual
   6.255 -#else
   6.256 -(isBP)	dep r28=-1,r28,61,3	// make address virtual
   6.257 -#endif
   6.258 -(isBP)	movl r2=ia64_boot_param
   6.259 -	;;
   6.260 -(isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
   6.261 -
   6.262 -#ifdef CONFIG_SMP
   6.263 -(isAP)	br.call.sptk.many rp=start_secondary
   6.264 -.ret0:
   6.265 -(isAP)	br.cond.sptk self
   6.266 -#endif
   6.267 -
   6.268 -	// This is executed by the bootstrap processor (bsp) only:
   6.269 -
   6.270 -#ifdef CONFIG_IA64_FW_EMU
   6.271 -	// initialize PAL & SAL emulator:
   6.272 -	br.call.sptk.many rp=sys_fw_init
   6.273 -.ret1:
   6.274 -#endif
   6.275 -	br.call.sptk.many rp=start_kernel
   6.276 -.ret2:	addl r3=@ltoff(halt_msg),gp
   6.277 -	;;
   6.278 -	alloc r2=ar.pfs,8,0,2,0
   6.279 -	;;
   6.280 -	ld8 out0=[r3]
   6.281 -	br.call.sptk.many b0=console_print
   6.282 -
   6.283 -self:	hint @pause
   6.284 -	;;
   6.285 -	br.sptk.many self		// endless loop
   6.286 -	;;
   6.287 -END(_start)
   6.288 -
   6.289 -GLOBAL_ENTRY(ia64_save_debug_regs)
   6.290 -	alloc r16=ar.pfs,1,0,0,0
   6.291 -	mov r20=ar.lc			// preserve ar.lc
   6.292 -	mov ar.lc=IA64_NUM_DBG_REGS-1
   6.293 -	mov r18=0
   6.294 -	add r19=IA64_NUM_DBG_REGS*8,in0
   6.295 -	;;
   6.296 -1:	mov r16=dbr[r18]
   6.297 -#ifdef CONFIG_ITANIUM
   6.298 -	;;
   6.299 -	srlz.d
   6.300 -#endif
   6.301 -	mov r17=ibr[r18]
   6.302 -	add r18=1,r18
   6.303 -	;;
   6.304 -	st8.nta [in0]=r16,8
   6.305 -	st8.nta [r19]=r17,8
   6.306 -	br.cloop.sptk.many 1b
   6.307 -	;;
   6.308 -	mov ar.lc=r20			// restore ar.lc
   6.309 -	br.ret.sptk.many rp
   6.310 -END(ia64_save_debug_regs)
   6.311 -
   6.312 -GLOBAL_ENTRY(ia64_load_debug_regs)
   6.313 -	alloc r16=ar.pfs,1,0,0,0
   6.314 -	lfetch.nta [in0]
   6.315 -	mov r20=ar.lc			// preserve ar.lc
   6.316 -	add r19=IA64_NUM_DBG_REGS*8,in0
   6.317 -	mov ar.lc=IA64_NUM_DBG_REGS-1
   6.318 -	mov r18=-1
   6.319 -	;;
   6.320 -1:	ld8.nta r16=[in0],8
   6.321 -	ld8.nta r17=[r19],8
   6.322 -	add r18=1,r18
   6.323 -	;;
   6.324 -	mov dbr[r18]=r16
   6.325 -#ifdef CONFIG_ITANIUM
   6.326 -	;;
   6.327 -	srlz.d				// Errata 132 (NoFix status)
   6.328 -#endif
   6.329 -	mov ibr[r18]=r17
   6.330 -	br.cloop.sptk.many 1b
   6.331 -	;;
   6.332 -	mov ar.lc=r20			// restore ar.lc
   6.333 -	br.ret.sptk.many rp
   6.334 -END(ia64_load_debug_regs)
   6.335 -
   6.336 -GLOBAL_ENTRY(__ia64_save_fpu)
   6.337 -	alloc r2=ar.pfs,1,4,0,0
   6.338 -	adds loc0=96*16-16,in0
   6.339 -	adds loc1=96*16-16-128,in0
   6.340 -	;;
   6.341 -	stf.spill.nta [loc0]=f127,-256
   6.342 -	stf.spill.nta [loc1]=f119,-256
   6.343 -	;;
   6.344 -	stf.spill.nta [loc0]=f111,-256
   6.345 -	stf.spill.nta [loc1]=f103,-256
   6.346 -	;;
   6.347 -	stf.spill.nta [loc0]=f95,-256
   6.348 -	stf.spill.nta [loc1]=f87,-256
   6.349 -	;;
   6.350 -	stf.spill.nta [loc0]=f79,-256
   6.351 -	stf.spill.nta [loc1]=f71,-256
   6.352 -	;;
   6.353 -	stf.spill.nta [loc0]=f63,-256
   6.354 -	stf.spill.nta [loc1]=f55,-256
   6.355 -	adds loc2=96*16-32,in0
   6.356 -	;;
   6.357 -	stf.spill.nta [loc0]=f47,-256
   6.358 -	stf.spill.nta [loc1]=f39,-256
   6.359 -	adds loc3=96*16-32-128,in0
   6.360 -	;;
   6.361 -	stf.spill.nta [loc2]=f126,-256
   6.362 -	stf.spill.nta [loc3]=f118,-256
   6.363 -	;;
   6.364 -	stf.spill.nta [loc2]=f110,-256
   6.365 -	stf.spill.nta [loc3]=f102,-256
   6.366 -	;;
   6.367 -	stf.spill.nta [loc2]=f94,-256
   6.368 -	stf.spill.nta [loc3]=f86,-256
   6.369 -	;;
   6.370 -	stf.spill.nta [loc2]=f78,-256
   6.371 -	stf.spill.nta [loc3]=f70,-256
   6.372 -	;;
   6.373 -	stf.spill.nta [loc2]=f62,-256
   6.374 -	stf.spill.nta [loc3]=f54,-256
   6.375 -	adds loc0=96*16-48,in0
   6.376 -	;;
   6.377 -	stf.spill.nta [loc2]=f46,-256
   6.378 -	stf.spill.nta [loc3]=f38,-256
   6.379 -	adds loc1=96*16-48-128,in0
   6.380 -	;;
   6.381 -	stf.spill.nta [loc0]=f125,-256
   6.382 -	stf.spill.nta [loc1]=f117,-256
   6.383 -	;;
   6.384 -	stf.spill.nta [loc0]=f109,-256
   6.385 -	stf.spill.nta [loc1]=f101,-256
   6.386 -	;;
   6.387 -	stf.spill.nta [loc0]=f93,-256
   6.388 -	stf.spill.nta [loc1]=f85,-256
   6.389 -	;;
   6.390 -	stf.spill.nta [loc0]=f77,-256
   6.391 -	stf.spill.nta [loc1]=f69,-256
   6.392 -	;;
   6.393 -	stf.spill.nta [loc0]=f61,-256
   6.394 -	stf.spill.nta [loc1]=f53,-256
   6.395 -	adds loc2=96*16-64,in0
   6.396 -	;;
   6.397 -	stf.spill.nta [loc0]=f45,-256
   6.398 -	stf.spill.nta [loc1]=f37,-256
   6.399 -	adds loc3=96*16-64-128,in0
   6.400 -	;;
   6.401 -	stf.spill.nta [loc2]=f124,-256
   6.402 -	stf.spill.nta [loc3]=f116,-256
   6.403 -	;;
   6.404 -	stf.spill.nta [loc2]=f108,-256
   6.405 -	stf.spill.nta [loc3]=f100,-256
   6.406 -	;;
   6.407 -	stf.spill.nta [loc2]=f92,-256
   6.408 -	stf.spill.nta [loc3]=f84,-256
   6.409 -	;;
   6.410 -	stf.spill.nta [loc2]=f76,-256
   6.411 -	stf.spill.nta [loc3]=f68,-256
   6.412 -	;;
   6.413 -	stf.spill.nta [loc2]=f60,-256
   6.414 -	stf.spill.nta [loc3]=f52,-256
   6.415 -	adds loc0=96*16-80,in0
   6.416 -	;;
   6.417 -	stf.spill.nta [loc2]=f44,-256
   6.418 -	stf.spill.nta [loc3]=f36,-256
   6.419 -	adds loc1=96*16-80-128,in0
   6.420 -	;;
   6.421 -	stf.spill.nta [loc0]=f123,-256
   6.422 -	stf.spill.nta [loc1]=f115,-256
   6.423 -	;;
   6.424 -	stf.spill.nta [loc0]=f107,-256
   6.425 -	stf.spill.nta [loc1]=f99,-256
   6.426 -	;;
   6.427 -	stf.spill.nta [loc0]=f91,-256
   6.428 -	stf.spill.nta [loc1]=f83,-256
   6.429 -	;;
   6.430 -	stf.spill.nta [loc0]=f75,-256
   6.431 -	stf.spill.nta [loc1]=f67,-256
   6.432 -	;;
   6.433 -	stf.spill.nta [loc0]=f59,-256
   6.434 -	stf.spill.nta [loc1]=f51,-256
   6.435 -	adds loc2=96*16-96,in0
   6.436 -	;;
   6.437 -	stf.spill.nta [loc0]=f43,-256
   6.438 -	stf.spill.nta [loc1]=f35,-256
   6.439 -	adds loc3=96*16-96-128,in0
   6.440 -	;;
   6.441 -	stf.spill.nta [loc2]=f122,-256
   6.442 -	stf.spill.nta [loc3]=f114,-256
   6.443 -	;;
   6.444 -	stf.spill.nta [loc2]=f106,-256
   6.445 -	stf.spill.nta [loc3]=f98,-256
   6.446 -	;;
   6.447 -	stf.spill.nta [loc2]=f90,-256
   6.448 -	stf.spill.nta [loc3]=f82,-256
   6.449 -	;;
   6.450 -	stf.spill.nta [loc2]=f74,-256
   6.451 -	stf.spill.nta [loc3]=f66,-256
   6.452 -	;;
   6.453 -	stf.spill.nta [loc2]=f58,-256
   6.454 -	stf.spill.nta [loc3]=f50,-256
   6.455 -	adds loc0=96*16-112,in0
   6.456 -	;;
   6.457 -	stf.spill.nta [loc2]=f42,-256
   6.458 -	stf.spill.nta [loc3]=f34,-256
   6.459 -	adds loc1=96*16-112-128,in0
   6.460 -	;;
   6.461 -	stf.spill.nta [loc0]=f121,-256
   6.462 -	stf.spill.nta [loc1]=f113,-256
   6.463 -	;;
   6.464 -	stf.spill.nta [loc0]=f105,-256
   6.465 -	stf.spill.nta [loc1]=f97,-256
   6.466 -	;;
   6.467 -	stf.spill.nta [loc0]=f89,-256
   6.468 -	stf.spill.nta [loc1]=f81,-256
   6.469 -	;;
   6.470 -	stf.spill.nta [loc0]=f73,-256
   6.471 -	stf.spill.nta [loc1]=f65,-256
   6.472 -	;;
   6.473 -	stf.spill.nta [loc0]=f57,-256
   6.474 -	stf.spill.nta [loc1]=f49,-256
   6.475 -	adds loc2=96*16-128,in0
   6.476 -	;;
   6.477 -	stf.spill.nta [loc0]=f41,-256
   6.478 -	stf.spill.nta [loc1]=f33,-256
   6.479 -	adds loc3=96*16-128-128,in0
   6.480 -	;;
   6.481 -	stf.spill.nta [loc2]=f120,-256
   6.482 -	stf.spill.nta [loc3]=f112,-256
   6.483 -	;;
   6.484 -	stf.spill.nta [loc2]=f104,-256
   6.485 -	stf.spill.nta [loc3]=f96,-256
   6.486 -	;;
   6.487 -	stf.spill.nta [loc2]=f88,-256
   6.488 -	stf.spill.nta [loc3]=f80,-256
   6.489 -	;;
   6.490 -	stf.spill.nta [loc2]=f72,-256
   6.491 -	stf.spill.nta [loc3]=f64,-256
   6.492 -	;;
   6.493 -	stf.spill.nta [loc2]=f56,-256
   6.494 -	stf.spill.nta [loc3]=f48,-256
   6.495 -	;;
   6.496 -	stf.spill.nta [loc2]=f40
   6.497 -	stf.spill.nta [loc3]=f32
   6.498 -	br.ret.sptk.many rp
   6.499 -END(__ia64_save_fpu)
   6.500 -
   6.501 -GLOBAL_ENTRY(__ia64_load_fpu)
   6.502 -	alloc r2=ar.pfs,1,2,0,0
   6.503 -	adds r3=128,in0
   6.504 -	adds r14=256,in0
   6.505 -	adds r15=384,in0
   6.506 -	mov loc0=512
   6.507 -	mov loc1=-1024+16
   6.508 -	;;
   6.509 -	ldf.fill.nta f32=[in0],loc0
   6.510 -	ldf.fill.nta f40=[ r3],loc0
   6.511 -	ldf.fill.nta f48=[r14],loc0
   6.512 -	ldf.fill.nta f56=[r15],loc0
   6.513 -	;;
   6.514 -	ldf.fill.nta f64=[in0],loc0
   6.515 -	ldf.fill.nta f72=[ r3],loc0
   6.516 -	ldf.fill.nta f80=[r14],loc0
   6.517 -	ldf.fill.nta f88=[r15],loc0
   6.518 -	;;
   6.519 -	ldf.fill.nta f96=[in0],loc1
   6.520 -	ldf.fill.nta f104=[ r3],loc1
   6.521 -	ldf.fill.nta f112=[r14],loc1
   6.522 -	ldf.fill.nta f120=[r15],loc1
   6.523 -	;;
   6.524 -	ldf.fill.nta f33=[in0],loc0
   6.525 -	ldf.fill.nta f41=[ r3],loc0
   6.526 -	ldf.fill.nta f49=[r14],loc0
   6.527 -	ldf.fill.nta f57=[r15],loc0
   6.528 -	;;
   6.529 -	ldf.fill.nta f65=[in0],loc0
   6.530 -	ldf.fill.nta f73=[ r3],loc0
   6.531 -	ldf.fill.nta f81=[r14],loc0
   6.532 -	ldf.fill.nta f89=[r15],loc0
   6.533 -	;;
   6.534 -	ldf.fill.nta f97=[in0],loc1
   6.535 -	ldf.fill.nta f105=[ r3],loc1
   6.536 -	ldf.fill.nta f113=[r14],loc1
   6.537 -	ldf.fill.nta f121=[r15],loc1
   6.538 -	;;
   6.539 -	ldf.fill.nta f34=[in0],loc0
   6.540 -	ldf.fill.nta f42=[ r3],loc0
   6.541 -	ldf.fill.nta f50=[r14],loc0
   6.542 -	ldf.fill.nta f58=[r15],loc0
   6.543 -	;;
   6.544 -	ldf.fill.nta f66=[in0],loc0
   6.545 -	ldf.fill.nta f74=[ r3],loc0
   6.546 -	ldf.fill.nta f82=[r14],loc0
   6.547 -	ldf.fill.nta f90=[r15],loc0
   6.548 -	;;
   6.549 -	ldf.fill.nta f98=[in0],loc1
   6.550 -	ldf.fill.nta f106=[ r3],loc1
   6.551 -	ldf.fill.nta f114=[r14],loc1
   6.552 -	ldf.fill.nta f122=[r15],loc1
   6.553 -	;;
   6.554 -	ldf.fill.nta f35=[in0],loc0
   6.555 -	ldf.fill.nta f43=[ r3],loc0
   6.556 -	ldf.fill.nta f51=[r14],loc0
   6.557 -	ldf.fill.nta f59=[r15],loc0
   6.558 -	;;
   6.559 -	ldf.fill.nta f67=[in0],loc0
   6.560 -	ldf.fill.nta f75=[ r3],loc0
   6.561 -	ldf.fill.nta f83=[r14],loc0
   6.562 -	ldf.fill.nta f91=[r15],loc0
   6.563 -	;;
   6.564 -	ldf.fill.nta f99=[in0],loc1
   6.565 -	ldf.fill.nta f107=[ r3],loc1
   6.566 -	ldf.fill.nta f115=[r14],loc1
   6.567 -	ldf.fill.nta f123=[r15],loc1
   6.568 -	;;
   6.569 -	ldf.fill.nta f36=[in0],loc0
   6.570 -	ldf.fill.nta f44=[ r3],loc0
   6.571 -	ldf.fill.nta f52=[r14],loc0
   6.572 -	ldf.fill.nta f60=[r15],loc0
   6.573 -	;;
   6.574 -	ldf.fill.nta f68=[in0],loc0
   6.575 -	ldf.fill.nta f76=[ r3],loc0
   6.576 -	ldf.fill.nta f84=[r14],loc0
   6.577 -	ldf.fill.nta f92=[r15],loc0
   6.578 -	;;
   6.579 -	ldf.fill.nta f100=[in0],loc1
   6.580 -	ldf.fill.nta f108=[ r3],loc1
   6.581 -	ldf.fill.nta f116=[r14],loc1
   6.582 -	ldf.fill.nta f124=[r15],loc1
   6.583 -	;;
   6.584 -	ldf.fill.nta f37=[in0],loc0
   6.585 -	ldf.fill.nta f45=[ r3],loc0
   6.586 -	ldf.fill.nta f53=[r14],loc0
   6.587 -	ldf.fill.nta f61=[r15],loc0
   6.588 -	;;
   6.589 -	ldf.fill.nta f69=[in0],loc0
   6.590 -	ldf.fill.nta f77=[ r3],loc0
   6.591 -	ldf.fill.nta f85=[r14],loc0
   6.592 -	ldf.fill.nta f93=[r15],loc0
   6.593 -	;;
   6.594 -	ldf.fill.nta f101=[in0],loc1
   6.595 -	ldf.fill.nta f109=[ r3],loc1
   6.596 -	ldf.fill.nta f117=[r14],loc1
   6.597 -	ldf.fill.nta f125=[r15],loc1
   6.598 -	;;
   6.599 -	ldf.fill.nta f38 =[in0],loc0
   6.600 -	ldf.fill.nta f46 =[ r3],loc0
   6.601 -	ldf.fill.nta f54 =[r14],loc0
   6.602 -	ldf.fill.nta f62 =[r15],loc0
   6.603 -	;;
   6.604 -	ldf.fill.nta f70 =[in0],loc0
   6.605 -	ldf.fill.nta f78 =[ r3],loc0
   6.606 -	ldf.fill.nta f86 =[r14],loc0
   6.607 -	ldf.fill.nta f94 =[r15],loc0
   6.608 -	;;
   6.609 -	ldf.fill.nta f102=[in0],loc1
   6.610 -	ldf.fill.nta f110=[ r3],loc1
   6.611 -	ldf.fill.nta f118=[r14],loc1
   6.612 -	ldf.fill.nta f126=[r15],loc1
   6.613 -	;;
   6.614 -	ldf.fill.nta f39 =[in0],loc0
   6.615 -	ldf.fill.nta f47 =[ r3],loc0
   6.616 -	ldf.fill.nta f55 =[r14],loc0
   6.617 -	ldf.fill.nta f63 =[r15],loc0
   6.618 -	;;
   6.619 -	ldf.fill.nta f71 =[in0],loc0
   6.620 -	ldf.fill.nta f79 =[ r3],loc0
   6.621 -	ldf.fill.nta f87 =[r14],loc0
   6.622 -	ldf.fill.nta f95 =[r15],loc0
   6.623 -	;;
   6.624 -	ldf.fill.nta f103=[in0]
   6.625 -	ldf.fill.nta f111=[ r3]
   6.626 -	ldf.fill.nta f119=[r14]
   6.627 -	ldf.fill.nta f127=[r15]
   6.628 -	br.ret.sptk.many rp
   6.629 -END(__ia64_load_fpu)
   6.630 -
   6.631 -GLOBAL_ENTRY(__ia64_init_fpu)
   6.632 -	stf.spill [sp]=f0		// M3
   6.633 -	mov	 f32=f0			// F
   6.634 -	nop.b	 0
   6.635 -
   6.636 -	ldfps	 f33,f34=[sp]		// M0
   6.637 -	ldfps	 f35,f36=[sp]		// M1
   6.638 -	mov      f37=f0			// F
   6.639 -	;;
   6.640 -
   6.641 -	setf.s	 f38=r0			// M2
   6.642 -	setf.s	 f39=r0			// M3
   6.643 -	mov      f40=f0			// F
   6.644 -
   6.645 -	ldfps	 f41,f42=[sp]		// M0
   6.646 -	ldfps	 f43,f44=[sp]		// M1
   6.647 -	mov      f45=f0			// F
   6.648 -
   6.649 -	setf.s	 f46=r0			// M2
   6.650 -	setf.s	 f47=r0			// M3
   6.651 -	mov      f48=f0			// F
   6.652 -
   6.653 -	ldfps	 f49,f50=[sp]		// M0
   6.654 -	ldfps	 f51,f52=[sp]		// M1
   6.655 -	mov      f53=f0			// F
   6.656 -
   6.657 -	setf.s	 f54=r0			// M2
   6.658 -	setf.s	 f55=r0			// M3
   6.659 -	mov      f56=f0			// F
   6.660 -
   6.661 -	ldfps	 f57,f58=[sp]		// M0
   6.662 -	ldfps	 f59,f60=[sp]		// M1
   6.663 -	mov      f61=f0			// F
   6.664 -
   6.665 -	setf.s	 f62=r0			// M2
   6.666 -	setf.s	 f63=r0			// M3
   6.667 -	mov      f64=f0			// F
   6.668 -
   6.669 -	ldfps	 f65,f66=[sp]		// M0
   6.670 -	ldfps	 f67,f68=[sp]		// M1
   6.671 -	mov      f69=f0			// F
   6.672 -
   6.673 -	setf.s	 f70=r0			// M2
   6.674 -	setf.s	 f71=r0			// M3
   6.675 -	mov      f72=f0			// F
   6.676 -
   6.677 -	ldfps	 f73,f74=[sp]		// M0
   6.678 -	ldfps	 f75,f76=[sp]		// M1
   6.679 -	mov      f77=f0			// F
   6.680 -
   6.681 -	setf.s	 f78=r0			// M2
   6.682 -	setf.s	 f79=r0			// M3
   6.683 -	mov      f80=f0			// F
   6.684 -
   6.685 -	ldfps	 f81,f82=[sp]		// M0
   6.686 -	ldfps	 f83,f84=[sp]		// M1
   6.687 -	mov      f85=f0			// F
   6.688 -
   6.689 -	setf.s	 f86=r0			// M2
   6.690 -	setf.s	 f87=r0			// M3
   6.691 -	mov      f88=f0			// F
   6.692 -
   6.693 -	/*
   6.694 -	 * When the instructions are cached, it would be faster to initialize
   6.695 -	 * the remaining registers with simply mov instructions (F-unit).
   6.696 -	 * This gets the time down to ~29 cycles.  However, this would use up
   6.697 -	 * 33 bundles, whereas continuing with the above pattern yields
   6.698 -	 * 10 bundles and ~30 cycles.
   6.699 -	 */
   6.700 -
   6.701 -	ldfps	 f89,f90=[sp]		// M0
   6.702 -	ldfps	 f91,f92=[sp]		// M1
   6.703 -	mov      f93=f0			// F
   6.704 -
   6.705 -	setf.s	 f94=r0			// M2
   6.706 -	setf.s	 f95=r0			// M3
   6.707 -	mov      f96=f0			// F
   6.708 -
   6.709 -	ldfps	 f97,f98=[sp]		// M0
   6.710 -	ldfps	 f99,f100=[sp]		// M1
   6.711 -	mov      f101=f0		// F
   6.712 -
   6.713 -	setf.s	 f102=r0		// M2
   6.714 -	setf.s	 f103=r0		// M3
   6.715 -	mov      f104=f0		// F
   6.716 -
   6.717 -	ldfps	 f105,f106=[sp]		// M0
   6.718 -	ldfps	 f107,f108=[sp]		// M1
   6.719 -	mov      f109=f0		// F
   6.720 -
   6.721 -	setf.s	 f110=r0		// M2
   6.722 -	setf.s	 f111=r0		// M3
   6.723 -	mov      f112=f0		// F
   6.724 -
   6.725 -	ldfps	 f113,f114=[sp]		// M0
   6.726 -	ldfps	 f115,f116=[sp]		// M1
   6.727 -	mov      f117=f0		// F
   6.728 -
   6.729 -	setf.s	 f118=r0		// M2
   6.730 -	setf.s	 f119=r0		// M3
   6.731 -	mov      f120=f0		// F
   6.732 -
   6.733 -	ldfps	 f121,f122=[sp]		// M0
   6.734 -	ldfps	 f123,f124=[sp]		// M1
   6.735 -	mov      f125=f0		// F
   6.736 -
   6.737 -	setf.s	 f126=r0		// M2
   6.738 -	setf.s	 f127=r0		// M3
   6.739 -	br.ret.sptk.many rp		// F
   6.740 -END(__ia64_init_fpu)
   6.741 -
   6.742 -/*
   6.743 - * Switch execution mode from virtual to physical
   6.744 - *
   6.745 - * Inputs:
   6.746 - *	r16 = new psr to establish
   6.747 - * Output:
   6.748 - *	r19 = old virtual address of ar.bsp
   6.749 - *	r20 = old virtual address of sp
   6.750 - *
   6.751 - * Note: RSE must already be in enforced lazy mode
   6.752 - */
   6.753 -GLOBAL_ENTRY(ia64_switch_mode_phys)
   6.754 - {
   6.755 -	alloc r2=ar.pfs,0,0,0,0
   6.756 -	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
   6.757 -	mov r15=ip
   6.758 - }
   6.759 -	;;
   6.760 - {
   6.761 -	flushrs				// must be first insn in group
   6.762 -	srlz.i
   6.763 - }
   6.764 -	;;
   6.765 -	mov cr.ipsr=r16			// set new PSR
   6.766 -	add r3=1f-ia64_switch_mode_phys,r15
   6.767 -
   6.768 -	mov r19=ar.bsp
   6.769 -	mov r20=sp
   6.770 -	mov r14=rp			// get return address into a general register
   6.771 -	;;
   6.772 -
   6.773 -	// going to physical mode, use tpa to translate virt->phys
   6.774 -	tpa r17=r19
   6.775 -	tpa r3=r3
   6.776 -	tpa sp=sp
   6.777 -	tpa r14=r14
   6.778 -	;;
   6.779 -
   6.780 -	mov r18=ar.rnat			// save ar.rnat
   6.781 -	mov ar.bspstore=r17		// this steps on ar.rnat
   6.782 -	mov cr.iip=r3
   6.783 -	mov cr.ifs=r0
   6.784 -	;;
   6.785 -	mov ar.rnat=r18			// restore ar.rnat
   6.786 -	rfi				// must be last insn in group
   6.787 -	;;
   6.788 -1:	mov rp=r14
   6.789 -	br.ret.sptk.many rp
   6.790 -END(ia64_switch_mode_phys)
   6.791 -
   6.792 -/*
   6.793 - * Switch execution mode from physical to virtual
   6.794 - *
   6.795 - * Inputs:
   6.796 - *	r16 = new psr to establish
   6.797 - *	r19 = new bspstore to establish
   6.798 - *	r20 = new sp to establish
   6.799 - *
   6.800 - * Note: RSE must already be in enforced lazy mode
   6.801 - */
   6.802 -GLOBAL_ENTRY(ia64_switch_mode_virt)
   6.803 - {
   6.804 -	alloc r2=ar.pfs,0,0,0,0
   6.805 -	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
   6.806 -	mov r15=ip
   6.807 - }
   6.808 -	;;
   6.809 - {
   6.810 -	flushrs				// must be first insn in group
   6.811 -	srlz.i
   6.812 - }
   6.813 -	;;
   6.814 -	mov cr.ipsr=r16			// set new PSR
   6.815 -	add r3=1f-ia64_switch_mode_virt,r15
   6.816 -
   6.817 -	mov r14=rp			// get return address into a general register
   6.818 -	;;
   6.819 -
   6.820 -	// going to virtual
   6.821 -	//   - for code addresses, set upper bits of addr to KERNEL_START
   6.822 -	//   - for stack addresses, copy from input argument
   6.823 -	movl r18=KERNEL_START
   6.824 -	dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
   6.825 -	dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
   6.826 -	mov sp=r20
   6.827 -	;;
   6.828 -	or r3=r3,r18
   6.829 -	or r14=r14,r18
   6.830 -	;;
   6.831 -
   6.832 -	mov r18=ar.rnat			// save ar.rnat
   6.833 -	mov ar.bspstore=r19		// this steps on ar.rnat
   6.834 -	mov cr.iip=r3
   6.835 -	mov cr.ifs=r0
   6.836 -	;;
   6.837 -	mov ar.rnat=r18			// restore ar.rnat
   6.838 -	rfi				// must be last insn in group
   6.839 -	;;
   6.840 -1:	mov rp=r14
   6.841 -	br.ret.sptk.many rp
   6.842 -END(ia64_switch_mode_virt)
   6.843 -
   6.844 -GLOBAL_ENTRY(ia64_delay_loop)
   6.845 -	.prologue
   6.846 -{	nop 0			// work around GAS unwind info generation bug...
   6.847 -	.save ar.lc,r2
   6.848 -	mov r2=ar.lc
   6.849 -	.body
   6.850 -	;;
   6.851 -	mov ar.lc=r32
   6.852 -}
   6.853 -	;;
   6.854 -	// force loop to be 32-byte aligned (GAS bug means we cannot use .align
   6.855 -	// inside function body without corrupting unwind info).
   6.856 -{	nop 0 }
   6.857 -1:	br.cloop.sptk.few 1b
   6.858 -	;;
   6.859 -	mov ar.lc=r2
   6.860 -	br.ret.sptk.many rp
   6.861 -END(ia64_delay_loop)
   6.862 -
   6.863 -/*
   6.864 - * Return a CPU-local timestamp in nano-seconds.  This timestamp is
   6.865 - * NOT synchronized across CPUs its return value must never be
   6.866 - * compared against the values returned on another CPU.  The usage in
   6.867 - * kernel/sched.c ensures that.
   6.868 - *
   6.869 - * The return-value of sched_clock() is NOT supposed to wrap-around.
   6.870 - * If it did, it would cause some scheduling hiccups (at the worst).
   6.871 - * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even
   6.872 - * that would happen only once every 5+ years.
   6.873 - *
   6.874 - * The code below basically calculates:
   6.875 - *
   6.876 - *   (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
   6.877 - *
   6.878 - * except that the multiplication and the shift are done with 128-bit
   6.879 - * intermediate precision so that we can produce a full 64-bit result.
   6.880 - */
   6.881 -GLOBAL_ENTRY(sched_clock)
   6.882 -#ifdef XEN
   6.883 -	movl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET
   6.884 -#else
   6.885 -	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
   6.886 -#endif
   6.887 -	mov.m r9=ar.itc		// fetch cycle-counter				(35 cyc)
   6.888 -	;;
   6.889 -	ldf8 f8=[r8]
   6.890 -	;;
   6.891 -	setf.sig f9=r9		// certain to stall, so issue it _after_ ldf8...
   6.892 -	;;
   6.893 -	xmpy.lu f10=f9,f8	// calculate low 64 bits of 128-bit product	(4 cyc)
   6.894 -	xmpy.hu f11=f9,f8	// calculate high 64 bits of 128-bit product
   6.895 -	;;
   6.896 -	getf.sig r8=f10		//						(5 cyc)
   6.897 -	getf.sig r9=f11
   6.898 -	;;
   6.899 -	shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
   6.900 -	br.ret.sptk.many rp
   6.901 -END(sched_clock)
   6.902 -
   6.903 -GLOBAL_ENTRY(start_kernel_thread)
   6.904 -	.prologue
   6.905 -	.save rp, r0				// this is the end of the call-chain
   6.906 -	.body
   6.907 -	alloc r2 = ar.pfs, 0, 0, 2, 0
   6.908 -	mov out0 = r9
   6.909 -	mov out1 = r11;;
   6.910 -	br.call.sptk.many rp = kernel_thread_helper;;
   6.911 -	mov out0 = r8
   6.912 -	br.call.sptk.many rp = sys_exit;;
   6.913 -1:	br.sptk.few 1b				// not reached
   6.914 -END(start_kernel_thread)
   6.915 -
   6.916 -#ifdef CONFIG_IA64_BRL_EMU
   6.917 -
   6.918 -/*
   6.919 - *  Assembly routines used by brl_emu.c to set preserved register state.
   6.920 - */
   6.921 -
   6.922 -#define SET_REG(reg)				\
   6.923 - GLOBAL_ENTRY(ia64_set_##reg);			\
   6.924 -	alloc r16=ar.pfs,1,0,0,0;		\
   6.925 -	mov reg=r32;				\
   6.926 -	;;					\
   6.927 -	br.ret.sptk.many rp;			\
   6.928 - END(ia64_set_##reg)
   6.929 -
   6.930 -SET_REG(b1);
   6.931 -SET_REG(b2);
   6.932 -SET_REG(b3);
   6.933 -SET_REG(b4);
   6.934 -SET_REG(b5);
   6.935 -
   6.936 -#endif /* CONFIG_IA64_BRL_EMU */
   6.937 -
   6.938 -#ifdef CONFIG_SMP
   6.939 -	/*
   6.940 -	 * This routine handles spinlock contention.  It uses a non-standard calling
   6.941 -	 * convention to avoid converting leaf routines into interior routines.  Because
   6.942 -	 * of this special convention, there are several restrictions:
   6.943 -	 *
   6.944 -	 * - do not use gp relative variables, this code is called from the kernel
   6.945 -	 *   and from modules, r1 is undefined.
   6.946 -	 * - do not use stacked registers, the caller owns them.
   6.947 -	 * - do not use the scratch stack space, the caller owns it.
   6.948 -	 * - do not use any registers other than the ones listed below
   6.949 -	 *
   6.950 -	 * Inputs:
   6.951 -	 *   ar.pfs - saved CFM of caller
   6.952 -	 *   ar.ccv - 0 (and available for use)
   6.953 -	 *   r27    - flags from spin_lock_irqsave or 0.  Must be preserved.
   6.954 -	 *   r28    - available for use.
   6.955 -	 *   r29    - available for use.
   6.956 -	 *   r30    - available for use.
   6.957 -	 *   r31    - address of lock, available for use.
   6.958 -	 *   b6     - return address
   6.959 -	 *   p14    - available for use.
   6.960 -	 *   p15    - used to track flag status.
   6.961 -	 *
   6.962 -	 * If you patch this code to use more registers, do not forget to update
   6.963 -	 * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h.
   6.964 -	 */
   6.965 -
   6.966 -#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
   6.967 -
   6.968 -GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4)
   6.969 -	.prologue
   6.970 -	.save ar.pfs, r0	// this code effectively has a zero frame size
   6.971 -	.save rp, r28
   6.972 -	.body
   6.973 -	nop 0
   6.974 -	tbit.nz p15,p0=r27,IA64_PSR_I_BIT
   6.975 -	.restore sp		// pop existing prologue after next insn
   6.976 -	mov b6 = r28
   6.977 -	.prologue
   6.978 -	.save ar.pfs, r0
   6.979 -	.altrp b6
   6.980 -	.body
   6.981 -	;;
   6.982 -(p15)	ssm psr.i		// reenable interrupts if they were on
   6.983 -				// DavidM says that srlz.d is slow and is not required in this case
   6.984 -.wait:
   6.985 -	// exponential backoff, kdb, lockmeter etc. go in here
   6.986 -	hint @pause
   6.987 -	ld4 r30=[r31]		// don't use ld4.bias; if it's contended, we won't write the word
   6.988 -	nop 0
   6.989 -	;;
   6.990 -	cmp4.ne p14,p0=r30,r0
   6.991 -(p14)	br.cond.sptk.few .wait
   6.992 -(p15)	rsm psr.i		// disable interrupts if we reenabled them
   6.993 -	br.cond.sptk.few b6	// lock is now free, try to acquire
   6.994 -	.global ia64_spinlock_contention_pre3_4_end	// for kernprof
   6.995 -ia64_spinlock_contention_pre3_4_end:
   6.996 -END(ia64_spinlock_contention_pre3_4)
   6.997 -
   6.998 -#else
   6.999 -
  6.1000 -GLOBAL_ENTRY(ia64_spinlock_contention)
  6.1001 -	.prologue
  6.1002 -	.altrp b6
  6.1003 -	.body
  6.1004 -	tbit.nz p15,p0=r27,IA64_PSR_I_BIT
  6.1005 -	;;
  6.1006 -.wait:
  6.1007 -(p15)	ssm psr.i		// reenable interrupts if they were on
  6.1008 -				// DavidM says that srlz.d is slow and is not required in this case
  6.1009 -.wait2:
  6.1010 -	// exponential backoff, kdb, lockmeter etc. go in here
  6.1011 -	hint @pause
  6.1012 -	ld4 r30=[r31]		// don't use ld4.bias; if it's contended, we won't write the word
  6.1013 -	;;
  6.1014 -	cmp4.ne p14,p0=r30,r0
  6.1015 -	mov r30 = 1
  6.1016 -(p14)	br.cond.sptk.few .wait2
  6.1017 -(p15)	rsm psr.i		// disable interrupts if we reenabled them
  6.1018 -	;;
  6.1019 -	cmpxchg4.acq r30=[r31], r30, ar.ccv
  6.1020 -	;;
  6.1021 -	cmp4.ne p14,p0=r0,r30
  6.1022 -(p14)	br.cond.sptk.few .wait
  6.1023 -
  6.1024 -	br.ret.sptk.many b6	// lock is now taken
  6.1025 -END(ia64_spinlock_contention)
  6.1026 -
  6.1027 -#endif
  6.1028 -
  6.1029 -#endif /* CONFIG_SMP */
     7.1 --- a/xen/arch/ia64/irq_ia64.c	Tue Aug 02 15:59:09 2005 -0800
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,381 +0,0 @@
     7.4 -/*
     7.5 - * linux/arch/ia64/kernel/irq.c
     7.6 - *
     7.7 - * Copyright (C) 1998-2001 Hewlett-Packard Co
     7.8 - *	Stephane Eranian <eranian@hpl.hp.com>
     7.9 - *	David Mosberger-Tang <davidm@hpl.hp.com>
    7.10 - *
    7.11 - *  6/10/99: Updated to bring in sync with x86 version to facilitate
    7.12 - *	     support for SMP and different interrupt controllers.
    7.13 - *
    7.14 - * 09/15/00 Goutham Rao <goutham.rao@intel.com> Implemented pci_irq_to_vector
    7.15 - *                      PCI to vector allocation routine.
    7.16 - * 04/14/2004 Ashok Raj <ashok.raj@intel.com>
    7.17 - *						Added CPU Hotplug handling for IPF.
    7.18 - */
    7.19 -
    7.20 -#include <linux/config.h>
    7.21 -#include <linux/module.h>
    7.22 -
    7.23 -#include <linux/jiffies.h>
    7.24 -#include <linux/errno.h>
    7.25 -#include <linux/init.h>
    7.26 -#include <linux/interrupt.h>
    7.27 -#include <linux/ioport.h>
    7.28 -#include <linux/kernel_stat.h>
    7.29 -#include <linux/slab.h>
    7.30 -#include <linux/ptrace.h>
    7.31 -#include <linux/random.h>	/* for rand_initialize_irq() */
    7.32 -#include <linux/signal.h>
    7.33 -#include <linux/smp.h>
    7.34 -#include <linux/smp_lock.h>
    7.35 -#include <linux/threads.h>
    7.36 -#include <linux/bitops.h>
    7.37 -
    7.38 -#include <asm/delay.h>
    7.39 -#include <asm/intrinsics.h>
    7.40 -#include <asm/io.h>
    7.41 -#include <asm/hw_irq.h>
    7.42 -#include <asm/machvec.h>
    7.43 -#include <asm/pgtable.h>
    7.44 -#include <asm/system.h>
    7.45 -
    7.46 -#ifdef CONFIG_PERFMON
    7.47 -# include <asm/perfmon.h>
    7.48 -#endif
    7.49 -
    7.50 -#define IRQ_DEBUG	0
    7.51 -
    7.52 -/* default base addr of IPI table */
    7.53 -void __iomem *ipi_base_addr = ((void __iomem *)
    7.54 -			       (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
    7.55 -
    7.56 -/*
    7.57 - * Legacy IRQ to IA-64 vector translation table.
    7.58 - */
    7.59 -__u8 isa_irq_to_vector_map[16] = {
    7.60 -	/* 8259 IRQ translation, first 16 entries */
    7.61 -	0x2f, 0x20, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
    7.62 -	0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21
    7.63 -};
    7.64 -EXPORT_SYMBOL(isa_irq_to_vector_map);
    7.65 -
    7.66 -static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
    7.67 -
    7.68 -int
    7.69 -assign_irq_vector (int irq)
    7.70 -{
    7.71 -	int pos, vector;
    7.72 - again:
    7.73 -	pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
    7.74 -	vector = IA64_FIRST_DEVICE_VECTOR + pos;
    7.75 -	if (vector > IA64_LAST_DEVICE_VECTOR)
    7.76 -		/* XXX could look for sharable vectors instead of panic'ing... */
    7.77 -		panic("assign_irq_vector: out of interrupt vectors!");
    7.78 -	if (test_and_set_bit(pos, ia64_vector_mask))
    7.79 -		goto again;
    7.80 -	return vector;
    7.81 -}
    7.82 -
    7.83 -void
    7.84 -free_irq_vector (int vector)
    7.85 -{
    7.86 -	int pos;
    7.87 -
    7.88 -	if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
    7.89 -		return;
    7.90 -
    7.91 -	pos = vector - IA64_FIRST_DEVICE_VECTOR;
    7.92 -	if (!test_and_clear_bit(pos, ia64_vector_mask))
    7.93 -		printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
    7.94 -}
    7.95 -
    7.96 -#ifdef CONFIG_SMP
    7.97 -#	define IS_RESCHEDULE(vec)	(vec == IA64_IPI_RESCHEDULE)
    7.98 -#else
    7.99 -#	define IS_RESCHEDULE(vec)	(0)
   7.100 -#endif
   7.101 -/*
   7.102 - * That's where the IVT branches when we get an external
   7.103 - * interrupt. This branches to the correct hardware IRQ handler via
   7.104 - * function ptr.
   7.105 - */
   7.106 -void
   7.107 -ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
   7.108 -{
   7.109 -	unsigned long saved_tpr;
   7.110 -
   7.111 -#if IRQ_DEBUG
   7.112 -#ifdef XEN
   7.113 -	xen_debug_irq(vector, regs);
   7.114 -#endif
   7.115 -	{
   7.116 -		unsigned long bsp, sp;
   7.117 -
   7.118 -		/*
   7.119 -		 * Note: if the interrupt happened while executing in
   7.120 -		 * the context switch routine (ia64_switch_to), we may
   7.121 -		 * get a spurious stack overflow here.  This is
   7.122 -		 * because the register and the memory stack are not
   7.123 -		 * switched atomically.
   7.124 -		 */
   7.125 -		bsp = ia64_getreg(_IA64_REG_AR_BSP);
   7.126 -		sp = ia64_getreg(_IA64_REG_SP);
   7.127 -
   7.128 -		if ((sp - bsp) < 1024) {
   7.129 -			static unsigned char count;
   7.130 -			static long last_time;
   7.131 -
   7.132 -			if (jiffies - last_time > 5*HZ)
   7.133 -				count = 0;
   7.134 -			if (++count < 5) {
   7.135 -				last_time = jiffies;
   7.136 -				printk("ia64_handle_irq: DANGER: less than "
   7.137 -				       "1KB of free stack space!!\n"
   7.138 -				       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
   7.139 -			}
   7.140 -		}
   7.141 -	}
   7.142 -#endif /* IRQ_DEBUG */
   7.143 -
   7.144 -	/*
   7.145 -	 * Always set TPR to limit maximum interrupt nesting depth to
   7.146 -	 * 16 (without this, it would be ~240, which could easily lead
   7.147 -	 * to kernel stack overflows).
   7.148 -	 */
   7.149 -	irq_enter();
   7.150 -	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
   7.151 -	ia64_srlz_d();
   7.152 -	while (vector != IA64_SPURIOUS_INT_VECTOR) {
   7.153 -		if (!IS_RESCHEDULE(vector)) {
   7.154 -			ia64_setreg(_IA64_REG_CR_TPR, vector);
   7.155 -			ia64_srlz_d();
   7.156 -
   7.157 -#ifdef XEN
   7.158 -			if (!xen_do_IRQ(vector))
   7.159 -#endif
   7.160 -			__do_IRQ(local_vector_to_irq(vector), regs);
   7.161 -
   7.162 -			/*
   7.163 -			 * Disable interrupts and send EOI:
   7.164 -			 */
   7.165 -			local_irq_disable();
   7.166 -			ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
   7.167 -		}
   7.168 -		ia64_eoi();
   7.169 -		vector = ia64_get_ivr();
   7.170 -	}
   7.171 -	/*
   7.172 -	 * This must be done *after* the ia64_eoi().  For example, the keyboard softirq
   7.173 -	 * handler needs to be able to wait for further keyboard interrupts, which can't
   7.174 -	 * come through until ia64_eoi() has been done.
   7.175 -	 */
   7.176 -	irq_exit();
   7.177 -}
   7.178 -
   7.179 -#ifdef  CONFIG_VTI
   7.180 -#define vmx_irq_enter()		\
   7.181 -	add_preempt_count(HARDIRQ_OFFSET);
   7.182 -
   7.183 -/* Now softirq will be checked when leaving hypervisor, or else
   7.184 - * scheduler irq will be executed too early.
   7.185 - */
   7.186 -#define vmx_irq_exit(void)	\
   7.187 -	sub_preempt_count(HARDIRQ_OFFSET);
   7.188 -/*
   7.189 - * That's where the IVT branches when we get an external
   7.190 - * interrupt. This branches to the correct hardware IRQ handler via
   7.191 - * function ptr.
   7.192 - */
   7.193 -void
   7.194 -vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
   7.195 -{
   7.196 -	unsigned long saved_tpr;
   7.197 -	int	wake_dom0 = 0;
   7.198 -
   7.199 -
   7.200 -#if IRQ_DEBUG
   7.201 -	{
   7.202 -		unsigned long bsp, sp;
   7.203 -
   7.204 -		/*
   7.205 -		 * Note: if the interrupt happened while executing in
   7.206 -		 * the context switch routine (ia64_switch_to), we may
   7.207 -		 * get a spurious stack overflow here.  This is
   7.208 -		 * because the register and the memory stack are not
   7.209 -		 * switched atomically.
   7.210 -		 */
   7.211 -		bsp = ia64_getreg(_IA64_REG_AR_BSP);
   7.212 -		sp = ia64_getreg(_IA64_REG_AR_SP);
   7.213 -
   7.214 -		if ((sp - bsp) < 1024) {
   7.215 -			static unsigned char count;
   7.216 -			static long last_time;
   7.217 -
   7.218 -			if (jiffies - last_time > 5*HZ)
   7.219 -				count = 0;
   7.220 -			if (++count < 5) {
   7.221 -				last_time = jiffies;
   7.222 -				printk("ia64_handle_irq: DANGER: less than "
   7.223 -				       "1KB of free stack space!!\n"
   7.224 -				       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
   7.225 -			}
   7.226 -		}
   7.227 -	}
   7.228 -#endif /* IRQ_DEBUG */
   7.229 -
   7.230 -	/*
   7.231 -	 * Always set TPR to limit maximum interrupt nesting depth to
   7.232 -	 * 16 (without this, it would be ~240, which could easily lead
   7.233 -	 * to kernel stack overflows).
   7.234 -	 */
   7.235 -	vmx_irq_enter();
   7.236 -	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
   7.237 -	ia64_srlz_d();
   7.238 -	while (vector != IA64_SPURIOUS_INT_VECTOR) {
   7.239 -	    if (!IS_RESCHEDULE(vector)) {
   7.240 -		ia64_setreg(_IA64_REG_CR_TPR, vector);
   7.241 -		ia64_srlz_d();
   7.242 -
   7.243 -		if (vector != IA64_TIMER_VECTOR) {
   7.244 -			/* FIXME: Leave IRQ re-route later */
   7.245 -			vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector);
   7.246 -			wake_dom0 = 1;
   7.247 -		}
   7.248 -		else {	// FIXME: Handle Timer only now
   7.249 -			__do_IRQ(local_vector_to_irq(vector), regs);
   7.250 -		}
   7.251 -		
   7.252 -		/*
   7.253 -		 * Disable interrupts and send EOI:
   7.254 -		 */
   7.255 -		local_irq_disable();
   7.256 -		ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
   7.257 -	    }
   7.258 -	    else {
   7.259 -                printf("Oops: RESCHEDULE IPI absorbed by HV\n");
   7.260 -            }
   7.261 -	    ia64_eoi();
   7.262 -	    vector = ia64_get_ivr();
   7.263 -	}
   7.264 -	/*
   7.265 -	 * This must be done *after* the ia64_eoi().  For example, the keyboard softirq
   7.266 -	 * handler needs to be able to wait for further keyboard interrupts, which can't
   7.267 -	 * come through until ia64_eoi() has been done.
   7.268 -	 */
   7.269 -	vmx_irq_exit();
   7.270 -	if ( wake_dom0 && current != dom0 ) 
   7.271 -		domain_wake(dom0->vcpu[0]);
   7.272 -}
   7.273 -#endif
   7.274 -
   7.275 -
   7.276 -#ifdef CONFIG_HOTPLUG_CPU
   7.277 -/*
   7.278 - * This function emulates a interrupt processing when a cpu is about to be
   7.279 - * brought down.
   7.280 - */
   7.281 -void ia64_process_pending_intr(void)
   7.282 -{
   7.283 -	ia64_vector vector;
   7.284 -	unsigned long saved_tpr;
   7.285 -	extern unsigned int vectors_in_migration[NR_IRQS];
   7.286 -
   7.287 -	vector = ia64_get_ivr();
   7.288 -
   7.289 -	 irq_enter();
   7.290 -	 saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
   7.291 -	 ia64_srlz_d();
   7.292 -
   7.293 -	 /*
   7.294 -	  * Perform normal interrupt style processing
   7.295 -	  */
   7.296 -	while (vector != IA64_SPURIOUS_INT_VECTOR) {
   7.297 -		if (!IS_RESCHEDULE(vector)) {
   7.298 -			ia64_setreg(_IA64_REG_CR_TPR, vector);
   7.299 -			ia64_srlz_d();
   7.300 -
   7.301 -			/*
   7.302 -			 * Now try calling normal ia64_handle_irq as it would have got called
   7.303 -			 * from a real intr handler. Try passing null for pt_regs, hopefully
   7.304 -			 * it will work. I hope it works!.
   7.305 -			 * Probably could shared code.
   7.306 -			 */
   7.307 -			vectors_in_migration[local_vector_to_irq(vector)]=0;
   7.308 -			__do_IRQ(local_vector_to_irq(vector), NULL);
   7.309 -
   7.310 -			/*
   7.311 -			 * Disable interrupts and send EOI
   7.312 -			 */
   7.313 -			local_irq_disable();
   7.314 -			ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
   7.315 -		}
   7.316 -		ia64_eoi();
   7.317 -		vector = ia64_get_ivr();
   7.318 -	}
   7.319 -	irq_exit();
   7.320 -}
   7.321 -#endif
   7.322 -
   7.323 -
   7.324 -#ifdef CONFIG_SMP
   7.325 -extern irqreturn_t handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
   7.326 -
   7.327 -static struct irqaction ipi_irqaction = {
   7.328 -	.handler =	handle_IPI,
   7.329 -	.flags =	SA_INTERRUPT,
   7.330 -	.name =		"IPI"
   7.331 -};
   7.332 -#endif
   7.333 -
   7.334 -void
   7.335 -register_percpu_irq (ia64_vector vec, struct irqaction *action)
   7.336 -{
   7.337 -	irq_desc_t *desc;
   7.338 -	unsigned int irq;
   7.339 -
   7.340 -	for (irq = 0; irq < NR_IRQS; ++irq)
   7.341 -		if (irq_to_vector(irq) == vec) {
   7.342 -			desc = irq_descp(irq);
   7.343 -			desc->status |= IRQ_PER_CPU;
   7.344 -			desc->handler = &irq_type_ia64_lsapic;
   7.345 -			if (action)
   7.346 -				setup_irq(irq, action);
   7.347 -		}
   7.348 -}
   7.349 -
   7.350 -void __init
   7.351 -init_IRQ (void)
   7.352 -{
   7.353 -	register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
   7.354 -#ifdef CONFIG_SMP
   7.355 -	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
   7.356 -#endif
   7.357 -#ifdef CONFIG_PERFMON
   7.358 -	pfm_init_percpu();
   7.359 -#endif
   7.360 -	platform_irq_init();
   7.361 -}
   7.362 -
   7.363 -void
   7.364 -ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
   7.365 -{
   7.366 -	void __iomem *ipi_addr;
   7.367 -	unsigned long ipi_data;
   7.368 -	unsigned long phys_cpu_id;
   7.369 -
   7.370 -#ifdef CONFIG_SMP
   7.371 -	phys_cpu_id = cpu_physical_id(cpu);
   7.372 -#else
   7.373 -	phys_cpu_id = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
   7.374 -#endif
   7.375 -
   7.376 -	/*
   7.377 -	 * cpu number is in 8bit ID and 8bit EID
   7.378 -	 */
   7.379 -
   7.380 -	ipi_data = (delivery_mode << 8) | (vector & 0xff);
   7.381 -	ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
   7.382 -
   7.383 -	writeq(ipi_data, ipi_addr);
   7.384 -}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/arch/ia64/linux-xen/efi.c	Tue Aug 02 16:25:11 2005 -0800
     8.3 @@ -0,0 +1,866 @@
     8.4 +/*
     8.5 + * Extensible Firmware Interface
     8.6 + *
     8.7 + * Based on Extensible Firmware Interface Specification version 0.9 April 30, 1999
     8.8 + *
     8.9 + * Copyright (C) 1999 VA Linux Systems
    8.10 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    8.11 + * Copyright (C) 1999-2003 Hewlett-Packard Co.
    8.12 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    8.13 + *	Stephane Eranian <eranian@hpl.hp.com>
    8.14 + *
    8.15 + * All EFI Runtime Services are not implemented yet as EFI only
    8.16 + * supports physical mode addressing on SoftSDV. This is to be fixed
    8.17 + * in a future version.  --drummond 1999-07-20
    8.18 + *
    8.19 + * Implemented EFI runtime services and virtual mode calls.  --davidm
    8.20 + *
    8.21 + * Goutham Rao: <goutham.rao@intel.com>
    8.22 + *	Skip non-WB memory and ignore empty memory ranges.
    8.23 + */
    8.24 +#include <linux/config.h>
    8.25 +#include <linux/module.h>
    8.26 +#include <linux/kernel.h>
    8.27 +#include <linux/init.h>
    8.28 +#include <linux/types.h>
    8.29 +#include <linux/time.h>
    8.30 +#include <linux/efi.h>
    8.31 +
    8.32 +#include <asm/io.h>
    8.33 +#include <asm/kregs.h>
    8.34 +#include <asm/meminit.h>
    8.35 +#include <asm/pgtable.h>
    8.36 +#include <asm/processor.h>
    8.37 +#include <asm/mca.h>
    8.38 +
    8.39 +#define EFI_DEBUG	0
    8.40 +
    8.41 +extern efi_status_t efi_call_phys (void *, ...);
    8.42 +
    8.43 +struct efi efi;
    8.44 +EXPORT_SYMBOL(efi);
    8.45 +static efi_runtime_services_t *runtime;
    8.46 +static unsigned long mem_limit = ~0UL, max_addr = ~0UL;
    8.47 +
    8.48 +#define efi_call_virt(f, args...)	(*(f))(args)
    8.49 +
    8.50 +#define STUB_GET_TIME(prefix, adjust_arg)							  \
    8.51 +static efi_status_t										  \
    8.52 +prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc)						  \
    8.53 +{												  \
    8.54 +	struct ia64_fpreg fr[6];								  \
    8.55 +	efi_time_cap_t *atc = NULL;								  \
    8.56 +	efi_status_t ret;									  \
    8.57 +												  \
    8.58 +	if (tc)											  \
    8.59 +		atc = adjust_arg(tc);								  \
    8.60 +	ia64_save_scratch_fpregs(fr);								  \
    8.61 +	ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), atc); \
    8.62 +	ia64_load_scratch_fpregs(fr);								  \
    8.63 +	return ret;										  \
    8.64 +}
    8.65 +
    8.66 +#define STUB_SET_TIME(prefix, adjust_arg)							\
    8.67 +static efi_status_t										\
    8.68 +prefix##_set_time (efi_time_t *tm)								\
    8.69 +{												\
    8.70 +	struct ia64_fpreg fr[6];								\
    8.71 +	efi_status_t ret;									\
    8.72 +												\
    8.73 +	ia64_save_scratch_fpregs(fr);								\
    8.74 +	ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm));	\
    8.75 +	ia64_load_scratch_fpregs(fr);								\
    8.76 +	return ret;										\
    8.77 +}
    8.78 +
    8.79 +#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg)						\
    8.80 +static efi_status_t										\
    8.81 +prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)		\
    8.82 +{												\
    8.83 +	struct ia64_fpreg fr[6];								\
    8.84 +	efi_status_t ret;									\
    8.85 +												\
    8.86 +	ia64_save_scratch_fpregs(fr);								\
    8.87 +	ret = efi_call_##prefix((efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time),	\
    8.88 +				adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm));	\
    8.89 +	ia64_load_scratch_fpregs(fr);								\
    8.90 +	return ret;										\
    8.91 +}
    8.92 +
    8.93 +#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg)						\
    8.94 +static efi_status_t										\
    8.95 +prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)					\
    8.96 +{												\
    8.97 +	struct ia64_fpreg fr[6];								\
    8.98 +	efi_time_t *atm = NULL;									\
    8.99 +	efi_status_t ret;									\
   8.100 +												\
   8.101 +	if (tm)											\
   8.102 +		atm = adjust_arg(tm);								\
   8.103 +	ia64_save_scratch_fpregs(fr);								\
   8.104 +	ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time),	\
   8.105 +				enabled, atm);							\
   8.106 +	ia64_load_scratch_fpregs(fr);								\
   8.107 +	return ret;										\
   8.108 +}
   8.109 +
   8.110 +#define STUB_GET_VARIABLE(prefix, adjust_arg)						\
   8.111 +static efi_status_t									\
   8.112 +prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,		\
   8.113 +		       unsigned long *data_size, void *data)				\
   8.114 +{											\
   8.115 +	struct ia64_fpreg fr[6];							\
   8.116 +	u32 *aattr = NULL;									\
   8.117 +	efi_status_t ret;								\
   8.118 +											\
   8.119 +	if (attr)									\
   8.120 +		aattr = adjust_arg(attr);						\
   8.121 +	ia64_save_scratch_fpregs(fr);							\
   8.122 +	ret = efi_call_##prefix((efi_get_variable_t *) __va(runtime->get_variable),	\
   8.123 +				adjust_arg(name), adjust_arg(vendor), aattr,		\
   8.124 +				adjust_arg(data_size), adjust_arg(data));		\
   8.125 +	ia64_load_scratch_fpregs(fr);							\
   8.126 +	return ret;									\
   8.127 +}
   8.128 +
   8.129 +#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg)						\
   8.130 +static efi_status_t										\
   8.131 +prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor)	\
   8.132 +{												\
   8.133 +	struct ia64_fpreg fr[6];								\
   8.134 +	efi_status_t ret;									\
   8.135 +												\
   8.136 +	ia64_save_scratch_fpregs(fr);								\
   8.137 +	ret = efi_call_##prefix((efi_get_next_variable_t *) __va(runtime->get_next_variable),	\
   8.138 +				adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor));	\
   8.139 +	ia64_load_scratch_fpregs(fr);								\
   8.140 +	return ret;										\
   8.141 +}
   8.142 +
   8.143 +#define STUB_SET_VARIABLE(prefix, adjust_arg)						\
   8.144 +static efi_status_t									\
   8.145 +prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, unsigned long attr,	\
   8.146 +		       unsigned long data_size, void *data)				\
   8.147 +{											\
   8.148 +	struct ia64_fpreg fr[6];							\
   8.149 +	efi_status_t ret;								\
   8.150 +											\
   8.151 +	ia64_save_scratch_fpregs(fr);							\
   8.152 +	ret = efi_call_##prefix((efi_set_variable_t *) __va(runtime->set_variable),	\
   8.153 +				adjust_arg(name), adjust_arg(vendor), attr, data_size,	\
   8.154 +				adjust_arg(data));					\
   8.155 +	ia64_load_scratch_fpregs(fr);							\
   8.156 +	return ret;									\
   8.157 +}
   8.158 +
   8.159 +#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg)					\
   8.160 +static efi_status_t										\
   8.161 +prefix##_get_next_high_mono_count (u32 *count)							\
   8.162 +{												\
   8.163 +	struct ia64_fpreg fr[6];								\
   8.164 +	efi_status_t ret;									\
   8.165 +												\
   8.166 +	ia64_save_scratch_fpregs(fr);								\
   8.167 +	ret = efi_call_##prefix((efi_get_next_high_mono_count_t *)				\
   8.168 +				__va(runtime->get_next_high_mono_count), adjust_arg(count));	\
   8.169 +	ia64_load_scratch_fpregs(fr);								\
   8.170 +	return ret;										\
   8.171 +}
   8.172 +
   8.173 +#define STUB_RESET_SYSTEM(prefix, adjust_arg)					\
   8.174 +static void									\
   8.175 +prefix##_reset_system (int reset_type, efi_status_t status,			\
   8.176 +		       unsigned long data_size, efi_char16_t *data)		\
   8.177 +{										\
   8.178 +	struct ia64_fpreg fr[6];						\
   8.179 +	efi_char16_t *adata = NULL;						\
   8.180 +										\
   8.181 +	if (data)								\
   8.182 +		adata = adjust_arg(data);					\
   8.183 +										\
   8.184 +	ia64_save_scratch_fpregs(fr);						\
   8.185 +	efi_call_##prefix((efi_reset_system_t *) __va(runtime->reset_system),	\
   8.186 +			  reset_type, status, data_size, adata);		\
   8.187 +	/* should not return, but just in case... */				\
   8.188 +	ia64_load_scratch_fpregs(fr);						\
   8.189 +}
   8.190 +
   8.191 +#define phys_ptr(arg)	((__typeof__(arg)) ia64_tpa(arg))
   8.192 +
   8.193 +STUB_GET_TIME(phys, phys_ptr)
   8.194 +STUB_SET_TIME(phys, phys_ptr)
   8.195 +STUB_GET_WAKEUP_TIME(phys, phys_ptr)
   8.196 +STUB_SET_WAKEUP_TIME(phys, phys_ptr)
   8.197 +STUB_GET_VARIABLE(phys, phys_ptr)
   8.198 +STUB_GET_NEXT_VARIABLE(phys, phys_ptr)
   8.199 +STUB_SET_VARIABLE(phys, phys_ptr)
   8.200 +STUB_GET_NEXT_HIGH_MONO_COUNT(phys, phys_ptr)
   8.201 +STUB_RESET_SYSTEM(phys, phys_ptr)
   8.202 +
   8.203 +#define id(arg)	arg
   8.204 +
   8.205 +STUB_GET_TIME(virt, id)
   8.206 +STUB_SET_TIME(virt, id)
   8.207 +STUB_GET_WAKEUP_TIME(virt, id)
   8.208 +STUB_SET_WAKEUP_TIME(virt, id)
   8.209 +STUB_GET_VARIABLE(virt, id)
   8.210 +STUB_GET_NEXT_VARIABLE(virt, id)
   8.211 +STUB_SET_VARIABLE(virt, id)
   8.212 +STUB_GET_NEXT_HIGH_MONO_COUNT(virt, id)
   8.213 +STUB_RESET_SYSTEM(virt, id)
   8.214 +
   8.215 +void
   8.216 +efi_gettimeofday (struct timespec *ts)
   8.217 +{
   8.218 +	efi_time_t tm;
   8.219 +
   8.220 +	memset(ts, 0, sizeof(ts));
   8.221 +	if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS)
   8.222 +		return;
   8.223 +
   8.224 +	ts->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
   8.225 +	ts->tv_nsec = tm.nanosecond;
   8.226 +}
   8.227 +
   8.228 +static int
   8.229 +is_available_memory (efi_memory_desc_t *md)
   8.230 +{
   8.231 +	if (!(md->attribute & EFI_MEMORY_WB))
   8.232 +		return 0;
   8.233 +
   8.234 +	switch (md->type) {
   8.235 +	      case EFI_LOADER_CODE:
   8.236 +	      case EFI_LOADER_DATA:
   8.237 +	      case EFI_BOOT_SERVICES_CODE:
   8.238 +	      case EFI_BOOT_SERVICES_DATA:
   8.239 +	      case EFI_CONVENTIONAL_MEMORY:
   8.240 +		return 1;
   8.241 +	}
   8.242 +	return 0;
   8.243 +}
   8.244 +
   8.245 +/*
   8.246 + * Trim descriptor MD so its starts at address START_ADDR.  If the descriptor covers
   8.247 + * memory that is normally available to the kernel, issue a warning that some memory
   8.248 + * is being ignored.
   8.249 + */
   8.250 +static void
   8.251 +trim_bottom (efi_memory_desc_t *md, u64 start_addr)
   8.252 +{
   8.253 +	u64 num_skipped_pages;
   8.254 +
   8.255 +	if (md->phys_addr >= start_addr || !md->num_pages)
   8.256 +		return;
   8.257 +
   8.258 +	num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
   8.259 +	if (num_skipped_pages > md->num_pages)
   8.260 +		num_skipped_pages = md->num_pages;
   8.261 +
   8.262 +	if (is_available_memory(md))
   8.263 +		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
   8.264 +		       "at 0x%lx\n", __FUNCTION__,
   8.265 +		       (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
   8.266 +		       md->phys_addr, start_addr - IA64_GRANULE_SIZE);
   8.267 +	/*
   8.268 +	 * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
   8.269 +	 * descriptor list to become unsorted.  In such a case, md->num_pages will be
   8.270 +	 * zero, so the Right Thing will happen.
   8.271 +	 */
   8.272 +	md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
   8.273 +	md->num_pages -= num_skipped_pages;
   8.274 +}
   8.275 +
   8.276 +static void
   8.277 +trim_top (efi_memory_desc_t *md, u64 end_addr)
   8.278 +{
   8.279 +	u64 num_dropped_pages, md_end_addr;
   8.280 +
   8.281 +	md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   8.282 +
   8.283 +	if (md_end_addr <= end_addr || !md->num_pages)
   8.284 +		return;
   8.285 +
   8.286 +	num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
   8.287 +	if (num_dropped_pages > md->num_pages)
   8.288 +		num_dropped_pages = md->num_pages;
   8.289 +
   8.290 +	if (is_available_memory(md))
   8.291 +		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
   8.292 +		       "at 0x%lx\n", __FUNCTION__,
   8.293 +		       (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
   8.294 +		       md->phys_addr, end_addr);
   8.295 +	md->num_pages -= num_dropped_pages;
   8.296 +}
   8.297 +
   8.298 +/*
   8.299 + * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
   8.300 + * has memory that is available for OS use.
   8.301 + */
   8.302 +void
   8.303 +efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
   8.304 +{
   8.305 +	int prev_valid = 0;
   8.306 +	struct range {
   8.307 +		u64 start;
   8.308 +		u64 end;
   8.309 +	} prev, curr;
   8.310 +	void *efi_map_start, *efi_map_end, *p, *q;
   8.311 +	efi_memory_desc_t *md, *check_md;
   8.312 +	u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0;
   8.313 +	unsigned long total_mem = 0;
   8.314 +
   8.315 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.316 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.317 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.318 +
   8.319 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.320 +		md = p;
   8.321 +
   8.322 +		/* skip over non-WB memory descriptors; that's all we're interested in... */
   8.323 +		if (!(md->attribute & EFI_MEMORY_WB))
   8.324 +			continue;
   8.325 +
   8.326 +#ifdef XEN
   8.327 +// this works around a problem in the ski bootloader
   8.328 +{
   8.329 +		extern long running_on_sim;
   8.330 +		if (running_on_sim && md->type != EFI_CONVENTIONAL_MEMORY)
   8.331 +			continue;
   8.332 +}
   8.333 +// this is a temporary hack to avoid CONFIG_VIRTUAL_MEM_MAP
   8.334 +		if (md->phys_addr >= 0x100000000) continue;
   8.335 +#endif
   8.336 +		/*
   8.337 +		 * granule_addr is the base of md's first granule.
   8.338 +		 * [granule_addr - first_non_wb_addr) is guaranteed to
   8.339 +		 * be contiguous WB memory.
   8.340 +		 */
   8.341 +		granule_addr = GRANULEROUNDDOWN(md->phys_addr);
   8.342 +		first_non_wb_addr = max(first_non_wb_addr, granule_addr);
   8.343 +
   8.344 +		if (first_non_wb_addr < md->phys_addr) {
   8.345 +			trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
   8.346 +			granule_addr = GRANULEROUNDDOWN(md->phys_addr);
   8.347 +			first_non_wb_addr = max(first_non_wb_addr, granule_addr);
   8.348 +		}
   8.349 +
   8.350 +		for (q = p; q < efi_map_end; q += efi_desc_size) {
   8.351 +			check_md = q;
   8.352 +
   8.353 +			if ((check_md->attribute & EFI_MEMORY_WB) &&
   8.354 +			    (check_md->phys_addr == first_non_wb_addr))
   8.355 +				first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
   8.356 +			else
   8.357 +				break;		/* non-WB or hole */
   8.358 +		}
   8.359 +
   8.360 +		last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
   8.361 +		if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
   8.362 +			trim_top(md, last_granule_addr);
   8.363 +
   8.364 +		if (is_available_memory(md)) {
   8.365 +			if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
   8.366 +				if (md->phys_addr >= max_addr)
   8.367 +					continue;
   8.368 +				md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
   8.369 +				first_non_wb_addr = max_addr;
   8.370 +			}
   8.371 +
   8.372 +			if (total_mem >= mem_limit)
   8.373 +				continue;
   8.374 +
   8.375 +			if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
   8.376 +				unsigned long limit_addr = md->phys_addr;
   8.377 +
   8.378 +				limit_addr += mem_limit - total_mem;
   8.379 +				limit_addr = GRANULEROUNDDOWN(limit_addr);
   8.380 +
   8.381 +				if (md->phys_addr > limit_addr)
   8.382 +					continue;
   8.383 +
   8.384 +				md->num_pages = (limit_addr - md->phys_addr) >>
   8.385 +				                EFI_PAGE_SHIFT;
   8.386 +				first_non_wb_addr = max_addr = md->phys_addr +
   8.387 +				              (md->num_pages << EFI_PAGE_SHIFT);
   8.388 +			}
   8.389 +			total_mem += (md->num_pages << EFI_PAGE_SHIFT);
   8.390 +
   8.391 +			if (md->num_pages == 0)
   8.392 +				continue;
   8.393 +
   8.394 +			curr.start = PAGE_OFFSET + md->phys_addr;
   8.395 +			curr.end   = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
   8.396 +
   8.397 +			if (!prev_valid) {
   8.398 +				prev = curr;
   8.399 +				prev_valid = 1;
   8.400 +			} else {
   8.401 +				if (curr.start < prev.start)
   8.402 +					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
   8.403 +
   8.404 +				if (prev.end == curr.start) {
   8.405 +					/* merge two consecutive memory ranges */
   8.406 +					prev.end = curr.end;
   8.407 +				} else {
   8.408 +					start = PAGE_ALIGN(prev.start);
   8.409 +					end = prev.end & PAGE_MASK;
   8.410 +					if ((end > start) && (*callback)(start, end, arg) < 0)
   8.411 +						return;
   8.412 +					prev = curr;
   8.413 +				}
   8.414 +			}
   8.415 +		}
   8.416 +	}
   8.417 +	if (prev_valid) {
   8.418 +		start = PAGE_ALIGN(prev.start);
   8.419 +		end = prev.end & PAGE_MASK;
   8.420 +		if (end > start)
   8.421 +			(*callback)(start, end, arg);
   8.422 +	}
   8.423 +}
   8.424 +
   8.425 +/*
   8.426 + * Look for the PAL_CODE region reported by EFI and maps it using an
   8.427 + * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
   8.428 + * Abstraction Layer chapter 11 in ADAG
   8.429 + */
   8.430 +
   8.431 +void *
   8.432 +efi_get_pal_addr (void)
   8.433 +{
   8.434 +	void *efi_map_start, *efi_map_end, *p;
   8.435 +	efi_memory_desc_t *md;
   8.436 +	u64 efi_desc_size;
   8.437 +	int pal_code_count = 0;
   8.438 +	u64 vaddr, mask;
   8.439 +
   8.440 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.441 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.442 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.443 +
   8.444 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.445 +		md = p;
   8.446 +		if (md->type != EFI_PAL_CODE)
   8.447 +			continue;
   8.448 +
   8.449 +		if (++pal_code_count > 1) {
   8.450 +			printk(KERN_ERR "Too many EFI Pal Code memory ranges, dropped @ %lx\n",
   8.451 +			       md->phys_addr);
   8.452 +			continue;
   8.453 +		}
   8.454 +		/*
   8.455 +		 * The only ITLB entry in region 7 that is used is the one installed by
   8.456 +		 * __start().  That entry covers a 64MB range.
   8.457 +		 */
   8.458 +		mask  = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1);
   8.459 +		vaddr = PAGE_OFFSET + md->phys_addr;
   8.460 +
   8.461 +		/*
   8.462 +		 * We must check that the PAL mapping won't overlap with the kernel
   8.463 +		 * mapping.
   8.464 +		 *
   8.465 +		 * PAL code is guaranteed to be aligned on a power of 2 between 4k and
   8.466 +		 * 256KB and that only one ITR is needed to map it. This implies that the
   8.467 +		 * PAL code is always aligned on its size, i.e., the closest matching page
   8.468 +		 * size supported by the TLB. Therefore PAL code is guaranteed never to
   8.469 +		 * cross a 64MB unless it is bigger than 64MB (very unlikely!).  So for
   8.470 +		 * now the following test is enough to determine whether or not we need a
   8.471 +		 * dedicated ITR for the PAL code.
   8.472 +		 */
   8.473 +		if ((vaddr & mask) == (KERNEL_START & mask)) {
   8.474 +			printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
   8.475 +			       __FUNCTION__);
   8.476 +			continue;
   8.477 +		}
   8.478 +
   8.479 +		if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE)
   8.480 +			panic("Woah!  PAL code size bigger than a granule!");
   8.481 +
   8.482 +#if EFI_DEBUG
   8.483 +		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
   8.484 +
   8.485 +		printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
   8.486 +			smp_processor_id(), md->phys_addr,
   8.487 +			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   8.488 +			vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
   8.489 +#endif
   8.490 +		return __va(md->phys_addr);
   8.491 +	}
   8.492 +	printk(KERN_WARNING "%s: no PAL-code memory-descriptor found",
   8.493 +	       __FUNCTION__);
   8.494 +	return NULL;
   8.495 +}
   8.496 +
   8.497 +void
   8.498 +efi_map_pal_code (void)
   8.499 +{
   8.500 +	void *pal_vaddr = efi_get_pal_addr ();
   8.501 +	u64 psr;
   8.502 +
   8.503 +	if (!pal_vaddr)
   8.504 +		return;
   8.505 +
   8.506 +	/*
   8.507 +	 * Cannot write to CRx with PSR.ic=1
   8.508 +	 */
   8.509 +	psr = ia64_clear_ic();
   8.510 +	ia64_itr(0x1, IA64_TR_PALCODE, GRANULEROUNDDOWN((unsigned long) pal_vaddr),
   8.511 +		 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
   8.512 +		 IA64_GRANULE_SHIFT);
   8.513 +	ia64_set_psr(psr);		/* restore psr */
   8.514 +	ia64_srlz_i();
   8.515 +}
   8.516 +
   8.517 +void __init
   8.518 +efi_init (void)
   8.519 +{
   8.520 +	void *efi_map_start, *efi_map_end;
   8.521 +	efi_config_table_t *config_tables;
   8.522 +	efi_char16_t *c16;
   8.523 +	u64 efi_desc_size;
   8.524 +	char *cp, *end, vendor[100] = "unknown";
   8.525 +	extern char saved_command_line[];
   8.526 +	int i;
   8.527 +
   8.528 +	/* it's too early to be able to use the standard kernel command line support... */
   8.529 +	for (cp = saved_command_line; *cp; ) {
   8.530 +		if (memcmp(cp, "mem=", 4) == 0) {
   8.531 +			cp += 4;
   8.532 +			mem_limit = memparse(cp, &end);
   8.533 +			if (end != cp)
   8.534 +				break;
   8.535 +			cp = end;
   8.536 +		} else if (memcmp(cp, "max_addr=", 9) == 0) {
   8.537 +			cp += 9;
   8.538 +			max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
   8.539 +			if (end != cp)
   8.540 +				break;
   8.541 +			cp = end;
   8.542 +		} else {
   8.543 +			while (*cp != ' ' && *cp)
   8.544 +				++cp;
   8.545 +			while (*cp == ' ')
   8.546 +				++cp;
   8.547 +		}
   8.548 +	}
   8.549 +	if (max_addr != ~0UL)
   8.550 +		printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20);
   8.551 +
   8.552 +	efi.systab = __va(ia64_boot_param->efi_systab);
   8.553 +
   8.554 +	/*
   8.555 +	 * Verify the EFI Table
   8.556 +	 */
   8.557 +	if (efi.systab == NULL)
   8.558 +		panic("Woah! Can't find EFI system table.\n");
   8.559 +	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
   8.560 +		panic("Woah! EFI system table signature incorrect\n");
   8.561 +	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
   8.562 +		printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
   8.563 +		       "got %d.%02d, expected %d.%02d\n",
   8.564 +		       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
   8.565 +		       EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
   8.566 +
   8.567 +	config_tables = __va(efi.systab->tables);
   8.568 +
   8.569 +	/* Show what we know for posterity */
   8.570 +	c16 = __va(efi.systab->fw_vendor);
   8.571 +	if (c16) {
   8.572 +		for (i = 0;i < (int) sizeof(vendor) && *c16; ++i)
   8.573 +			vendor[i] = *c16++;
   8.574 +		vendor[i] = '\0';
   8.575 +	}
   8.576 +
   8.577 +	printk(KERN_INFO "EFI v%u.%.02u by %s:",
   8.578 +	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
   8.579 +
   8.580 +	for (i = 0; i < (int) efi.systab->nr_tables; i++) {
   8.581 +		if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
   8.582 +			efi.mps = __va(config_tables[i].table);
   8.583 +			printk(" MPS=0x%lx", config_tables[i].table);
   8.584 +		} else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
   8.585 +			efi.acpi20 = __va(config_tables[i].table);
   8.586 +			printk(" ACPI 2.0=0x%lx", config_tables[i].table);
   8.587 +		} else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
   8.588 +			efi.acpi = __va(config_tables[i].table);
   8.589 +			printk(" ACPI=0x%lx", config_tables[i].table);
   8.590 +		} else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
   8.591 +			efi.smbios = __va(config_tables[i].table);
   8.592 +			printk(" SMBIOS=0x%lx", config_tables[i].table);
   8.593 +		} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
   8.594 +			efi.sal_systab = __va(config_tables[i].table);
   8.595 +			printk(" SALsystab=0x%lx", config_tables[i].table);
   8.596 +		} else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
   8.597 +			efi.hcdp = __va(config_tables[i].table);
   8.598 +			printk(" HCDP=0x%lx", config_tables[i].table);
   8.599 +		}
   8.600 +	}
   8.601 +	printk("\n");
   8.602 +
   8.603 +	runtime = __va(efi.systab->runtime);
   8.604 +	efi.get_time = phys_get_time;
   8.605 +	efi.set_time = phys_set_time;
   8.606 +	efi.get_wakeup_time = phys_get_wakeup_time;
   8.607 +	efi.set_wakeup_time = phys_set_wakeup_time;
   8.608 +	efi.get_variable = phys_get_variable;
   8.609 +	efi.get_next_variable = phys_get_next_variable;
   8.610 +	efi.set_variable = phys_set_variable;
   8.611 +	efi.get_next_high_mono_count = phys_get_next_high_mono_count;
   8.612 +	efi.reset_system = phys_reset_system;
   8.613 +
   8.614 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.615 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.616 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.617 +
   8.618 +#if EFI_DEBUG
   8.619 +	/* print EFI memory map: */
   8.620 +	{
   8.621 +		efi_memory_desc_t *md;
   8.622 +		void *p;
   8.623 +
   8.624 +		for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
   8.625 +			md = p;
   8.626 +			printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
   8.627 +			       i, md->type, md->attribute, md->phys_addr,
   8.628 +			       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   8.629 +			       md->num_pages >> (20 - EFI_PAGE_SHIFT));
   8.630 +		}
   8.631 +	}
   8.632 +#endif
   8.633 +
   8.634 +	efi_map_pal_code();
   8.635 +	efi_enter_virtual_mode();
   8.636 +}
   8.637 +
   8.638 +void
   8.639 +efi_enter_virtual_mode (void)
   8.640 +{
   8.641 +	void *efi_map_start, *efi_map_end, *p;
   8.642 +	efi_memory_desc_t *md;
   8.643 +	efi_status_t status;
   8.644 +	u64 efi_desc_size;
   8.645 +
   8.646 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.647 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.648 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.649 +
   8.650 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.651 +		md = p;
   8.652 +		if (md->attribute & EFI_MEMORY_RUNTIME) {
   8.653 +			/*
   8.654 +			 * Some descriptors have multiple bits set, so the order of
   8.655 +			 * the tests is relevant.
   8.656 +			 */
   8.657 +			if (md->attribute & EFI_MEMORY_WB) {
   8.658 +				md->virt_addr = (u64) __va(md->phys_addr);
   8.659 +			} else if (md->attribute & EFI_MEMORY_UC) {
   8.660 +				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   8.661 +			} else if (md->attribute & EFI_MEMORY_WC) {
   8.662 +#if 0
   8.663 +				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
   8.664 +									   | _PAGE_D
   8.665 +									   | _PAGE_MA_WC
   8.666 +									   | _PAGE_PL_0
   8.667 +									   | _PAGE_AR_RW));
   8.668 +#else
   8.669 +				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
   8.670 +				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   8.671 +#endif
   8.672 +			} else if (md->attribute & EFI_MEMORY_WT) {
   8.673 +#if 0
   8.674 +				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P
   8.675 +									   | _PAGE_D | _PAGE_MA_WT
   8.676 +									   | _PAGE_PL_0
   8.677 +									   | _PAGE_AR_RW));
   8.678 +#else
   8.679 +				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
   8.680 +				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
   8.681 +#endif
   8.682 +			}
   8.683 +		}
   8.684 +	}
   8.685 +
   8.686 +	status = efi_call_phys(__va(runtime->set_virtual_address_map),
   8.687 +			       ia64_boot_param->efi_memmap_size,
   8.688 +			       efi_desc_size, ia64_boot_param->efi_memdesc_version,
   8.689 +			       ia64_boot_param->efi_memmap);
   8.690 +	if (status != EFI_SUCCESS) {
   8.691 +		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode "
   8.692 +		       "(status=%lu)\n", status);
   8.693 +		return;
   8.694 +	}
   8.695 +
   8.696 +	/*
   8.697 +	 * Now that EFI is in virtual mode, we call the EFI functions more efficiently:
   8.698 +	 */
   8.699 +	efi.get_time = virt_get_time;
   8.700 +	efi.set_time = virt_set_time;
   8.701 +	efi.get_wakeup_time = virt_get_wakeup_time;
   8.702 +	efi.set_wakeup_time = virt_set_wakeup_time;
   8.703 +	efi.get_variable = virt_get_variable;
   8.704 +	efi.get_next_variable = virt_get_next_variable;
   8.705 +	efi.set_variable = virt_set_variable;
   8.706 +	efi.get_next_high_mono_count = virt_get_next_high_mono_count;
   8.707 +	efi.reset_system = virt_reset_system;
   8.708 +}
   8.709 +
   8.710 +/*
   8.711 + * Walk the EFI memory map looking for the I/O port range.  There can only be one entry of
   8.712 + * this type, other I/O port ranges should be described via ACPI.
   8.713 + */
   8.714 +u64
   8.715 +efi_get_iobase (void)
   8.716 +{
   8.717 +	void *efi_map_start, *efi_map_end, *p;
   8.718 +	efi_memory_desc_t *md;
   8.719 +	u64 efi_desc_size;
   8.720 +
   8.721 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.722 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.723 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.724 +
   8.725 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.726 +		md = p;
   8.727 +		if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
   8.728 +			if (md->attribute & EFI_MEMORY_UC)
   8.729 +				return md->phys_addr;
   8.730 +		}
   8.731 +	}
   8.732 +	return 0;
   8.733 +}
   8.734 +
   8.735 +#ifdef XEN
   8.736 +// variation of efi_get_iobase which returns entire memory descriptor
   8.737 +efi_memory_desc_t *
   8.738 +efi_get_io_md (void)
   8.739 +{
   8.740 +	void *efi_map_start, *efi_map_end, *p;
   8.741 +	efi_memory_desc_t *md;
   8.742 +	u64 efi_desc_size;
   8.743 +
   8.744 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.745 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.746 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.747 +
   8.748 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.749 +		md = p;
   8.750 +		if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
   8.751 +			if (md->attribute & EFI_MEMORY_UC)
   8.752 +				return md;
   8.753 +		}
   8.754 +	}
   8.755 +	return 0;
   8.756 +}
   8.757 +#endif
   8.758 +
   8.759 +u32
   8.760 +efi_mem_type (unsigned long phys_addr)
   8.761 +{
   8.762 +	void *efi_map_start, *efi_map_end, *p;
   8.763 +	efi_memory_desc_t *md;
   8.764 +	u64 efi_desc_size;
   8.765 +
   8.766 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.767 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.768 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.769 +
   8.770 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.771 +		md = p;
   8.772 +
   8.773 +		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
   8.774 +			 return md->type;
   8.775 +	}
   8.776 +	return 0;
   8.777 +}
   8.778 +
   8.779 +u64
   8.780 +efi_mem_attributes (unsigned long phys_addr)
   8.781 +{
   8.782 +	void *efi_map_start, *efi_map_end, *p;
   8.783 +	efi_memory_desc_t *md;
   8.784 +	u64 efi_desc_size;
   8.785 +
   8.786 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.787 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.788 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.789 +
   8.790 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.791 +		md = p;
   8.792 +
   8.793 +		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
   8.794 +			return md->attribute;
   8.795 +	}
   8.796 +	return 0;
   8.797 +}
   8.798 +EXPORT_SYMBOL(efi_mem_attributes);
   8.799 +
   8.800 +int
   8.801 +valid_phys_addr_range (unsigned long phys_addr, unsigned long *size)
   8.802 +{
   8.803 +	void *efi_map_start, *efi_map_end, *p;
   8.804 +	efi_memory_desc_t *md;
   8.805 +	u64 efi_desc_size;
   8.806 +
   8.807 +	efi_map_start = __va(ia64_boot_param->efi_memmap);
   8.808 +	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
   8.809 +	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   8.810 +
   8.811 +	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   8.812 +		md = p;
   8.813 +
   8.814 +		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) {
   8.815 +			if (!(md->attribute & EFI_MEMORY_WB))
   8.816 +				return 0;
   8.817 +
   8.818 +			if (*size > md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr)
   8.819 +				*size = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr;
   8.820 +			return 1;
   8.821 +		}
   8.822 +	}
   8.823 +	return 0;
   8.824 +}
   8.825 +
   8.826 +int __init
   8.827 +efi_uart_console_only(void)
   8.828 +{
   8.829 +	efi_status_t status;
   8.830 +	char *s, name[] = "ConOut";
   8.831 +	efi_guid_t guid = EFI_GLOBAL_VARIABLE_GUID;
   8.832 +	efi_char16_t *utf16, name_utf16[32];
   8.833 +	unsigned char data[1024];
   8.834 +	unsigned long size = sizeof(data);
   8.835 +	struct efi_generic_dev_path *hdr, *end_addr;
   8.836 +	int uart = 0;
   8.837 +
   8.838 +	/* Convert to UTF-16 */
   8.839 +	utf16 = name_utf16;
   8.840 +	s = name;
   8.841 +	while (*s)
   8.842 +		*utf16++ = *s++ & 0x7f;
   8.843 +	*utf16 = 0;
   8.844 +
   8.845 +	status = efi.get_variable(name_utf16, &guid, NULL, &size, data);
   8.846 +	if (status != EFI_SUCCESS) {
   8.847 +		printk(KERN_ERR "No EFI %s variable?\n", name);
   8.848 +		return 0;
   8.849 +	}
   8.850 +
   8.851 +	hdr = (struct efi_generic_dev_path *) data;
   8.852 +	end_addr = (struct efi_generic_dev_path *) ((u8 *) data + size);
   8.853 +	while (hdr < end_addr) {
   8.854 +		if (hdr->type == EFI_DEV_MSG &&
   8.855 +		    hdr->sub_type == EFI_DEV_MSG_UART)
   8.856 +			uart = 1;
   8.857 +		else if (hdr->type == EFI_DEV_END_PATH ||
   8.858 +			  hdr->type == EFI_DEV_END_PATH2) {
   8.859 +			if (!uart)
   8.860 +				return 0;
   8.861 +			if (hdr->sub_type == EFI_DEV_END_ENTIRE)
   8.862 +				return 1;
   8.863 +			uart = 0;
   8.864 +		}
   8.865 +		hdr = (struct efi_generic_dev_path *) ((u8 *) hdr + hdr->length);
   8.866 +	}
   8.867 +	printk(KERN_ERR "Malformed %s value\n", name);
   8.868 +	return 0;
   8.869 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/arch/ia64/linux-xen/entry.S	Tue Aug 02 16:25:11 2005 -0800
     9.3 @@ -0,0 +1,1653 @@
     9.4 +/*
     9.5 + * ia64/kernel/entry.S
     9.6 + *
     9.7 + * Kernel entry points.
     9.8 + *
     9.9 + * Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
    9.10 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    9.11 + * Copyright (C) 1999, 2002-2003
    9.12 + *	Asit Mallick <Asit.K.Mallick@intel.com>
    9.13 + * 	Don Dugger <Don.Dugger@intel.com>
    9.14 + *	Suresh Siddha <suresh.b.siddha@intel.com>
    9.15 + *	Fenghua Yu <fenghua.yu@intel.com>
    9.16 + * Copyright (C) 1999 VA Linux Systems
    9.17 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    9.18 + */
    9.19 +/*
    9.20 + * ia64_switch_to now places correct virtual mapping in in TR2 for
    9.21 + * kernel stack. This allows us to handle interrupts without changing
    9.22 + * to physical mode.
    9.23 + *
    9.24 + * Jonathan Nicklin	<nicklin@missioncriticallinux.com>
    9.25 + * Patrick O'Rourke	<orourke@missioncriticallinux.com>
    9.26 + * 11/07/2000
    9.27 + */
    9.28 +/*
    9.29 + * Global (preserved) predicate usage on syscall entry/exit path:
    9.30 + *
    9.31 + *	pKStk:		See entry.h.
    9.32 + *	pUStk:		See entry.h.
    9.33 + *	pSys:		See entry.h.
    9.34 + *	pNonSys:	!pSys
    9.35 + */
    9.36 +
    9.37 +#include <linux/config.h>
    9.38 +
    9.39 +#include <asm/asmmacro.h>
    9.40 +#include <asm/cache.h>
    9.41 +#include <asm/errno.h>
    9.42 +#include <asm/kregs.h>
    9.43 +#include <asm/offsets.h>
    9.44 +#include <asm/pgtable.h>
    9.45 +#include <asm/percpu.h>
    9.46 +#include <asm/processor.h>
    9.47 +#include <asm/thread_info.h>
    9.48 +#include <asm/unistd.h>
    9.49 +
    9.50 +#include "minstate.h"
    9.51 +
    9.52 +#ifndef XEN
    9.53 +	/*
    9.54 +	 * execve() is special because in case of success, we need to
    9.55 +	 * setup a null register window frame.
    9.56 +	 */
    9.57 +ENTRY(ia64_execve)
    9.58 +	/*
    9.59 +	 * Allocate 8 input registers since ptrace() may clobber them
    9.60 +	 */
    9.61 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
    9.62 +	alloc loc1=ar.pfs,8,2,4,0
    9.63 +	mov loc0=rp
    9.64 +	.body
    9.65 +	mov out0=in0			// filename
    9.66 +	;;				// stop bit between alloc and call
    9.67 +	mov out1=in1			// argv
    9.68 +	mov out2=in2			// envp
    9.69 +	add out3=16,sp			// regs
    9.70 +	br.call.sptk.many rp=sys_execve
    9.71 +.ret0:
    9.72 +#ifdef CONFIG_IA32_SUPPORT
    9.73 +	/*
    9.74 +	 * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers
    9.75 +	 * from pt_regs.
    9.76 +	 */
    9.77 +	adds r16=PT(CR_IPSR)+16,sp
    9.78 +	;;
    9.79 +	ld8 r16=[r16]
    9.80 +#endif
    9.81 +	cmp4.ge p6,p7=r8,r0
    9.82 +	mov ar.pfs=loc1			// restore ar.pfs
    9.83 +	sxt4 r8=r8			// return 64-bit result
    9.84 +	;;
    9.85 +	stf.spill [sp]=f0
    9.86 +(p6)	cmp.ne pKStk,pUStk=r0,r0	// a successful execve() lands us in user-mode...
    9.87 +	mov rp=loc0
    9.88 +(p6)	mov ar.pfs=r0			// clear ar.pfs on success
    9.89 +(p7)	br.ret.sptk.many rp
    9.90 +
    9.91 +	/*
    9.92 +	 * In theory, we'd have to zap this state only to prevent leaking of
    9.93 +	 * security sensitive state (e.g., if current->mm->dumpable is zero).  However,
    9.94 +	 * this executes in less than 20 cycles even on Itanium, so it's not worth
    9.95 +	 * optimizing for...).
    9.96 +	 */
    9.97 +	mov ar.unat=0; 		mov ar.lc=0
    9.98 +	mov r4=0;		mov f2=f0;		mov b1=r0
    9.99 +	mov r5=0;		mov f3=f0;		mov b2=r0
   9.100 +	mov r6=0;		mov f4=f0;		mov b3=r0
   9.101 +	mov r7=0;		mov f5=f0;		mov b4=r0
   9.102 +	ldf.fill f12=[sp];	mov f13=f0;		mov b5=r0
   9.103 +	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
   9.104 +	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
   9.105 +	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
   9.106 +	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
   9.107 +	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
   9.108 +	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
   9.109 +#ifdef CONFIG_IA32_SUPPORT
   9.110 +	tbit.nz p6,p0=r16, IA64_PSR_IS_BIT
   9.111 +	movl loc0=ia64_ret_from_ia32_execve
   9.112 +	;;
   9.113 +(p6)	mov rp=loc0
   9.114 +#endif
   9.115 +	br.ret.sptk.many rp
   9.116 +END(ia64_execve)
   9.117 +
   9.118 +/*
   9.119 + * sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 parent_tidptr, u64 child_tidptr,
   9.120 + *	      u64 tls)
   9.121 + */
   9.122 +GLOBAL_ENTRY(sys_clone2)
   9.123 +	/*
   9.124 +	 * Allocate 8 input registers since ptrace() may clobber them
   9.125 +	 */
   9.126 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
   9.127 +	alloc r16=ar.pfs,8,2,6,0
   9.128 +	DO_SAVE_SWITCH_STACK
   9.129 +	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
   9.130 +	mov loc0=rp
   9.131 +	mov loc1=r16				// save ar.pfs across do_fork
   9.132 +	.body
   9.133 +	mov out1=in1
   9.134 +	mov out3=in2
   9.135 +	tbit.nz p6,p0=in0,CLONE_SETTLS_BIT
   9.136 +	mov out4=in3	// parent_tidptr: valid only w/CLONE_PARENT_SETTID
   9.137 +	;;
   9.138 +(p6)	st8 [r2]=in5				// store TLS in r16 for copy_thread()
   9.139 +	mov out5=in4	// child_tidptr:  valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
   9.140 +	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
   9.141 +	mov out0=in0				// out0 = clone_flags
   9.142 +	br.call.sptk.many rp=do_fork
   9.143 +.ret1:	.restore sp
   9.144 +	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
   9.145 +	mov ar.pfs=loc1
   9.146 +	mov rp=loc0
   9.147 +	br.ret.sptk.many rp
   9.148 +END(sys_clone2)
   9.149 +
   9.150 +/*
   9.151 + * sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
   9.152 + *	Deprecated.  Use sys_clone2() instead.
   9.153 + */
   9.154 +GLOBAL_ENTRY(sys_clone)
   9.155 +	/*
   9.156 +	 * Allocate 8 input registers since ptrace() may clobber them
   9.157 +	 */
   9.158 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
   9.159 +	alloc r16=ar.pfs,8,2,6,0
   9.160 +	DO_SAVE_SWITCH_STACK
   9.161 +	adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
   9.162 +	mov loc0=rp
   9.163 +	mov loc1=r16				// save ar.pfs across do_fork
   9.164 +	.body
   9.165 +	mov out1=in1
   9.166 +	mov out3=16				// stacksize (compensates for 16-byte scratch area)
   9.167 +	tbit.nz p6,p0=in0,CLONE_SETTLS_BIT
   9.168 +	mov out4=in2	// parent_tidptr: valid only w/CLONE_PARENT_SETTID
   9.169 +	;;
   9.170 +(p6)	st8 [r2]=in4				// store TLS in r13 (tp)
   9.171 +	mov out5=in3	// child_tidptr:  valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
   9.172 +	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
   9.173 +	mov out0=in0				// out0 = clone_flags
   9.174 +	br.call.sptk.many rp=do_fork
   9.175 +.ret2:	.restore sp
   9.176 +	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
   9.177 +	mov ar.pfs=loc1
   9.178 +	mov rp=loc0
   9.179 +	br.ret.sptk.many rp
   9.180 +END(sys_clone)
   9.181 +#endif /* !XEN */
   9.182 +
   9.183 +/*
   9.184 + * prev_task <- ia64_switch_to(struct task_struct *next)
   9.185 + *	With Ingo's new scheduler, interrupts are disabled when this routine gets
   9.186 + *	called.  The code starting at .map relies on this.  The rest of the code
   9.187 + *	doesn't care about the interrupt masking status.
   9.188 + */
   9.189 +GLOBAL_ENTRY(ia64_switch_to)
   9.190 +	.prologue
   9.191 +	alloc r16=ar.pfs,1,0,0,0
   9.192 +	DO_SAVE_SWITCH_STACK
   9.193 +	.body
   9.194 +
   9.195 +	adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
   9.196 +	movl r25=init_task
   9.197 +	mov r27=IA64_KR(CURRENT_STACK)
   9.198 +	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
   9.199 +#ifdef XEN
   9.200 +	dep r20=0,in0,60,4		// physical address of "next"
   9.201 +#else
   9.202 +	dep r20=0,in0,61,3		// physical address of "next"
   9.203 +#endif
   9.204 +	;;
   9.205 +	st8 [r22]=sp			// save kernel stack pointer of old task
   9.206 +	shr.u r26=r20,IA64_GRANULE_SHIFT
   9.207 +	cmp.eq p7,p6=r25,in0
   9.208 +	;;
   9.209 +	/*
   9.210 +	 * If we've already mapped this task's page, we can skip doing it again.
   9.211 +	 */
   9.212 +(p6)	cmp.eq p7,p6=r26,r27
   9.213 +(p6)	br.cond.dpnt .map
   9.214 +	;;
   9.215 +.done:
   9.216 +(p6)	ssm psr.ic			// if we had to map, reenable the psr.ic bit FIRST!!!
   9.217 +	;;
   9.218 +(p6)	srlz.d
   9.219 +	ld8 sp=[r21]			// load kernel stack pointer of new task
   9.220 +	mov IA64_KR(CURRENT)=in0	// update "current" application register
   9.221 +	mov r8=r13			// return pointer to previously running task
   9.222 +	mov r13=in0			// set "current" pointer
   9.223 +	;;
   9.224 +	DO_LOAD_SWITCH_STACK
   9.225 +
   9.226 +#ifdef CONFIG_SMP
   9.227 +	sync.i				// ensure "fc"s done by this CPU are visible on other CPUs
   9.228 +#endif
   9.229 +	br.ret.sptk.many rp		// boogie on out in new context
   9.230 +
   9.231 +.map:
   9.232 +#ifdef XEN
   9.233 +	// avoid overlapping with kernel TR
   9.234 +	movl r25=KERNEL_START
   9.235 +	dep  r23=0,in0,0,KERNEL_TR_PAGE_SHIFT
   9.236 +	;;
   9.237 +	cmp.eq p7,p0=r25,r23
   9.238 +	;;
   9.239 +(p7)	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
   9.240 +(p7)	br.cond.sptk .done
   9.241 +#endif
   9.242 +	rsm psr.ic			// interrupts (psr.i) are already disabled here
   9.243 +	movl r25=PAGE_KERNEL
   9.244 +	;;
   9.245 +	srlz.d
   9.246 +	or r23=r25,r20			// construct PA | page properties
   9.247 +	mov r25=IA64_GRANULE_SHIFT<<2
   9.248 +	;;
   9.249 +	mov cr.itir=r25
   9.250 +	mov cr.ifa=in0			// VA of next task...
   9.251 +	;;
   9.252 +	mov r25=IA64_TR_CURRENT_STACK
   9.253 +	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
   9.254 +	;;
   9.255 +	itr.d dtr[r25]=r23		// wire in new mapping...
   9.256 +	br.cond.sptk .done
   9.257 +END(ia64_switch_to)
   9.258 +
   9.259 +/*
   9.260 + * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
   9.261 + * means that we may get an interrupt with "sp" pointing to the new kernel stack while
   9.262 + * ar.bspstore is still pointing to the old kernel backing store area.  Since ar.rsc,
   9.263 + * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts, this is not a
   9.264 + * problem.  Also, we don't need to specify unwind information for preserved registers
   9.265 + * that are not modified in save_switch_stack as the right unwind information is already
   9.266 + * specified at the call-site of save_switch_stack.
   9.267 + */
   9.268 +
   9.269 +/*
   9.270 + * save_switch_stack:
   9.271 + *	- r16 holds ar.pfs
   9.272 + *	- b7 holds address to return to
   9.273 + *	- rp (b0) holds return address to save
   9.274 + */
   9.275 +GLOBAL_ENTRY(save_switch_stack)
   9.276 +	.prologue
   9.277 +	.altrp b7
   9.278 +	flushrs			// flush dirty regs to backing store (must be first in insn group)
   9.279 +	.save @priunat,r17
   9.280 +	mov r17=ar.unat		// preserve caller's
   9.281 +	.body
   9.282 +#ifdef CONFIG_ITANIUM
   9.283 +	adds r2=16+128,sp
   9.284 +	adds r3=16+64,sp
   9.285 +	adds r14=SW(R4)+16,sp
   9.286 +	;;
   9.287 +	st8.spill [r14]=r4,16		// spill r4
   9.288 +	lfetch.fault.excl.nt1 [r3],128
   9.289 +	;;
   9.290 +	lfetch.fault.excl.nt1 [r2],128
   9.291 +	lfetch.fault.excl.nt1 [r3],128
   9.292 +	;;
   9.293 +	lfetch.fault.excl [r2]
   9.294 +	lfetch.fault.excl [r3]
   9.295 +	adds r15=SW(R5)+16,sp
   9.296 +#else
   9.297 +	add r2=16+3*128,sp
   9.298 +	add r3=16,sp
   9.299 +	add r14=SW(R4)+16,sp
   9.300 +	;;
   9.301 +	st8.spill [r14]=r4,SW(R6)-SW(R4)	// spill r4 and prefetch offset 0x1c0
   9.302 +	lfetch.fault.excl.nt1 [r3],128	//		prefetch offset 0x010
   9.303 +	;;
   9.304 +	lfetch.fault.excl.nt1 [r3],128	//		prefetch offset 0x090
   9.305 +	lfetch.fault.excl.nt1 [r2],128	//		prefetch offset 0x190
   9.306 +	;;
   9.307 +	lfetch.fault.excl.nt1 [r3]	//		prefetch offset 0x110
   9.308 +	lfetch.fault.excl.nt1 [r2]	//		prefetch offset 0x210
   9.309 +	adds r15=SW(R5)+16,sp
   9.310 +#endif
   9.311 +	;;
   9.312 +	st8.spill [r15]=r5,SW(R7)-SW(R5)	// spill r5
   9.313 +	mov.m ar.rsc=0			// put RSE in mode: enforced lazy, little endian, pl 0
   9.314 +	add r2=SW(F2)+16,sp		// r2 = &sw->f2
   9.315 +	;;
   9.316 +	st8.spill [r14]=r6,SW(B0)-SW(R6)	// spill r6
   9.317 +	mov.m r18=ar.fpsr		// preserve fpsr
   9.318 +	add r3=SW(F3)+16,sp		// r3 = &sw->f3
   9.319 +	;;
   9.320 +	stf.spill [r2]=f2,32
   9.321 +	mov.m r19=ar.rnat
   9.322 +	mov r21=b0
   9.323 +
   9.324 +	stf.spill [r3]=f3,32
   9.325 +	st8.spill [r15]=r7,SW(B2)-SW(R7)	// spill r7
   9.326 +	mov r22=b1
   9.327 +	;;
   9.328 +	// since we're done with the spills, read and save ar.unat:
   9.329 +	mov.m r29=ar.unat
   9.330 +	mov.m r20=ar.bspstore
   9.331 +	mov r23=b2
   9.332 +	stf.spill [r2]=f4,32
   9.333 +	stf.spill [r3]=f5,32
   9.334 +	mov r24=b3
   9.335 +	;;
   9.336 +	st8 [r14]=r21,SW(B1)-SW(B0)		// save b0
   9.337 +	st8 [r15]=r23,SW(B3)-SW(B2)		// save b2
   9.338 +	mov r25=b4
   9.339 +	mov r26=b5
   9.340 +	;;
   9.341 +	st8 [r14]=r22,SW(B4)-SW(B1)		// save b1
   9.342 +	st8 [r15]=r24,SW(AR_PFS)-SW(B3)		// save b3
   9.343 +	mov r21=ar.lc		// I-unit
   9.344 +	stf.spill [r2]=f12,32
   9.345 +	stf.spill [r3]=f13,32
   9.346 +	;;
   9.347 +	st8 [r14]=r25,SW(B5)-SW(B4)		// save b4
   9.348 +	st8 [r15]=r16,SW(AR_LC)-SW(AR_PFS)	// save ar.pfs
   9.349 +	stf.spill [r2]=f14,32
   9.350 +	stf.spill [r3]=f15,32
   9.351 +	;;
   9.352 +	st8 [r14]=r26				// save b5
   9.353 +	st8 [r15]=r21				// save ar.lc
   9.354 +	stf.spill [r2]=f16,32
   9.355 +	stf.spill [r3]=f17,32
   9.356 +	;;
   9.357 +	stf.spill [r2]=f18,32
   9.358 +	stf.spill [r3]=f19,32
   9.359 +	;;
   9.360 +	stf.spill [r2]=f20,32
   9.361 +	stf.spill [r3]=f21,32
   9.362 +	;;
   9.363 +	stf.spill [r2]=f22,32
   9.364 +	stf.spill [r3]=f23,32
   9.365 +	;;
   9.366 +	stf.spill [r2]=f24,32
   9.367 +	stf.spill [r3]=f25,32
   9.368 +	;;
   9.369 +	stf.spill [r2]=f26,32
   9.370 +	stf.spill [r3]=f27,32
   9.371 +	;;
   9.372 +	stf.spill [r2]=f28,32
   9.373 +	stf.spill [r3]=f29,32
   9.374 +	;;
   9.375 +	stf.spill [r2]=f30,SW(AR_UNAT)-SW(F30)
   9.376 +	stf.spill [r3]=f31,SW(PR)-SW(F31)
   9.377 +	add r14=SW(CALLER_UNAT)+16,sp
   9.378 +	;;
   9.379 +	st8 [r2]=r29,SW(AR_RNAT)-SW(AR_UNAT)	// save ar.unat
   9.380 +	st8 [r14]=r17,SW(AR_FPSR)-SW(CALLER_UNAT) // save caller_unat
   9.381 +	mov r21=pr
   9.382 +	;;
   9.383 +	st8 [r2]=r19,SW(AR_BSPSTORE)-SW(AR_RNAT) // save ar.rnat
   9.384 +	st8 [r3]=r21				// save predicate registers
   9.385 +	;;
   9.386 +	st8 [r2]=r20				// save ar.bspstore
   9.387 +	st8 [r14]=r18				// save fpsr
   9.388 +	mov ar.rsc=3		// put RSE back into eager mode, pl 0
   9.389 +	br.cond.sptk.many b7
   9.390 +END(save_switch_stack)
   9.391 +
   9.392 +/*
   9.393 + * load_switch_stack:
   9.394 + *	- "invala" MUST be done at call site (normally in DO_LOAD_SWITCH_STACK)
   9.395 + *	- b7 holds address to return to
   9.396 + *	- must not touch r8-r11
   9.397 + */
   9.398 +#ifdef XEN
   9.399 +GLOBAL_ENTRY(load_switch_stack)
   9.400 +#else
   9.401 +ENTRY(load_switch_stack)
   9.402 +#endif
   9.403 +	.prologue
   9.404 +	.altrp b7
   9.405 +
   9.406 +	.body
   9.407 +	lfetch.fault.nt1 [sp]
   9.408 +	adds r2=SW(AR_BSPSTORE)+16,sp
   9.409 +	adds r3=SW(AR_UNAT)+16,sp
   9.410 +	mov ar.rsc=0						// put RSE into enforced lazy mode
   9.411 +	adds r14=SW(CALLER_UNAT)+16,sp
   9.412 +	adds r15=SW(AR_FPSR)+16,sp
   9.413 +	;;
   9.414 +	ld8 r27=[r2],(SW(B0)-SW(AR_BSPSTORE))	// bspstore
   9.415 +	ld8 r29=[r3],(SW(B1)-SW(AR_UNAT))	// unat
   9.416 +	;;
   9.417 +	ld8 r21=[r2],16		// restore b0
   9.418 +	ld8 r22=[r3],16		// restore b1
   9.419 +	;;
   9.420 +	ld8 r23=[r2],16		// restore b2
   9.421 +	ld8 r24=[r3],16		// restore b3
   9.422 +	;;
   9.423 +	ld8 r25=[r2],16		// restore b4
   9.424 +	ld8 r26=[r3],16		// restore b5
   9.425 +	;;
   9.426 +	ld8 r16=[r2],(SW(PR)-SW(AR_PFS))	// ar.pfs
   9.427 +	ld8 r17=[r3],(SW(AR_RNAT)-SW(AR_LC))	// ar.lc
   9.428 +	;;
   9.429 +	ld8 r28=[r2]		// restore pr
   9.430 +	ld8 r30=[r3]		// restore rnat
   9.431 +	;;
   9.432 +	ld8 r18=[r14],16	// restore caller's unat
   9.433 +	ld8 r19=[r15],24	// restore fpsr
   9.434 +	;;
   9.435 +	ldf.fill f2=[r14],32
   9.436 +	ldf.fill f3=[r15],32
   9.437 +	;;
   9.438 +	ldf.fill f4=[r14],32
   9.439 +	ldf.fill f5=[r15],32
   9.440 +	;;
   9.441 +	ldf.fill f12=[r14],32
   9.442 +	ldf.fill f13=[r15],32
   9.443 +	;;
   9.444 +	ldf.fill f14=[r14],32
   9.445 +	ldf.fill f15=[r15],32
   9.446 +	;;
   9.447 +	ldf.fill f16=[r14],32
   9.448 +	ldf.fill f17=[r15],32
   9.449 +	;;
   9.450 +	ldf.fill f18=[r14],32
   9.451 +	ldf.fill f19=[r15],32
   9.452 +	mov b0=r21
   9.453 +	;;
   9.454 +	ldf.fill f20=[r14],32
   9.455 +	ldf.fill f21=[r15],32
   9.456 +	mov b1=r22
   9.457 +	;;
   9.458 +	ldf.fill f22=[r14],32
   9.459 +	ldf.fill f23=[r15],32
   9.460 +	mov b2=r23
   9.461 +	;;
   9.462 +	mov ar.bspstore=r27
   9.463 +	mov ar.unat=r29		// establish unat holding the NaT bits for r4-r7
   9.464 +	mov b3=r24
   9.465 +	;;
   9.466 +	ldf.fill f24=[r14],32
   9.467 +	ldf.fill f25=[r15],32
   9.468 +	mov b4=r25
   9.469 +	;;
   9.470 +	ldf.fill f26=[r14],32
   9.471 +	ldf.fill f27=[r15],32
   9.472 +	mov b5=r26
   9.473 +	;;
   9.474 +	ldf.fill f28=[r14],32
   9.475 +	ldf.fill f29=[r15],32
   9.476 +	mov ar.pfs=r16
   9.477 +	;;
   9.478 +	ldf.fill f30=[r14],32
   9.479 +	ldf.fill f31=[r15],24
   9.480 +	mov ar.lc=r17
   9.481 +	;;
   9.482 +	ld8.fill r4=[r14],16
   9.483 +	ld8.fill r5=[r15],16
   9.484 +	mov pr=r28,-1
   9.485 +	;;
   9.486 +	ld8.fill r6=[r14],16
   9.487 +	ld8.fill r7=[r15],16
   9.488 +
   9.489 +	mov ar.unat=r18				// restore caller's unat
   9.490 +	mov ar.rnat=r30				// must restore after bspstore but before rsc!
   9.491 +	mov ar.fpsr=r19				// restore fpsr
   9.492 +	mov ar.rsc=3				// put RSE back into eager mode, pl 0
   9.493 +	br.cond.sptk.many b7
   9.494 +END(load_switch_stack)
   9.495 +
   9.496 +#ifndef XEN
   9.497 +GLOBAL_ENTRY(__ia64_syscall)
   9.498 +	.regstk 6,0,0,0
   9.499 +	mov r15=in5				// put syscall number in place
   9.500 +	break __BREAK_SYSCALL
   9.501 +	movl r2=errno
   9.502 +	cmp.eq p6,p7=-1,r10
   9.503 +	;;
   9.504 +(p6)	st4 [r2]=r8
   9.505 +(p6)	mov r8=-1
   9.506 +	br.ret.sptk.many rp
   9.507 +END(__ia64_syscall)
   9.508 +
   9.509 +GLOBAL_ENTRY(execve)
   9.510 +	mov r15=__NR_execve			// put syscall number in place
   9.511 +	break __BREAK_SYSCALL
   9.512 +	br.ret.sptk.many rp
   9.513 +END(execve)
   9.514 +
   9.515 +GLOBAL_ENTRY(clone)
   9.516 +	mov r15=__NR_clone			// put syscall number in place
   9.517 +	break __BREAK_SYSCALL
   9.518 +	br.ret.sptk.many rp
   9.519 +END(clone)
   9.520 +
   9.521 +	/*
   9.522 +	 * Invoke a system call, but do some tracing before and after the call.
   9.523 +	 * We MUST preserve the current register frame throughout this routine
   9.524 +	 * because some system calls (such as ia64_execve) directly
   9.525 +	 * manipulate ar.pfs.
   9.526 +	 */
   9.527 +GLOBAL_ENTRY(ia64_trace_syscall)
   9.528 +	PT_REGS_UNWIND_INFO(0)
   9.529 +	/*
   9.530 +	 * We need to preserve the scratch registers f6-f11 in case the system
   9.531 +	 * call is sigreturn.
   9.532 +	 */
   9.533 +	adds r16=PT(F6)+16,sp
   9.534 +	adds r17=PT(F7)+16,sp
   9.535 +	;;
   9.536 + 	stf.spill [r16]=f6,32
   9.537 + 	stf.spill [r17]=f7,32
   9.538 +	;;
   9.539 + 	stf.spill [r16]=f8,32
   9.540 + 	stf.spill [r17]=f9,32
   9.541 +	;;
   9.542 + 	stf.spill [r16]=f10
   9.543 + 	stf.spill [r17]=f11
   9.544 +	br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
   9.545 +	adds r16=PT(F6)+16,sp
   9.546 +	adds r17=PT(F7)+16,sp
   9.547 +	;;
   9.548 +	ldf.fill f6=[r16],32
   9.549 +	ldf.fill f7=[r17],32
   9.550 +	;;
   9.551 +	ldf.fill f8=[r16],32
   9.552 +	ldf.fill f9=[r17],32
   9.553 +	;;
   9.554 +	ldf.fill f10=[r16]
   9.555 +	ldf.fill f11=[r17]
   9.556 +	// the syscall number may have changed, so re-load it and re-calculate the
   9.557 +	// syscall entry-point:
   9.558 +	adds r15=PT(R15)+16,sp			// r15 = &pt_regs.r15 (syscall #)
   9.559 +	;;
   9.560 +	ld8 r15=[r15]
   9.561 +	mov r3=NR_syscalls - 1
   9.562 +	;;
   9.563 +	adds r15=-1024,r15
   9.564 +	movl r16=sys_call_table
   9.565 +	;;
   9.566 +	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
   9.567 +	cmp.leu p6,p7=r15,r3
   9.568 +	;;
   9.569 +(p6)	ld8 r20=[r20]				// load address of syscall entry point
   9.570 +(p7)	movl r20=sys_ni_syscall
   9.571 +	;;
   9.572 +	mov b6=r20
   9.573 +	br.call.sptk.many rp=b6			// do the syscall
   9.574 +.strace_check_retval:
   9.575 +	cmp.lt p6,p0=r8,r0			// syscall failed?
   9.576 +	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   9.577 +	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
   9.578 +	mov r10=0
   9.579 +(p6)	br.cond.sptk strace_error		// syscall failed ->
   9.580 +	;;					// avoid RAW on r10
   9.581 +.strace_save_retval:
   9.582 +.mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
   9.583 +.mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
   9.584 +	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
   9.585 +.ret3:	br.cond.sptk .work_pending_syscall_end
   9.586 +
   9.587 +strace_error:
   9.588 +	ld8 r3=[r2]				// load pt_regs.r8
   9.589 +	sub r9=0,r8				// negate return value to get errno value
   9.590 +	;;
   9.591 +	cmp.ne p6,p0=r3,r0			// is pt_regs.r8!=0?
   9.592 +	adds r3=16,r2				// r3=&pt_regs.r10
   9.593 +	;;
   9.594 +(p6)	mov r10=-1
   9.595 +(p6)	mov r8=r9
   9.596 +	br.cond.sptk .strace_save_retval
   9.597 +END(ia64_trace_syscall)
   9.598 +
   9.599 +	/*
   9.600 +	 * When traced and returning from sigreturn, we invoke syscall_trace but then
   9.601 +	 * go straight to ia64_leave_kernel rather than ia64_leave_syscall.
   9.602 +	 */
   9.603 +GLOBAL_ENTRY(ia64_strace_leave_kernel)
   9.604 +	PT_REGS_UNWIND_INFO(0)
   9.605 +{	/*
   9.606 +	 * Some versions of gas generate bad unwind info if the first instruction of a
   9.607 +	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
   9.608 +	 */
   9.609 +	nop.m 0
   9.610 +	nop.i 0
   9.611 +	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
   9.612 +}
   9.613 +.ret4:	br.cond.sptk ia64_leave_kernel
   9.614 +END(ia64_strace_leave_kernel)
   9.615 +#endif
   9.616 +
   9.617 +GLOBAL_ENTRY(ia64_ret_from_clone)
   9.618 +	PT_REGS_UNWIND_INFO(0)
   9.619 +{	/*
   9.620 +	 * Some versions of gas generate bad unwind info if the first instruction of a
   9.621 +	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
   9.622 +	 */
   9.623 +	nop.m 0
   9.624 +	nop.i 0
   9.625 +	/*
   9.626 +	 * We need to call schedule_tail() to complete the scheduling process.
   9.627 +	 * Called by ia64_switch_to() after do_fork()->copy_thread().  r8 contains the
   9.628 +	 * address of the previously executing task.
   9.629 +	 */
   9.630 +	br.call.sptk.many rp=ia64_invoke_schedule_tail
   9.631 +}
   9.632 +#ifdef XEN
   9.633 +	// new domains are cloned but not exec'ed so switch to user mode here
   9.634 +	cmp.ne pKStk,pUStk=r0,r0
   9.635 +#ifdef CONFIG_VTI
   9.636 +	br.cond.spnt ia64_leave_hypervisor
   9.637 +#else // CONFIG_VTI
   9.638 +	br.cond.spnt ia64_leave_kernel
   9.639 +#endif // CONFIG_VTI
   9.640 +#else
   9.641 +.ret8:
   9.642 +	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
   9.643 +	;;
   9.644 +	ld4 r2=[r2]
   9.645 +	;;
   9.646 +	mov r8=0
   9.647 +	and r2=_TIF_SYSCALL_TRACEAUDIT,r2
   9.648 +	;;
   9.649 +	cmp.ne p6,p0=r2,r0
   9.650 +(p6)	br.cond.spnt .strace_check_retval
   9.651 +#endif
   9.652 +	;;					// added stop bits to prevent r8 dependency
   9.653 +END(ia64_ret_from_clone)
   9.654 +	// fall through
   9.655 +GLOBAL_ENTRY(ia64_ret_from_syscall)
   9.656 +	PT_REGS_UNWIND_INFO(0)
   9.657 +	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
   9.658 +	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   9.659 +	mov r10=r0				// clear error indication in r10
   9.660 +(p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
   9.661 +END(ia64_ret_from_syscall)
   9.662 +	// fall through
   9.663 +/*
   9.664 + * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
   9.665 + *	need to switch to bank 0 and doesn't restore the scratch registers.
   9.666 + *	To avoid leaking kernel bits, the scratch registers are set to
   9.667 + *	the following known-to-be-safe values:
   9.668 + *
   9.669 + *		  r1: restored (global pointer)
   9.670 + *		  r2: cleared
   9.671 + *		  r3: 1 (when returning to user-level)
   9.672 + *	      r8-r11: restored (syscall return value(s))
   9.673 + *		 r12: restored (user-level stack pointer)
   9.674 + *		 r13: restored (user-level thread pointer)
   9.675 + *		 r14: cleared
   9.676 + *		 r15: restored (syscall #)
   9.677 + *	     r16-r17: cleared
   9.678 + *		 r18: user-level b6
   9.679 + *		 r19: cleared
   9.680 + *		 r20: user-level ar.fpsr
   9.681 + *		 r21: user-level b0
   9.682 + *		 r22: cleared
   9.683 + *		 r23: user-level ar.bspstore
   9.684 + *		 r24: user-level ar.rnat
   9.685 + *		 r25: user-level ar.unat
   9.686 + *		 r26: user-level ar.pfs
   9.687 + *		 r27: user-level ar.rsc
   9.688 + *		 r28: user-level ip
   9.689 + *		 r29: user-level psr
   9.690 + *		 r30: user-level cfm
   9.691 + *		 r31: user-level pr
   9.692 + *	      f6-f11: cleared
   9.693 + *		  pr: restored (user-level pr)
   9.694 + *		  b0: restored (user-level rp)
   9.695 + *	          b6: restored
   9.696 + *		  b7: cleared
   9.697 + *	     ar.unat: restored (user-level ar.unat)
   9.698 + *	      ar.pfs: restored (user-level ar.pfs)
   9.699 + *	      ar.rsc: restored (user-level ar.rsc)
   9.700 + *	     ar.rnat: restored (user-level ar.rnat)
   9.701 + *	 ar.bspstore: restored (user-level ar.bspstore)
   9.702 + *	     ar.fpsr: restored (user-level ar.fpsr)
   9.703 + *	      ar.ccv: cleared
   9.704 + *	      ar.csd: cleared
   9.705 + *	      ar.ssd: cleared
   9.706 + */
   9.707 +ENTRY(ia64_leave_syscall)
   9.708 +	PT_REGS_UNWIND_INFO(0)
   9.709 +	/*
   9.710 +	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
   9.711 +	 * user- or fsys-mode, hence we disable interrupts early on.
   9.712 +	 *
   9.713 +	 * p6 controls whether current_thread_info()->flags needs to be check for
   9.714 +	 * extra work.  We always check for extra work when returning to user-level.
   9.715 +	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
   9.716 +	 * is 0.  After extra work processing has been completed, execution
   9.717 +	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
   9.718 +	 * needs to be redone.
   9.719 +	 */
   9.720 +#ifdef CONFIG_PREEMPT
   9.721 +	rsm psr.i				// disable interrupts
   9.722 +	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
   9.723 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
   9.724 +	;;
   9.725 +	.pred.rel.mutex pUStk,pKStk
   9.726 +(pKStk) ld4 r21=[r20]			// r21 <- preempt_count
   9.727 +(pUStk)	mov r21=0			// r21 <- 0
   9.728 +	;;
   9.729 +	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
   9.730 +#else /* !CONFIG_PREEMPT */
   9.731 +(pUStk)	rsm psr.i
   9.732 +	cmp.eq pLvSys,p0=r0,r0		// pLvSys=1: leave from syscall
   9.733 +(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
   9.734 +#endif
   9.735 +.work_processed_syscall:
   9.736 +	adds r2=PT(LOADRS)+16,r12
   9.737 +	adds r3=PT(AR_BSPSTORE)+16,r12
   9.738 +#ifdef XEN
   9.739 +	;;
   9.740 +#else
   9.741 +	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
   9.742 +	;;
   9.743 +(p6)	ld4 r31=[r18]				// load current_thread_info()->flags
   9.744 +#endif
   9.745 +	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
   9.746 +	mov b7=r0		// clear b7
   9.747 +	;;
   9.748 +	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
   9.749 +	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
   9.750 +#ifndef XEN
   9.751 +(p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
   9.752 +#endif
   9.753 +	;;
   9.754 +	mov r16=ar.bsp				// M2  get existing backing store pointer
   9.755 +#ifndef XEN
   9.756 +(p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
   9.757 +(p6)	br.cond.spnt .work_pending_syscall
   9.758 +#endif
   9.759 +	;;
   9.760 +	// start restoring the state saved on the kernel stack (struct pt_regs):
   9.761 +	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
   9.762 +	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
   9.763 +	mov f6=f0		// clear f6
   9.764 +	;;
   9.765 +	invala			// M0|1 invalidate ALAT
   9.766 +	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
   9.767 +	mov f9=f0		// clear f9
   9.768 +
   9.769 +	ld8 r29=[r2],16		// load cr.ipsr
   9.770 +	ld8 r28=[r3],16			// load cr.iip
   9.771 +	mov f8=f0		// clear f8
   9.772 +	;;
   9.773 +	ld8 r30=[r2],16		// M0|1 load cr.ifs
   9.774 +	mov.m ar.ssd=r0		// M2 clear ar.ssd
   9.775 +	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
   9.776 +	;;
   9.777 +	ld8 r25=[r3],16		// M0|1 load ar.unat
   9.778 +	mov.m ar.csd=r0		// M2 clear ar.csd
   9.779 +	mov r22=r0		// clear r22
   9.780 +	;;
   9.781 +	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
   9.782 +(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
   9.783 +	mov f10=f0		// clear f10
   9.784 +	;;
   9.785 +	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
   9.786 +	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// load ar.rsc
   9.787 +	mov f11=f0		// clear f11
   9.788 +	;;
   9.789 +	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
   9.790 +	ld8 r31=[r3],PT(R1)-PT(PR)		// load predicates
   9.791 +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
   9.792 +	;;
   9.793 +	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
   9.794 +	ld8.fill r1=[r3],16	// load r1
   9.795 +(pUStk) mov r17=1
   9.796 +	;;
   9.797 +	srlz.d			// M0  ensure interruption collection is off
   9.798 +	ld8.fill r13=[r3],16
   9.799 +	mov f7=f0		// clear f7
   9.800 +	;;
   9.801 +	ld8.fill r12=[r2]	// restore r12 (sp)
   9.802 +	ld8.fill r15=[r3]	// restore r15
   9.803 +#ifdef XEN
   9.804 +	movl r3=THIS_CPU(ia64_phys_stacked_size_p8)
   9.805 +#else
   9.806 +	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
   9.807 +#endif
   9.808 +	;;
   9.809 +(pUStk)	ld4 r3=[r3]		// r3 = cpu_data->phys_stacked_size_p8
   9.810 +(pUStk) st1 [r14]=r17
   9.811 +	mov b6=r18		// I0  restore b6
   9.812 +	;;
   9.813 +	mov r14=r0		// clear r14
   9.814 +	shr.u r18=r19,16	// I0|1 get byte size of existing "dirty" partition
   9.815 +(pKStk) br.cond.dpnt.many skip_rbs_switch
   9.816 +
   9.817 +	mov.m ar.ccv=r0		// clear ar.ccv
   9.818 +(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
   9.819 +	br.cond.sptk.many rbs_switch
   9.820 +END(ia64_leave_syscall)
   9.821 +
   9.822 +#ifdef CONFIG_IA32_SUPPORT
   9.823 +GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
   9.824 +	PT_REGS_UNWIND_INFO(0)
   9.825 +	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
   9.826 +	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
   9.827 +	;;
   9.828 +	.mem.offset 0,0
   9.829 +	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
   9.830 +	.mem.offset 8,0
   9.831 +	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
   9.832 +END(ia64_ret_from_ia32_execve_syscall)
   9.833 +	// fall through
   9.834 +#endif /* CONFIG_IA32_SUPPORT */
   9.835 +GLOBAL_ENTRY(ia64_leave_kernel)
   9.836 +	PT_REGS_UNWIND_INFO(0)
   9.837 +	/*
   9.838 +	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
   9.839 +	 * user- or fsys-mode, hence we disable interrupts early on.
   9.840 +	 *
   9.841 +	 * p6 controls whether current_thread_info()->flags needs to be check for
   9.842 +	 * extra work.  We always check for extra work when returning to user-level.
   9.843 +	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
   9.844 +	 * is 0.  After extra work processing has been completed, execution
   9.845 +	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
   9.846 +	 * needs to be redone.
   9.847 +	 */
   9.848 +#ifdef CONFIG_PREEMPT
   9.849 +	rsm psr.i				// disable interrupts
   9.850 +	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
   9.851 +(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
   9.852 +	;;
   9.853 +	.pred.rel.mutex pUStk,pKStk
   9.854 +(pKStk)	ld4 r21=[r20]			// r21 <- preempt_count
   9.855 +(pUStk)	mov r21=0			// r21 <- 0
   9.856 +	;;
   9.857 +	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
   9.858 +#else
   9.859 +(pUStk)	rsm psr.i
   9.860 +	cmp.eq p0,pLvSys=r0,r0		// pLvSys=0: leave from kernel
   9.861 +(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
   9.862 +#endif
   9.863 +.work_processed_kernel:
   9.864 +#ifdef XEN
   9.865 +	alloc loc0=ar.pfs,0,1,1,0
   9.866 +	adds out0=16,r12
   9.867 +	;;
   9.868 +(p6)	br.call.sptk.many b0=deliver_pending_interrupt
   9.869 +	mov ar.pfs=loc0
   9.870 +	mov r31=r0
   9.871 +#else
   9.872 +	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
   9.873 +	;;
   9.874 +(p6)	ld4 r31=[r17]				// load current_thread_info()->flags
   9.875 +#endif
   9.876 +	adds r21=PT(PR)+16,r12
   9.877 +	;;
   9.878 +
   9.879 +	lfetch [r21],PT(CR_IPSR)-PT(PR)
   9.880 +	adds r2=PT(B6)+16,r12
   9.881 +	adds r3=PT(R16)+16,r12
   9.882 +	;;
   9.883 +	lfetch [r21]
   9.884 +	ld8 r28=[r2],8		// load b6
   9.885 +	adds r29=PT(R24)+16,r12
   9.886 +
   9.887 +	ld8.fill r16=[r3]
   9.888 +	adds r30=PT(AR_CCV)+16,r12
   9.889 +(p6)	and r19=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
   9.890 +	;;
   9.891 +	adds r3=PT(AR_CSD)-PT(R16),r3
   9.892 +	ld8.fill r24=[r29]
   9.893 +	ld8 r15=[r30]		// load ar.ccv
   9.894 +(p6)	cmp4.ne.unc p6,p0=r19, r0		// any special work pending?
   9.895 +	;;
   9.896 +	ld8 r29=[r2],16		// load b7
   9.897 +	ld8 r30=[r3],16		// load ar.csd
   9.898 +#ifndef XEN
   9.899 +(p6)	br.cond.spnt .work_pending
   9.900 +#endif
   9.901 +	;;
   9.902 +	ld8 r31=[r2],16		// load ar.ssd
   9.903 +	ld8.fill r8=[r3],16
   9.904 +	;;
   9.905 +	ld8.fill r9=[r2],16
   9.906 +	ld8.fill r10=[r3],PT(R17)-PT(R10)
   9.907 +	;;
   9.908 +	ld8.fill r11=[r2],PT(R18)-PT(R11)
   9.909 +	ld8.fill r17=[r3],16
   9.910 +	;;
   9.911 +	ld8.fill r18=[r2],16
   9.912 +	ld8.fill r19=[r3],16
   9.913 +	;;
   9.914 +	ld8.fill r20=[r2],16
   9.915 +	ld8.fill r21=[r3],16
   9.916 +	mov ar.csd=r30
   9.917 +	mov ar.ssd=r31
   9.918 +	;;
   9.919 +	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
   9.920 +	invala			// invalidate ALAT
   9.921 +	;;
   9.922 +	ld8.fill r22=[r2],24
   9.923 +	ld8.fill r23=[r3],24
   9.924 +	mov b6=r28
   9.925 +	;;
   9.926 +	ld8.fill r25=[r2],16
   9.927 +	ld8.fill r26=[r3],16
   9.928 +	mov b7=r29
   9.929 +	;;
   9.930 +	ld8.fill r27=[r2],16
   9.931 +	ld8.fill r28=[r3],16
   9.932 +	;;
   9.933 +	ld8.fill r29=[r2],16
   9.934 +	ld8.fill r30=[r3],24
   9.935 +	;;
   9.936 +	ld8.fill r31=[r2],PT(F9)-PT(R31)
   9.937 +	adds r3=PT(F10)-PT(F6),r3
   9.938 +	;;
   9.939 +	ldf.fill f9=[r2],PT(F6)-PT(F9)
   9.940 +	ldf.fill f10=[r3],PT(F8)-PT(F10)
   9.941 +	;;
   9.942 +	ldf.fill f6=[r2],PT(F7)-PT(F6)
   9.943 +	;;
   9.944 +	ldf.fill f7=[r2],PT(F11)-PT(F7)
   9.945 +	ldf.fill f8=[r3],32
   9.946 +	;;
   9.947 +	srlz.i			// ensure interruption collection is off
   9.948 +	mov ar.ccv=r15
   9.949 +	;;
   9.950 +	ldf.fill f11=[r2]
   9.951 +	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
   9.952 +	;;
   9.953 +(pUStk)	mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
   9.954 +	adds r16=PT(CR_IPSR)+16,r12
   9.955 +	adds r17=PT(CR_IIP)+16,r12
   9.956 +
   9.957 +(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
   9.958 +	nop.i 0
   9.959 +	nop.i 0
   9.960 +	;;
   9.961 +	ld8 r29=[r16],16	// load cr.ipsr
   9.962 +	ld8 r28=[r17],16	// load cr.iip
   9.963 +	;;
   9.964 +	ld8 r30=[r16],16	// load cr.ifs
   9.965 +	ld8 r25=[r17],16	// load ar.unat
   9.966 +	;;
   9.967 +	ld8 r26=[r16],16	// load ar.pfs
   9.968 +	ld8 r27=[r17],16	// load ar.rsc
   9.969 +	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
   9.970 +	;;
   9.971 +	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
   9.972 +	ld8 r23=[r17],16	// load ar.bspstore (may be garbage)
   9.973 +	;;
   9.974 +	ld8 r31=[r16],16	// load predicates
   9.975 +	ld8 r21=[r17],16	// load b0
   9.976 +	;;
   9.977 +	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
   9.978 +	ld8.fill r1=[r17],16	// load r1
   9.979 +	;;
   9.980 +	ld8.fill r12=[r16],16
   9.981 +	ld8.fill r13=[r17],16
   9.982 +(pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
   9.983 +	;;
   9.984 +	ld8 r20=[r16],16	// ar.fpsr
   9.985 +	ld8.fill r15=[r17],16
   9.986 +	;;
   9.987 +	ld8.fill r14=[r16],16
   9.988 +	ld8.fill r2=[r17]
   9.989 +(pUStk)	mov r17=1
   9.990 +	;;
   9.991 +	ld8.fill r3=[r16]
   9.992 +(pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
   9.993 +	shr.u r18=r19,16	// get byte size of existing "dirty" partition
   9.994 +	;;
   9.995 +	mov r16=ar.bsp		// get existing backing store pointer
   9.996 +#ifdef XEN
   9.997 +	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
   9.998 +#else
   9.999 +	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
  9.1000 +#endif
  9.1001 +	;;
  9.1002 +	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
  9.1003 +(pKStk)	br.cond.dpnt skip_rbs_switch
  9.1004 +
  9.1005 +	/*
  9.1006 +	 * Restore user backing store.
  9.1007 +	 *
  9.1008 +	 * NOTE: alloc, loadrs, and cover can't be predicated.
  9.1009 +	 */
  9.1010 +(pNonSys) br.cond.dpnt dont_preserve_current_frame
  9.1011 +
  9.1012 +rbs_switch:
  9.1013 +	cover				// add current frame into dirty partition and set cr.ifs
  9.1014 +	;;
  9.1015 +	mov r19=ar.bsp			// get new backing store pointer
  9.1016 +	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
  9.1017 +	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
  9.1018 +	;;
  9.1019 +	sub r19=r19,r16			// calculate total byte size of dirty partition
  9.1020 +	add r18=64,r18			// don't force in0-in7 into memory...
  9.1021 +	;;
  9.1022 +	shl r19=r19,16			// shift size of dirty partition into loadrs position
  9.1023 +	;;
  9.1024 +dont_preserve_current_frame:
  9.1025 +	/*
  9.1026 +	 * To prevent leaking bits between the kernel and user-space,
  9.1027 +	 * we must clear the stacked registers in the "invalid" partition here.
  9.1028 +	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
  9.1029 +	 * 5 registers/cycle on McKinley).
  9.1030 +	 */
  9.1031 +#	define pRecurse	p6
  9.1032 +#	define pReturn	p7
  9.1033 +#ifdef CONFIG_ITANIUM
  9.1034 +#	define Nregs	10
  9.1035 +#else
  9.1036 +#	define Nregs	14
  9.1037 +#endif
  9.1038 +	alloc loc0=ar.pfs,2,Nregs-2,2,0
  9.1039 +	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
  9.1040 +	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
  9.1041 +	;;
  9.1042 +	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
  9.1043 +	shladd in0=loc1,3,r17
  9.1044 +	mov in1=0
  9.1045 +	;;
  9.1046 +	TEXT_ALIGN(32)
  9.1047 +rse_clear_invalid:
  9.1048 +#ifdef CONFIG_ITANIUM
  9.1049 +	// cycle 0
  9.1050 + { .mii
  9.1051 +	alloc loc0=ar.pfs,2,Nregs-2,2,0
  9.1052 +	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
  9.1053 +	add out0=-Nregs*8,in0
  9.1054 +}{ .mfb
  9.1055 +	add out1=1,in1			// increment recursion count
  9.1056 +	nop.f 0
  9.1057 +	nop.b 0				// can't do br.call here because of alloc (WAW on CFM)
  9.1058 +	;;
  9.1059 +}{ .mfi	// cycle 1
  9.1060 +	mov loc1=0
  9.1061 +	nop.f 0
  9.1062 +	mov loc2=0
  9.1063 +}{ .mib
  9.1064 +	mov loc3=0
  9.1065 +	mov loc4=0
  9.1066 +(pRecurse) br.call.sptk.many b0=rse_clear_invalid
  9.1067 +
  9.1068 +}{ .mfi	// cycle 2
  9.1069 +	mov loc5=0
  9.1070 +	nop.f 0
  9.1071 +	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
  9.1072 +}{ .mib
  9.1073 +	mov loc6=0
  9.1074 +	mov loc7=0
  9.1075 +(pReturn) br.ret.sptk.many b0
  9.1076 +}
  9.1077 +#else /* !CONFIG_ITANIUM */
  9.1078 +	alloc loc0=ar.pfs,2,Nregs-2,2,0
  9.1079 +	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
  9.1080 +	add out0=-Nregs*8,in0
  9.1081 +	add out1=1,in1			// increment recursion count
  9.1082 +	mov loc1=0
  9.1083 +	mov loc2=0
  9.1084 +	;;
  9.1085 +	mov loc3=0
  9.1086 +	mov loc4=0
  9.1087 +	mov loc5=0
  9.1088 +	mov loc6=0
  9.1089 +	mov loc7=0
  9.1090 +(pRecurse) br.call.sptk.few b0=rse_clear_invalid
  9.1091 +	;;
  9.1092 +	mov loc8=0
  9.1093 +	mov loc9=0
  9.1094 +	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
  9.1095 +	mov loc10=0
  9.1096 +	mov loc11=0
  9.1097 +(pReturn) br.ret.sptk.many b0
  9.1098 +#endif /* !CONFIG_ITANIUM */
  9.1099 +#	undef pRecurse
  9.1100 +#	undef pReturn
  9.1101 +	;;
  9.1102 +	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
  9.1103 +	;;
  9.1104 +	loadrs
  9.1105 +	;;
  9.1106 +skip_rbs_switch:
  9.1107 +	mov ar.unat=r25		// M2
  9.1108 +(pKStk)	extr.u r22=r22,21,1	// I0 extract current value of psr.pp from r22
  9.1109 +(pLvSys)mov r19=r0		// A  clear r19 for leave_syscall, no-op otherwise
  9.1110 +	;;
  9.1111 +(pUStk)	mov ar.bspstore=r23	// M2
  9.1112 +(pKStk)	dep r29=r22,r29,21,1	// I0 update ipsr.pp with psr.pp
  9.1113 +(pLvSys)mov r16=r0		// A  clear r16 for leave_syscall, no-op otherwise
  9.1114 +	;;
  9.1115 +	mov cr.ipsr=r29		// M2
  9.1116 +	mov ar.pfs=r26		// I0
  9.1117 +(pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
  9.1118 +
  9.1119 +(p9)	mov cr.ifs=r30		// M2
  9.1120 +	mov b0=r21		// I0
  9.1121 +(pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
  9.1122 +
  9.1123 +	mov ar.fpsr=r20		// M2
  9.1124 +	mov cr.iip=r28		// M2
  9.1125 +	nop 0
  9.1126 +	;;
  9.1127 +(pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
  9.1128 +	nop 0
  9.1129 +(pLvSys)mov r2=r0
  9.1130 +
  9.1131 +	mov ar.rsc=r27		// M2
  9.1132 +	mov pr=r31,-1		// I0
  9.1133 +	rfi			// B
  9.1134 +
  9.1135 +#ifndef XEN
  9.1136 +	/*
  9.1137 +	 * On entry:
  9.1138 +	 *	r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
  9.1139 +	 *	r31 = current->thread_info->flags
  9.1140 +	 * On exit:
  9.1141 +	 *	p6 = TRUE if work-pending-check needs to be redone
  9.1142 +	 */
  9.1143 +.work_pending_syscall:
  9.1144 +	add r2=-8,r2
  9.1145 +	add r3=-8,r3
  9.1146 +	;;
  9.1147 +	st8 [r2]=r8
  9.1148 +	st8 [r3]=r10
  9.1149 +.work_pending:
  9.1150 +	tbit.nz p6,p0=r31,TIF_SIGDELAYED		// signal delayed from  MCA/INIT/NMI/PMI context?
  9.1151 +(p6)	br.cond.sptk.few .sigdelayed
  9.1152 +	;;
  9.1153 +	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
  9.1154 +(p6)	br.cond.sptk.few .notify
  9.1155 +#ifdef CONFIG_PREEMPT
  9.1156 +(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
  9.1157 +	;;
  9.1158 +(pKStk) st4 [r20]=r21
  9.1159 +	ssm psr.i		// enable interrupts
  9.1160 +#endif
  9.1161 +	br.call.spnt.many rp=schedule
  9.1162 +.ret9:	cmp.eq p6,p0=r0,r0				// p6 <- 1
  9.1163 +	rsm psr.i		// disable interrupts
  9.1164 +	;;
  9.1165 +#ifdef CONFIG_PREEMPT
  9.1166 +(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
  9.1167 +	;;
  9.1168 +(pKStk)	st4 [r20]=r0		// preempt_count() <- 0
  9.1169 +#endif
  9.1170 +(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  9.1171 +	br.cond.sptk.many .work_processed_kernel	// re-check
  9.1172 +
  9.1173 +.notify:
  9.1174 +(pUStk)	br.call.spnt.many rp=notify_resume_user
  9.1175 +.ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
  9.1176 +(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  9.1177 +	br.cond.sptk.many .work_processed_kernel	// don't re-check
  9.1178 +
  9.1179 +// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
  9.1180 +// it could not be delivered.  Deliver it now.  The signal might be for us and
  9.1181 +// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
  9.1182 +// signal.
  9.1183 +
  9.1184 +.sigdelayed:
  9.1185 +	br.call.sptk.many rp=do_sigdelayed
  9.1186 +	cmp.eq p6,p0=r0,r0				// p6 <- 1, always re-check
  9.1187 +(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
  9.1188 +	br.cond.sptk.many .work_processed_kernel	// re-check
  9.1189 +
  9.1190 +.work_pending_syscall_end:
  9.1191 +	adds r2=PT(R8)+16,r12
  9.1192 +	adds r3=PT(R10)+16,r12
  9.1193 +	;;
  9.1194 +	ld8 r8=[r2]
  9.1195 +	ld8 r10=[r3]
  9.1196 +	br.cond.sptk.many .work_processed_syscall	// re-check
  9.1197 +#endif
  9.1198 +
  9.1199 +END(ia64_leave_kernel)
  9.1200 +
  9.1201 +ENTRY(handle_syscall_error)
  9.1202 +	/*
  9.1203 +	 * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
  9.1204 +	 * lead us to mistake a negative return value as a failed syscall.  Those syscall
  9.1205 +	 * must deposit a non-zero value in pt_regs.r8 to indicate an error.  If
  9.1206 +	 * pt_regs.r8 is zero, we assume that the call completed successfully.
  9.1207 +	 */
  9.1208 +	PT_REGS_UNWIND_INFO(0)
  9.1209 +	ld8 r3=[r2]		// load pt_regs.r8
  9.1210 +	;;
  9.1211 +	cmp.eq p6,p7=r3,r0	// is pt_regs.r8==0?
  9.1212 +	;;
  9.1213 +(p7)	mov r10=-1
  9.1214 +(p7)	sub r8=0,r8		// negate return value to get errno
  9.1215 +	br.cond.sptk ia64_leave_syscall
  9.1216 +END(handle_syscall_error)
  9.1217 +
  9.1218 +	/*
  9.1219 +	 * Invoke schedule_tail(task) while preserving in0-in7, which may be needed
  9.1220 +	 * in case a system call gets restarted.
  9.1221 +	 */
  9.1222 +GLOBAL_ENTRY(ia64_invoke_schedule_tail)
  9.1223 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  9.1224 +	alloc loc1=ar.pfs,8,2,1,0
  9.1225 +	mov loc0=rp
  9.1226 +	mov out0=r8				// Address of previous task
  9.1227 +	;;
  9.1228 +	br.call.sptk.many rp=schedule_tail
  9.1229 +.ret11:	mov ar.pfs=loc1
  9.1230 +	mov rp=loc0
  9.1231 +	br.ret.sptk.many rp
  9.1232 +END(ia64_invoke_schedule_tail)
  9.1233 +
  9.1234 +#ifndef XEN
  9.1235 +	/*
  9.1236 +	 * Setup stack and call do_notify_resume_user().  Note that pSys and pNonSys need to
  9.1237 +	 * be set up by the caller.  We declare 8 input registers so the system call
  9.1238 +	 * args get preserved, in case we need to restart a system call.
  9.1239 +	 */
  9.1240 +ENTRY(notify_resume_user)
  9.1241 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  9.1242 +	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
  9.1243 +	mov r9=ar.unat
  9.1244 +	mov loc0=rp				// save return address
  9.1245 +	mov out0=0				// there is no "oldset"
  9.1246 +	adds out1=8,sp				// out1=&sigscratch->ar_pfs
  9.1247 +(pSys)	mov out2=1				// out2==1 => we're in a syscall
  9.1248 +	;;
  9.1249 +(pNonSys) mov out2=0				// out2==0 => not a syscall
  9.1250 +	.fframe 16
  9.1251 +	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
  9.1252 +	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
  9.1253 +	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
  9.1254 +	.body
  9.1255 +	br.call.sptk.many rp=do_notify_resume_user
  9.1256 +.ret15:	.restore sp
  9.1257 +	adds sp=16,sp				// pop scratch stack space
  9.1258 +	;;
  9.1259 +	ld8 r9=[sp]				// load new unat from sigscratch->scratch_unat
  9.1260 +	mov rp=loc0
  9.1261 +	;;
  9.1262 +	mov ar.unat=r9
  9.1263 +	mov ar.pfs=loc1
  9.1264 +	br.ret.sptk.many rp
  9.1265 +END(notify_resume_user)
  9.1266 +
  9.1267 +GLOBAL_ENTRY(sys_rt_sigsuspend)
  9.1268 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  9.1269 +	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
  9.1270 +	mov r9=ar.unat
  9.1271 +	mov loc0=rp				// save return address
  9.1272 +	mov out0=in0				// mask
  9.1273 +	mov out1=in1				// sigsetsize
  9.1274 +	adds out2=8,sp				// out2=&sigscratch->ar_pfs
  9.1275 +	;;
  9.1276 +	.fframe 16
  9.1277 +	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
  9.1278 +	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
  9.1279 +	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
  9.1280 +	.body
  9.1281 +	br.call.sptk.many rp=ia64_rt_sigsuspend
  9.1282 +.ret17:	.restore sp
  9.1283 +	adds sp=16,sp				// pop scratch stack space
  9.1284 +	;;
  9.1285 +	ld8 r9=[sp]				// load new unat from sw->caller_unat
  9.1286 +	mov rp=loc0
  9.1287 +	;;
  9.1288 +	mov ar.unat=r9
  9.1289 +	mov ar.pfs=loc1
  9.1290 +	br.ret.sptk.many rp
  9.1291 +END(sys_rt_sigsuspend)
  9.1292 +
  9.1293 +ENTRY(sys_rt_sigreturn)
  9.1294 +	PT_REGS_UNWIND_INFO(0)
  9.1295 +	/*
  9.1296 +	 * Allocate 8 input registers since ptrace() may clobber them
  9.1297 +	 */
  9.1298 +	alloc r2=ar.pfs,8,0,1,0
  9.1299 +	.prologue
  9.1300 +	PT_REGS_SAVES(16)
  9.1301 +	adds sp=-16,sp
  9.1302 +	.body
  9.1303 +	cmp.eq pNonSys,pSys=r0,r0		// sigreturn isn't a normal syscall...
  9.1304 +	;;
  9.1305 +	/*
  9.1306 +	 * leave_kernel() restores f6-f11 from pt_regs, but since the streamlined
  9.1307 +	 * syscall-entry path does not save them we save them here instead.  Note: we
  9.1308 +	 * don't need to save any other registers that are not saved by the stream-lined
  9.1309 +	 * syscall path, because restore_sigcontext() restores them.
  9.1310 +	 */
  9.1311 +	adds r16=PT(F6)+32,sp
  9.1312 +	adds r17=PT(F7)+32,sp
  9.1313 +	;;
  9.1314 + 	stf.spill [r16]=f6,32
  9.1315 + 	stf.spill [r17]=f7,32
  9.1316 +	;;
  9.1317 + 	stf.spill [r16]=f8,32
  9.1318 + 	stf.spill [r17]=f9,32
  9.1319 +	;;
  9.1320 + 	stf.spill [r16]=f10
  9.1321 + 	stf.spill [r17]=f11
  9.1322 +	adds out0=16,sp				// out0 = &sigscratch
  9.1323 +	br.call.sptk.many rp=ia64_rt_sigreturn
  9.1324 +.ret19:	.restore sp 0
  9.1325 +	adds sp=16,sp
  9.1326 +	;;
  9.1327 +	ld8 r9=[sp]				// load new ar.unat
  9.1328 +	mov.sptk b7=r8,ia64_leave_kernel
  9.1329 +	;;
  9.1330 +	mov ar.unat=r9
  9.1331 +	br.many b7
  9.1332 +END(sys_rt_sigreturn)
  9.1333 +#endif
  9.1334 +
  9.1335 +GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
  9.1336 +	.prologue
  9.1337 +	/*
  9.1338 +	 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
  9.1339 +	 */
  9.1340 +	mov r16=r0
  9.1341 +	DO_SAVE_SWITCH_STACK
  9.1342 +	br.call.sptk.many rp=ia64_handle_unaligned	// stack frame setup in ivt
  9.1343 +.ret21:	.body
  9.1344 +	DO_LOAD_SWITCH_STACK
  9.1345 +	br.cond.sptk.many rp				// goes to ia64_leave_kernel
  9.1346 +END(ia64_prepare_handle_unaligned)
  9.1347 +
  9.1348 +#ifndef XEN
  9.1349 +	//
  9.1350 +	// unw_init_running(void (*callback)(info, arg), void *arg)
  9.1351 +	//
  9.1352 +#	define EXTRA_FRAME_SIZE	((UNW_FRAME_INFO_SIZE+15)&~15)
  9.1353 +
  9.1354 +GLOBAL_ENTRY(unw_init_running)
  9.1355 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  9.1356 +	alloc loc1=ar.pfs,2,3,3,0
  9.1357 +	;;
  9.1358 +	ld8 loc2=[in0],8
  9.1359 +	mov loc0=rp
  9.1360 +	mov r16=loc1
  9.1361 +	DO_SAVE_SWITCH_STACK
  9.1362 +	.body
  9.1363 +
  9.1364 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  9.1365 +	.fframe IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE
  9.1366 +	SWITCH_STACK_SAVES(EXTRA_FRAME_SIZE)
  9.1367 +	adds sp=-EXTRA_FRAME_SIZE,sp
  9.1368 +	.body
  9.1369 +	;;
  9.1370 +	adds out0=16,sp				// &info
  9.1371 +	mov out1=r13				// current
  9.1372 +	adds out2=16+EXTRA_FRAME_SIZE,sp	// &switch_stack
  9.1373 +	br.call.sptk.many rp=unw_init_frame_info
  9.1374 +1:	adds out0=16,sp				// &info
  9.1375 +	mov b6=loc2
  9.1376 +	mov loc2=gp				// save gp across indirect function call
  9.1377 +	;;
  9.1378 +	ld8 gp=[in0]
  9.1379 +	mov out1=in1				// arg
  9.1380 +	br.call.sptk.many rp=b6			// invoke the callback function
  9.1381 +1:	mov gp=loc2				// restore gp
  9.1382 +
  9.1383 +	// For now, we don't allow changing registers from within
  9.1384 +	// unw_init_running; if we ever want to allow that, we'd
  9.1385 +	// have to do a load_switch_stack here:
  9.1386 +	.restore sp
  9.1387 +	adds sp=IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE,sp
  9.1388 +
  9.1389 +	mov ar.pfs=loc1
  9.1390 +	mov rp=loc0
  9.1391 +	br.ret.sptk.many rp
  9.1392 +END(unw_init_running)
  9.1393 +
  9.1394 +	.rodata
  9.1395 +	.align 8
  9.1396 +	.globl sys_call_table
  9.1397 +sys_call_table:
  9.1398 +	data8 sys_ni_syscall		//  This must be sys_ni_syscall!  See ivt.S.
  9.1399 +	data8 sys_exit				// 1025
  9.1400 +	data8 sys_read
  9.1401 +	data8 sys_write
  9.1402 +	data8 sys_open
  9.1403 +	data8 sys_close
  9.1404 +	data8 sys_creat				// 1030
  9.1405 +	data8 sys_link
  9.1406 +	data8 sys_unlink
  9.1407 +	data8 ia64_execve
  9.1408 +	data8 sys_chdir
  9.1409 +	data8 sys_fchdir			// 1035
  9.1410 +	data8 sys_utimes
  9.1411 +	data8 sys_mknod
  9.1412 +	data8 sys_chmod
  9.1413 +	data8 sys_chown
  9.1414 +	data8 sys_lseek				// 1040
  9.1415 +	data8 sys_getpid
  9.1416 +	data8 sys_getppid
  9.1417 +	data8 sys_mount
  9.1418 +	data8 sys_umount
  9.1419 +	data8 sys_setuid			// 1045
  9.1420 +	data8 sys_getuid
  9.1421 +	data8 sys_geteuid
  9.1422 +	data8 sys_ptrace
  9.1423 +	data8 sys_access
  9.1424 +	data8 sys_sync				// 1050
  9.1425 +	data8 sys_fsync
  9.1426 +	data8 sys_fdatasync
  9.1427 +	data8 sys_kill
  9.1428 +	data8 sys_rename
  9.1429 +	data8 sys_mkdir				// 1055
  9.1430 +	data8 sys_rmdir
  9.1431 +	data8 sys_dup
  9.1432 +	data8 sys_pipe
  9.1433 +	data8 sys_times
  9.1434 +	data8 ia64_brk				// 1060
  9.1435 +	data8 sys_setgid
  9.1436 +	data8 sys_getgid
  9.1437 +	data8 sys_getegid
  9.1438 +	data8 sys_acct
  9.1439 +	data8 sys_ioctl				// 1065
  9.1440 +	data8 sys_fcntl
  9.1441 +	data8 sys_umask
  9.1442 +	data8 sys_chroot
  9.1443 +	data8 sys_ustat
  9.1444 +	data8 sys_dup2				// 1070
  9.1445 +	data8 sys_setreuid
  9.1446 +	data8 sys_setregid
  9.1447 +	data8 sys_getresuid
  9.1448 +	data8 sys_setresuid
  9.1449 +	data8 sys_getresgid			// 1075
  9.1450 +	data8 sys_setresgid
  9.1451 +	data8 sys_getgroups
  9.1452 +	data8 sys_setgroups
  9.1453 +	data8 sys_getpgid
  9.1454 +	data8 sys_setpgid			// 1080
  9.1455 +	data8 sys_setsid
  9.1456 +	data8 sys_getsid
  9.1457 +	data8 sys_sethostname
  9.1458 +	data8 sys_setrlimit
  9.1459 +	data8 sys_getrlimit			// 1085
  9.1460 +	data8 sys_getrusage
  9.1461 +	data8 sys_gettimeofday
  9.1462 +	data8 sys_settimeofday
  9.1463 +	data8 sys_select
  9.1464 +	data8 sys_poll				// 1090
  9.1465 +	data8 sys_symlink
  9.1466 +	data8 sys_readlink
  9.1467 +	data8 sys_uselib
  9.1468 +	data8 sys_swapon
  9.1469 +	data8 sys_swapoff			// 1095
  9.1470 +	data8 sys_reboot
  9.1471 +	data8 sys_truncate
  9.1472 +	data8 sys_ftruncate
  9.1473 +	data8 sys_fchmod
  9.1474 +	data8 sys_fchown			// 1100
  9.1475 +	data8 ia64_getpriority
  9.1476 +	data8 sys_setpriority
  9.1477 +	data8 sys_statfs
  9.1478 +	data8 sys_fstatfs
  9.1479 +	data8 sys_gettid			// 1105
  9.1480 +	data8 sys_semget
  9.1481 +	data8 sys_semop
  9.1482 +	data8 sys_semctl
  9.1483 +	data8 sys_msgget
  9.1484 +	data8 sys_msgsnd			// 1110
  9.1485 +	data8 sys_msgrcv
  9.1486 +	data8 sys_msgctl
  9.1487 +	data8 sys_shmget
  9.1488 +	data8 ia64_shmat
  9.1489 +	data8 sys_shmdt				// 1115
  9.1490 +	data8 sys_shmctl
  9.1491 +	data8 sys_syslog
  9.1492 +	data8 sys_setitimer
  9.1493 +	data8 sys_getitimer
  9.1494 +	data8 sys_ni_syscall			// 1120		/* was: ia64_oldstat */
  9.1495 +	data8 sys_ni_syscall					/* was: ia64_oldlstat */
  9.1496 +	data8 sys_ni_syscall					/* was: ia64_oldfstat */
  9.1497 +	data8 sys_vhangup
  9.1498 +	data8 sys_lchown
  9.1499 +	data8 sys_remap_file_pages		// 1125
  9.1500 +	data8 sys_wait4
  9.1501 +	data8 sys_sysinfo
  9.1502 +	data8 sys_clone
  9.1503 +	data8 sys_setdomainname
  9.1504 +	data8 sys_newuname			// 1130
  9.1505 +	data8 sys_adjtimex
  9.1506 +	data8 sys_ni_syscall					/* was: ia64_create_module */
  9.1507 +	data8 sys_init_module
  9.1508 +	data8 sys_delete_module
  9.1509 +	data8 sys_ni_syscall			// 1135		/* was: sys_get_kernel_syms */
  9.1510 +	data8 sys_ni_syscall					/* was: sys_query_module */
  9.1511 +	data8 sys_quotactl
  9.1512 +	data8 sys_bdflush
  9.1513 +	data8 sys_sysfs
  9.1514 +	data8 sys_personality			// 1140
  9.1515 +	data8 sys_ni_syscall		// sys_afs_syscall
  9.1516 +	data8 sys_setfsuid
  9.1517 +	data8 sys_setfsgid
  9.1518 +	data8 sys_getdents
  9.1519 +	data8 sys_flock				// 1145
  9.1520 +	data8 sys_readv
  9.1521 +	data8 sys_writev
  9.1522 +	data8 sys_pread64
  9.1523 +	data8 sys_pwrite64
  9.1524 +	data8 sys_sysctl			// 1150
  9.1525 +	data8 sys_mmap
  9.1526 +	data8 sys_munmap
  9.1527 +	data8 sys_mlock
  9.1528 +	data8 sys_mlockall
  9.1529 +	data8 sys_mprotect			// 1155
  9.1530 +	data8 ia64_mremap
  9.1531 +	data8 sys_msync
  9.1532 +	data8 sys_munlock
  9.1533 +	data8 sys_munlockall
  9.1534 +	data8 sys_sched_getparam		// 1160
  9.1535 +	data8 sys_sched_setparam
  9.1536 +	data8 sys_sched_getscheduler
  9.1537 +	data8 sys_sched_setscheduler
  9.1538 +	data8 sys_sched_yield
  9.1539 +	data8 sys_sched_get_priority_max	// 1165
  9.1540 +	data8 sys_sched_get_priority_min
  9.1541 +	data8 sys_sched_rr_get_interval
  9.1542 +	data8 sys_nanosleep
  9.1543 +	data8 sys_nfsservctl
  9.1544 +	data8 sys_prctl				// 1170
  9.1545 +	data8 sys_getpagesize
  9.1546 +	data8 sys_mmap2
  9.1547 +	data8 sys_pciconfig_read
  9.1548 +	data8 sys_pciconfig_write
  9.1549 +	data8 sys_perfmonctl			// 1175
  9.1550 +	data8 sys_sigaltstack
  9.1551 +	data8 sys_rt_sigaction
  9.1552 +	data8 sys_rt_sigpending
  9.1553 +	data8 sys_rt_sigprocmask
  9.1554 +	data8 sys_rt_sigqueueinfo		// 1180
  9.1555 +	data8 sys_rt_sigreturn
  9.1556 +	data8 sys_rt_sigsuspend
  9.1557 +	data8 sys_rt_sigtimedwait
  9.1558 +	data8 sys_getcwd
  9.1559 +	data8 sys_capget			// 1185
  9.1560 +	data8 sys_capset
  9.1561 +	data8 sys_sendfile64
  9.1562 +	data8 sys_ni_syscall		// sys_getpmsg (STREAMS)
  9.1563 +	data8 sys_ni_syscall		// sys_putpmsg (STREAMS)
  9.1564 +	data8 sys_socket			// 1190
  9.1565 +	data8 sys_bind
  9.1566 +	data8 sys_connect
  9.1567 +	data8 sys_listen
  9.1568 +	data8 sys_accept
  9.1569 +	data8 sys_getsockname			// 1195
  9.1570 +	data8 sys_getpeername
  9.1571 +	data8 sys_socketpair
  9.1572 +	data8 sys_send
  9.1573 +	data8 sys_sendto
  9.1574 +	data8 sys_recv				// 1200
  9.1575 +	data8 sys_recvfrom
  9.1576 +	data8 sys_shutdown
  9.1577 +	data8 sys_setsockopt
  9.1578 +	data8 sys_getsockopt
  9.1579 +	data8 sys_sendmsg			// 1205
  9.1580 +	data8 sys_recvmsg
  9.1581 +	data8 sys_pivot_root
  9.1582 +	data8 sys_mincore
  9.1583 +	data8 sys_madvise
  9.1584 +	data8 sys_newstat			// 1210
  9.1585 +	data8 sys_newlstat
  9.1586 +	data8 sys_newfstat
  9.1587 +	data8 sys_clone2
  9.1588 +	data8 sys_getdents64
  9.1589 +	data8 sys_getunwind			// 1215
  9.1590 +	data8 sys_readahead
  9.1591 +	data8 sys_setxattr
  9.1592 +	data8 sys_lsetxattr
  9.1593 +	data8 sys_fsetxattr
  9.1594 +	data8 sys_getxattr			// 1220
  9.1595 +	data8 sys_lgetxattr
  9.1596 +	data8 sys_fgetxattr
  9.1597 +	data8 sys_listxattr
  9.1598 +	data8 sys_llistxattr
  9.1599 +	data8 sys_flistxattr			// 1225
  9.1600 +	data8 sys_removexattr
  9.1601 +	data8 sys_lremovexattr
  9.1602 +	data8 sys_fremovexattr
  9.1603 +	data8 sys_tkill
  9.1604 +	data8 sys_futex				// 1230
  9.1605 +	data8 sys_sched_setaffinity
  9.1606 +	data8 sys_sched_getaffinity
  9.1607 +	data8 sys_set_tid_address
  9.1608 +	data8 sys_fadvise64_64
  9.1609 +	data8 sys_tgkill 			// 1235
  9.1610 +	data8 sys_exit_group
  9.1611 +	data8 sys_lookup_dcookie
  9.1612 +	data8 sys_io_setup
  9.1613 +	data8 sys_io_destroy
  9.1614 +	data8 sys_io_getevents			// 1240
  9.1615 +	data8 sys_io_submit
  9.1616 +	data8 sys_io_cancel
  9.1617 +	data8 sys_epoll_create
  9.1618 +	data8 sys_epoll_ctl
  9.1619 +	data8 sys_epoll_wait			// 1245
  9.1620 +	data8 sys_restart_syscall
  9.1621 +	data8 sys_semtimedop
  9.1622 +	data8 sys_timer_create
  9.1623 +	data8 sys_timer_settime
  9.1624 +	data8 sys_timer_gettime			// 1250
  9.1625 +	data8 sys_timer_getoverrun
  9.1626 +	data8 sys_timer_delete
  9.1627 +	data8 sys_clock_settime
  9.1628 +	data8 sys_clock_gettime
  9.1629 +	data8 sys_clock_getres			// 1255
  9.1630 +	data8 sys_clock_nanosleep
  9.1631 +	data8 sys_fstatfs64
  9.1632 +	data8 sys_statfs64
  9.1633 +	data8 sys_mbind
  9.1634 +	data8 sys_get_mempolicy			// 1260
  9.1635 +	data8 sys_set_mempolicy
  9.1636 +	data8 sys_mq_open
  9.1637 +	data8 sys_mq_unlink
  9.1638 +	data8 sys_mq_timedsend
  9.1639 +	data8 sys_mq_timedreceive		// 1265
  9.1640 +	data8 sys_mq_notify
  9.1641 +	data8 sys_mq_getsetattr
  9.1642 +	data8 sys_ni_syscall			// reserved for kexec_load
  9.1643 +	data8 sys_ni_syscall			// reserved for vserver
  9.1644 +	data8 sys_waitid			// 1270
  9.1645 +	data8 sys_add_key
  9.1646 +	data8 sys_request_key
  9.1647 +	data8 sys_keyctl
  9.1648 +	data8 sys_ni_syscall
  9.1649 +	data8 sys_ni_syscall			// 1275
  9.1650 +	data8 sys_ni_syscall
  9.1651 +	data8 sys_ni_syscall
  9.1652 +	data8 sys_ni_syscall
  9.1653 +	data8 sys_ni_syscall
  9.1654 +
  9.1655 +	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
  9.1656 +#endif
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xen/arch/ia64/linux-xen/entry.h	Tue Aug 02 16:25:11 2005 -0800
    10.3 @@ -0,0 +1,97 @@
    10.4 +#include <linux/config.h>
    10.5 +
    10.6 +/*
    10.7 + * Preserved registers that are shared between code in ivt.S and
    10.8 + * entry.S.  Be careful not to step on these!
    10.9 + */
   10.10 +#define PRED_LEAVE_SYSCALL	1 /* TRUE iff leave from syscall */
   10.11 +#define PRED_KERNEL_STACK	2 /* returning to kernel-stacks? */
   10.12 +#define PRED_USER_STACK		3 /* returning to user-stacks? */
   10.13 +#ifdef CONFIG_VTI
   10.14 +#define PRED_EMUL		2 /* Need to save r4-r7 for inst emulation */
   10.15 +#define PRED_NON_EMUL		3 /* No need to save r4-r7 for normal path */
   10.16 +#define PRED_BN0		6 /* Guest is in bank 0 */
   10.17 +#define PRED_BN1		7 /* Guest is in bank 1 */
   10.18 +#endif // CONFIG_VTI
   10.19 +#define PRED_SYSCALL		4 /* inside a system call? */
   10.20 +#define PRED_NON_SYSCALL	5 /* complement of PRED_SYSCALL */
   10.21 +
   10.22 +#ifdef __ASSEMBLY__
   10.23 +# define PASTE2(x,y)	x##y
   10.24 +# define PASTE(x,y)	PASTE2(x,y)
   10.25 +
   10.26 +# define pLvSys		PASTE(p,PRED_LEAVE_SYSCALL)
   10.27 +# define pKStk		PASTE(p,PRED_KERNEL_STACK)
   10.28 +# define pUStk		PASTE(p,PRED_USER_STACK)
   10.29 +#ifdef CONFIG_VTI
   10.30 +# define pEml		PASTE(p,PRED_EMUL)
   10.31 +# define pNonEml	PASTE(p,PRED_NON_EMUL)
   10.32 +# define pBN0		PASTE(p,PRED_BN0)
   10.33 +# define pBN1		PASTE(p,PRED_BN1)
   10.34 +#endif // CONFIG_VTI
   10.35 +# define pSys		PASTE(p,PRED_SYSCALL)
   10.36 +# define pNonSys	PASTE(p,PRED_NON_SYSCALL)
   10.37 +#endif
   10.38 +
   10.39 +#define PT(f)		(IA64_PT_REGS_##f##_OFFSET)
   10.40 +#define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
   10.41 +#ifdef CONFIG_VTI
   10.42 +#define VPD(f)      (VPD_##f##_START_OFFSET)
   10.43 +#endif // CONFIG_VTI
   10.44 +
   10.45 +#define PT_REGS_SAVES(off)			\
   10.46 +	.unwabi 3, 'i';				\
   10.47 +	.fframe IA64_PT_REGS_SIZE+16+(off);	\
   10.48 +	.spillsp rp, PT(CR_IIP)+16+(off);	\
   10.49 +	.spillsp ar.pfs, PT(CR_IFS)+16+(off);	\
   10.50 +	.spillsp ar.unat, PT(AR_UNAT)+16+(off);	\
   10.51 +	.spillsp ar.fpsr, PT(AR_FPSR)+16+(off);	\
   10.52 +	.spillsp pr, PT(PR)+16+(off);
   10.53 +
   10.54 +#define PT_REGS_UNWIND_INFO(off)		\
   10.55 +	.prologue;				\
   10.56 +	PT_REGS_SAVES(off);			\
   10.57 +	.body
   10.58 +
   10.59 +#define SWITCH_STACK_SAVES(off)							\
   10.60 +	.savesp ar.unat,SW(CALLER_UNAT)+16+(off);				\
   10.61 +	.savesp ar.fpsr,SW(AR_FPSR)+16+(off);					\
   10.62 +	.spillsp f2,SW(F2)+16+(off); .spillsp f3,SW(F3)+16+(off);		\
   10.63 +	.spillsp f4,SW(F4)+16+(off); .spillsp f5,SW(F5)+16+(off);		\
   10.64 +	.spillsp f16,SW(F16)+16+(off); .spillsp f17,SW(F17)+16+(off);		\
   10.65 +	.spillsp f18,SW(F18)+16+(off); .spillsp f19,SW(F19)+16+(off);		\
   10.66 +	.spillsp f20,SW(F20)+16+(off); .spillsp f21,SW(F21)+16+(off);		\
   10.67 +	.spillsp f22,SW(F22)+16+(off); .spillsp f23,SW(F23)+16+(off);		\
   10.68 +	.spillsp f24,SW(F24)+16+(off); .spillsp f25,SW(F25)+16+(off);		\
   10.69 +	.spillsp f26,SW(F26)+16+(off); .spillsp f27,SW(F27)+16+(off);		\
   10.70 +	.spillsp f28,SW(F28)+16+(off); .spillsp f29,SW(F29)+16+(off);		\
   10.71 +	.spillsp f30,SW(F30)+16+(off); .spillsp f31,SW(F31)+16+(off);		\
   10.72 +	.spillsp r4,SW(R4)+16+(off); .spillsp r5,SW(R5)+16+(off);		\
   10.73 +	.spillsp r6,SW(R6)+16+(off); .spillsp r7,SW(R7)+16+(off);		\
   10.74 +	.spillsp b0,SW(B0)+16+(off); .spillsp b1,SW(B1)+16+(off);		\
   10.75 +	.spillsp b2,SW(B2)+16+(off); .spillsp b3,SW(B3)+16+(off);		\
   10.76 +	.spillsp b4,SW(B4)+16+(off); .spillsp b5,SW(B5)+16+(off);		\
   10.77 +	.spillsp ar.pfs,SW(AR_PFS)+16+(off); .spillsp ar.lc,SW(AR_LC)+16+(off);	\
   10.78 +	.spillsp @priunat,SW(AR_UNAT)+16+(off);					\
   10.79 +	.spillsp ar.rnat,SW(AR_RNAT)+16+(off);					\
   10.80 +	.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off);				\
   10.81 +	.spillsp pr,SW(PR)+16+(off))
   10.82 +
   10.83 +#define DO_SAVE_SWITCH_STACK			\
   10.84 +	movl r28=1f;				\
   10.85 +	;;					\
   10.86 +	.fframe IA64_SWITCH_STACK_SIZE;		\
   10.87 +	adds sp=-IA64_SWITCH_STACK_SIZE,sp;	\
   10.88 +	mov.ret.sptk b7=r28,1f;			\
   10.89 +	SWITCH_STACK_SAVES(0);			\
   10.90 +	br.cond.sptk.many save_switch_stack;	\
   10.91 +1:
   10.92 +
   10.93 +#define DO_LOAD_SWITCH_STACK			\
   10.94 +	movl r28=1f;				\
   10.95 +	;;					\
   10.96 +	invala;					\
   10.97 +	mov.ret.sptk b7=r28,1f;			\
   10.98 +	br.cond.sptk.many load_switch_stack;	\
   10.99 +1:	.restore sp;				\
  10.100 +	adds sp=IA64_SWITCH_STACK_SIZE,sp
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/arch/ia64/linux-xen/head.S	Tue Aug 02 16:25:11 2005 -0800
    11.3 @@ -0,0 +1,1026 @@
    11.4 +/*
    11.5 + * Here is where the ball gets rolling as far as the kernel is concerned.
    11.6 + * When control is transferred to _start, the bootload has already
    11.7 + * loaded us to the correct address.  All that's left to do here is
    11.8 + * to set up the kernel's global pointer and jump to the kernel
    11.9 + * entry point.
   11.10 + *
   11.11 + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
   11.12 + *	David Mosberger-Tang <davidm@hpl.hp.com>
   11.13 + *	Stephane Eranian <eranian@hpl.hp.com>
   11.14 + * Copyright (C) 1999 VA Linux Systems
   11.15 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
   11.16 + * Copyright (C) 1999 Intel Corp.
   11.17 + * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
   11.18 + * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
   11.19 + * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com>
   11.20 + *   -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
   11.21 + */
   11.22 +
   11.23 +#include <linux/config.h>
   11.24 +
   11.25 +#include <asm/asmmacro.h>
   11.26 +#include <asm/fpu.h>
   11.27 +#include <asm/kregs.h>
   11.28 +#include <asm/mmu_context.h>
   11.29 +#include <asm/offsets.h>
   11.30 +#include <asm/pal.h>
   11.31 +#include <asm/pgtable.h>
   11.32 +#include <asm/processor.h>
   11.33 +#include <asm/ptrace.h>
   11.34 +#include <asm/system.h>
   11.35 +
   11.36 +	.section __special_page_section,"ax"
   11.37 +
   11.38 +	.global empty_zero_page
   11.39 +empty_zero_page:
   11.40 +	.skip PAGE_SIZE
   11.41 +
   11.42 +	.global swapper_pg_dir
   11.43 +swapper_pg_dir:
   11.44 +	.skip PAGE_SIZE
   11.45 +
   11.46 +	.rodata
   11.47 +halt_msg:
   11.48 +	stringz "Halting kernel\n"
   11.49 +
   11.50 +	.text
   11.51 +
   11.52 +	.global start_ap
   11.53 +
   11.54 +	/*
   11.55 +	 * Start the kernel.  When the bootloader passes control to _start(), r28
   11.56 +	 * points to the address of the boot parameter area.  Execution reaches
   11.57 +	 * here in physical mode.
   11.58 +	 */
   11.59 +GLOBAL_ENTRY(_start)
   11.60 +start_ap:
   11.61 +	.prologue
   11.62 +	.save rp, r0		// terminate unwind chain with a NULL rp
   11.63 +	.body
   11.64 +
   11.65 +	rsm psr.i | psr.ic
   11.66 +	;;
   11.67 +	srlz.i
   11.68 +	;;
   11.69 +	/*
   11.70 +	 * Initialize kernel region registers:
   11.71 +	 *	rr[0]: VHPT enabled, page size = PAGE_SHIFT
   11.72 +	 *	rr[1]: VHPT enabled, page size = PAGE_SHIFT
   11.73 +	 *	rr[2]: VHPT enabled, page size = PAGE_SHIFT
   11.74 +	 *	rr[3]: VHPT enabled, page size = PAGE_SHIFT
   11.75 +	 *	rr[4]: VHPT enabled, page size = PAGE_SHIFT
   11.76 +	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT
   11.77 +	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
   11.78 +	 *	rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT
   11.79 +	 * We initialize all of them to prevent inadvertently assuming
   11.80 +	 * something about the state of address translation early in boot.
   11.81 +	 */
   11.82 +	movl r6=((ia64_rid(IA64_REGION_ID_KERNEL, (0<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.83 +	movl r7=(0<<61)
   11.84 +	movl r8=((ia64_rid(IA64_REGION_ID_KERNEL, (1<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.85 +	movl r9=(1<<61)
   11.86 +	movl r10=((ia64_rid(IA64_REGION_ID_KERNEL, (2<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.87 +	movl r11=(2<<61)
   11.88 +	movl r12=((ia64_rid(IA64_REGION_ID_KERNEL, (3<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.89 +	movl r13=(3<<61)
   11.90 +	movl r14=((ia64_rid(IA64_REGION_ID_KERNEL, (4<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.91 +	movl r15=(4<<61)
   11.92 +	movl r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
   11.93 +	movl r17=(5<<61)
   11.94 +	movl r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
   11.95 +	movl r19=(6<<61)
   11.96 +	movl r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
   11.97 +	movl r21=(7<<61)
   11.98 +	;;
   11.99 +	mov rr[r7]=r6
  11.100 +	mov rr[r9]=r8
  11.101 +	mov rr[r11]=r10
  11.102 +	mov rr[r13]=r12
  11.103 +	mov rr[r15]=r14
  11.104 +	mov rr[r17]=r16
  11.105 +	mov rr[r19]=r18
  11.106 +	mov rr[r21]=r20
  11.107 +	;;
  11.108 +	/*
  11.109 +	 * Now pin mappings into the TLB for kernel text and data
  11.110 +	 */
  11.111 +	mov r18=KERNEL_TR_PAGE_SHIFT<<2
  11.112 +	movl r17=KERNEL_START
  11.113 +	;;
  11.114 +	mov cr.itir=r18
  11.115 +	mov cr.ifa=r17
  11.116 +	mov r16=IA64_TR_KERNEL
  11.117 +	mov r3=ip
  11.118 +	movl r18=PAGE_KERNEL
  11.119 +	;;
  11.120 +	dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
  11.121 +	;;
  11.122 +	or r18=r2,r18
  11.123 +	;;
  11.124 +	srlz.i
  11.125 +	;;
  11.126 +	itr.i itr[r16]=r18
  11.127 +	;;
  11.128 +	itr.d dtr[r16]=r18
  11.129 +	;;
  11.130 +	srlz.i
  11.131 +
  11.132 +	/*
  11.133 +	 * Switch into virtual mode:
  11.134 +	 */
  11.135 +#ifdef CONFIG_VTI
  11.136 +	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH \
  11.137 +		  |IA64_PSR_DI)
  11.138 +#else // CONFIG_VTI
  11.139 +	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
  11.140 +		  |IA64_PSR_DI)
  11.141 +#endif // CONFIG_VTI
  11.142 +	;;
  11.143 +	mov cr.ipsr=r16
  11.144 +	movl r17=1f
  11.145 +	;;
  11.146 +	mov cr.iip=r17
  11.147 +	mov cr.ifs=r0
  11.148 +	;;
  11.149 +	rfi
  11.150 +	;;
  11.151 +1:	// now we are in virtual mode
  11.152 +
  11.153 +	// set IVT entry point---can't access I/O ports without it
  11.154 +#ifdef CONFIG_VTI
  11.155 +    movl r3=vmx_ia64_ivt
  11.156 +#else // CONFIG_VTI
  11.157 +	movl r3=ia64_ivt
  11.158 +#endif // CONFIG_VTI
  11.159 +	;;
  11.160 +	mov cr.iva=r3
  11.161 +	movl r2=FPSR_DEFAULT
  11.162 +	;;
  11.163 +	srlz.i
  11.164 +	movl gp=__gp
  11.165 +
  11.166 +	mov ar.fpsr=r2
  11.167 +	;;
  11.168 +
  11.169 +#define isAP	p2	// are we an Application Processor?
  11.170 +#define isBP	p3	// are we the Bootstrap Processor?
  11.171 +
  11.172 +#ifdef CONFIG_SMP
  11.173 +	/*
  11.174 +	 * Find the init_task for the currently booting CPU.  At poweron, and in
  11.175 +	 * UP mode, task_for_booting_cpu is NULL.
  11.176 +	 */
  11.177 +	movl r3=task_for_booting_cpu
  11.178 + 	;;
  11.179 +	ld8 r3=[r3]
  11.180 +	movl r2=init_task
  11.181 +	;;
  11.182 +	cmp.eq isBP,isAP=r3,r0
  11.183 +	;;
  11.184 +(isAP)	mov r2=r3
  11.185 +#else
  11.186 +	movl r2=init_task
  11.187 +	cmp.eq isBP,isAP=r0,r0
  11.188 +#endif
  11.189 +	;;
  11.190 +	tpa r3=r2		// r3 == phys addr of task struct
  11.191 +	mov r16=-1
  11.192 +(isBP)	br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it
  11.193 +
  11.194 +	// load mapping for stack (virtaddr in r2, physaddr in r3)
  11.195 +	rsm psr.ic
  11.196 +	movl r17=PAGE_KERNEL
  11.197 +	;;
  11.198 +	srlz.d
  11.199 +	dep r18=0,r3,0,12
  11.200 +	;;
  11.201 +	or r18=r17,r18
  11.202 +#ifdef XEN
  11.203 +	dep r2=-1,r3,60,4	// IMVA of task
  11.204 +#else
  11.205 +	dep r2=-1,r3,61,3	// IMVA of task
  11.206 +#endif
  11.207 +	;;
  11.208 +	mov r17=rr[r2]
  11.209 +	shr.u r16=r3,IA64_GRANULE_SHIFT
  11.210 +	;;
  11.211 +	dep r17=0,r17,8,24
  11.212 +	;;
  11.213 +	mov cr.itir=r17
  11.214 +	mov cr.ifa=r2
  11.215 +
  11.216 +	mov r19=IA64_TR_CURRENT_STACK
  11.217 +	;;
  11.218 +	itr.d dtr[r19]=r18
  11.219 +	;;
  11.220 +	ssm psr.ic
  11.221 +	srlz.d
  11.222 +  	;;
  11.223 +
  11.224 +.load_current:
  11.225 +	// load the "current" pointer (r13) and ar.k6 with the current task
  11.226 +#ifdef CONFIG_VTI
  11.227 +	mov r21=r2		// virtual address
  11.228 +	;;
  11.229 +	bsw.1
  11.230 +	;;
  11.231 +#else // CONFIG_VTI
  11.232 +	mov IA64_KR(CURRENT)=r2		// virtual address
  11.233 +	mov IA64_KR(CURRENT_STACK)=r16
  11.234 +#endif // CONFIG_VTI
  11.235 +	mov r13=r2
  11.236 +	/*
  11.237 +	 * Reserve space at the top of the stack for "struct pt_regs".  Kernel threads
  11.238 +	 * don't store interesting values in that structure, but the space still needs
  11.239 +	 * to be there because time-critical stuff such as the context switching can
  11.240 +	 * be implemented more efficiently (for example, __switch_to()
  11.241 +	 * always sets the psr.dfh bit of the task it is switching to).
  11.242 +	 */
  11.243 +	addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2
  11.244 +	addl r2=IA64_RBS_OFFSET,r2	// initialize the RSE
  11.245 +	mov ar.rsc=0		// place RSE in enforced lazy mode
  11.246 +	;;
  11.247 +	loadrs			// clear the dirty partition
  11.248 +	;;
  11.249 +	mov ar.bspstore=r2	// establish the new RSE stack
  11.250 +	;;
  11.251 +	mov ar.rsc=0x3		// place RSE in eager mode
  11.252 +
  11.253 +#ifdef XEN
  11.254 +(isBP)	dep r28=-1,r28,60,4	// make address virtual
  11.255 +#else
  11.256 +(isBP)	dep r28=-1,r28,61,3	// make address virtual
  11.257 +#endif
  11.258 +(isBP)	movl r2=ia64_boot_param
  11.259 +	;;
  11.260 +(isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
  11.261 +
  11.262 +#ifdef CONFIG_SMP
  11.263 +(isAP)	br.call.sptk.many rp=start_secondary
  11.264 +.ret0:
  11.265 +(isAP)	br.cond.sptk self
  11.266 +#endif
  11.267 +
  11.268 +	// This is executed by the bootstrap processor (bsp) only:
  11.269 +
  11.270 +#ifdef CONFIG_IA64_FW_EMU
  11.271 +	// initialize PAL & SAL emulator:
  11.272 +	br.call.sptk.many rp=sys_fw_init
  11.273 +.ret1:
  11.274 +#endif
  11.275 +	br.call.sptk.many rp=start_kernel
  11.276 +.ret2:	addl r3=@ltoff(halt_msg),gp
  11.277 +	;;
  11.278 +	alloc r2=ar.pfs,8,0,2,0
  11.279 +	;;
  11.280 +	ld8 out0=[r3]
  11.281 +	br.call.sptk.many b0=console_print
  11.282 +
  11.283 +self:	hint @pause
  11.284 +	;;
  11.285 +	br.sptk.many self		// endless loop
  11.286 +	;;
  11.287 +END(_start)
  11.288 +
  11.289 +GLOBAL_ENTRY(ia64_save_debug_regs)
  11.290 +	alloc r16=ar.pfs,1,0,0,0
  11.291 +	mov r20=ar.lc			// preserve ar.lc
  11.292 +	mov ar.lc=IA64_NUM_DBG_REGS-1
  11.293 +	mov r18=0
  11.294 +	add r19=IA64_NUM_DBG_REGS*8,in0
  11.295 +	;;
  11.296 +1:	mov r16=dbr[r18]
  11.297 +#ifdef CONFIG_ITANIUM
  11.298 +	;;
  11.299 +	srlz.d
  11.300 +#endif
  11.301 +	mov r17=ibr[r18]
  11.302 +	add r18=1,r18
  11.303 +	;;
  11.304 +	st8.nta [in0]=r16,8
  11.305 +	st8.nta [r19]=r17,8
  11.306 +	br.cloop.sptk.many 1b
  11.307 +	;;
  11.308 +	mov ar.lc=r20			// restore ar.lc
  11.309 +	br.ret.sptk.many rp
  11.310 +END(ia64_save_debug_regs)
  11.311 +
  11.312 +GLOBAL_ENTRY(ia64_load_debug_regs)
  11.313 +	alloc r16=ar.pfs,1,0,0,0
  11.314 +	lfetch.nta [in0]
  11.315 +	mov r20=ar.lc			// preserve ar.lc
  11.316 +	add r19=IA64_NUM_DBG_REGS*8,in0
  11.317 +	mov ar.lc=IA64_NUM_DBG_REGS-1
  11.318 +	mov r18=-1
  11.319 +	;;
  11.320 +1:	ld8.nta r16=[in0],8
  11.321 +	ld8.nta r17=[r19],8
  11.322 +	add r18=1,r18
  11.323 +	;;
  11.324 +	mov dbr[r18]=r16
  11.325 +#ifdef CONFIG_ITANIUM
  11.326 +	;;
  11.327 +	srlz.d				// Errata 132 (NoFix status)
  11.328 +#endif
  11.329 +	mov ibr[r18]=r17
  11.330 +	br.cloop.sptk.many 1b
  11.331 +	;;
  11.332 +	mov ar.lc=r20			// restore ar.lc
  11.333 +	br.ret.sptk.many rp
  11.334 +END(ia64_load_debug_regs)
  11.335 +
  11.336 +GLOBAL_ENTRY(__ia64_save_fpu)
  11.337 +	alloc r2=ar.pfs,1,4,0,0
  11.338 +	adds loc0=96*16-16,in0
  11.339 +	adds loc1=96*16-16-128,in0
  11.340 +	;;
  11.341 +	stf.spill.nta [loc0]=f127,-256
  11.342 +	stf.spill.nta [loc1]=f119,-256
  11.343 +	;;
  11.344 +	stf.spill.nta [loc0]=f111,-256
  11.345 +	stf.spill.nta [loc1]=f103,-256
  11.346 +	;;
  11.347 +	stf.spill.nta [loc0]=f95,-256
  11.348 +	stf.spill.nta [loc1]=f87,-256
  11.349 +	;;
  11.350 +	stf.spill.nta [loc0]=f79,-256
  11.351 +	stf.spill.nta [loc1]=f71,-256
  11.352 +	;;
  11.353 +	stf.spill.nta [loc0]=f63,-256
  11.354 +	stf.spill.nta [loc1]=f55,-256
  11.355 +	adds loc2=96*16-32,in0
  11.356 +	;;
  11.357 +	stf.spill.nta [loc0]=f47,-256
  11.358 +	stf.spill.nta [loc1]=f39,-256
  11.359 +	adds loc3=96*16-32-128,in0
  11.360 +	;;
  11.361 +	stf.spill.nta [loc2]=f126,-256
  11.362 +	stf.spill.nta [loc3]=f118,-256
  11.363 +	;;
  11.364 +	stf.spill.nta [loc2]=f110,-256
  11.365 +	stf.spill.nta [loc3]=f102,-256
  11.366 +	;;
  11.367 +	stf.spill.nta [loc2]=f94,-256
  11.368 +	stf.spill.nta [loc3]=f86,-256
  11.369 +	;;
  11.370 +	stf.spill.nta [loc2]=f78,-256
  11.371 +	stf.spill.nta [loc3]=f70,-256
  11.372 +	;;
  11.373 +	stf.spill.nta [loc2]=f62,-256
  11.374 +	stf.spill.nta [loc3]=f54,-256
  11.375 +	adds loc0=96*16-48,in0
  11.376 +	;;
  11.377 +	stf.spill.nta [loc2]=f46,-256
  11.378 +	stf.spill.nta [loc3]=f38,-256
  11.379 +	adds loc1=96*16-48-128,in0
  11.380 +	;;
  11.381 +	stf.spill.nta [loc0]=f125,-256
  11.382 +	stf.spill.nta [loc1]=f117,-256
  11.383 +	;;
  11.384 +	stf.spill.nta [loc0]=f109,-256
  11.385 +	stf.spill.nta [loc1]=f101,-256
  11.386 +	;;
  11.387 +	stf.spill.nta [loc0]=f93,-256
  11.388 +	stf.spill.nta [loc1]=f85,-256
  11.389 +	;;
  11.390 +	stf.spill.nta [loc0]=f77,-256
  11.391 +	stf.spill.nta [loc1]=f69,-256
  11.392 +	;;
  11.393 +	stf.spill.nta [loc0]=f61,-256
  11.394 +	stf.spill.nta [loc1]=f53,-256
  11.395 +	adds loc2=96*16-64,in0
  11.396 +	;;
  11.397 +	stf.spill.nta [loc0]=f45,-256
  11.398 +	stf.spill.nta [loc1]=f37,-256
  11.399 +	adds loc3=96*16-64-128,in0
  11.400 +	;;
  11.401 +	stf.spill.nta [loc2]=f124,-256
  11.402 +	stf.spill.nta [loc3]=f116,-256
  11.403 +	;;
  11.404 +	stf.spill.nta [loc2]=f108,-256
  11.405 +	stf.spill.nta [loc3]=f100,-256
  11.406 +	;;
  11.407 +	stf.spill.nta [loc2]=f92,-256
  11.408 +	stf.spill.nta [loc3]=f84,-256
  11.409 +	;;
  11.410 +	stf.spill.nta [loc2]=f76,-256
  11.411 +	stf.spill.nta [loc3]=f68,-256
  11.412 +	;;
  11.413 +	stf.spill.nta [loc2]=f60,-256
  11.414 +	stf.spill.nta [loc3]=f52,-256
  11.415 +	adds loc0=96*16-80,in0
  11.416 +	;;
  11.417 +	stf.spill.nta [loc2]=f44,-256
  11.418 +	stf.spill.nta [loc3]=f36,-256
  11.419 +	adds loc1=96*16-80-128,in0
  11.420 +	;;
  11.421 +	stf.spill.nta [loc0]=f123,-256
  11.422 +	stf.spill.nta [loc1]=f115,-256
  11.423 +	;;
  11.424 +	stf.spill.nta [loc0]=f107,-256
  11.425 +	stf.spill.nta [loc1]=f99,-256
  11.426 +	;;
  11.427 +	stf.spill.nta [loc0]=f91,-256
  11.428 +	stf.spill.nta [loc1]=f83,-256
  11.429 +	;;
  11.430 +	stf.spill.nta [loc0]=f75,-256
  11.431 +	stf.spill.nta [loc1]=f67,-256
  11.432 +	;;
  11.433 +	stf.spill.nta [loc0]=f59,-256
  11.434 +	stf.spill.nta [loc1]=f51,-256
  11.435 +	adds loc2=96*16-96,in0
  11.436 +	;;
  11.437 +	stf.spill.nta [loc0]=f43,-256
  11.438 +	stf.spill.nta [loc1]=f35,-256
  11.439 +	adds loc3=96*16-96-128,in0
  11.440 +	;;
  11.441 +	stf.spill.nta [loc2]=f122,-256
  11.442 +	stf.spill.nta [loc3]=f114,-256
  11.443 +	;;
  11.444 +	stf.spill.nta [loc2]=f106,-256
  11.445 +	stf.spill.nta [loc3]=f98,-256
  11.446 +	;;
  11.447 +	stf.spill.nta [loc2]=f90,-256
  11.448 +	stf.spill.nta [loc3]=f82,-256
  11.449 +	;;
  11.450 +	stf.spill.nta [loc2]=f74,-256
  11.451 +	stf.spill.nta [loc3]=f66,-256
  11.452 +	;;
  11.453 +	stf.spill.nta [loc2]=f58,-256
  11.454 +	stf.spill.nta [loc3]=f50,-256
  11.455 +	adds loc0=96*16-112,in0
  11.456 +	;;
  11.457 +	stf.spill.nta [loc2]=f42,-256
  11.458 +	stf.spill.nta [loc3]=f34,-256
  11.459 +	adds loc1=96*16-112-128,in0
  11.460 +	;;
  11.461 +	stf.spill.nta [loc0]=f121,-256
  11.462 +	stf.spill.nta [loc1]=f113,-256
  11.463 +	;;
  11.464 +	stf.spill.nta [loc0]=f105,-256
  11.465 +	stf.spill.nta [loc1]=f97,-256
  11.466 +	;;
  11.467 +	stf.spill.nta [loc0]=f89,-256
  11.468 +	stf.spill.nta [loc1]=f81,-256
  11.469 +	;;
  11.470 +	stf.spill.nta [loc0]=f73,-256
  11.471 +	stf.spill.nta [loc1]=f65,-256
  11.472 +	;;
  11.473 +	stf.spill.nta [loc0]=f57,-256
  11.474 +	stf.spill.nta [loc1]=f49,-256
  11.475 +	adds loc2=96*16-128,in0
  11.476 +	;;
  11.477 +	stf.spill.nta [loc0]=f41,-256
  11.478 +	stf.spill.nta [loc1]=f33,-256
  11.479 +	adds loc3=96*16-128-128,in0
  11.480 +	;;
  11.481 +	stf.spill.nta [loc2]=f120,-256
  11.482 +	stf.spill.nta [loc3]=f112,-256
  11.483 +	;;
  11.484 +	stf.spill.nta [loc2]=f104,-256
  11.485 +	stf.spill.nta [loc3]=f96,-256
  11.486 +	;;
  11.487 +	stf.spill.nta [loc2]=f88,-256
  11.488 +	stf.spill.nta [loc3]=f80,-256
  11.489 +	;;
  11.490 +	stf.spill.nta [loc2]=f72,-256
  11.491 +	stf.spill.nta [loc3]=f64,-256
  11.492 +	;;
  11.493 +	stf.spill.nta [loc2]=f56,-256
  11.494 +	stf.spill.nta [loc3]=f48,-256
  11.495 +	;;
  11.496 +	stf.spill.nta [loc2]=f40
  11.497 +	stf.spill.nta [loc3]=f32
  11.498 +	br.ret.sptk.many rp
  11.499 +END(__ia64_save_fpu)
  11.500 +
  11.501 +GLOBAL_ENTRY(__ia64_load_fpu)
  11.502 +	alloc r2=ar.pfs,1,2,0,0
  11.503 +	adds r3=128,in0
  11.504 +	adds r14=256,in0
  11.505 +	adds r15=384,in0
  11.506 +	mov loc0=512
  11.507 +	mov loc1=-1024+16
  11.508 +	;;
  11.509 +	ldf.fill.nta f32=[in0],loc0
  11.510 +	ldf.fill.nta f40=[ r3],loc0
  11.511 +	ldf.fill.nta f48=[r14],loc0
  11.512 +	ldf.fill.nta f56=[r15],loc0
  11.513 +	;;
  11.514 +	ldf.fill.nta f64=[in0],loc0
  11.515 +	ldf.fill.nta f72=[ r3],loc0
  11.516 +	ldf.fill.nta f80=[r14],loc0
  11.517 +	ldf.fill.nta f88=[r15],loc0
  11.518 +	;;
  11.519 +	ldf.fill.nta f96=[in0],loc1
  11.520 +	ldf.fill.nta f104=[ r3],loc1
  11.521 +	ldf.fill.nta f112=[r14],loc1
  11.522 +	ldf.fill.nta f120=[r15],loc1
  11.523 +	;;
  11.524 +	ldf.fill.nta f33=[in0],loc0
  11.525 +	ldf.fill.nta f41=[ r3],loc0
  11.526 +	ldf.fill.nta f49=[r14],loc0
  11.527 +	ldf.fill.nta f57=[r15],loc0
  11.528 +	;;
  11.529 +	ldf.fill.nta f65=[in0],loc0
  11.530 +	ldf.fill.nta f73=[ r3],loc0
  11.531 +	ldf.fill.nta f81=[r14],loc0
  11.532 +	ldf.fill.nta f89=[r15],loc0
  11.533 +	;;
  11.534 +	ldf.fill.nta f97=[in0],loc1
  11.535 +	ldf.fill.nta f105=[ r3],loc1
  11.536 +	ldf.fill.nta f113=[r14],loc1
  11.537 +	ldf.fill.nta f121=[r15],loc1
  11.538 +	;;
  11.539 +	ldf.fill.nta f34=[in0],loc0
  11.540 +	ldf.fill.nta f42=[ r3],loc0
  11.541 +	ldf.fill.nta f50=[r14],loc0
  11.542 +	ldf.fill.nta f58=[r15],loc0
  11.543 +	;;
  11.544 +	ldf.fill.nta f66=[in0],loc0
  11.545 +	ldf.fill.nta f74=[ r3],loc0
  11.546 +	ldf.fill.nta f82=[r14],loc0
  11.547 +	ldf.fill.nta f90=[r15],loc0
  11.548 +	;;
  11.549 +	ldf.fill.nta f98=[in0],loc1
  11.550 +	ldf.fill.nta f106=[ r3],loc1
  11.551 +	ldf.fill.nta f114=[r14],loc1
  11.552 +	ldf.fill.nta f122=[r15],loc1
  11.553 +	;;
  11.554 +	ldf.fill.nta f35=[in0],loc0
  11.555 +	ldf.fill.nta f43=[ r3],loc0
  11.556 +	ldf.fill.nta f51=[r14],loc0
  11.557 +	ldf.fill.nta f59=[r15],loc0
  11.558 +	;;
  11.559 +	ldf.fill.nta f67=[in0],loc0
  11.560 +	ldf.fill.nta f75=[ r3],loc0
  11.561 +	ldf.fill.nta f83=[r14],loc0
  11.562 +	ldf.fill.nta f91=[r15],loc0
  11.563 +	;;
  11.564 +	ldf.fill.nta f99=[in0],loc1
  11.565 +	ldf.fill.nta f107=[ r3],loc1
  11.566 +	ldf.fill.nta f115=[r14],loc1
  11.567 +	ldf.fill.nta f123=[r15],loc1
  11.568 +	;;
  11.569 +	ldf.fill.nta f36=[in0],loc0
  11.570 +	ldf.fill.nta f44=[ r3],loc0
  11.571 +	ldf.fill.nta f52=[r14],loc0
  11.572 +	ldf.fill.nta f60=[r15],loc0
  11.573 +	;;
  11.574 +	ldf.fill.nta f68=[in0],loc0
  11.575 +	ldf.fill.nta f76=[ r3],loc0
  11.576 +	ldf.fill.nta f84=[r14],loc0
  11.577 +	ldf.fill.nta f92=[r15],loc0
  11.578 +	;;
  11.579 +	ldf.fill.nta f100=[in0],loc1
  11.580 +	ldf.fill.nta f108=[ r3],loc1
  11.581 +	ldf.fill.nta f116=[r14],loc1
  11.582 +	ldf.fill.nta f124=[r15],loc1
  11.583 +	;;
  11.584 +	ldf.fill.nta f37=[in0],loc0
  11.585 +	ldf.fill.nta f45=[ r3],loc0
  11.586 +	ldf.fill.nta f53=[r14],loc0
  11.587 +	ldf.fill.nta f61=[r15],loc0
  11.588 +	;;
  11.589 +	ldf.fill.nta f69=[in0],loc0
  11.590 +	ldf.fill.nta f77=[ r3],loc0
  11.591 +	ldf.fill.nta f85=[r14],loc0
  11.592 +	ldf.fill.nta f93=[r15],loc0
  11.593 +	;;
  11.594 +	ldf.fill.nta f101=[in0],loc1
  11.595 +	ldf.fill.nta f109=[ r3],loc1
  11.596 +	ldf.fill.nta f117=[r14],loc1
  11.597 +	ldf.fill.nta f125=[r15],loc1
  11.598 +	;;
  11.599 +	ldf.fill.nta f38 =[in0],loc0
  11.600 +	ldf.fill.nta f46 =[ r3],loc0
  11.601 +	ldf.fill.nta f54 =[r14],loc0
  11.602 +	ldf.fill.nta f62 =[r15],loc0
  11.603 +	;;
  11.604 +	ldf.fill.nta f70 =[in0],loc0
  11.605 +	ldf.fill.nta f78 =[ r3],loc0
  11.606 +	ldf.fill.nta f86 =[r14],loc0
  11.607 +	ldf.fill.nta f94 =[r15],loc0
  11.608 +	;;
  11.609 +	ldf.fill.nta f102=[in0],loc1
  11.610 +	ldf.fill.nta f110=[ r3],loc1
  11.611 +	ldf.fill.nta f118=[r14],loc1
  11.612 +	ldf.fill.nta f126=[r15],loc1
  11.613 +	;;
  11.614 +	ldf.fill.nta f39 =[in0],loc0
  11.615 +	ldf.fill.nta f47 =[ r3],loc0
  11.616 +	ldf.fill.nta f55 =[r14],loc0
  11.617 +	ldf.fill.nta f63 =[r15],loc0
  11.618 +	;;
  11.619 +	ldf.fill.nta f71 =[in0],loc0
  11.620 +	ldf.fill.nta f79 =[ r3],loc0
  11.621 +	ldf.fill.nta f87 =[r14],loc0
  11.622 +	ldf.fill.nta f95 =[r15],loc0
  11.623 +	;;
  11.624 +	ldf.fill.nta f103=[in0]
  11.625 +	ldf.fill.nta f111=[ r3]
  11.626 +	ldf.fill.nta f119=[r14]
  11.627 +	ldf.fill.nta f127=[r15]
  11.628 +	br.ret.sptk.many rp
  11.629 +END(__ia64_load_fpu)
  11.630 +
  11.631 +GLOBAL_ENTRY(__ia64_init_fpu)
  11.632 +	stf.spill [sp]=f0		// M3
  11.633 +	mov	 f32=f0			// F
  11.634 +	nop.b	 0
  11.635 +
  11.636 +	ldfps	 f33,f34=[sp]		// M0
  11.637 +	ldfps	 f35,f36=[sp]		// M1
  11.638 +	mov      f37=f0			// F
  11.639 +	;;
  11.640 +
  11.641 +	setf.s	 f38=r0			// M2
  11.642 +	setf.s	 f39=r0			// M3
  11.643 +	mov      f40=f0			// F
  11.644 +
  11.645 +	ldfps	 f41,f42=[sp]		// M0
  11.646 +	ldfps	 f43,f44=[sp]		// M1
  11.647 +	mov      f45=f0			// F
  11.648 +
  11.649 +	setf.s	 f46=r0			// M2
  11.650 +	setf.s	 f47=r0			// M3
  11.651 +	mov      f48=f0			// F
  11.652 +
  11.653 +	ldfps	 f49,f50=[sp]		// M0
  11.654 +	ldfps	 f51,f52=[sp]		// M1
  11.655 +	mov      f53=f0			// F
  11.656 +
  11.657 +	setf.s	 f54=r0			// M2
  11.658 +	setf.s	 f55=r0			// M3
  11.659 +	mov      f56=f0			// F
  11.660 +
  11.661 +	ldfps	 f57,f58=[sp]		// M0
  11.662 +	ldfps	 f59,f60=[sp]		// M1
  11.663 +	mov      f61=f0			// F
  11.664 +
  11.665 +	setf.s	 f62=r0			// M2
  11.666 +	setf.s	 f63=r0			// M3
  11.667 +	mov      f64=f0			// F
  11.668 +
  11.669 +	ldfps	 f65,f66=[sp]		// M0
  11.670 +	ldfps	 f67,f68=[sp]		// M1
  11.671 +	mov      f69=f0			// F
  11.672 +
  11.673 +	setf.s	 f70=r0			// M2
  11.674 +	setf.s	 f71=r0			// M3
  11.675 +	mov      f72=f0			// F
  11.676 +
  11.677 +	ldfps	 f73,f74=[sp]		// M0
  11.678 +	ldfps	 f75,f76=[sp]		// M1
  11.679 +	mov      f77=f0			// F
  11.680 +
  11.681 +	setf.s	 f78=r0			// M2
  11.682 +	setf.s	 f79=r0			// M3
  11.683 +	mov      f80=f0			// F
  11.684 +
  11.685 +	ldfps	 f81,f82=[sp]		// M0
  11.686 +	ldfps	 f83,f84=[sp]		// M1
  11.687 +	mov      f85=f0			// F
  11.688 +
  11.689 +	setf.s	 f86=r0			// M2
  11.690 +	setf.s	 f87=r0			// M3
  11.691 +	mov      f88=f0			// F
  11.692 +
  11.693 +	/*
  11.694 +	 * When the instructions are cached, it would be faster to initialize
  11.695 +	 * the remaining registers with simply mov instructions (F-unit).
  11.696 +	 * This gets the time down to ~29 cycles.  However, this would use up
  11.697 +	 * 33 bundles, whereas continuing with the above pattern yields
  11.698 +	 * 10 bundles and ~30 cycles.
  11.699 +	 */
  11.700 +
  11.701 +	ldfps	 f89,f90=[sp]		// M0
  11.702 +	ldfps	 f91,f92=[sp]		// M1
  11.703 +	mov      f93=f0			// F
  11.704 +
  11.705 +	setf.s	 f94=r0			// M2
  11.706 +	setf.s	 f95=r0			// M3
  11.707 +	mov      f96=f0			// F
  11.708 +
  11.709 +	ldfps	 f97,f98=[sp]		// M0
  11.710 +	ldfps	 f99,f100=[sp]		// M1
  11.711 +	mov      f101=f0		// F
  11.712 +
  11.713 +	setf.s	 f102=r0		// M2
  11.714 +	setf.s	 f103=r0		// M3
  11.715 +	mov      f104=f0		// F
  11.716 +
  11.717 +	ldfps	 f105,f106=[sp]		// M0
  11.718 +	ldfps	 f107,f108=[sp]		// M1
  11.719 +	mov      f109=f0		// F
  11.720 +
  11.721 +	setf.s	 f110=r0		// M2
  11.722 +	setf.s	 f111=r0		// M3
  11.723 +	mov      f112=f0		// F
  11.724 +
  11.725 +	ldfps	 f113,f114=[sp]		// M0
  11.726 +	ldfps	 f115,f116=[sp]		// M1
  11.727 +	mov      f117=f0		// F
  11.728 +
  11.729 +	setf.s	 f118=r0		// M2
  11.730 +	setf.s	 f119=r0		// M3
  11.731 +	mov      f120=f0		// F
  11.732 +
  11.733 +	ldfps	 f121,f122=[sp]		// M0
  11.734 +	ldfps	 f123,f124=[sp]		// M1
  11.735 +	mov      f125=f0		// F
  11.736 +
  11.737 +	setf.s	 f126=r0		// M2
  11.738 +	setf.s	 f127=r0		// M3
  11.739 +	br.ret.sptk.many rp		// F
  11.740 +END(__ia64_init_fpu)
  11.741 +
  11.742 +/*
  11.743 + * Switch execution mode from virtual to physical
  11.744 + *
  11.745 + * Inputs:
  11.746 + *	r16 = new psr to establish
  11.747 + * Output:
  11.748 + *	r19 = old virtual address of ar.bsp
  11.749 + *	r20 = old virtual address of sp
  11.750 + *
  11.751 + * Note: RSE must already be in enforced lazy mode
  11.752 + */
  11.753 +GLOBAL_ENTRY(ia64_switch_mode_phys)
  11.754 + {
  11.755 +	alloc r2=ar.pfs,0,0,0,0
  11.756 +	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
  11.757 +	mov r15=ip
  11.758 + }
  11.759 +	;;
  11.760 + {
  11.761 +	flushrs				// must be first insn in group
  11.762 +	srlz.i
  11.763 + }
  11.764 +	;;
  11.765 +	mov cr.ipsr=r16			// set new PSR
  11.766 +	add r3=1f-ia64_switch_mode_phys,r15
  11.767 +
  11.768 +	mov r19=ar.bsp
  11.769 +	mov r20=sp
  11.770 +	mov r14=rp			// get return address into a general register
  11.771 +	;;
  11.772 +
  11.773 +	// going to physical mode, use tpa to translate virt->phys
  11.774 +	tpa r17=r19
  11.775 +	tpa r3=r3
  11.776 +	tpa sp=sp
  11.777 +	tpa r14=r14
  11.778 +	;;
  11.779 +
  11.780 +	mov r18=ar.rnat			// save ar.rnat
  11.781 +	mov ar.bspstore=r17		// this steps on ar.rnat
  11.782 +	mov cr.iip=r3
  11.783 +	mov cr.ifs=r0
  11.784 +	;;
  11.785 +	mov ar.rnat=r18			// restore ar.rnat
  11.786 +	rfi				// must be last insn in group
  11.787 +	;;
  11.788 +1:	mov rp=r14
  11.789 +	br.ret.sptk.many rp
  11.790 +END(ia64_switch_mode_phys)
  11.791 +
  11.792 +/*
  11.793 + * Switch execution mode from physical to virtual
  11.794 + *
  11.795 + * Inputs:
  11.796 + *	r16 = new psr to establish
  11.797 + *	r19 = new bspstore to establish
  11.798 + *	r20 = new sp to establish
  11.799 + *
  11.800 + * Note: RSE must already be in enforced lazy mode
  11.801 + */
  11.802 +GLOBAL_ENTRY(ia64_switch_mode_virt)
  11.803 + {
  11.804 +	alloc r2=ar.pfs,0,0,0,0
  11.805 +	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
  11.806 +	mov r15=ip
  11.807 + }
  11.808 +	;;
  11.809 + {
  11.810 +	flushrs				// must be first insn in group
  11.811 +	srlz.i
  11.812 + }
  11.813 +	;;
  11.814 +	mov cr.ipsr=r16			// set new PSR
  11.815 +	add r3=1f-ia64_switch_mode_virt,r15
  11.816 +
  11.817 +	mov r14=rp			// get return address into a general register
  11.818 +	;;
  11.819 +
  11.820 +	// going to virtual
  11.821 +	//   - for code addresses, set upper bits of addr to KERNEL_START
  11.822 +	//   - for stack addresses, copy from input argument
  11.823 +	movl r18=KERNEL_START
  11.824 +	dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
  11.825 +	dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
  11.826 +	mov sp=r20
  11.827 +	;;
  11.828 +	or r3=r3,r18
  11.829 +	or r14=r14,r18
  11.830 +	;;
  11.831 +
  11.832 +	mov r18=ar.rnat			// save ar.rnat
  11.833 +	mov ar.bspstore=r19		// this steps on ar.rnat
  11.834 +	mov cr.iip=r3
  11.835 +	mov cr.ifs=r0
  11.836 +	;;
  11.837 +	mov ar.rnat=r18			// restore ar.rnat
  11.838 +	rfi				// must be last insn in group
  11.839 +	;;
  11.840 +1:	mov rp=r14
  11.841 +	br.ret.sptk.many rp
  11.842 +END(ia64_switch_mode_virt)
  11.843 +
  11.844 +GLOBAL_ENTRY(ia64_delay_loop)
  11.845 +	.prologue
  11.846 +{	nop 0			// work around GAS unwind info generation bug...
  11.847 +	.save ar.lc,r2
  11.848 +	mov r2=ar.lc
  11.849 +	.body
  11.850 +	;;
  11.851 +	mov ar.lc=r32
  11.852 +}
  11.853 +	;;
  11.854 +	// force loop to be 32-byte aligned (GAS bug means we cannot use .align
  11.855 +	// inside function body without corrupting unwind info).
  11.856 +{	nop 0 }
  11.857 +1:	br.cloop.sptk.few 1b
  11.858 +	;;
  11.859 +	mov ar.lc=r2
  11.860 +	br.ret.sptk.many rp
  11.861 +END(ia64_delay_loop)
  11.862 +
  11.863 +/*
  11.864 + * Return a CPU-local timestamp in nano-seconds.  This timestamp is
  11.865 + * NOT synchronized across CPUs its return value must never be
  11.866 + * compared against the values returned on another CPU.  The usage in
  11.867 + * kernel/sched.c ensures that.
  11.868 + *
  11.869 + * The return-value of sched_clock() is NOT supposed to wrap-around.
  11.870 + * If it did, it would cause some scheduling hiccups (at the worst).
  11.871 + * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even
  11.872 + * that would happen only once every 5+ years.
  11.873 + *
  11.874 + * The code below basically calculates:
  11.875 + *
  11.876 + *   (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
  11.877 + *
  11.878 + * except that the multiplication and the shift are done with 128-bit
  11.879 + * intermediate precision so that we can produce a full 64-bit result.
  11.880 + */
  11.881 +GLOBAL_ENTRY(sched_clock)
  11.882 +#ifdef XEN
  11.883 +	movl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET
  11.884 +#else
  11.885 +	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
  11.886 +#endif
  11.887 +	mov.m r9=ar.itc		// fetch cycle-counter				(35 cyc)
  11.888 +	;;
  11.889 +	ldf8 f8=[r8]
  11.890 +	;;
  11.891 +	setf.sig f9=r9		// certain to stall, so issue it _after_ ldf8...
  11.892 +	;;
  11.893 +	xmpy.lu f10=f9,f8	// calculate low 64 bits of 128-bit product	(4 cyc)
  11.894 +	xmpy.hu f11=f9,f8	// calculate high 64 bits of 128-bit product
  11.895 +	;;
  11.896 +	getf.sig r8=f10		//						(5 cyc)
  11.897 +	getf.sig r9=f11
  11.898 +	;;
  11.899 +	shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
  11.900 +	br.ret.sptk.many rp
  11.901 +END(sched_clock)
  11.902 +
  11.903 +GLOBAL_ENTRY(start_kernel_thread)
  11.904 +	.prologue
  11.905 +	.save rp, r0				// this is the end of the call-chain
  11.906 +	.body
  11.907 +	alloc r2 = ar.pfs, 0, 0, 2, 0
  11.908 +	mov out0 = r9
  11.909 +	mov out1 = r11;;
  11.910 +	br.call.sptk.many rp = kernel_thread_helper;;
  11.911 +	mov out0 = r8
  11.912 +	br.call.sptk.many rp = sys_exit;;
  11.913 +1:	br.sptk.few 1b				// not reached
  11.914 +END(start_kernel_thread)
  11.915 +
  11.916 +#ifdef CONFIG_IA64_BRL_EMU
  11.917 +
  11.918 +/*
  11.919 + *  Assembly routines used by brl_emu.c to set preserved register state.
  11.920 + */
  11.921 +
  11.922 +#define SET_REG(reg)				\
  11.923 + GLOBAL_ENTRY(ia64_set_##reg);			\
  11.924 +	alloc r16=ar.pfs,1,0,0,0;		\
  11.925 +	mov reg=r32;				\
  11.926 +	;;					\
  11.927 +	br.ret.sptk.many rp;			\
  11.928 + END(ia64_set_##reg)
  11.929 +
  11.930 +SET_REG(b1);
  11.931 +SET_REG(b2);
  11.932 +SET_REG(b3);
  11.933 +SET_REG(b4);
  11.934 +SET_REG(b5);
  11.935 +
  11.936 +#endif /* CONFIG_IA64_BRL_EMU */
  11.937 +
  11.938 +#ifdef CONFIG_SMP
  11.939 +	/*
  11.940 +	 * This routine handles spinlock contention.  It uses a non-standard calling
  11.941 +	 * convention to avoid converting leaf routines into interior routines.  Because
  11.942 +	 * of this special convention, there are several restrictions:
  11.943 +	 *
  11.944 +	 * - do not use gp relative variables, this code is called from the kernel
  11.945 +	 *   and from modules, r1 is undefined.
  11.946 +	 * - do not use stacked registers, the caller owns them.
  11.947 +	 * - do not use the scratch stack space, the caller owns it.
  11.948 +	 * - do not use any registers other than the ones listed below
  11.949 +	 *
  11.950 +	 * Inputs:
  11.951 +	 *   ar.pfs - saved CFM of caller
  11.952 +	 *   ar.ccv - 0 (and available for use)
  11.953 +	 *   r27    - flags from spin_lock_irqsave or 0.  Must be preserved.
  11.954 +	 *   r28    - available for use.
  11.955 +	 *   r29    - available for use.
  11.956 +	 *   r30    - available for use.
  11.957 +	 *   r31    - address of lock, available for use.
  11.958 +	 *   b6     - return address
  11.959 +	 *   p14    - available for use.
  11.960 +	 *   p15    - used to track flag status.
  11.961 +	 *
  11.962 +	 * If you patch this code to use more registers, do not forget to update
  11.963 +	 * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h.
  11.964 +	 */
  11.965 +
  11.966 +#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
  11.967 +
  11.968 +GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4)
  11.969 +	.prologue
  11.970 +	.save ar.pfs, r0	// this code effectively has a zero frame size
  11.971 +	.save rp, r28
  11.972 +	.body
  11.973 +	nop 0
  11.974 +	tbit.nz p15,p0=r27,IA64_PSR_I_BIT
  11.975 +	.restore sp		// pop existing prologue after next insn
  11.976 +	mov b6 = r28
  11.977 +	.prologue
  11.978 +	.save ar.pfs, r0
  11.979 +	.altrp b6
  11.980 +	.body
  11.981 +	;;
  11.982 +(p15)	ssm psr.i		// reenable interrupts if they were on
  11.983 +				// DavidM says that srlz.d is slow and is not required in this case
  11.984 +.wait:
  11.985 +	// exponential backoff, kdb, lockmeter etc. go in here
  11.986 +	hint @pause
  11.987 +	ld4 r30=[r31]		// don't use ld4.bias; if it's contended, we won't write the word
  11.988 +	nop 0
  11.989 +	;;
  11.990 +	cmp4.ne p14,p0=r30,r0
  11.991 +(p14)	br.cond.sptk.few .wait
  11.992 +(p15)	rsm psr.i		// disable interrupts if we reenabled them
  11.993 +	br.cond.sptk.few b6	// lock is now free, try to acquire
  11.994 +	.global ia64_spinlock_contention_pre3_4_end	// for kernprof
  11.995 +ia64_spinlock_contention_pre3_4_end:
  11.996 +END(ia64_spinlock_contention_pre3_4)
  11.997 +
  11.998 +#else
  11.999 +
 11.1000 +GLOBAL_ENTRY(ia64_spinlock_contention)
 11.1001 +	.prologue
 11.1002 +	.altrp b6
 11.1003 +	.body
 11.1004 +	tbit.nz p15,p0=r27,IA64_PSR_I_BIT
 11.1005 +	;;
 11.1006 +.wait:
 11.1007 +(p15)	ssm psr.i		// reenable interrupts if they were on
 11.1008 +				// DavidM says that srlz.d is slow and is not required in this case
 11.1009 +.wait2:
 11.1010 +	// exponential backoff, kdb, lockmeter etc. go in here
 11.1011 +	hint @pause
 11.1012 +	ld4 r30=[r31]		// don't use ld4.bias; if it's contended, we won't write the word
 11.1013 +	;;
 11.1014 +	cmp4.ne p14,p0=r30,r0
 11.1015 +	mov r30 = 1
 11.1016 +(p14)	br.cond.sptk.few .wait2
 11.1017 +(p15)	rsm psr.i		// disable interrupts if we reenabled them
 11.1018 +	;;
 11.1019 +	cmpxchg4.acq r30=[r31], r30, ar.ccv
 11.1020 +	;;
 11.1021 +	cmp4.ne p14,p0=r0,r30
 11.1022 +(p14)	br.cond.sptk.few .wait
 11.1023 +
 11.1024 +	br.ret.sptk.many b6	// lock is now taken
 11.1025 +END(ia64_spinlock_contention)
 11.1026 +
 11.1027 +#endif
 11.1028 +
 11.1029 +#endif /* CONFIG_SMP */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen/arch/ia64/linux-xen/irq_ia64.c	Tue Aug 02 16:25:11 2005 -0800
    12.3 @@ -0,0 +1,381 @@
    12.4 +/*
    12.5 + * linux/arch/ia64/kernel/irq.c
    12.6 + *
    12.7 + * Copyright (C) 1998-2001 Hewlett-Packard Co
    12.8 + *	Stephane Eranian <eranian@hpl.hp.com>
    12.9 + *	David Mosberger-Tang <davidm@hpl.hp.com>
   12.10 + *
   12.11 + *  6/10/99: Updated to bring in sync with x86 version to facilitate
   12.12 + *	     support for SMP and different interrupt controllers.
   12.13 + *
   12.14 + * 09/15/00 Goutham Rao <goutham.rao@intel.com> Implemented pci_irq_to_vector
   12.15 + *                      PCI to vector allocation routine.
   12.16 + * 04/14/2004 Ashok Raj <ashok.raj@intel.com>
   12.17 + *						Added CPU Hotplug handling for IPF.
   12.18 + */
   12.19 +
   12.20 +#include <linux/config.h>
   12.21 +#include <linux/module.h>
   12.22 +
   12.23 +#include <linux/jiffies.h>
   12.24 +#include <linux/errno.h>
   12.25 +#include <linux/init.h>
   12.26 +#include <linux/interrupt.h>
   12.27 +#include <linux/ioport.h>
   12.28 +#include <linux/kernel_stat.h>
   12.29 +#include <linux/slab.h>
   12.30 +#include <linux/ptrace.h>
   12.31 +#include <linux/random.h>	/* for rand_initialize_irq() */
   12.32 +#include <linux/signal.h>
   12.33 +#include <linux/smp.h>
   12.34 +#include <linux/smp_lock.h>
   12.35 +#include <linux/threads.h>
   12.36 +#include <linux/bitops.h>
   12.37 +
   12.38 +#include <asm/delay.h>
   12.39 +#include <asm/intrinsics.h>
   12.40 +#include <asm/io.h>
   12.41 +#include <asm/hw_irq.h>
   12.42 +#include <asm/machvec.h>
   12.43 +#include <asm/pgtable.h>
   12.44 +#include <asm/system.h>
   12.45 +
   12.46 +#ifdef CONFIG_PERFMON
   12.47 +# include <asm/perfmon.h>
   12.48 +#endif
   12.49 +
   12.50 +#define IRQ_DEBUG	0
   12.51 +
   12.52 +/* default base addr of IPI table */
   12.53 +void __iomem *ipi_base_addr = ((void __iomem *)
   12.54 +			       (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
   12.55 +
   12.56 +/*
   12.57 + * Legacy IRQ to IA-64 vector translation table.
   12.58 + */
   12.59 +__u8 isa_irq_to_vector_map[16] = {
   12.60 +	/* 8259 IRQ translation, first 16 entries */
   12.61 +	0x2f, 0x20, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
   12.62 +	0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21
   12.63 +};
   12.64 +EXPORT_SYMBOL(isa_irq_to_vector_map);
   12.65 +
   12.66 +static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
   12.67 +
   12.68 +int
   12.69 +assign_irq_vector (int irq)
   12.70 +{
   12.71 +	int pos, vector;
   12.72 + again:
   12.73 +	pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
   12.74 +	vector = IA64_FIRST_DEVICE_VECTOR + pos;
   12.75 +	if (vector > IA64_LAST_DEVICE_VECTOR)
   12.76 +		/* XXX could look for sharable vectors instead of panic'ing... */
   12.77 +		panic("assign_irq_vector: out of interrupt vectors!");
   12.78 +	if (test_and_set_bit(pos, ia64_vector_mask))
   12.79 +		goto again;
   12.80 +	return vector;
   12.81 +}
   12.82 +
   12.83 +void
   12.84 +free_irq_vector (int vector)
   12.85 +{
   12.86 +	int pos;
   12.87 +
   12.88 +	if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
   12.89 +		return;
   12.90 +
   12.91 +	pos = vector - IA64_FIRST_DEVICE_VECTOR;
   12.92 +	if (!test_and_clear_bit(pos, ia64_vector_mask))
   12.93 +		printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
   12.94 +}
   12.95 +
   12.96 +#ifdef CONFIG_SMP
   12.97 +#	define IS_RESCHEDULE(vec)	(vec == IA64_IPI_RESCHEDULE)
   12.98 +#else
   12.99 +#	define IS_RESCHEDULE(vec)	(0)
  12.100 +#endif
  12.101 +/*
  12.102 + * That's where the IVT branches when we get an external
  12.103 + * interrupt. This branches to the correct hardware IRQ handler via
  12.104 + * function ptr.
  12.105 + */
  12.106 +void
  12.107 +ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
  12.108 +{
  12.109 +	unsigned long saved_tpr;
  12.110 +
  12.111 +#if IRQ_DEBUG
  12.112 +#ifdef XEN
  12.113 +	xen_debug_irq(vector, regs);
  12.114 +#endif
  12.115 +	{
  12.116 +		unsigned long bsp, sp;
  12.117 +
  12.118 +		/*
  12.119 +		 * Note: if the interrupt happened while executing in
  12.120 +		 * the context switch routine (ia64_switch_to), we may
  12.121 +		 * get a spurious stack overflow here.  This is
  12.122 +		 * because the register and the memory stack are not
  12.123 +		 * switched atomically.
  12.124 +		 */
  12.125 +		bsp = ia64_getreg(_IA64_REG_AR_BSP);
  12.126 +		sp = ia64_getreg(_IA64_REG_SP);
  12.127 +
  12.128 +		if ((sp - bsp) < 1024) {
  12.129 +			static unsigned char count;
  12.130 +			static long last_time;
  12.131 +
  12.132 +			if (jiffies - last_time > 5*HZ)
  12.133 +				count = 0;
  12.134 +			if (++count < 5) {
  12.135 +				last_time = jiffies;
  12.136 +				printk("ia64_handle_irq: DANGER: less than "
  12.137 +				       "1KB of free stack space!!\n"
  12.138 +				       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
  12.139 +			}
  12.140 +		}
  12.141 +	}
  12.142 +#endif /* IRQ_DEBUG */
  12.143 +
  12.144 +	/*
  12.145 +	 * Always set TPR to limit maximum interrupt nesting depth to
  12.146 +	 * 16 (without this, it would be ~240, which could easily lead
  12.147 +	 * to kernel stack overflows).
  12.148 +	 */
  12.149 +	irq_enter();
  12.150 +	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
  12.151 +	ia64_srlz_d();
  12.152 +	while (vector != IA64_SPURIOUS_INT_VECTOR) {
  12.153 +		if (!IS_RESCHEDULE(vector)) {
  12.154 +			ia64_setreg(_IA64_REG_CR_TPR, vector);
  12.155 +			ia64_srlz_d();
  12.156 +
  12.157 +#ifdef XEN
  12.158 +			if (!xen_do_IRQ(vector))
  12.159 +#endif
  12.160 +			__do_IRQ(local_vector_to_irq(vector), regs);
  12.161 +
  12.162 +			/*
  12.163 +			 * Disable interrupts and send EOI:
  12.164 +			 */
  12.165 +			local_irq_disable();
  12.166 +			ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
  12.167 +		}
  12.168 +		ia64_eoi();
  12.169 +		vector = ia64_get_ivr();
  12.170 +	}
  12.171 +	/*
  12.172 +	 * This must be done *after* the ia64_eoi().  For example, the keyboard softirq
  12.173 +	 * handler needs to be able to wait for further keyboard interrupts, which can't
  12.174 +	 * come through until ia64_eoi() has been done.
  12.175 +	 */
  12.176 +	irq_exit();
  12.177 +}
  12.178 +
  12.179 +#ifdef  CONFIG_VTI
  12.180 +#define vmx_irq_enter()		\
  12.181 +	add_preempt_count(HARDIRQ_OFFSET);
  12.182 +
  12.183 +/* Now softirq will be checked when leaving hypervisor, or else
  12.184 + * scheduler irq will be executed too early.
  12.185 + */
  12.186 +#define vmx_irq_exit(void)	\
  12.187 +	sub_preempt_count(HARDIRQ_OFFSET);
  12.188 +/*
  12.189 + * That's where the IVT branches when we get an external
  12.190 + * interrupt. This branches to the correct hardware IRQ handler via
  12.191 + * function ptr.
  12.192 + */
  12.193 +void
  12.194 +vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
  12.195 +{
  12.196 +	unsigned long saved_tpr;
  12.197 +	int	wake_dom0 = 0;
  12.198 +
  12.199 +
  12.200 +#if IRQ_DEBUG
  12.201 +	{
  12.202 +		unsigned long bsp, sp;
  12.203 +
  12.204 +		/*
  12.205 +		 * Note: if the interrupt happened while executing in
  12.206 +		 * the context switch routine (ia64_switch_to), we may
  12.207 +		 * get a spurious stack overflow here.  This is
  12.208 +		 * because the register and the memory stack are not
  12.209 +		 * switched atomically.
  12.210 +		 */
  12.211 +		bsp = ia64_getreg(_IA64_REG_AR_BSP);
  12.212 +		sp = ia64_getreg(_IA64_REG_AR_SP);
  12.213 +
  12.214 +		if ((sp - bsp) < 1024) {
  12.215 +			static unsigned char count;
  12.216 +			static long last_time;
  12.217 +
  12.218 +			if (jiffies - last_time > 5*HZ)
  12.219 +				count = 0;
  12.220 +			if (++count < 5) {
  12.221 +				last_time = jiffies;
  12.222 +				printk("ia64_handle_irq: DANGER: less than "
  12.223 +				       "1KB of free stack space!!\n"
  12.224 +				       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
  12.225 +			}
  12.226 +		}
  12.227 +	}
  12.228 +#endif /* IRQ_DEBUG */
  12.229 +
  12.230 +	/*
  12.231 +	 * Always set TPR to limit maximum interrupt nesting depth to
  12.232 +	 * 16 (without this, it would be ~240, which could easily lead
  12.233 +	 * to kernel stack overflows).
  12.234 +	 */
  12.235 +	vmx_irq_enter();
  12.236 +	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
  12.237 +	ia64_srlz_d();
  12.238 +	while (vector != IA64_SPURIOUS_INT_VECTOR) {
  12.239 +	    if (!IS_RESCHEDULE(vector)) {
  12.240 +		ia64_setreg(_IA64_REG_CR_TPR, vector);
  12.241 +		ia64_srlz_d();
  12.242 +
  12.243 +		if (vector != IA64_TIMER_VECTOR) {
  12.244 +			/* FIXME: Leave IRQ re-route later */
  12.245 +			vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector);
  12.246 +			wake_dom0 = 1;
  12.247 +		}
  12.248 +		else {	// FIXME: Handle Timer only now
  12.249 +			__do_IRQ(local_vector_to_irq(vector), regs);
  12.250 +		}
  12.251 +		
  12.252 +		/*
  12.253 +		 * Disable interrupts and send EOI:
  12.254 +		 */
  12.255 +		local_irq_disable();
  12.256 +		ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
  12.257 +	    }
  12.258 +	    else {
  12.259 +                printf("Oops: RESCHEDULE IPI absorbed by HV\n");
  12.260 +            }
  12.261 +	    ia64_eoi();
  12.262 +	    vector = ia64_get_ivr();
  12.263 +	}
  12.264 +	/*
  12.265 +	 * This must be done *after* the ia64_eoi().  For example, the keyboard softirq
  12.266 +	 * handler needs to be able to wait for further keyboard interrupts, which can't
  12.267 +	 * come through until ia64_eoi() has been done.
  12.268 +	 */
  12.269 +	vmx_irq_exit();
  12.270 +	if ( wake_dom0 && current != dom0 ) 
  12.271 +		domain_wake(dom0->vcpu[0]);
  12.272 +}
  12.273 +#endif
  12.274 +
  12.275 +
  12.276 +#ifdef CONFIG_HOTPLUG_CPU
  12.277 +/*
  12.278 + * This function emulates a interrupt processing when a cpu is about to be
  12.279 + * brought down.
  12.280 + */
  12.281 +void ia64_process_pending_intr(void)
  12.282 +{
  12.283 +	ia64_vector vector;
  12.284 +	unsigned long saved_tpr;
  12.285 +	extern unsigned int vectors_in_migration[NR_IRQS];
  12.286 +
  12.287 +	vector = ia64_get_ivr();
  12.288 +
  12.289 +	 irq_enter();
  12.290 +	 saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
  12.291 +	 ia64_srlz_d();
  12.292 +
  12.293 +	 /*
  12.294 +	  * Perform normal interrupt style processing
  12.295 +	  */
  12.296 +	while (vector != IA64_SPURIOUS_INT_VECTOR) {
  12.297 +		if (!IS_RESCHEDULE(vector)) {
  12.298 +			ia64_setreg(_IA64_REG_CR_TPR, vector);
  12.299 +			ia64_srlz_d();
  12.300 +
  12.301 +			/*
  12.302 +			 * Now try calling normal ia64_handle_irq as it would have got called
  12.303 +			 * from a real intr handler. Try passing null for pt_regs, hopefully
  12.304 +			 * it will work. I hope it works!.
  12.305 +			 * Probably could shared code.
  12.306 +			 */
  12.307 +			vectors_in_migration[local_vector_to_irq(vector)]=0;
  12.308 +			__do_IRQ(local_vector_to_irq(vector), NULL);
  12.309 +
  12.310 +			/*
  12.311 +			 * Disable interrupts and send EOI
  12.312 +			 */
  12.313 +			local_irq_disable();
  12.314 +			ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
  12.315 +		}
  12.316 +		ia64_eoi();
  12.317 +		vector = ia64_get_ivr();
  12.318 +	}
  12.319 +	irq_exit();
  12.320 +}
  12.321 +#endif
  12.322 +
  12.323 +
  12.324 +#ifdef CONFIG_SMP
  12.325 +extern irqreturn_t handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
  12.326 +
  12.327 +static struct irqaction ipi_irqaction = {
  12.328 +	.handler =	handle_IPI,
  12.329 +	.flags =	SA_INTERRUPT,
  12.330 +	.name =		"IPI"
  12.331 +};
  12.332 +#endif
  12.333 +
  12.334 +void
  12.335 +register_percpu_irq (ia64_vector vec, struct irqaction *action)
  12.336 +{
  12.337 +	irq_desc_t *desc;
  12.338 +	unsigned int irq;
  12.339 +
  12.340 +	for (irq = 0; irq < NR_IRQS; ++irq)
  12.341 +		if (irq_to_vector(irq) == vec) {
  12.342 +			desc = irq_descp(irq);
  12.343 +			desc->status |= IRQ_PER_CPU;
  12.344 +			desc->handler = &irq_type_ia64_lsapic;
  12.345 +			if (action)
  12.346 +				setup_irq(irq, action);
  12.347 +		}
  12.348 +}
  12.349 +
  12.350 +void __init
  12.351 +init_IRQ (void)
  12.352 +{
  12.353 +	register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
  12.354 +#ifdef CONFIG_SMP
  12.355 +	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
  12.356 +#endif
  12.357 +#ifdef CONFIG_PERFMON
  12.358 +	pfm_init_percpu();
  12.359 +#endif
  12.360 +	platform_irq_init();
  12.361 +}
  12.362 +
  12.363 +void
  12.364 +ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
  12.365 +{
  12.366 +	void __iomem *ipi_addr;
  12.367 +	unsigned long ipi_data;
  12.368 +	unsigned long phys_cpu_id;
  12.369 +
  12.370 +#ifdef CONFIG_SMP
  12.371 +	phys_cpu_id = cpu_physical_id(cpu);
  12.372 +#else
  12.373 +	phys_cpu_id = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
  12.374 +#endif
  12.375 +
  12.376 +	/*
  12.377 +	 * cpu number is in 8bit ID and 8bit EID
  12.378 +	 */
  12.379 +
  12.380 +	ipi_data = (delivery_mode << 8) | (vector & 0xff);
  12.381 +	ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
  12.382 +
  12.383 +	writeq(ipi_data, ipi_addr);
  12.384 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xen/arch/ia64/linux-xen/mm_contig.c	Tue Aug 02 16:25:11 2005 -0800
    13.3 @@ -0,0 +1,305 @@
    13.4 +/*
    13.5 + * This file is subject to the terms and conditions of the GNU General Public
    13.6 + * License.  See the file "COPYING" in the main directory of this archive
    13.7 + * for more details.
    13.8 + *
    13.9 + * Copyright (C) 1998-2003 Hewlett-Packard Co
   13.10 + *	David Mosberger-Tang <davidm@hpl.hp.com>
   13.11 + *	Stephane Eranian <eranian@hpl.hp.com>
   13.12 + * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
   13.13 + * Copyright (C) 1999 VA Linux Systems
   13.14 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
   13.15 + * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved.
   13.16 + *
   13.17 + * Routines used by ia64 machines with contiguous (or virtually contiguous)
   13.18 + * memory.
   13.19 + */
   13.20 +#include <linux/config.h>
   13.21 +#include <linux/bootmem.h>
   13.22 +#include <linux/efi.h>
   13.23 +#include <linux/mm.h>
   13.24 +#include <linux/swap.h>
   13.25 +
   13.26 +#include <asm/meminit.h>
   13.27 +#include <asm/pgalloc.h>
   13.28 +#include <asm/pgtable.h>
   13.29 +#include <asm/sections.h>
   13.30 +#include <asm/mca.h>
   13.31 +
   13.32 +#ifdef CONFIG_VIRTUAL_MEM_MAP
   13.33 +static unsigned long num_dma_physpages;
   13.34 +#endif
   13.35 +
   13.36 +/**
   13.37 + * show_mem - display a memory statistics summary
   13.38 + *
   13.39 + * Just walks the pages in the system and describes where they're allocated.
   13.40 + */
   13.41 +#ifndef XEN
   13.42 +void
   13.43 +show_mem (void)
   13.44 +{
   13.45 +	int i, total = 0, reserved = 0;
   13.46 +	int shared = 0, cached = 0;
   13.47 +
   13.48 +	printk("Mem-info:\n");
   13.49 +	show_free_areas();
   13.50 +
   13.51 +	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
   13.52 +	i = max_mapnr;
   13.53 +	while (i-- > 0) {
   13.54 +		if (!pfn_valid(i))
   13.55 +			continue;
   13.56 +		total++;
   13.57 +		if (PageReserved(mem_map+i))
   13.58 +			reserved++;
   13.59 +		else if (PageSwapCache(mem_map+i))
   13.60 +			cached++;
   13.61 +		else if (page_count(mem_map + i))
   13.62 +			shared += page_count(mem_map + i) - 1;
   13.63 +	}
   13.64 +	printk("%d pages of RAM\n", total);
   13.65 +	printk("%d reserved pages\n", reserved);
   13.66 +	printk("%d pages shared\n", shared);
   13.67 +	printk("%d pages swap cached\n", cached);
   13.68 +	printk("%ld pages in page table cache\n", pgtable_cache_size);
   13.69 +}
   13.70 +#endif
   13.71 +
   13.72 +/* physical address where the bootmem map is located */
   13.73 +unsigned long bootmap_start;
   13.74 +
   13.75 +/**
   13.76 + * find_max_pfn - adjust the maximum page number callback
   13.77 + * @start: start of range
   13.78 + * @end: end of range
   13.79 + * @arg: address of pointer to global max_pfn variable
   13.80 + *
   13.81 + * Passed as a callback function to efi_memmap_walk() to determine the highest
   13.82 + * available page frame number in the system.
   13.83 + */
   13.84 +int
   13.85 +find_max_pfn (unsigned long start, unsigned long end, void *arg)
   13.86 +{
   13.87 +	unsigned long *max_pfnp = arg, pfn;
   13.88 +
   13.89 +	pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT;
   13.90 +	if (pfn > *max_pfnp)
   13.91 +		*max_pfnp = pfn;
   13.92 +	return 0;
   13.93 +}
   13.94 +
   13.95 +/**
   13.96 + * find_bootmap_location - callback to find a memory area for the bootmap
   13.97 + * @start: start of region
   13.98 + * @end: end of region
   13.99 + * @arg: unused callback data
  13.100 + *
  13.101 + * Find a place to put the bootmap and return its starting address in
  13.102 + * bootmap_start.  This address must be page-aligned.
  13.103 + */
  13.104 +int
  13.105 +find_bootmap_location (unsigned long start, unsigned long end, void *arg)
  13.106 +{
  13.107 +	unsigned long needed = *(unsigned long *)arg;
  13.108 +	unsigned long range_start, range_end, free_start;
  13.109 +	int i;
  13.110 +
  13.111 +#if IGNORE_PFN0
  13.112 +	if (start == PAGE_OFFSET) {
  13.113 +		start += PAGE_SIZE;
  13.114 +		if (start >= end)
  13.115 +			return 0;
  13.116 +	}
  13.117 +#endif
  13.118 +
  13.119 +	free_start = PAGE_OFFSET;
  13.120 +
  13.121 +	for (i = 0; i < num_rsvd_regions; i++) {
  13.122 +		range_start = max(start, free_start);
  13.123 +		range_end   = min(end, rsvd_region[i].start & PAGE_MASK);
  13.124 +
  13.125 +		free_start = PAGE_ALIGN(rsvd_region[i].end);
  13.126 +
  13.127 +		if (range_end <= range_start)
  13.128 +			continue; /* skip over empty range */
  13.129 +
  13.130 +		if (range_end - range_start >= needed) {
  13.131 +			bootmap_start = __pa(range_start);
  13.132 +			return -1;	/* done */
  13.133 +		}
  13.134 +
  13.135 +		/* nothing more available in this segment */
  13.136 +		if (range_end == end)
  13.137 +			return 0;
  13.138 +	}
  13.139 +	return 0;
  13.140 +}
  13.141 +
  13.142 +/**
  13.143 + * find_memory - setup memory map
  13.144 + *
  13.145 + * Walk the EFI memory map and find usable memory for the system, taking
  13.146 + * into account reserved areas.
  13.147 + */
  13.148 +#ifndef XEN
  13.149 +void
  13.150 +find_memory (void)
  13.151 +{
  13.152 +	unsigned long bootmap_size;
  13.153 +
  13.154 +	reserve_memory();
  13.155 +
  13.156 +	/* first find highest page frame number */
  13.157 +	max_pfn = 0;
  13.158 +	efi_memmap_walk(find_max_pfn, &max_pfn);
  13.159 +
  13.160 +	/* how many bytes to cover all the pages */
  13.161 +	bootmap_size = bootmem_bootmap_pages(max_pfn) << PAGE_SHIFT;
  13.162 +
  13.163 +	/* look for a location to hold the bootmap */
  13.164 +	bootmap_start = ~0UL;
  13.165 +	efi_memmap_walk(find_bootmap_location, &bootmap_size);
  13.166 +	if (bootmap_start == ~0UL)
  13.167 +		panic("Cannot find %ld bytes for bootmap\n", bootmap_size);
  13.168 +
  13.169 +	bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
  13.170 +
  13.171 +	/* Free all available memory, then mark bootmem-map as being in use. */
  13.172 +	efi_memmap_walk(filter_rsvd_memory, free_bootmem);
  13.173 +	reserve_bootmem(bootmap_start, bootmap_size);
  13.174 +
  13.175 +	find_initrd();
  13.176 +}
  13.177 +#endif
  13.178 +
  13.179 +#ifdef CONFIG_SMP
  13.180 +/**
  13.181 + * per_cpu_init - setup per-cpu variables
  13.182 + *
  13.183 + * Allocate and setup per-cpu data areas.
  13.184 + */
  13.185 +void *
  13.186 +per_cpu_init (void)
  13.187 +{
  13.188 +	void *cpu_data;
  13.189 +	int cpu;
  13.190 +
  13.191 +	/*
  13.192 +	 * get_free_pages() cannot be used before cpu_init() done.  BSP
  13.193 +	 * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
  13.194 +	 * get_zeroed_page().
  13.195 +	 */
  13.196 +	if (smp_processor_id() == 0) {
  13.197 +		cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
  13.198 +					   PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
  13.199 +		for (cpu = 0; cpu < NR_CPUS; cpu++) {
  13.200 +			memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
  13.201 +			__per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
  13.202 +			cpu_data += PERCPU_PAGE_SIZE;
  13.203 +			per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
  13.204 +		}
  13.205 +	}
  13.206 +	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
  13.207 +}
  13.208 +#endif /* CONFIG_SMP */
  13.209 +
  13.210 +static int
  13.211 +count_pages (u64 start, u64 end, void *arg)
  13.212 +{
  13.213 +	unsigned long *count = arg;
  13.214 +
  13.215 +	*count += (end - start) >> PAGE_SHIFT;
  13.216 +	return 0;
  13.217 +}
  13.218 +
  13.219 +#ifdef CONFIG_VIRTUAL_MEM_MAP
  13.220 +static int
  13.221 +count_dma_pages (u64 start, u64 end, void *arg)
  13.222 +{
  13.223 +	unsigned long *count = arg;
  13.224 +
  13.225 +	if (start < MAX_DMA_ADDRESS)
  13.226 +		*count += (min(end, MAX_DMA_ADDRESS) - start) >> PAGE_SHIFT;
  13.227 +	return 0;
  13.228 +}
  13.229 +#endif
  13.230 +
  13.231 +/*
  13.232 + * Set up the page tables.
  13.233 + */
  13.234 +
  13.235 +#ifndef XEN
  13.236 +void
  13.237 +paging_init (void)
  13.238 +{
  13.239 +	unsigned long max_dma;
  13.240 +	unsigned long zones_size[MAX_NR_ZONES];
  13.241 +#ifdef CONFIG_VIRTUAL_MEM_MAP
  13.242 +	unsigned long zholes_size[MAX_NR_ZONES];
  13.243 +	unsigned long max_gap;
  13.244 +#endif
  13.245 +
  13.246 +	/* initialize mem_map[] */
  13.247 +
  13.248 +	memset(zones_size, 0, sizeof(zones_size));
  13.249 +
  13.250 +	num_physpages = 0;
  13.251 +	efi_memmap_walk(count_pages, &num_physpages);
  13.252 +
  13.253 +	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
  13.254 +
  13.255 +#ifdef CONFIG_VIRTUAL_MEM_MAP
  13.256 +	memset(zholes_size, 0, sizeof(zholes_size));
  13.257 +
  13.258 +	num_dma_physpages = 0;
  13.259 +	efi_memmap_walk(count_dma_pages, &num_dma_physpages);
  13.260 +
  13.261 +	if (max_low_pfn < max_dma) {
  13.262 +		zones_size[ZONE_DMA] = max_low_pfn;
  13.263 +		zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
  13.264 +	} else {
  13.265 +		zones_size[ZONE_DMA] = max_dma;
  13.266 +		zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
  13.267 +		if (num_physpages > num_dma_physpages) {
  13.268 +			zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
  13.269 +			zholes_size[ZONE_NORMAL] =
  13.270 +				((max_low_pfn - max_dma) -
  13.271 +				 (num_physpages - num_dma_physpages));
  13.272 +		}
  13.273 +	}
  13.274 +
  13.275 +	max_gap = 0;
  13.276 +	efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
  13.277 +	if (max_gap < LARGE_GAP) {
  13.278 +		vmem_map = (struct page *) 0;
  13.279 +		free_area_init_node(0, &contig_page_data, zones_size, 0,
  13.280 +				    zholes_size);
  13.281 +	} else {
  13.282 +		unsigned long map_size;
  13.283 +
  13.284 +		/* allocate virtual_mem_map */
  13.285 +
  13.286 +		map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page));
  13.287 +		vmalloc_end -= map_size;
  13.288 +		vmem_map = (struct page *) vmalloc_end;
  13.289 +		efi_memmap_walk(create_mem_map_page_table, NULL);
  13.290 +
  13.291 +		mem_map = contig_page_data.node_mem_map = vmem_map;
  13.292 +		free_area_init_node(0, &contig_page_data, zones_size,
  13.293 +				    0, zholes_size);
  13.294 +
  13.295 +		printk("Virtual mem_map starts at 0x%p\n", mem_map);
  13.296 +	}
  13.297 +#else /* !CONFIG_VIRTUAL_MEM_MAP */
  13.298 +	if (max_low_pfn < max_dma)
  13.299 +		zones_size[ZONE_DMA] = max_low_pfn;
  13.300 +	else {
  13.301 +		zones_size[ZONE_DMA] = max_dma;
  13.302 +		zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
  13.303 +	}
  13.304 +	free_area_init(zones_size);
  13.305 +#endif /* !CONFIG_VIRTUAL_MEM_MAP */
  13.306 +	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
  13.307 +}
  13.308 +#endif /* !CONFIG_XEN */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xen/arch/ia64/linux-xen/pal.S	Tue Aug 02 16:25:11 2005 -0800
    14.3 @@ -0,0 +1,310 @@
    14.4 +/*
    14.5 + * PAL Firmware support
    14.6 + * IA-64 Processor Programmers Reference Vol 2
    14.7 + *
    14.8 + * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
    14.9 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
   14.10 + * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
   14.11 + *	David Mosberger <davidm@hpl.hp.com>
   14.12 + *	Stephane Eranian <eranian@hpl.hp.com>
   14.13 + *
   14.14 + * 05/22/2000 eranian Added support for stacked register calls
   14.15 + * 05/24/2000 eranian Added support for physical mode static calls
   14.16 + */
   14.17 +
   14.18 +#include <asm/asmmacro.h>
   14.19 +#include <asm/processor.h>
   14.20 +
   14.21 +	.data
   14.22 +pal_entry_point:
   14.23 +	data8 ia64_pal_default_handler
   14.24 +	.text
   14.25 +
   14.26 +/*
   14.27 + * Set the PAL entry point address.  This could be written in C code, but we do it here
   14.28 + * to keep it all in one module (besides, it's so trivial that it's
   14.29 + * not a big deal).
   14.30 + *
   14.31 + * in0		Address of the PAL entry point (text address, NOT a function descriptor).
   14.32 + */
   14.33 +GLOBAL_ENTRY(ia64_pal_handler_init)
   14.34 +	alloc r3=ar.pfs,1,0,0,0
   14.35 +	movl r2=pal_entry_point
   14.36 +	;;
   14.37 +	st8 [r2]=in0
   14.38 +	br.ret.sptk.many rp
   14.39 +END(ia64_pal_handler_init)
   14.40 +
   14.41 +/*
   14.42 + * Default PAL call handler.  This needs to be coded in assembly because it uses
   14.43 + * the static calling convention, i.e., the RSE may not be used and calls are
   14.44 + * done via "br.cond" (not "br.call").
   14.45 + */
   14.46 +GLOBAL_ENTRY(ia64_pal_default_handler)
   14.47 +	mov r8=-1
   14.48 +	br.cond.sptk.many rp
   14.49 +END(ia64_pal_default_handler)
   14.50 +
   14.51 +/*
   14.52 + * Make a PAL call using the static calling convention.
   14.53 + *
   14.54 + * in0         Index of PAL service
   14.55 + * in1 - in3   Remaining PAL arguments
   14.56 + * in4	       1 ==> clear psr.ic,  0 ==> don't clear psr.ic
   14.57 + *
   14.58 + */
   14.59 +GLOBAL_ENTRY(ia64_pal_call_static)
   14.60 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
   14.61 +	alloc loc1 = ar.pfs,5,5,0,0
   14.62 +	movl loc2 = pal_entry_point
   14.63 +1:	{
   14.64 +	  mov r28 = in0
   14.65 +	  mov r29 = in1
   14.66 +	  mov r8 = ip
   14.67 +	}
   14.68 +	;;
   14.69 +	ld8 loc2 = [loc2]		// loc2 <- entry point
   14.70 +	tbit.nz p6,p7 = in4, 0
   14.71 +	adds r8 = 1f-1b,r8
   14.72 +	mov loc4=ar.rsc			// save RSE configuration
   14.73 +	;;
   14.74 +	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
   14.75 +	mov loc3 = psr
   14.76 +	mov loc0 = rp
   14.77 +	.body
   14.78 +	mov r30 = in2
   14.79 +
   14.80 +(p6)	rsm psr.i | psr.ic
   14.81 +	mov r31 = in3
   14.82 +	mov b7 = loc2
   14.83 +
   14.84 +(p7)	rsm psr.i
   14.85 +	;;
   14.86 +(p6)	srlz.i
   14.87 +	mov rp = r8
   14.88 +	br.cond.sptk.many b7
   14.89 +1:	mov psr.l = loc3
   14.90 +	mov ar.rsc = loc4		// restore RSE configuration
   14.91 +	mov ar.pfs = loc1
   14.92 +	mov rp = loc0
   14.93 +	;;
   14.94 +	srlz.d				// seralize restoration of psr.l
   14.95 +	br.ret.sptk.many b0
   14.96 +END(ia64_pal_call_static)
   14.97 +
   14.98 +/*
   14.99 + * Make a PAL call using the stacked registers calling convention.
  14.100 + *
  14.101 + * Inputs:
  14.102 + * 	in0         Index of PAL service
  14.103 + * 	in2 - in3   Remaning PAL arguments
  14.104 + */
  14.105 +GLOBAL_ENTRY(ia64_pal_call_stacked)
  14.106 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
  14.107 +	alloc loc1 = ar.pfs,4,4,4,0
  14.108 +	movl loc2 = pal_entry_point
  14.109 +
  14.110 +	mov r28  = in0			// Index MUST be copied to r28
  14.111 +	mov out0 = in0			// AND in0 of PAL function
  14.112 +	mov loc0 = rp
  14.113 +	.body
  14.114 +	;;
  14.115 +	ld8 loc2 = [loc2]		// loc2 <- entry point
  14.116 +	mov out1 = in1
  14.117 +	mov out2 = in2
  14.118 +	mov out3 = in3
  14.119 +	mov loc3 = psr
  14.120 +	;;
  14.121 +	rsm psr.i
  14.122 +	mov b7 = loc2
  14.123 +	;;
  14.124 +	br.call.sptk.many rp=b7		// now make the call
  14.125 +.ret0:	mov psr.l  = loc3
  14.126 +	mov ar.pfs = loc1
  14.127 +	mov rp = loc0
  14.128 +	;;
  14.129 +	srlz.d				// serialize restoration of psr.l
  14.130 +	br.ret.sptk.many b0
  14.131 +END(ia64_pal_call_stacked)
  14.132 +
  14.133 +/*
  14.134 + * Make a physical mode PAL call using the static registers calling convention.
  14.135 + *
  14.136 + * Inputs:
  14.137 + * 	in0         Index of PAL service
  14.138 + * 	in2 - in3   Remaning PAL arguments
  14.139 + *
  14.140 + * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
  14.141 + * So we don't need to clear them.
  14.142 + */
  14.143 +#define PAL_PSR_BITS_TO_CLEAR							\
  14.144 +	(IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT  | IA64_PSR_DB | IA64_PSR_RT |	\
  14.145 +	 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |		\
  14.146 +	 IA64_PSR_DFL | IA64_PSR_DFH)
  14.147 +
  14.148 +#define PAL_PSR_BITS_TO_SET							\
  14.149 +	(IA64_PSR_BN)
  14.150 +
  14.151 +
  14.152 +GLOBAL_ENTRY(ia64_pal_call_phys_static)
  14.153 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
  14.154 +	alloc loc1 = ar.pfs,4,7,0,0
  14.155 +	movl loc2 = pal_entry_point
  14.156 +1:	{
  14.157 +	  mov r28  = in0		// copy procedure index
  14.158 +	  mov r8   = ip			// save ip to compute branch
  14.159 +	  mov loc0 = rp			// save rp
  14.160 +	}
  14.161 +	.body
  14.162 +	;;
  14.163 +	ld8 loc2 = [loc2]		// loc2 <- entry point
  14.164 +	mov r29  = in1			// first argument
  14.165 +	mov r30  = in2			// copy arg2
  14.166 +	mov r31  = in3			// copy arg3
  14.167 +	;;
  14.168 +	mov loc3 = psr			// save psr
  14.169 +	adds r8  = 1f-1b,r8		// calculate return address for call
  14.170 +	;;
  14.171 +	mov loc4=ar.rsc			// save RSE configuration
  14.172 +#ifdef XEN
  14.173 +	dep.z loc2=loc2,0,60		// convert pal entry point to physical
  14.174 +#else // XEN
  14.175 +	dep.z loc2=loc2,0,61		// convert pal entry point to physical
  14.176 +#endif // XEN
  14.177 +	tpa r8=r8			// convert rp to physical
  14.178 +	;;
  14.179 +	mov b7 = loc2			// install target to branch reg
  14.180 +	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
  14.181 +	movl r16=PAL_PSR_BITS_TO_CLEAR
  14.182 +	movl r17=PAL_PSR_BITS_TO_SET
  14.183 +	;;
  14.184 +	or loc3=loc3,r17		// add in psr the bits to set
  14.185 +	;;
  14.186 +	andcm r16=loc3,r16		// removes bits to clear from psr
  14.187 +	br.call.sptk.many rp=ia64_switch_mode_phys
  14.188 +.ret1:	mov rp = r8			// install return address (physical)
  14.189 +	mov loc5 = r19
  14.190 +	mov loc6 = r20
  14.191 +	br.cond.sptk.many b7
  14.192 +1:
  14.193 +	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
  14.194 +	mov r16=loc3			// r16= original psr
  14.195 +	mov r19=loc5
  14.196 +	mov r20=loc6
  14.197 +	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
  14.198 +.ret2:
  14.199 +	mov psr.l = loc3		// restore init PSR
  14.200 +
  14.201 +	mov ar.pfs = loc1
  14.202 +	mov rp = loc0
  14.203 +	;;
  14.204 +	mov ar.rsc=loc4			// restore RSE configuration
  14.205 +	srlz.d				// seralize restoration of psr.l
  14.206 +	br.ret.sptk.many b0
  14.207 +END(ia64_pal_call_phys_static)
  14.208 +
  14.209 +/*
  14.210 + * Make a PAL call using the stacked registers in physical mode.
  14.211 + *
  14.212 + * Inputs:
  14.213 + * 	in0         Index of PAL service
  14.214 + * 	in2 - in3   Remaning PAL arguments
  14.215 + */
  14.216 +GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
  14.217 +	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
  14.218 +	alloc	loc1 = ar.pfs,5,7,4,0
  14.219 +	movl	loc2 = pal_entry_point
  14.220 +1:	{
  14.221 +	  mov r28  = in0		// copy procedure index
  14.222 +	  mov loc0 = rp		// save rp
  14.223 +	}
  14.224 +	.body
  14.225 +	;;
  14.226 +	ld8 loc2 = [loc2]		// loc2 <- entry point
  14.227 +	mov out0 = in0		// first argument
  14.228 +	mov out1 = in1		// copy arg2
  14.229 +	mov out2 = in2		// copy arg3
  14.230 +	mov out3 = in3		// copy arg3
  14.231 +	;;
  14.232 +	mov loc3 = psr		// save psr
  14.233 +	;;
  14.234 +	mov loc4=ar.rsc			// save RSE configuration
  14.235 +#ifdef XEN
  14.236 +	dep.z loc2=loc2,0,60		// convert pal entry point to physical
  14.237 +#else // XEN
  14.238 +	dep.z loc2=loc2,0,61		// convert pal entry point to physical
  14.239 +#endif // XEN
  14.240 +	;;
  14.241 +	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
  14.242 +	movl r16=PAL_PSR_BITS_TO_CLEAR
  14.243 +	movl r17=PAL_PSR_BITS_TO_SET
  14.244 +	;;
  14.245 +	or loc3=loc3,r17		// add in psr the bits to set
  14.246 +	mov b7 = loc2			// install target to branch reg
  14.247 +	;;
  14.248 +	andcm r16=loc3,r16		// removes bits to clear from psr
  14.249 +	br.call.sptk.many rp=ia64_switch_mode_phys
  14.250 +.ret6:
  14.251 +	mov loc5 = r19
  14.252 +	mov loc6 = r20
  14.253 +	br.call.sptk.many rp=b7		// now make the call
  14.254 +.ret7:
  14.255 +	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
  14.256 +	mov r16=loc3			// r16= original psr
  14.257 +	mov r19=loc5
  14.258 +	mov r20=loc6
  14.259 +	br.call.sptk.many rp=ia64_switch_mode_virt	// return to virtual mode
  14.260 +
  14.261 +.ret8:	mov psr.l  = loc3		// restore init PSR
  14.262 +	mov ar.pfs = loc1
  14.263 +	mov rp = loc0
  14.264 +	;;
  14.265 +	mov ar.rsc=loc4			// restore RSE configuration
  14.266 +	srlz.d				// seralize restoration of psr.l
  14.267 +	br.ret.sptk.many b0
  14.268 +END(ia64_pal_call_phys_stacked)
  14.269 +
  14.270 +/*
  14.271 + * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15).
  14.272 + *
  14.273 + * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch
  14.274 + * regs fp-low partition.
  14.275 + *
  14.276 + * Inputs:
  14.277 + *      in0	Address of stack storage for fp regs
  14.278 + */
  14.279 +GLOBAL_ENTRY(ia64_save_scratch_fpregs)
  14.280 +	alloc r3=ar.pfs,1,0,0,0
  14.281 +	add r2=16,in0
  14.282 +	;;
  14.283 +	stf.spill [in0] = f10,32
  14.284 +	stf.spill [r2]  = f11,32
  14.285 +	;;
  14.286 +	stf.spill [in0] = f12,32
  14.287 +	stf.spill [r2]  = f13,32
  14.288 +	;;
  14.289 +	stf.spill [in0] = f14,32
  14.290 +	stf.spill [r2]  = f15,32
  14.291 +	br.ret.sptk.many rp
  14.292 +END(ia64_save_scratch_fpregs)
  14.293 +
  14.294 +/*
  14.295 + * Load scratch fp scratch regs (fp10-fp15)
  14.296 + *
  14.297 + * Inputs:
  14.298 + *      in0	Address of stack storage for fp regs
  14.299 + */
  14.300 +GLOBAL_ENTRY(ia64_load_scratch_fpregs)
  14.301 +	alloc r3=ar.pfs,1,0,0,0
  14.302 +	add r2=16,in0
  14.303 +	;;
  14.304 +	ldf.fill  f10 = [in0],32
  14.305 +	ldf.fill  f11 = [r2],32
  14.306 +	;;
  14.307 +	ldf.fill  f12 = [in0],32
  14.308 +	ldf.fill  f13 = [r2],32
  14.309 +	;;
  14.310 +	ldf.fill  f14 = [in0],32
  14.311 +	ldf.fill  f15 = [r2],32
  14.312 +	br.ret.sptk.many rp
  14.313 +END(ia64_load_scratch_fpregs)
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xen/arch/ia64/linux-xen/setup.c	Tue Aug 02 16:25:11 2005 -0800
    15.3 @@ -0,0 +1,773 @@
    15.4 +/*
    15.5 + * Architecture-specific setup.
    15.6 + *
    15.7 + * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
    15.8 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    15.9 + *	Stephane Eranian <eranian@hpl.hp.com>
   15.10 + * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
   15.11 + * Copyright (C) 1999 VA Linux Systems
   15.12 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
   15.13 + *
   15.14 + * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo().
   15.15 + * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
   15.16 + * 03/31/00 R.Seth	cpu_initialized and current->processor fixes
   15.17 + * 02/04/00 D.Mosberger	some more get_cpuinfo fixes...
   15.18 + * 02/01/00 R.Seth	fixed get_cpuinfo for SMP
   15.19 + * 01/07/99 S.Eranian	added the support for command line argument
   15.20 + * 06/24/99 W.Drummond	added boot_cpu_data.
   15.21 + */
   15.22 +#include <linux/config.h>
   15.23 +#include <linux/module.h>
   15.24 +#include <linux/init.h>
   15.25 +
   15.26 +#include <linux/acpi.h>
   15.27 +#include <linux/bootmem.h>
   15.28 +#include <linux/console.h>
   15.29 +#include <linux/delay.h>
   15.30 +#include <linux/kernel.h>
   15.31 +#include <linux/reboot.h>
   15.32 +#include <linux/sched.h>
   15.33 +#include <linux/seq_file.h>
   15.34 +#include <linux/string.h>
   15.35 +#include <linux/threads.h>
   15.36 +#include <linux/tty.h>
   15.37 +#include <linux/serial.h>
   15.38 +#include <linux/serial_core.h>
   15.39 +#include <linux/efi.h>
   15.40 +#include <linux/initrd.h>
   15.41 +
   15.42 +#include <asm/ia32.h>
   15.43 +#include <asm/machvec.h>
   15.44 +#include <asm/mca.h>
   15.45 +#include <asm/meminit.h>
   15.46 +#include <asm/page.h>
   15.47 +#include <asm/patch.h>
   15.48 +#include <asm/pgtable.h>
   15.49 +#include <asm/processor.h>
   15.50 +#include <asm/sal.h>
   15.51 +#include <asm/sections.h>
   15.52 +#include <asm/serial.h>
   15.53 +#include <asm/setup.h>
   15.54 +#include <asm/smp.h>
   15.55 +#include <asm/system.h>
   15.56 +#include <asm/unistd.h>
   15.57 +#ifdef CONFIG_VTI
   15.58 +#include <asm/vmx.h>
   15.59 +#endif // CONFIG_VTI
   15.60 +#include <asm/io.h>
   15.61 +
   15.62 +#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
   15.63 +# error "struct cpuinfo_ia64 too big!"
   15.64 +#endif
   15.65 +
   15.66 +#ifdef CONFIG_SMP
   15.67 +unsigned long __per_cpu_offset[NR_CPUS];
   15.68 +EXPORT_SYMBOL(__per_cpu_offset);
   15.69 +#endif
   15.70 +
   15.71 +DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
   15.72 +DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
   15.73 +DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
   15.74 +unsigned long ia64_cycles_per_usec;
   15.75 +struct ia64_boot_param *ia64_boot_param;
   15.76 +struct screen_info screen_info;
   15.77 +
   15.78 +unsigned long ia64_max_cacheline_size;
   15.79 +unsigned long ia64_iobase;	/* virtual address for I/O accesses */
   15.80 +EXPORT_SYMBOL(ia64_iobase);
   15.81 +struct io_space io_space[MAX_IO_SPACES];
   15.82 +EXPORT_SYMBOL(io_space);
   15.83 +unsigned int num_io_spaces;
   15.84 +
   15.85 +unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
   15.86 +
   15.87 +/*
   15.88 + * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
   15.89 + * mask specifies a mask of address bits that must be 0 in order for two buffers to be
   15.90 + * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
   15.91 + * address of the second buffer must be aligned to (merge_mask+1) in order to be
   15.92 + * mergeable).  By default, we assume there is no I/O MMU which can merge physically
   15.93 + * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu
   15.94 + * page-size of 2^64.
   15.95 + */
   15.96 +unsigned long ia64_max_iommu_merge_mask = ~0UL;
   15.97 +EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
   15.98 +
   15.99 +/*
  15.100 + * We use a special marker for the end of memory and it uses the extra (+1) slot
  15.101 + */
  15.102 +struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
  15.103 +int num_rsvd_regions;
  15.104 +
  15.105 +
  15.106 +/*
  15.107 + * Filter incoming memory segments based on the primitive map created from the boot
  15.108 + * parameters. Segments contained in the map are removed from the memory ranges. A
  15.109 + * caller-specified function is called with the memory ranges that remain after filtering.
  15.110 + * This routine does not assume the incoming segments are sorted.
  15.111 + */
  15.112 +int
  15.113 +filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
  15.114 +{
  15.115 +	unsigned long range_start, range_end, prev_start;
  15.116 +	void (*func)(unsigned long, unsigned long, int);
  15.117 +	int i;
  15.118 +
  15.119 +#if IGNORE_PFN0
  15.120 +	if (start == PAGE_OFFSET) {
  15.121 +		printk(KERN_WARNING "warning: skipping physical page 0\n");
  15.122 +		start += PAGE_SIZE;
  15.123 +		if (start >= end) return 0;
  15.124 +	}
  15.125 +#endif
  15.126 +	/*
  15.127 +	 * lowest possible address(walker uses virtual)
  15.128 +	 */
  15.129 +	prev_start = PAGE_OFFSET;
  15.130 +	func = arg;
  15.131 +
  15.132 +	for (i = 0; i < num_rsvd_regions; ++i) {
  15.133 +		range_start = max(start, prev_start);
  15.134 +		range_end   = min(end, rsvd_region[i].start);
  15.135 +
  15.136 +		if (range_start < range_end)
  15.137 +#ifdef XEN
  15.138 +		{
  15.139 +		/* init_boot_pages requires "ps, pe" */
  15.140 +			printk("Init boot pages: 0x%lx -> 0x%lx.\n",
  15.141 +				__pa(range_start), __pa(range_end));
  15.142 +			(*func)(__pa(range_start), __pa(range_end), 0);
  15.143 +		}
  15.144 +#else
  15.145 +			call_pernode_memory(__pa(range_start), range_end - range_start, func);
  15.146 +#endif
  15.147 +
  15.148 +		/* nothing more available in this segment */
  15.149 +		if (range_end == end) return 0;
  15.150 +
  15.151 +		prev_start = rsvd_region[i].end;
  15.152 +	}
  15.153 +	/* end of memory marker allows full processing inside loop body */
  15.154 +	return 0;
  15.155 +}
  15.156 +
  15.157 +static void
  15.158 +sort_regions (struct rsvd_region *rsvd_region, int max)
  15.159 +{
  15.160 +	int j;
  15.161 +
  15.162 +	/* simple bubble sorting */
  15.163 +	while (max--) {
  15.164 +		for (j = 0; j < max; ++j) {
  15.165 +			if (rsvd_region[j].start > rsvd_region[j+1].start) {
  15.166 +				struct rsvd_region tmp;
  15.167 +				tmp = rsvd_region[j];
  15.168 +				rsvd_region[j] = rsvd_region[j + 1];
  15.169 +				rsvd_region[j + 1] = tmp;
  15.170 +			}
  15.171 +		}
  15.172 +	}
  15.173 +}
  15.174 +
  15.175 +/**
  15.176 + * reserve_memory - setup reserved memory areas
  15.177 + *
  15.178 + * Setup the reserved memory areas set aside for the boot parameters,
  15.179 + * initrd, etc.  There are currently %IA64_MAX_RSVD_REGIONS defined,
  15.180 + * see include/asm-ia64/meminit.h if you need to define more.
  15.181 + */
  15.182 +void
  15.183 +reserve_memory (void)
  15.184 +{
  15.185 +	int n = 0;
  15.186 +
  15.187 +	/*
  15.188 +	 * none of the entries in this table overlap
  15.189 +	 */
  15.190 +	rsvd_region[n].start = (unsigned long) ia64_boot_param;
  15.191 +	rsvd_region[n].end   = rsvd_region[n].start + sizeof(*ia64_boot_param);
  15.192 +	n++;
  15.193 +
  15.194 +	rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->efi_memmap);
  15.195 +	rsvd_region[n].end   = rsvd_region[n].start + ia64_boot_param->efi_memmap_size;
  15.196 +	n++;
  15.197 +
  15.198 +	rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->command_line);
  15.199 +	rsvd_region[n].end   = (rsvd_region[n].start
  15.200 +				+ strlen(__va(ia64_boot_param->command_line)) + 1);
  15.201 +	n++;
  15.202 +
  15.203 +	rsvd_region[n].start = (unsigned long) ia64_imva((void *)KERNEL_START);
  15.204 +#ifdef XEN
  15.205 +	/* Reserve xen image/bitmap/xen-heap */
  15.206 +	rsvd_region[n].end   = rsvd_region[n].start + xenheap_size;
  15.207 +#else
  15.208 +	rsvd_region[n].end   = (unsigned long) ia64_imva(_end);
  15.209 +#endif
  15.210 +	n++;
  15.211 +
  15.212 +#ifdef CONFIG_BLK_DEV_INITRD
  15.213 +	if (ia64_boot_param->initrd_start) {
  15.214 +		rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
  15.215 +		rsvd_region[n].end   = rsvd_region[n].start + ia64_boot_param->initrd_size;
  15.216 +		n++;
  15.217 +	}
  15.218 +#endif
  15.219 +
  15.220 +	/* end of memory marker */
  15.221 +	rsvd_region[n].start = ~0UL;
  15.222 +	rsvd_region[n].end   = ~0UL;
  15.223 +	n++;
  15.224 +
  15.225 +	num_rsvd_regions = n;
  15.226 +
  15.227 +	sort_regions(rsvd_region, num_rsvd_regions);
  15.228 +}
  15.229 +
  15.230 +/**
  15.231 + * find_initrd - get initrd parameters from the boot parameter structure
  15.232 + *
  15.233 + * Grab the initrd start and end from the boot parameter struct given us by
  15.234 + * the boot loader.
  15.235 + */
  15.236 +void
  15.237 +find_initrd (void)
  15.238 +{
  15.239 +#ifdef CONFIG_BLK_DEV_INITRD
  15.240 +	if (ia64_boot_param->initrd_start) {
  15.241 +		initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
  15.242 +		initrd_end   = initrd_start+ia64_boot_param->initrd_size;
  15.243 +
  15.244 +		printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
  15.245 +		       initrd_start, ia64_boot_param->initrd_size);
  15.246 +	}
  15.247 +#endif
  15.248 +}
  15.249 +
  15.250 +static void __init
  15.251 +io_port_init (void)
  15.252 +{
  15.253 +	extern unsigned long ia64_iobase;
  15.254 +	unsigned long phys_iobase;
  15.255 +
  15.256 +	/*
  15.257 +	 *  Set `iobase' to the appropriate address in region 6 (uncached access range).
  15.258 +	 *
  15.259 +	 *  The EFI memory map is the "preferred" location to get the I/O port space base,
  15.260 +	 *  rather the relying on AR.KR0. This should become more clear in future SAL
  15.261 +	 *  specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
  15.262 +	 *  found in the memory map.
  15.263 +	 */
  15.264 +	phys_iobase = efi_get_iobase();
  15.265 +	if (phys_iobase)
  15.266 +		/* set AR.KR0 since this is all we use it for anyway */
  15.267 +		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
  15.268 +	else {
  15.269 +		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
  15.270 +		printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
  15.271 +		       "to AR.KR0\n");
  15.272 +		printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
  15.273 +	}
  15.274 +	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
  15.275 +
  15.276 +	/* setup legacy IO port space */
  15.277 +	io_space[0].mmio_base = ia64_iobase;
  15.278 +	io_space[0].sparse = 1;
  15.279 +	num_io_spaces = 1;
  15.280 +}
  15.281 +
  15.282 +/**
  15.283 + * early_console_setup - setup debugging console
  15.284 + *
  15.285 + * Consoles started here require little enough setup that we can start using
  15.286 + * them very early in the boot process, either right after the machine
  15.287 + * vector initialization, or even before if the drivers can detect their hw.
  15.288 + *
  15.289 + * Returns non-zero if a console couldn't be setup.
  15.290 + */
  15.291 +static inline int __init
  15.292 +early_console_setup (char *cmdline)
  15.293 +{
  15.294 +#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
  15.295 +	{
  15.296 +		extern int sn_serial_console_early_setup(void);
  15.297 +		if (!sn_serial_console_early_setup())
  15.298 +			return 0;
  15.299 +	}
  15.300 +#endif
  15.301 +#ifdef CONFIG_EFI_PCDP
  15.302 +	if (!efi_setup_pcdp_console(cmdline))
  15.303 +		return 0;
  15.304 +#endif
  15.305 +#ifdef CONFIG_SERIAL_8250_CONSOLE
  15.306 +	if (!early_serial_console_init(cmdline))
  15.307 +		return 0;
  15.308 +#endif
  15.309 +
  15.310 +	return -1;
  15.311 +}
  15.312 +
  15.313 +static inline void
  15.314 +mark_bsp_online (void)
  15.315 +{
  15.316 +#ifdef CONFIG_SMP
  15.317 +	/* If we register an early console, allow CPU 0 to printk */
  15.318 +	cpu_set(smp_processor_id(), cpu_online_map);
  15.319 +#endif
  15.320 +}
  15.321 +
  15.322 +void __init
  15.323 +#ifdef XEN
  15.324 +early_setup_arch (char **cmdline_p)
  15.325 +#else
  15.326 +setup_arch (char **cmdline_p)
  15.327 +#endif
  15.328 +{
  15.329 +	unw_init();
  15.330 +
  15.331 +	ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
  15.332 +
  15.333 +	*cmdline_p = __va(ia64_boot_param->command_line);
  15.334 +#ifdef XEN
  15.335 +	efi_init();
  15.336 +#else
  15.337 +	strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
  15.338 +
  15.339 +	efi_init();
  15.340 +	io_port_init();
  15.341 +#endif
  15.342 +
  15.343 +#ifdef CONFIG_IA64_GENERIC
  15.344 +	{
  15.345 +		const char *mvec_name = strstr (*cmdline_p, "machvec=");
  15.346 +		char str[64];
  15.347 +
  15.348 +		if (mvec_name) {
  15.349 +			const char *end;
  15.350 +			size_t len;
  15.351 +
  15.352 +			mvec_name += 8;
  15.353 +			end = strchr (mvec_name, ' ');
  15.354 +			if (end)
  15.355 +				len = end - mvec_name;
  15.356 +			else
  15.357 +				len = strlen (mvec_name);
  15.358 +			len = min(len, sizeof (str) - 1);
  15.359 +			strncpy (str, mvec_name, len);
  15.360 +			str[len] = '\0';
  15.361 +			mvec_name = str;
  15.362 +		} else
  15.363 +			mvec_name = acpi_get_sysname();
  15.364 +		machvec_init(mvec_name);
  15.365 +	}
  15.366 +#endif
  15.367 +
  15.368 +#ifdef XEN
  15.369 +	early_cmdline_parse(cmdline_p);
  15.370 +	cmdline_parse(*cmdline_p);
  15.371 +#undef CONFIG_ACPI_BOOT
  15.372 +#endif
  15.373 +	if (early_console_setup(*cmdline_p) == 0)
  15.374 +		mark_bsp_online();
  15.375 +
  15.376 +#ifdef CONFIG_ACPI_BOOT
  15.377 +	/* Initialize the ACPI boot-time table parser */
  15.378 +	acpi_table_init();
  15.379 +# ifdef CONFIG_ACPI_NUMA
  15.380 +	acpi_numa_init();
  15.381 +# endif
  15.382 +#else
  15.383 +# ifdef CONFIG_SMP
  15.384 +	smp_build_cpu_map();	/* happens, e.g., with the Ski simulator */
  15.385 +# endif
  15.386 +#endif /* CONFIG_APCI_BOOT */
  15.387 +
  15.388 +#ifndef XEN
  15.389 +	find_memory();
  15.390 +#else
  15.391 +	io_port_init();
  15.392 +}
  15.393 +
  15.394 +void __init
  15.395 +late_setup_arch (char **cmdline_p)
  15.396 +{
  15.397 +#undef CONFIG_ACPI_BOOT
  15.398 +	acpi_table_init();
  15.399 +#endif
  15.400 +	/* process SAL system table: */
  15.401 +	ia64_sal_init(efi.sal_systab);
  15.402 +
  15.403 +#ifdef CONFIG_SMP
  15.404 +	cpu_physical_id(0) = hard_smp_processor_id();
  15.405 +#endif
  15.406 +
  15.407 +#ifdef CONFIG_VTI
  15.408 +	identify_vmx_feature();
  15.409 +#endif // CONFIG_VTI
  15.410 +
  15.411 +	cpu_init();	/* initialize the bootstrap CPU */
  15.412 +
  15.413 +#ifdef CONFIG_ACPI_BOOT
  15.414 +	acpi_boot_init();
  15.415 +#endif
  15.416 +
  15.417 +#ifdef CONFIG_VT
  15.418 +	if (!conswitchp) {
  15.419 +# if defined(CONFIG_DUMMY_CONSOLE)
  15.420 +		conswitchp = &dummy_con;
  15.421 +# endif
  15.422 +# if defined(CONFIG_VGA_CONSOLE)
  15.423 +		/*
  15.424 +		 * Non-legacy systems may route legacy VGA MMIO range to system
  15.425 +		 * memory.  vga_con probes the MMIO hole, so memory looks like
  15.426 +		 * a VGA device to it.  The EFI memory map can tell us if it's
  15.427 +		 * memory so we can avoid this problem.
  15.428 +		 */
  15.429 +		if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY)
  15.430 +			conswitchp = &vga_con;
  15.431 +# endif
  15.432 +	}
  15.433 +#endif
  15.434 +
  15.435 +	/* enable IA-64 Machine Check Abort Handling unless disabled */
  15.436 +	if (!strstr(saved_command_line, "nomca"))
  15.437 +		ia64_mca_init();
  15.438 +
  15.439 +	platform_setup(cmdline_p);
  15.440 +	paging_init();
  15.441 +}
  15.442 +
  15.443 +/*
  15.444 + * Display cpu info for all cpu's.
  15.445 + */
  15.446 +static int
  15.447 +show_cpuinfo (struct seq_file *m, void *v)
  15.448 +{
  15.449 +#ifdef CONFIG_SMP
  15.450 +#	define lpj	c->loops_per_jiffy
  15.451 +#	define cpunum	c->cpu
  15.452 +#else
  15.453 +#	define lpj	loops_per_jiffy
  15.454 +#	define cpunum	0
  15.455 +#endif
  15.456 +	static struct {
  15.457 +		unsigned long mask;
  15.458 +		const char *feature_name;
  15.459 +	} feature_bits[] = {
  15.460 +		{ 1UL << 0, "branchlong" },
  15.461 +		{ 1UL << 1, "spontaneous deferral"},
  15.462 +		{ 1UL << 2, "16-byte atomic ops" }
  15.463 +	};
  15.464 +	char family[32], features[128], *cp, sep;
  15.465 +	struct cpuinfo_ia64 *c = v;
  15.466 +	unsigned long mask;
  15.467 +	int i;
  15.468 +
  15.469 +	mask = c->features;
  15.470 +
  15.471 +	switch (c->family) {
  15.472 +	      case 0x07:	memcpy(family, "Itanium", 8); break;
  15.473 +	      case 0x1f:	memcpy(family, "Itanium 2", 10); break;
  15.474 +	      default:		sprintf(family, "%u", c->family); break;
  15.475 +	}
  15.476 +
  15.477 +	/* build the feature string: */
  15.478 +	memcpy(features, " standard", 10);
  15.479 +	cp = features;
  15.480 +	sep = 0;
  15.481 +	for (i = 0; i < (int) ARRAY_SIZE(feature_bits); ++i) {
  15.482 +		if (mask & feature_bits[i].mask) {
  15.483 +			if (sep)
  15.484 +				*cp++ = sep;
  15.485 +			sep = ',';
  15.486 +			*cp++ = ' ';
  15.487 +			strcpy(cp, feature_bits[i].feature_name);
  15.488 +			cp += strlen(feature_bits[i].feature_name);
  15.489 +			mask &= ~feature_bits[i].mask;
  15.490 +		}
  15.491 +	}
  15.492 +	if (mask) {
  15.493 +		/* print unknown features as a hex value: */
  15.494 +		if (sep)
  15.495 +			*cp++ = sep;
  15.496 +		sprintf(cp, " 0x%lx", mask);
  15.497 +	}
  15.498 +
  15.499 +	seq_printf(m,
  15.500 +		   "processor  : %d\n"
  15.501 +		   "vendor     : %s\n"
  15.502 +		   "arch       : IA-64\n"
  15.503 +		   "family     : %s\n"
  15.504 +		   "model      : %u\n"
  15.505 +		   "revision   : %u\n"
  15.506 +		   "archrev    : %u\n"
  15.507 +		   "features   :%s\n"	/* don't change this---it _is_ right! */
  15.508 +		   "cpu number : %lu\n"
  15.509 +		   "cpu regs   : %u\n"
  15.510 +		   "cpu MHz    : %lu.%06lu\n"
  15.511 +		   "itc MHz    : %lu.%06lu\n"
  15.512 +		   "BogoMIPS   : %lu.%02lu\n\n",
  15.513 +		   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
  15.514 +		   features, c->ppn, c->number,
  15.515 +		   c->proc_freq / 1000000, c->proc_freq % 1000000,
  15.516 +		   c->itc_freq / 1000000, c->itc_freq % 1000000,
  15.517 +		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
  15.518 +	return 0;
  15.519 +}
  15.520 +
  15.521 +static void *
  15.522 +c_start (struct seq_file *m, loff_t *pos)
  15.523 +{
  15.524 +#ifdef CONFIG_SMP
  15.525 +	while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
  15.526 +		++*pos;
  15.527 +#endif
  15.528 +	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
  15.529 +}
  15.530 +
  15.531 +static void *
  15.532 +c_next (struct seq_file *m, void *v, loff_t *pos)
  15.533 +{
  15.534 +	++*pos;
  15.535 +	return c_start(m, pos);
  15.536 +}
  15.537 +
  15.538 +static void
  15.539 +c_stop (struct seq_file *m, void *v)
  15.540 +{
  15.541 +}
  15.542 +
  15.543 +#ifndef XEN
  15.544 +struct seq_operations cpuinfo_op = {
  15.545 +	.start =	c_start,
  15.546 +	.next =		c_next,
  15.547 +	.stop =		c_stop,
  15.548 +	.show =		show_cpuinfo
  15.549 +};
  15.550 +#endif
  15.551 +
  15.552 +void
  15.553 +identify_cpu (struct cpuinfo_ia64 *c)
  15.554 +{
  15.555 +	union {
  15.556 +		unsigned long bits[5];
  15.557 +		struct {
  15.558 +			/* id 0 & 1: */
  15.559 +			char vendor[16];
  15.560 +
  15.561 +			/* id 2 */
  15.562 +			u64 ppn;		/* processor serial number */
  15.563 +
  15.564 +			/* id 3: */
  15.565 +			unsigned number		:  8;
  15.566 +			unsigned revision	:  8;
  15.567 +			unsigned model		:  8;
  15.568 +			unsigned family		:  8;
  15.569 +			unsigned archrev	:  8;
  15.570 +			unsigned reserved	: 24;
  15.571 +
  15.572 +			/* id 4: */
  15.573 +			u64 features;
  15.574 +		} field;
  15.575 +	} cpuid;
  15.576 +	pal_vm_info_1_u_t vm1;
  15.577 +	pal_vm_info_2_u_t vm2;
  15.578 +	pal_status_t status;
  15.579 +	unsigned long impl_va_msb = 50, phys_addr_size = 44;	/* Itanium defaults */
  15.580 +	int i;
  15.581 +
  15.582 +	for (i = 0; i < 5; ++i)
  15.583 +		cpuid.bits[i] = ia64_get_cpuid(i);
  15.584 +
  15.585 +	memcpy(c->vendor, cpuid.field.vendor, 16);
  15.586 +#ifdef CONFIG_SMP
  15.587 +	c->cpu = smp_processor_id();
  15.588 +#endif
  15.589 +	c->ppn = cpuid.field.ppn;
  15.590 +	c->number = cpuid.field.number;
  15.591 +	c->revision = cpuid.field.revision;
  15.592 +	c->model = cpuid.field.model;
  15.593 +	c->family = cpuid.field.family;
  15.594 +	c->archrev = cpuid.field.archrev;
  15.595 +	c->features = cpuid.field.features;
  15.596 +
  15.597 +	status = ia64_pal_vm_summary(&vm1, &vm2);
  15.598 +	if (status == PAL_STATUS_SUCCESS) {
  15.599 +		impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
  15.600 +		phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
  15.601 +	}
  15.602 +	c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
  15.603 +	c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
  15.604 +
  15.605 +#ifdef CONFIG_VTI
  15.606 +	/* If vmx feature is on, do necessary initialization for vmx */
  15.607 +	if (vmx_enabled)
  15.608 +		vmx_init_env();
  15.609 +#endif
  15.610 +}
  15.611 +
  15.612 +void
  15.613 +setup_per_cpu_areas (void)
  15.614 +{
  15.615 +	/* start_kernel() requires this... */
  15.616 +}
  15.617 +
  15.618 +static void
  15.619 +get_max_cacheline_size (void)
  15.620 +{
  15.621 +	unsigned long line_size, max = 1;
  15.622 +	u64 l, levels, unique_caches;
  15.623 +        pal_cache_config_info_t cci;
  15.624 +        s64 status;
  15.625 +
  15.626 +        status = ia64_pal_cache_summary(&levels, &unique_caches);
  15.627 +        if (status != 0) {
  15.628 +                printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
  15.629 +                       __FUNCTION__, status);
  15.630 +                max = SMP_CACHE_BYTES;
  15.631 +		goto out;
  15.632 +        }
  15.633 +
  15.634 +	for (l = 0; l < levels; ++l) {
  15.635 +		status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2,
  15.636 +						    &cci);
  15.637 +		if (status != 0) {
  15.638 +			printk(KERN_ERR
  15.639 +			       "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",
  15.640 +			       __FUNCTION__, l, status);
  15.641 +			max = SMP_CACHE_BYTES;
  15.642 +		}
  15.643 +		line_size = 1 << cci.pcci_line_size;
  15.644 +		if (line_size > max)
  15.645 +			max = line_size;
  15.646 +        }
  15.647 +  out:
  15.648 +	if (max > ia64_max_cacheline_size)
  15.649 +		ia64_max_cacheline_size = max;
  15.650 +}
  15.651 +
  15.652 +/*
  15.653 + * cpu_init() initializes state that is per-CPU.  This function acts
  15.654 + * as a 'CPU state barrier', nothing should get across.
  15.655 + */
  15.656 +void
  15.657 +cpu_init (void)
  15.658 +{
  15.659 +	extern void __devinit ia64_mmu_init (void *);
  15.660 +	unsigned long num_phys_stacked;
  15.661 +	pal_vm_info_2_u_t vmi;
  15.662 +	unsigned int max_ctx;
  15.663 +	struct cpuinfo_ia64 *cpu_info;
  15.664 +	void *cpu_data;
  15.665 +
  15.666 +	cpu_data = per_cpu_init();
  15.667 +
  15.668 +	/*
  15.669 +	 * We set ar.k3 so that assembly code in MCA handler can compute
  15.670 +	 * physical addresses of per cpu variables with a simple:
  15.671 +	 *   phys = ar.k3 + &per_cpu_var
  15.672 +	 */
  15.673 +	ia64_set_kr(IA64_KR_PER_CPU_DATA,
  15.674 +		    ia64_tpa(cpu_data) - (long) __per_cpu_start);
  15.675 +
  15.676 +	get_max_cacheline_size();
  15.677 +
  15.678 +	/*
  15.679 +	 * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
  15.680 +	 * ia64_mmu_init() yet.  And we can't call ia64_mmu_init() first because it
  15.681 +	 * depends on the data returned by identify_cpu().  We break the dependency by
  15.682 +	 * accessing cpu_data() through the canonical per-CPU address.
  15.683 +	 */
  15.684 +	cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start);
  15.685 +	identify_cpu(cpu_info);
  15.686 +
  15.687 +#ifdef CONFIG_MCKINLEY
  15.688 +	{
  15.689 +#		define FEATURE_SET 16
  15.690 +		struct ia64_pal_retval iprv;
  15.691 +
  15.692 +		if (cpu_info->family == 0x1f) {
  15.693 +			PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0);
  15.694 +			if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80))
  15.695 +				PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES,
  15.696 +				              (iprv.v1 | 0x80), FEATURE_SET, 0);
  15.697 +		}
  15.698 +	}
  15.699 +#endif
  15.700 +
  15.701 +	/* Clear the stack memory reserved for pt_regs: */
  15.702 +	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
  15.703 +
  15.704 +	ia64_set_kr(IA64_KR_FPU_OWNER, 0);
  15.705 +
  15.706 +	/*
  15.707 +	 * Initialize default control register to defer all speculative faults.  The
  15.708 +	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
  15.709 +	 * the kernel must have recovery code for all speculative accesses).  Turn on
  15.710 +	 * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps
  15.711 +	 * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
  15.712 +	 * be fine).
  15.713 +	 */
  15.714 +	ia64_setreg(_IA64_REG_CR_DCR,  (  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
  15.715 +					| IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
  15.716 +	atomic_inc(&init_mm.mm_count);
  15.717 +	current->active_mm = &init_mm;
  15.718 +#ifdef XEN
  15.719 +	if (current->domain->arch.mm)
  15.720 +#else
  15.721 +	if (current->mm)
  15.722 +#endif
  15.723 +		BUG();
  15.724 +
  15.725 +	ia64_mmu_init(ia64_imva(cpu_data));
  15.726 +	ia64_mca_cpu_init(ia64_imva(cpu_data));
  15.727 +
  15.728 +#ifdef CONFIG_IA32_SUPPORT
  15.729 +	ia32_cpu_init();
  15.730 +#endif
  15.731 +
  15.732 +	/* Clear ITC to eliminiate sched_clock() overflows in human time.  */
  15.733 +	ia64_set_itc(0);
  15.734 +
  15.735 +	/* disable all local interrupt sources: */
  15.736 +	ia64_set_itv(1 << 16);
  15.737 +	ia64_set_lrr0(1 << 16);
  15.738 +	ia64_set_lrr1(1 << 16);
  15.739 +	ia64_setreg(_IA64_REG_CR_PMV, 1 << 16);
  15.740 +	ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16);
  15.741 +
  15.742 +	/* clear TPR & XTP to enable all interrupt classes: */
  15.743 +	ia64_setreg(_IA64_REG_CR_TPR, 0);
  15.744 +#ifdef CONFIG_SMP
  15.745 +	normal_xtp();
  15.746 +#endif
  15.747 +
  15.748 +	/* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */
  15.749 +	if (ia64_pal_vm_summary(NULL, &vmi) == 0)
  15.750 +		max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
  15.751 +	else {
  15.752 +		printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
  15.753 +		max_ctx = (1U << 15) - 1;	/* use architected minimum */
  15.754 +	}
  15.755 +	while (max_ctx < ia64_ctx.max_ctx) {
  15.756 +		unsigned int old = ia64_ctx.max_ctx;
  15.757 +		if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old)
  15.758 +			break;
  15.759 +	}
  15.760 +
  15.761 +	if (ia64_pal_rse_info(&num_phys_stacked, NULL) != 0) {
  15.762 +		printk(KERN_WARNING "cpu_init: PAL RSE info failed; assuming 96 physical "
  15.763 +		       "stacked regs\n");
  15.764 +		num_phys_stacked = 96;
  15.765 +	}
  15.766 +	/* size of physical stacked register partition plus 8 bytes: */
  15.767 +	__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
  15.768 +	platform_cpu_init();
  15.769 +}
  15.770 +
  15.771 +void
  15.772 +check_bugs (void)
  15.773 +{
  15.774 +	ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
  15.775 +			       (unsigned long) __end___mckinley_e9_bundles);
  15.776 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/arch/ia64/linux-xen/time.c	Tue Aug 02 16:25:11 2005 -0800
    16.3 @@ -0,0 +1,264 @@
    16.4 +/*
    16.5 + * linux/arch/ia64/kernel/time.c
    16.6 + *
    16.7 + * Copyright (C) 1998-2003 Hewlett-Packard Co
    16.8 + *	Stephane Eranian <eranian@hpl.hp.com>
    16.9 + *	David Mosberger <davidm@hpl.hp.com>
   16.10 + * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
   16.11 + * Copyright (C) 1999-2000 VA Linux Systems
   16.12 + * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
   16.13 + */
   16.14 +#include <linux/config.h>
   16.15 +
   16.16 +#include <linux/cpu.h>
   16.17 +#include <linux/init.h>
   16.18 +#include <linux/kernel.h>
   16.19 +#include <linux/module.h>
   16.20 +#include <linux/profile.h>
   16.21 +#include <linux/sched.h>
   16.22 +#include <linux/time.h>
   16.23 +#include <linux/interrupt.h>
   16.24 +#include <linux/efi.h>
   16.25 +#include <linux/profile.h>
   16.26 +#include <linux/timex.h>
   16.27 +
   16.28 +#include <asm/machvec.h>
   16.29 +#include <asm/delay.h>
   16.30 +#include <asm/hw_irq.h>
   16.31 +#include <asm/ptrace.h>
   16.32 +#include <asm/sal.h>
   16.33 +#include <asm/sections.h>
   16.34 +#include <asm/system.h>
   16.35 +#ifdef XEN
   16.36 +#include <linux/jiffies.h>	// not included by xen/sched.h
   16.37 +#endif
   16.38 +
   16.39 +extern unsigned long wall_jiffies;
   16.40 +
   16.41 +u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
   16.42 +
   16.43 +EXPORT_SYMBOL(jiffies_64);
   16.44 +
   16.45 +#define TIME_KEEPER_ID	0	/* smp_processor_id() of time-keeper */
   16.46 +
   16.47 +#ifdef CONFIG_IA64_DEBUG_IRQ
   16.48 +
   16.49 +unsigned long last_cli_ip;
   16.50 +EXPORT_SYMBOL(last_cli_ip);
   16.51 +
   16.52 +#endif
   16.53 +
   16.54 +#ifndef XEN
   16.55 +static struct time_interpolator itc_interpolator = {
   16.56 +	.shift = 16,
   16.57 +	.mask = 0xffffffffffffffffLL,
   16.58 +	.source = TIME_SOURCE_CPU
   16.59 +};
   16.60 +
   16.61 +static irqreturn_t
   16.62 +timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
   16.63 +{
   16.64 +	unsigned long new_itm;
   16.65 +
   16.66 +	if (unlikely(cpu_is_offline(smp_processor_id()))) {
   16.67 +		return IRQ_HANDLED;
   16.68 +	}
   16.69 +
   16.70 +	platform_timer_interrupt(irq, dev_id, regs);
   16.71 +
   16.72 +	new_itm = local_cpu_data->itm_next;
   16.73 +
   16.74 +	if (!time_after(ia64_get_itc(), new_itm))
   16.75 +		printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
   16.76 +		       ia64_get_itc(), new_itm);
   16.77 +
   16.78 +	profile_tick(CPU_PROFILING, regs);
   16.79 +
   16.80 +	while (1) {
   16.81 +		update_process_times(user_mode(regs));
   16.82 +
   16.83 +		new_itm += local_cpu_data->itm_delta;
   16.84 +
   16.85 +		if (smp_processor_id() == TIME_KEEPER_ID) {
   16.86 +			/*
   16.87 +			 * Here we are in the timer irq handler. We have irqs locally
   16.88 +			 * disabled, but we don't know if the timer_bh is running on
   16.89 +			 * another CPU. We need to avoid to SMP race by acquiring the
   16.90 +			 * xtime_lock.
   16.91 +			 */
   16.92 +			write_seqlock(&xtime_lock);
   16.93 +			do_timer(regs);
   16.94 +			local_cpu_data->itm_next = new_itm;
   16.95 +			write_sequnlock(&xtime_lock);
   16.96 +		} else
   16.97 +			local_cpu_data->itm_next = new_itm;
   16.98 +
   16.99 +		if (time_after(new_itm, ia64_get_itc()))
  16.100 +			break;
  16.101 +	}
  16.102 +
  16.103 +	do {
  16.104 +		/*
  16.105 +		 * If we're too close to the next clock tick for
  16.106 +		 * comfort, we increase the safety margin by
  16.107 +		 * intentionally dropping the next tick(s).  We do NOT
  16.108 +		 * update itm.next because that would force us to call
  16.109 +		 * do_timer() which in turn would let our clock run
  16.110 +		 * too fast (with the potentially devastating effect
  16.111 +		 * of losing monotony of time).
  16.112 +		 */
  16.113 +		while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2))
  16.114 +			new_itm += local_cpu_data->itm_delta;
  16.115 +		ia64_set_itm(new_itm);
  16.116 +		/* double check, in case we got hit by a (slow) PMI: */
  16.117 +	} while (time_after_eq(ia64_get_itc(), new_itm));
  16.118 +	return IRQ_HANDLED;
  16.119 +}
  16.120 +#endif
  16.121 +
  16.122 +/*
  16.123 + * Encapsulate access to the itm structure for SMP.
  16.124 + */
  16.125 +void
  16.126 +ia64_cpu_local_tick (void)
  16.127 +{
  16.128 +	int cpu = smp_processor_id();
  16.129 +	unsigned long shift = 0, delta;
  16.130 +
  16.131 +	/* arrange for the cycle counter to generate a timer interrupt: */
  16.132 +	ia64_set_itv(IA64_TIMER_VECTOR);
  16.133 +
  16.134 +	delta = local_cpu_data->itm_delta;
  16.135 +	/*
  16.136 +	 * Stagger the timer tick for each CPU so they don't occur all at (almost) the
  16.137 +	 * same time:
  16.138 +	 */
  16.139 +	if (cpu) {
  16.140 +		unsigned long hi = 1UL << ia64_fls(cpu);
  16.141 +		shift = (2*(cpu - hi) + 1) * delta/hi/2;
  16.142 +	}
  16.143 +	local_cpu_data->itm_next = ia64_get_itc() + delta + shift;
  16.144 +	ia64_set_itm(local_cpu_data->itm_next);
  16.145 +}
  16.146 +
  16.147 +static int nojitter;
  16.148 +
  16.149 +static int __init nojitter_setup(char *str)
  16.150 +{
  16.151 +	nojitter = 1;
  16.152 +	printk("Jitter checking for ITC timers disabled\n");
  16.153 +	return 1;
  16.154 +}
  16.155 +
  16.156 +__setup("nojitter", nojitter_setup);
  16.157 +
  16.158 +
  16.159 +void __devinit
  16.160 +ia64_init_itm (void)
  16.161 +{
  16.162 +	unsigned long platform_base_freq, itc_freq;
  16.163 +	struct pal_freq_ratio itc_ratio, proc_ratio;
  16.164 +	long status, platform_base_drift, itc_drift;
  16.165 +
  16.166 +	/*
  16.167 +	 * According to SAL v2.6, we need to use a SAL call to determine the platform base
  16.168 +	 * frequency and then a PAL call to determine the frequency ratio between the ITC
  16.169 +	 * and the base frequency.
  16.170 +	 */
  16.171 +	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
  16.172 +				    &platform_base_freq, &platform_base_drift);
  16.173 +	if (status != 0) {
  16.174 +		printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
  16.175 +	} else {
  16.176 +		status = ia64_pal_freq_ratios(&proc_ratio, NULL, &itc_ratio);
  16.177 +		if (status != 0)
  16.178 +			printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status);
  16.179 +	}
  16.180 +	if (status != 0) {
  16.181 +		/* invent "random" values */
  16.182 +		printk(KERN_ERR
  16.183 +		       "SAL/PAL failed to obtain frequency info---inventing reasonable values\n");
  16.184 +		platform_base_freq = 100000000;
  16.185 +		platform_base_drift = -1;	/* no drift info */
  16.186 +		itc_ratio.num = 3;
  16.187 +		itc_ratio.den = 1;
  16.188 +	}
  16.189 +	if (platform_base_freq < 40000000) {
  16.190 +		printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
  16.191 +		       platform_base_freq);
  16.192 +		platform_base_freq = 75000000;
  16.193 +		platform_base_drift = -1;
  16.194 +	}
  16.195 +	if (!proc_ratio.den)
  16.196 +		proc_ratio.den = 1;	/* avoid division by zero */
  16.197 +	if (!itc_ratio.den)
  16.198 +		itc_ratio.den = 1;	/* avoid division by zero */
  16.199 +
  16.200 +	itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
  16.201 +
  16.202 +	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
  16.203 +	printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
  16.204 +	       "ITC freq=%lu.%03luMHz", smp_processor_id(),
  16.205 +	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
  16.206 +	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
  16.207 +
  16.208 +	if (platform_base_drift != -1) {
  16.209 +		itc_drift = platform_base_drift*itc_ratio.num/itc_ratio.den;
  16.210 +		printk("+/-%ldppm\n", itc_drift);
  16.211 +	} else {
  16.212 +		itc_drift = -1;
  16.213 +		printk("\n");
  16.214 +	}
  16.215 +
  16.216 +	local_cpu_data->proc_freq = (platform_base_freq*proc_ratio.num)/proc_ratio.den;
  16.217 +	local_cpu_data->itc_freq = itc_freq;
  16.218 +	local_cpu_data->cyc_per_usec = (itc_freq + USEC_PER_SEC/2) / USEC_PER_SEC;
  16.219 +	local_cpu_data->nsec_per_cyc = ((NSEC_PER_SEC<<IA64_NSEC_PER_CYC_SHIFT)
  16.220 +					+ itc_freq/2)/itc_freq;
  16.221 +
  16.222 +	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
  16.223 +#ifndef XEN
  16.224 +		itc_interpolator.frequency = local_cpu_data->itc_freq;
  16.225 +		itc_interpolator.drift = itc_drift;
  16.226 +#ifdef CONFIG_SMP
  16.227 +		/* On IA64 in an SMP configuration ITCs are never accurately synchronized.
  16.228 +		 * Jitter compensation requires a cmpxchg which may limit
  16.229 +		 * the scalability of the syscalls for retrieving time.
  16.230 +		 * The ITC synchronization is usually successful to within a few
  16.231 +		 * ITC ticks but this is not a sure thing. If you need to improve
  16.232 +		 * timer performance in SMP situations then boot the kernel with the
  16.233 +		 * "nojitter" option. However, doing so may result in time fluctuating (maybe
  16.234 +		 * even going backward) if the ITC offsets between the individual CPUs
  16.235 +		 * are too large.
  16.236 +		 */
  16.237 +		if (!nojitter) itc_interpolator.jitter = 1;
  16.238 +#endif
  16.239 +		register_time_interpolator(&itc_interpolator);
  16.240 +#endif
  16.241 +	}
  16.242 +
  16.243 +	/* Setup the CPU local timer tick */
  16.244 +	ia64_cpu_local_tick();
  16.245 +}
  16.246 +
  16.247 +#ifndef XEN
  16.248 +static struct irqaction timer_irqaction = {
  16.249 +	.handler =	timer_interrupt,
  16.250 +	.flags =	SA_INTERRUPT,
  16.251 +	.name =		"timer"
  16.252 +};
  16.253 +
  16.254 +void __init
  16.255 +time_init (void)
  16.256 +{
  16.257 +	register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
  16.258 +	efi_gettimeofday(&xtime);
  16.259 +	ia64_init_itm();
  16.260 +
  16.261 +	/*
  16.262 +	 * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
  16.263 +	 * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
  16.264 +	 */
  16.265 +	set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
  16.266 +}
  16.267 +#endif
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/arch/ia64/linux-xen/tlb.c	Tue Aug 02 16:25:11 2005 -0800
    17.3 @@ -0,0 +1,199 @@
    17.4 +/*
    17.5 + * TLB support routines.
    17.6 + *
    17.7 + * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
    17.8 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    17.9 + *
   17.10 + * 08/02/00 A. Mallick <asit.k.mallick@intel.com>
   17.11 + *		Modified RID allocation for SMP
   17.12 + *          Goutham Rao <goutham.rao@intel.com>
   17.13 + *              IPI based ptc implementation and A-step IPI implementation.
   17.14 + */
   17.15 +#include <linux/config.h>
   17.16 +#include <linux/module.h>
   17.17 +#include <linux/init.h>
   17.18 +#include <linux/kernel.h>
   17.19 +#include <linux/sched.h>
   17.20 +#include <linux/smp.h>
   17.21 +#include <linux/mm.h>
   17.22 +
   17.23 +#include <asm/delay.h>
   17.24 +#include <asm/mmu_context.h>
   17.25 +#include <asm/pgalloc.h>
   17.26 +#include <asm/pal.h>
   17.27 +#include <asm/tlbflush.h>
   17.28 +
   17.29 +static struct {
   17.30 +	unsigned long mask;	/* mask of supported purge page-sizes */
   17.31 +	unsigned long max_bits;	/* log2() of largest supported purge page-size */
   17.32 +} purge;
   17.33 +
   17.34 +struct ia64_ctx ia64_ctx = {
   17.35 +	.lock =		SPIN_LOCK_UNLOCKED,
   17.36 +	.next =		1,
   17.37 +	.limit =	(1 << 15) - 1,		/* start out with the safe (architected) limit */
   17.38 +	.max_ctx =	~0U
   17.39 +};
   17.40 +
   17.41 +DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
   17.42 +
   17.43 +/*
   17.44 + * Acquire the ia64_ctx.lock before calling this function!
   17.45 + */
   17.46 +void
   17.47 +wrap_mmu_context (struct mm_struct *mm)
   17.48 +{
   17.49 +#ifdef XEN
   17.50 +printf("wrap_mmu_context: called, not implemented\n");
   17.51 +#else
   17.52 +	unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
   17.53 +	struct task_struct *tsk;
   17.54 +	int i;
   17.55 +
   17.56 +	if (ia64_ctx.next > max_ctx)
   17.57 +		ia64_ctx.next = 300;	/* skip daemons */
   17.58 +	ia64_ctx.limit = max_ctx + 1;
   17.59 +
   17.60 +	/*
   17.61 +	 * Scan all the task's mm->context and set proper safe range
   17.62 +	 */
   17.63 +
   17.64 +	read_lock(&tasklist_lock);
   17.65 +  repeat:
   17.66 +	for_each_process(tsk) {
   17.67 +		if (!tsk->mm)
   17.68 +			continue;
   17.69 +		tsk_context = tsk->mm->context;
   17.70 +		if (tsk_context == ia64_ctx.next) {
   17.71 +			if (++ia64_ctx.next >= ia64_ctx.limit) {
   17.72 +				/* empty range: reset the range limit and start over */
   17.73 +				if (ia64_ctx.next > max_ctx)
   17.74 +					ia64_ctx.next = 300;
   17.75 +				ia64_ctx.limit = max_ctx + 1;
   17.76 +				goto repeat;
   17.77 +			}
   17.78 +		}
   17.79 +		if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
   17.80 +			ia64_ctx.limit = tsk_context;
   17.81 +	}
   17.82 +	read_unlock(&tasklist_lock);
   17.83 +	/* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
   17.84 +	{
   17.85 +		int cpu = get_cpu(); /* prevent preemption/migration */
   17.86 +		for (i = 0; i < NR_CPUS; ++i)
   17.87 +			if (cpu_online(i) && (i != cpu))
   17.88 +				per_cpu(ia64_need_tlb_flush, i) = 1;
   17.89 +		put_cpu();
   17.90 +	}
   17.91 +	local_flush_tlb_all();
   17.92 +#endif
   17.93 +}
   17.94 +
   17.95 +void
   17.96 +ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
   17.97 +{
   17.98 +	static DEFINE_SPINLOCK(ptcg_lock);
   17.99 +
  17.100 +	/* HW requires global serialization of ptc.ga.  */
  17.101 +	spin_lock(&ptcg_lock);
  17.102 +	{
  17.103 +		do {
  17.104 +			/*
  17.105 +			 * Flush ALAT entries also.
  17.106 +			 */
  17.107 +			ia64_ptcga(start, (nbits<<2));
  17.108 +			ia64_srlz_i();
  17.109 +			start += (1UL << nbits);
  17.110 +		} while (start < end);
  17.111 +	}
  17.112 +	spin_unlock(&ptcg_lock);
  17.113 +}
  17.114 +
  17.115 +void
  17.116 +local_flush_tlb_all (void)
  17.117 +{
  17.118 +	unsigned long i, j, flags, count0, count1, stride0, stride1, addr;
  17.119 +
  17.120 +	addr    = local_cpu_data->ptce_base;
  17.121 +	count0  = local_cpu_data->ptce_count[0];
  17.122 +	count1  = local_cpu_data->ptce_count[1];
  17.123 +	stride0 = local_cpu_data->ptce_stride[0];
  17.124 +	stride1 = local_cpu_data->ptce_stride[1];
  17.125 +
  17.126 +	local_irq_save(flags);
  17.127 +	for (i = 0; i < count0; ++i) {
  17.128 +		for (j = 0; j < count1; ++j) {
  17.129 +			ia64_ptce(addr);
  17.130 +			addr += stride1;
  17.131 +		}
  17.132 +		addr += stride0;
  17.133 +	}
  17.134 +	local_irq_restore(flags);
  17.135 +	ia64_srlz_i();			/* srlz.i implies srlz.d */
  17.136 +}
  17.137 +EXPORT_SYMBOL(local_flush_tlb_all);
  17.138 +
  17.139 +void
  17.140 +flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end)
  17.141 +{
  17.142 +#ifdef XEN
  17.143 +printf("flush_tlb_range: called, not implemented\n");
  17.144 +#else
  17.145 +	struct mm_struct *mm = vma->vm_mm;
  17.146 +	unsigned long size = end - start;
  17.147 +	unsigned long nbits;
  17.148 +
  17.149 +	if (mm != current->active_mm) {
  17.150 +		/* this does happen, but perhaps it's not worth optimizing for? */
  17.151 +#ifdef CONFIG_SMP
  17.152 +		flush_tlb_all();
  17.153 +#else
  17.154 +		mm->context = 0;
  17.155 +#endif
  17.156 +		return;
  17.157 +	}
  17.158 +
  17.159 +	nbits = ia64_fls(size + 0xfff);
  17.160 +	while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
  17.161 +		++nbits;
  17.162 +	if (nbits > purge.max_bits)
  17.163 +		nbits = purge.max_bits;
  17.164 +	start &= ~((1UL << nbits) - 1);
  17.165 +
  17.166 +# ifdef CONFIG_SMP
  17.167 +	platform_global_tlb_purge(start, end, nbits);
  17.168 +# else
  17.169 +	do {
  17.170 +		ia64_ptcl(start, (nbits<<2));
  17.171 +		start += (1UL << nbits);
  17.172 +	} while (start < end);
  17.173 +# endif
  17.174 +
  17.175 +	ia64_srlz_i();			/* srlz.i implies srlz.d */
  17.176 +#endif
  17.177 +}
  17.178 +EXPORT_SYMBOL(flush_tlb_range);
  17.179 +
  17.180 +void __devinit
  17.181 +ia64_tlb_init (void)
  17.182 +{
  17.183 +	ia64_ptce_info_t ptce_info;
  17.184 +	unsigned long tr_pgbits;
  17.185 +	long status;
  17.186 +
  17.187 +	if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
  17.188 +		printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;"
  17.189 +		       "defaulting to architected purge page-sizes.\n", status);
  17.190 +		purge.mask = 0x115557000UL;
  17.191 +	}
  17.192 +	purge.max_bits = ia64_fls(purge.mask);
  17.193 +
  17.194 +	ia64_get_ptce(&ptce_info);
  17.195 +	local_cpu_data->ptce_base = ptce_info.base;
  17.196 +	local_cpu_data->ptce_count[0] = ptce_info.count[0];
  17.197 +	local_cpu_data->ptce_count[1] = ptce_info.count[1];
  17.198 +	local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
  17.199 +	local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
  17.200 +
  17.201 +	local_flush_tlb_all();		/* nuke left overs from bootstrapping... */
  17.202 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/xen/arch/ia64/linux-xen/unaligned.c	Tue Aug 02 16:25:11 2005 -0800
    18.3 @@ -0,0 +1,1653 @@
    18.4 +/*
    18.5 + * Architecture-specific unaligned trap handling.
    18.6 + *
    18.7 + * Copyright (C) 1999-2002, 2004 Hewlett-Packard Co
    18.8 + *	Stephane Eranian <eranian@hpl.hp.com>
    18.9 + *	David Mosberger-Tang <davidm@hpl.hp.com>
   18.10 + *
   18.11 + * 2002/12/09   Fix rotating register handling (off-by-1 error, missing fr-rotation).  Fix
   18.12 + *		get_rse_reg() to not leak kernel bits to user-level (reading an out-of-frame
   18.13 + *		stacked register returns an undefined value; it does NOT trigger a
   18.14 + *		"rsvd register fault").
   18.15 + * 2001/10/11	Fix unaligned access to rotating registers in s/w pipelined loops.
   18.16 + * 2001/08/13	Correct size of extended floats (float_fsz) from 16 to 10 bytes.
   18.17 + * 2001/01/17	Add support emulation of unaligned kernel accesses.
   18.18 + */
   18.19 +#include <linux/kernel.h>
   18.20 +#include <linux/sched.h>
   18.21 +#include <linux/smp_lock.h>
   18.22 +#include <linux/tty.h>
   18.23 +
   18.24 +#include <asm/intrinsics.h>
   18.25 +#include <asm/processor.h>
   18.26 +#include <asm/rse.h>
   18.27 +#include <asm/uaccess.h>
   18.28 +#include <asm/unaligned.h>
   18.29 +
   18.30 +extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
   18.31 +
   18.32 +#undef DEBUG_UNALIGNED_TRAP
   18.33 +
   18.34 +#ifdef DEBUG_UNALIGNED_TRAP
   18.35 +# define DPRINT(a...)	do { printk("%s %u: ", __FUNCTION__, __LINE__); printk (a); } while (0)
   18.36 +# define DDUMP(str,vp,len)	dump(str, vp, len)
   18.37 +
   18.38 +static void
   18.39 +dump (const char *str, void *vp, size_t len)
   18.40 +{
   18.41 +	unsigned char *cp = vp;
   18.42 +	int i;
   18.43 +
   18.44 +	printk("%s", str);
   18.45 +	for (i = 0; i < len; ++i)
   18.46 +		printk (" %02x", *cp++);
   18.47 +	printk("\n");
   18.48 +}
   18.49 +#else
   18.50 +# define DPRINT(a...)
   18.51 +# define DDUMP(str,vp,len)
   18.52 +#endif
   18.53 +
   18.54 +#define IA64_FIRST_STACKED_GR	32
   18.55 +#define IA64_FIRST_ROTATING_FR	32
   18.56 +#define SIGN_EXT9		0xffffffffffffff00ul
   18.57 +
   18.58 +/*
   18.59 + * For M-unit:
   18.60 + *
   18.61 + *  opcode |   m  |   x6    |
   18.62 + * --------|------|---------|
   18.63 + * [40-37] | [36] | [35:30] |
   18.64 + * --------|------|---------|
   18.65 + *     4   |   1  |    6    | = 11 bits
   18.66 + * --------------------------
   18.67 + * However bits [31:30] are not directly useful to distinguish between
   18.68 + * load/store so we can use [35:32] instead, which gives the following
   18.69 + * mask ([40:32]) using 9 bits. The 'e' comes from the fact that we defer
   18.70 + * checking the m-bit until later in the load/store emulation.
   18.71 + */
   18.72 +#define IA64_OPCODE_MASK	0x1ef
   18.73 +#define IA64_OPCODE_SHIFT	32
   18.74 +
   18.75 +/*
   18.76 + * Table C-28 Integer Load/Store
   18.77 + *
   18.78 + * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
   18.79 + *
   18.80 + * ld8.fill, st8.fill  MUST be aligned because the RNATs are based on
   18.81 + * the address (bits [8:3]), so we must failed.
   18.82 + */
   18.83 +#define LD_OP            0x080
   18.84 +#define LDS_OP           0x081
   18.85 +#define LDA_OP           0x082
   18.86 +#define LDSA_OP          0x083
   18.87 +#define LDBIAS_OP        0x084
   18.88 +#define LDACQ_OP         0x085
   18.89 +/* 0x086, 0x087 are not relevant */
   18.90 +#define LDCCLR_OP        0x088
   18.91 +#define LDCNC_OP         0x089
   18.92 +#define LDCCLRACQ_OP     0x08a
   18.93 +#define ST_OP            0x08c
   18.94 +#define STREL_OP         0x08d
   18.95 +/* 0x08e,0x8f are not relevant */
   18.96 +
   18.97 +/*
   18.98 + * Table C-29 Integer Load +Reg
   18.99 + *
  18.100 + * we use the ld->m (bit [36:36]) field to determine whether or not we have
  18.101 + * a load/store of this form.
  18.102 + */
  18.103 +
  18.104 +/*
  18.105 + * Table C-30 Integer Load/Store +Imm
  18.106 + *
  18.107 + * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
  18.108 + *
  18.109 + * ld8.fill, st8.fill  must be aligned because the Nat register are based on
  18.110 + * the address, so we must fail and the program must be fixed.
  18.111 + */
  18.112 +#define LD_IMM_OP            0x0a0
  18.113 +#define LDS_IMM_OP           0x0a1
  18.114 +#define LDA_IMM_OP           0x0a2
  18.115 +#define LDSA_IMM_OP          0x0a3
  18.116 +#define LDBIAS_IMM_OP        0x0a4
  18.117 +#define LDACQ_IMM_OP         0x0a5
  18.118 +/* 0x0a6, 0xa7 are not relevant */
  18.119 +#define LDCCLR_IMM_OP        0x0a8
  18.120 +#define LDCNC_IMM_OP         0x0a9
  18.121 +#define LDCCLRACQ_IMM_OP     0x0aa
  18.122 +#define ST_IMM_OP            0x0ac
  18.123 +#define STREL_IMM_OP         0x0ad
  18.124 +/* 0x0ae,0xaf are not relevant */
  18.125 +
  18.126 +/*
  18.127 + * Table C-32 Floating-point Load/Store
  18.128 + */
  18.129 +#define LDF_OP           0x0c0
  18.130 +#define LDFS_OP          0x0c1
  18.131 +#define LDFA_OP          0x0c2
  18.132 +#define LDFSA_OP         0x0c3
  18.133 +/* 0x0c6 is irrelevant */
  18.134 +#define LDFCCLR_OP       0x0c8
  18.135 +#define LDFCNC_OP        0x0c9
  18.136 +/* 0x0cb is irrelevant  */
  18.137 +#define STF_OP           0x0cc
  18.138 +
  18.139 +/*
  18.140 + * Table C-33 Floating-point Load +Reg
  18.141 + *
  18.142 + * we use the ld->m (bit [36:36]) field to determine whether or not we have
  18.143 + * a load/store of this form.
  18.144 + */
  18.145 +
  18.146 +/*
  18.147 + * Table C-34 Floating-point Load/Store +Imm
  18.148 + */
  18.149 +#define LDF_IMM_OP       0x0e0
  18.150 +#define LDFS_IMM_OP      0x0e1
  18.151 +#define LDFA_IMM_OP      0x0e2
  18.152 +#define LDFSA_IMM_OP     0x0e3
  18.153 +/* 0x0e6 is irrelevant */
  18.154 +#define LDFCCLR_IMM_OP   0x0e8
  18.155 +#define LDFCNC_IMM_OP    0x0e9
  18.156 +#define STF_IMM_OP       0x0ec
  18.157 +
  18.158 +typedef struct {
  18.159 +	unsigned long	 qp:6;	/* [0:5]   */
  18.160 +	unsigned long    r1:7;	/* [6:12]  */
  18.161 +	unsigned long   imm:7;	/* [13:19] */
  18.162 +	unsigned long    r3:7;	/* [20:26] */
  18.163 +	unsigned long     x:1;  /* [27:27] */
  18.164 +	unsigned long  hint:2;	/* [28:29] */
  18.165 +	unsigned long x6_sz:2;	/* [30:31] */
  18.166 +	unsigned long x6_op:4;	/* [32:35], x6 = x6_sz|x6_op */
  18.167 +	unsigned long     m:1;	/* [36:36] */
  18.168 +	unsigned long    op:4;	/* [37:40] */
  18.169 +	unsigned long   pad:23; /* [41:63] */
  18.170 +} load_store_t;
  18.171 +
  18.172 +
  18.173 +typedef enum {
  18.174 +	UPD_IMMEDIATE,	/* ldXZ r1=[r3],imm(9) */