ia64/xen-unstable

changeset 9488:0a6f5527ca4b

[IA64] set itv handoff as masked and enable reading irr[0-3]

Set initial vcpu itv handoff state to mask the timer vector.
This seems to match hardware and makes logical sense from a
spurious interrupt perspective. Enable vcpu_get_irr[0-3]
functions as they seem to work and have the proper backing.
This enables the check_sal_cache_flush() in arch/ia64/kernel.sal.c
to work unmodified, allowing us to remove the Xen changes from
the file (and thus the file from the sparse tree).

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Apr 04 09:39:45 2006 -0600 (2006-04-04)
parents 40d96f4e9fcb
children 827c65c06a66
files linux-2.6-xen-sparse/arch/ia64/kernel/sal.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/vcpu.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/sal.c	Mon Apr 03 14:39:27 2006 -0600
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,380 +0,0 @@
     1.4 -/*
     1.5 - * System Abstraction Layer (SAL) interface routines.
     1.6 - *
     1.7 - * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
     1.8 - *	David Mosberger-Tang <davidm@hpl.hp.com>
     1.9 - * Copyright (C) 1999 VA Linux Systems
    1.10 - * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
    1.11 - */
    1.12 -#include <linux/config.h>
    1.13 -
    1.14 -#include <linux/kernel.h>
    1.15 -#include <linux/init.h>
    1.16 -#include <linux/module.h>
    1.17 -#include <linux/spinlock.h>
    1.18 -#include <linux/string.h>
    1.19 -
    1.20 -#include <asm/delay.h>
    1.21 -#include <asm/page.h>
    1.22 -#include <asm/sal.h>
    1.23 -#include <asm/pal.h>
    1.24 -
    1.25 - __cacheline_aligned DEFINE_SPINLOCK(sal_lock);
    1.26 -unsigned long sal_platform_features;
    1.27 -
    1.28 -unsigned short sal_revision;
    1.29 -unsigned short sal_version;
    1.30 -
    1.31 -#define SAL_MAJOR(x) ((x) >> 8)
    1.32 -#define SAL_MINOR(x) ((x) & 0xff)
    1.33 -
    1.34 -static struct {
    1.35 -	void *addr;	/* function entry point */
    1.36 -	void *gpval;	/* gp value to use */
    1.37 -} pdesc;
    1.38 -
    1.39 -static long
    1.40 -default_handler (void)
    1.41 -{
    1.42 -	return -1;
    1.43 -}
    1.44 -
    1.45 -ia64_sal_handler ia64_sal = (ia64_sal_handler) default_handler;
    1.46 -ia64_sal_desc_ptc_t *ia64_ptc_domain_info;
    1.47 -
    1.48 -const char *
    1.49 -ia64_sal_strerror (long status)
    1.50 -{
    1.51 -	const char *str;
    1.52 -	switch (status) {
    1.53 -	      case 0: str = "Call completed without error"; break;
    1.54 -	      case 1: str = "Effect a warm boot of the system to complete "
    1.55 -			      "the update"; break;
    1.56 -	      case -1: str = "Not implemented"; break;
    1.57 -	      case -2: str = "Invalid argument"; break;
    1.58 -	      case -3: str = "Call completed with error"; break;
    1.59 -	      case -4: str = "Virtual address not registered"; break;
    1.60 -	      case -5: str = "No information available"; break;
    1.61 -	      case -6: str = "Insufficient space to add the entry"; break;
    1.62 -	      case -7: str = "Invalid entry_addr value"; break;
    1.63 -	      case -8: str = "Invalid interrupt vector"; break;
    1.64 -	      case -9: str = "Requested memory not available"; break;
    1.65 -	      case -10: str = "Unable to write to the NVM device"; break;
    1.66 -	      case -11: str = "Invalid partition type specified"; break;
    1.67 -	      case -12: str = "Invalid NVM_Object id specified"; break;
    1.68 -	      case -13: str = "NVM_Object already has the maximum number "
    1.69 -				"of partitions"; break;
    1.70 -	      case -14: str = "Insufficient space in partition for the "
    1.71 -				"requested write sub-function"; break;
    1.72 -	      case -15: str = "Insufficient data buffer space for the "
    1.73 -				"requested read record sub-function"; break;
    1.74 -	      case -16: str = "Scratch buffer required for the write/delete "
    1.75 -				"sub-function"; break;
    1.76 -	      case -17: str = "Insufficient space in the NVM_Object for the "
    1.77 -				"requested create sub-function"; break;
    1.78 -	      case -18: str = "Invalid value specified in the partition_rec "
    1.79 -				"argument"; break;
    1.80 -	      case -19: str = "Record oriented I/O not supported for this "
    1.81 -				"partition"; break;
    1.82 -	      case -20: str = "Bad format of record to be written or "
    1.83 -				"required keyword variable not "
    1.84 -				"specified"; break;
    1.85 -	      default: str = "Unknown SAL status code"; break;
    1.86 -	}
    1.87 -	return str;
    1.88 -}
    1.89 -
    1.90 -void __init
    1.91 -ia64_sal_handler_init (void *entry_point, void *gpval)
    1.92 -{
    1.93 -	/* fill in the SAL procedure descriptor and point ia64_sal to it: */
    1.94 -	pdesc.addr = entry_point;
    1.95 -	pdesc.gpval = gpval;
    1.96 -	ia64_sal = (ia64_sal_handler) &pdesc;
    1.97 -}
    1.98 -
    1.99 -static void __init
   1.100 -check_versions (struct ia64_sal_systab *systab)
   1.101 -{
   1.102 -	sal_revision = (systab->sal_rev_major << 8) | systab->sal_rev_minor;
   1.103 -	sal_version = (systab->sal_b_rev_major << 8) | systab->sal_b_rev_minor;
   1.104 -
   1.105 -	/* Check for broken firmware */
   1.106 -	if ((sal_revision == SAL_VERSION_CODE(49, 29))
   1.107 -	    && (sal_version == SAL_VERSION_CODE(49, 29)))
   1.108 -	{
   1.109 -		/*
   1.110 -		 * Old firmware for zx2000 prototypes have this weird version number,
   1.111 -		 * reset it to something sane.
   1.112 -		 */
   1.113 -		sal_revision = SAL_VERSION_CODE(2, 8);
   1.114 -		sal_version = SAL_VERSION_CODE(0, 0);
   1.115 -	}
   1.116 -}
   1.117 -
   1.118 -static void __init
   1.119 -sal_desc_entry_point (void *p)
   1.120 -{
   1.121 -	struct ia64_sal_desc_entry_point *ep = p;
   1.122 -	ia64_pal_handler_init(__va(ep->pal_proc));
   1.123 -	ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
   1.124 -}
   1.125 -
   1.126 -#ifdef CONFIG_SMP
   1.127 -static void __init
   1.128 -set_smp_redirect (int flag)
   1.129 -{
   1.130 -#ifndef CONFIG_HOTPLUG_CPU
   1.131 -	if (no_int_routing)
   1.132 -		smp_int_redirect &= ~flag;
   1.133 -	else
   1.134 -		smp_int_redirect |= flag;
   1.135 -#else
   1.136 -	/*
   1.137 -	 * For CPU Hotplug we dont want to do any chipset supported
   1.138 -	 * interrupt redirection. The reason is this would require that
   1.139 -	 * All interrupts be stopped and hard bind the irq to a cpu.
   1.140 -	 * Later when the interrupt is fired we need to set the redir hint
   1.141 -	 * on again in the vector. This is combersome for something that the
   1.142 -	 * user mode irq balancer will solve anyways.
   1.143 -	 */
   1.144 -	no_int_routing=1;
   1.145 -	smp_int_redirect &= ~flag;
   1.146 -#endif
   1.147 -}
   1.148 -#else
   1.149 -#define set_smp_redirect(flag)	do { } while (0)
   1.150 -#endif
   1.151 -
   1.152 -static void __init
   1.153 -sal_desc_platform_feature (void *p)
   1.154 -{
   1.155 -	struct ia64_sal_desc_platform_feature *pf = p;
   1.156 -	sal_platform_features = pf->feature_mask;
   1.157 -
   1.158 -	printk(KERN_INFO "SAL Platform features:");
   1.159 -	if (!sal_platform_features) {
   1.160 -		printk(" None\n");
   1.161 -		return;
   1.162 -	}
   1.163 -
   1.164 -	if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
   1.165 -		printk(" BusLock");
   1.166 -	if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) {
   1.167 -		printk(" IRQ_Redirection");
   1.168 -		set_smp_redirect(SMP_IRQ_REDIRECTION);
   1.169 -	}
   1.170 -	if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) {
   1.171 -		printk(" IPI_Redirection");
   1.172 -		set_smp_redirect(SMP_IPI_REDIRECTION);
   1.173 -	}
   1.174 -	if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)
   1.175 -		printk(" ITC_Drift");
   1.176 -	printk("\n");
   1.177 -}
   1.178 -
   1.179 -#ifdef CONFIG_SMP
   1.180 -static void __init
   1.181 -sal_desc_ap_wakeup (void *p)
   1.182 -{
   1.183 -	struct ia64_sal_desc_ap_wakeup *ap = p;
   1.184 -
   1.185 -	switch (ap->mechanism) {
   1.186 -	case IA64_SAL_AP_EXTERNAL_INT:
   1.187 -		ap_wakeup_vector = ap->vector;
   1.188 -		printk(KERN_INFO "SAL: AP wakeup using external interrupt "
   1.189 -				"vector 0x%lx\n", ap_wakeup_vector);
   1.190 -		break;
   1.191 -	default:
   1.192 -		printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n");
   1.193 -		break;
   1.194 -	}
   1.195 -}
   1.196 -
   1.197 -static void __init
   1.198 -chk_nointroute_opt(void)
   1.199 -{
   1.200 -	char *cp;
   1.201 -	extern char saved_command_line[];
   1.202 -
   1.203 -	for (cp = saved_command_line; *cp; ) {
   1.204 -		if (memcmp(cp, "nointroute", 10) == 0) {
   1.205 -			no_int_routing = 1;
   1.206 -			printk ("no_int_routing on\n");
   1.207 -			break;
   1.208 -		} else {
   1.209 -			while (*cp != ' ' && *cp)
   1.210 -				++cp;
   1.211 -			while (*cp == ' ')
   1.212 -				++cp;
   1.213 -		}
   1.214 -	}
   1.215 -}
   1.216 -
   1.217 -#else
   1.218 -static void __init sal_desc_ap_wakeup(void *p) { }
   1.219 -#endif
   1.220 -
   1.221 -/*
   1.222 - * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading
   1.223 - * cr.ivr, but it never writes cr.eoi.  This leaves any interrupt marked as
   1.224 - * "in-service" and masks other interrupts of equal or lower priority.
   1.225 - *
   1.226 - * HP internal defect reports: F1859, F2775, F3031.
   1.227 - */
   1.228 -static int sal_cache_flush_drops_interrupts;
   1.229 -
   1.230 -static void __init
   1.231 -check_sal_cache_flush (void)
   1.232 -{
   1.233 -	unsigned long flags, itv;
   1.234 -	int cpu;
   1.235 -	u64 vector;
   1.236 -
   1.237 -	cpu = get_cpu();
   1.238 -	local_irq_save(flags);
   1.239 -
   1.240 -	/*
   1.241 -	 * Schedule a timer interrupt, wait until it's reported, and see if
   1.242 -	 * SAL_CACHE_FLUSH drops it.
   1.243 -	 */
   1.244 -	itv = ia64_get_itv();
   1.245 -	BUG_ON((itv & (1 << 16)) == 0);
   1.246 -
   1.247 -	ia64_set_itv(IA64_TIMER_VECTOR);
   1.248 -	ia64_set_itm(ia64_get_itc() + 1000);
   1.249 -
   1.250 -	while (!ia64_get_irr(IA64_TIMER_VECTOR))
   1.251 -		cpu_relax();
   1.252 -
   1.253 -	ia64_sal_cache_flush(3);
   1.254 -
   1.255 -	if (ia64_get_irr(IA64_TIMER_VECTOR)) {
   1.256 -		vector = ia64_get_ivr();
   1.257 -		ia64_eoi();
   1.258 -		WARN_ON(vector != IA64_TIMER_VECTOR);
   1.259 -	} else {
   1.260 -		sal_cache_flush_drops_interrupts = 1;
   1.261 -		printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; "
   1.262 -			"PAL_CACHE_FLUSH will be used instead\n");
   1.263 -		ia64_eoi();
   1.264 -	}
   1.265 -
   1.266 -	ia64_set_itv(itv);
   1.267 -	local_irq_restore(flags);
   1.268 -	put_cpu();
   1.269 -}
   1.270 -
   1.271 -s64
   1.272 -ia64_sal_cache_flush (u64 cache_type)
   1.273 -{
   1.274 -	struct ia64_sal_retval isrv;
   1.275 -
   1.276 -	if (sal_cache_flush_drops_interrupts) {
   1.277 -		unsigned long flags;
   1.278 -		u64 progress;
   1.279 -		s64 rc;
   1.280 -
   1.281 -		progress = 0;
   1.282 -		local_irq_save(flags);
   1.283 -		rc = ia64_pal_cache_flush(cache_type,
   1.284 -			PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL);
   1.285 -		local_irq_restore(flags);
   1.286 -		return rc;
   1.287 -	}
   1.288 -
   1.289 -	SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
   1.290 -	return isrv.status;
   1.291 -}
   1.292 -
   1.293 -void __init
   1.294 -ia64_sal_init (struct ia64_sal_systab *systab)
   1.295 -{
   1.296 -	char *p;
   1.297 -	int i;
   1.298 -
   1.299 -	if (!systab) {
   1.300 -		printk(KERN_WARNING "Hmm, no SAL System Table.\n");
   1.301 -		return;
   1.302 -	}
   1.303 -
   1.304 -	if (strncmp(systab->signature, "SST_", 4) != 0)
   1.305 -		printk(KERN_ERR "bad signature in system table!");
   1.306 -
   1.307 -	check_versions(systab);
   1.308 -#ifdef CONFIG_SMP
   1.309 -	chk_nointroute_opt();
   1.310 -#endif
   1.311 -
   1.312 -	/* revisions are coded in BCD, so %x does the job for us */
   1.313 -	printk(KERN_INFO "SAL %x.%x: %.32s %.32s%sversion %x.%x\n",
   1.314 -			SAL_MAJOR(sal_revision), SAL_MINOR(sal_revision),
   1.315 -			systab->oem_id, systab->product_id,
   1.316 -			systab->product_id[0] ? " " : "",
   1.317 -			SAL_MAJOR(sal_version), SAL_MINOR(sal_version));
   1.318 -
   1.319 -	p = (char *) (systab + 1);
   1.320 -	for (i = 0; i < systab->entry_count; i++) {
   1.321 -		/*
   1.322 -		 * The first byte of each entry type contains the type
   1.323 -		 * descriptor.
   1.324 -		 */
   1.325 -		switch (*p) {
   1.326 -		case SAL_DESC_ENTRY_POINT:
   1.327 -			sal_desc_entry_point(p);
   1.328 -			break;
   1.329 -		case SAL_DESC_PLATFORM_FEATURE:
   1.330 -			sal_desc_platform_feature(p);
   1.331 -			break;
   1.332 -		case SAL_DESC_PTC:
   1.333 -			ia64_ptc_domain_info = (ia64_sal_desc_ptc_t *)p;
   1.334 -			break;
   1.335 -		case SAL_DESC_AP_WAKEUP:
   1.336 -			sal_desc_ap_wakeup(p);
   1.337 -			break;
   1.338 -		}
   1.339 -		p += SAL_DESC_SIZE(*p);
   1.340 -	}
   1.341 -
   1.342 -#ifdef CONFIG_XEN
   1.343 -	if (!running_on_xen)
   1.344 -#endif
   1.345 -	check_sal_cache_flush();
   1.346 -}
   1.347 -
   1.348 -int
   1.349 -ia64_sal_oemcall(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
   1.350 -		 u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7)
   1.351 -{
   1.352 -	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
   1.353 -		return -1;
   1.354 -	SAL_CALL(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
   1.355 -	return 0;
   1.356 -}
   1.357 -EXPORT_SYMBOL(ia64_sal_oemcall);
   1.358 -
   1.359 -int
   1.360 -ia64_sal_oemcall_nolock(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
   1.361 -			u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
   1.362 -			u64 arg7)
   1.363 -{
   1.364 -	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
   1.365 -		return -1;
   1.366 -	SAL_CALL_NOLOCK(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
   1.367 -			arg7);
   1.368 -	return 0;
   1.369 -}
   1.370 -EXPORT_SYMBOL(ia64_sal_oemcall_nolock);
   1.371 -
   1.372 -int
   1.373 -ia64_sal_oemcall_reentrant(struct ia64_sal_retval *isrvp, u64 oemfunc,
   1.374 -			   u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5,
   1.375 -			   u64 arg6, u64 arg7)
   1.376 -{
   1.377 -	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
   1.378 -		return -1;
   1.379 -	SAL_CALL_REENTRANT(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
   1.380 -			   arg7);
   1.381 -	return 0;
   1.382 -}
   1.383 -EXPORT_SYMBOL(ia64_sal_oemcall_reentrant);
     2.1 --- a/xen/arch/ia64/xen/domain.c	Mon Apr 03 14:39:27 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Apr 04 09:39:45 2006 -0600
     2.3 @@ -487,6 +487,7 @@ void new_thread(struct vcpu *v,
     2.4  		VCPU(v, metaphysical_mode) = 1;
     2.5  		VCPU(v, interrupt_mask_addr) =
     2.6  		    (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
     2.7 +		VCPU(v, itv) = (1 << 16); /* timer vector masked */
     2.8  	}
     2.9  }
    2.10  
     3.1 --- a/xen/arch/ia64/xen/vcpu.c	Mon Apr 03 14:39:27 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/vcpu.c	Tue Apr 04 09:39:45 2006 -0600
     3.3 @@ -823,46 +823,26 @@ IA64FAULT vcpu_get_eoi(VCPU *vcpu, UINT6
     3.4  
     3.5  IA64FAULT vcpu_get_irr0(VCPU *vcpu, UINT64 *pval)
     3.6  {
     3.7 -#ifndef IRR_USE_FIXED
     3.8 -	printk("vcpu_get_irr: called, not implemented yet\n");
     3.9 -	return IA64_ILLOP_FAULT;
    3.10 -#else
    3.11 -	*pval = vcpu->irr[0];
    3.12 +	*pval = PSCBX(vcpu, irr[0]);
    3.13  	return (IA64_NO_FAULT);
    3.14 -#endif
    3.15  }
    3.16  
    3.17  IA64FAULT vcpu_get_irr1(VCPU *vcpu, UINT64 *pval)
    3.18  {
    3.19 -#ifndef IRR_USE_FIXED
    3.20 -	printk("vcpu_get_irr: called, not implemented yet\n");
    3.21 -	return IA64_ILLOP_FAULT;
    3.22 -#else
    3.23 -	*pval = vcpu->irr[1];
    3.24 +	*pval = PSCBX(vcpu, irr[1]);
    3.25  	return (IA64_NO_FAULT);
    3.26 -#endif
    3.27  }
    3.28  
    3.29  IA64FAULT vcpu_get_irr2(VCPU *vcpu, UINT64 *pval)
    3.30  {
    3.31 -#ifndef IRR_USE_FIXED
    3.32 -	printk("vcpu_get_irr: called, not implemented yet\n");
    3.33 -	return IA64_ILLOP_FAULT;
    3.34 -#else
    3.35 -	*pval = vcpu->irr[2];
    3.36 +	*pval = PSCBX(vcpu, irr[2]);
    3.37  	return (IA64_NO_FAULT);
    3.38 -#endif
    3.39  }
    3.40  
    3.41  IA64FAULT vcpu_get_irr3(VCPU *vcpu, UINT64 *pval)
    3.42  {
    3.43 -#ifndef IRR_USE_FIXED
    3.44 -	printk("vcpu_get_irr: called, not implemented yet\n");
    3.45 -	return IA64_ILLOP_FAULT;
    3.46 -#else
    3.47 -	*pval = vcpu->irr[3];
    3.48 +	*pval = PSCBX(vcpu, irr[3]);
    3.49  	return (IA64_NO_FAULT);
    3.50 -#endif
    3.51  }
    3.52  
    3.53  IA64FAULT vcpu_get_itv(VCPU *vcpu, UINT64 *pval)