ia64/xen-unstable
changeset 6872:3b6d422fc0be
Start fleshing out -sparse tree for xenlinux/ia64
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Wed Sep 21 09:06:30 2005 -0600 1.3 @@ -0,0 +1,460 @@ 1.4 +# 1.5 +# For a description of the syntax of this configuration file, 1.6 +# see Documentation/kbuild/kconfig-language.txt. 1.7 +# 1.8 + 1.9 +mainmenu "IA-64 Linux Kernel Configuration" 1.10 + 1.11 +source "init/Kconfig" 1.12 + 1.13 +menu "Processor type and features" 1.14 + 1.15 +config IA64 1.16 + bool 1.17 + default y 1.18 + help 1.19 + The Itanium Processor Family is Intel's 64-bit successor to 1.20 + the 32-bit X86 line. The IA-64 Linux project has a home 1.21 + page at <http://www.linuxia64.org/> and a mailing list at 1.22 + <linux-ia64@vger.kernel.org>. 1.23 + 1.24 +config 64BIT 1.25 + bool 1.26 + default y 1.27 + 1.28 +config MMU 1.29 + bool 1.30 + default y 1.31 + 1.32 +config RWSEM_XCHGADD_ALGORITHM 1.33 + bool 1.34 + default y 1.35 + 1.36 +config GENERIC_CALIBRATE_DELAY 1.37 + bool 1.38 + default y 1.39 + 1.40 +config TIME_INTERPOLATION 1.41 + bool 1.42 + default y 1.43 + 1.44 +config EFI 1.45 + bool 1.46 + default y 1.47 + 1.48 +config GENERIC_IOMAP 1.49 + bool 1.50 + default y 1.51 + 1.52 +config XEN 1.53 + bool 1.54 + default y 1.55 + help 1.56 + Enable Xen hypervisor support. Resulting kernel runs 1.57 + both as a guest OS on Xen and natively on hardware. 1.58 + 1.59 +config XEN_PHYSDEV_ACCESS 1.60 + depends on XEN 1.61 + bool 1.62 + default y 1.63 + 1.64 +config XEN_BLKDEV_GRANT 1.65 + depends on XEN 1.66 + bool 1.67 + default y 1.68 + 1.69 +config SCHED_NO_NO_OMIT_FRAME_POINTER 1.70 + bool 1.71 + default y 1.72 + 1.73 +choice 1.74 + prompt "System type" 1.75 + default IA64_GENERIC 1.76 + 1.77 +config IA64_GENERIC 1.78 + bool "generic" 1.79 + select NUMA 1.80 + select ACPI_NUMA 1.81 + select VIRTUAL_MEM_MAP 1.82 + select DISCONTIGMEM 1.83 + help 1.84 + This selects the system type of your hardware. A "generic" kernel 1.85 + will run on any supported IA-64 system. However, if you configure 1.86 + a kernel for your specific system, it will be faster and smaller. 1.87 + 1.88 + generic For any supported IA-64 system 1.89 + DIG-compliant For DIG ("Developer's Interface Guide") compliant systems 1.90 + HP-zx1/sx1000 For HP systems 1.91 + HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices. 1.92 + SGI-SN2 For SGI Altix systems 1.93 + Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/> 1.94 + 1.95 + If you don't know what to do, choose "generic". 1.96 + 1.97 +config IA64_DIG 1.98 + bool "DIG-compliant" 1.99 + 1.100 +config IA64_HP_ZX1 1.101 + bool "HP-zx1/sx1000" 1.102 + help 1.103 + Build a kernel that runs on HP zx1 and sx1000 systems. This adds 1.104 + support for the HP I/O MMU. 1.105 + 1.106 +config IA64_HP_ZX1_SWIOTLB 1.107 + bool "HP-zx1/sx1000 with software I/O TLB" 1.108 + help 1.109 + Build a kernel that runs on HP zx1 and sx1000 systems even when they 1.110 + have broken PCI devices which cannot DMA to full 32 bits. Apart 1.111 + from support for the HP I/O MMU, this includes support for the software 1.112 + I/O TLB, which allows supporting the broken devices at the expense of 1.113 + wasting some kernel memory (about 2MB by default). 1.114 + 1.115 +config IA64_SGI_SN2 1.116 + bool "SGI-SN2" 1.117 + help 1.118 + Selecting this option will optimize the kernel for use on sn2 based 1.119 + systems, but the resulting kernel binary will not run on other 1.120 + types of ia64 systems. If you have an SGI Altix system, it's safe 1.121 + to select this option. If in doubt, select ia64 generic support 1.122 + instead. 1.123 + 1.124 +config IA64_HP_SIM 1.125 + bool "Ski-simulator" 1.126 + 1.127 +endchoice 1.128 + 1.129 +choice 1.130 + prompt "Processor type" 1.131 + default ITANIUM 1.132 + 1.133 +config ITANIUM 1.134 + bool "Itanium" 1.135 + help 1.136 + Select your IA-64 processor type. The default is Itanium. 1.137 + This choice is safe for all IA-64 systems, but may not perform 1.138 + optimally on systems with, say, Itanium 2 or newer processors. 1.139 + 1.140 +config MCKINLEY 1.141 + bool "Itanium 2" 1.142 + help 1.143 + Select this to configure for an Itanium 2 (McKinley) processor. 1.144 + 1.145 +endchoice 1.146 + 1.147 +choice 1.148 + prompt "Kernel page size" 1.149 + default IA64_PAGE_SIZE_16KB 1.150 + 1.151 +config IA64_PAGE_SIZE_4KB 1.152 + bool "4KB" 1.153 + help 1.154 + This lets you select the page size of the kernel. For best IA-64 1.155 + performance, a page size of 8KB or 16KB is recommended. For best 1.156 + IA-32 compatibility, a page size of 4KB should be selected (the vast 1.157 + majority of IA-32 binaries work perfectly fine with a larger page 1.158 + size). For Itanium 2 or newer systems, a page size of 64KB can also 1.159 + be selected. 1.160 + 1.161 + 4KB For best IA-32 compatibility 1.162 + 8KB For best IA-64 performance 1.163 + 16KB For best IA-64 performance 1.164 + 64KB Requires Itanium 2 or newer processor. 1.165 + 1.166 + If you don't know what to do, choose 16KB. 1.167 + 1.168 +config IA64_PAGE_SIZE_8KB 1.169 + bool "8KB" 1.170 + 1.171 +config IA64_PAGE_SIZE_16KB 1.172 + bool "16KB" 1.173 + 1.174 +config IA64_PAGE_SIZE_64KB 1.175 + depends on !ITANIUM 1.176 + bool "64KB" 1.177 + 1.178 +endchoice 1.179 + 1.180 +config IA64_BRL_EMU 1.181 + bool 1.182 + depends on ITANIUM 1.183 + default y 1.184 + 1.185 +# align cache-sensitive data to 128 bytes 1.186 +config IA64_L1_CACHE_SHIFT 1.187 + int 1.188 + default "7" if MCKINLEY 1.189 + default "6" if ITANIUM 1.190 + 1.191 +# align cache-sensitive data to 64 bytes 1.192 +config NUMA 1.193 + bool "NUMA support" 1.194 + depends on !IA64_HP_SIM 1.195 + default y if IA64_SGI_SN2 1.196 + select ACPI_NUMA 1.197 + help 1.198 + Say Y to compile the kernel to support NUMA (Non-Uniform Memory 1.199 + Access). This option is for configuring high-end multiprocessor 1.200 + server systems. If in doubt, say N. 1.201 + 1.202 +config VIRTUAL_MEM_MAP 1.203 + bool "Virtual mem map" 1.204 + default y if !IA64_HP_SIM 1.205 + help 1.206 + Say Y to compile the kernel with support for a virtual mem map. 1.207 + This code also only takes effect if a memory hole of greater than 1.208 + 1 Gb is found during boot. You must turn this option on if you 1.209 + require the DISCONTIGMEM option for your machine. If you are 1.210 + unsure, say Y. 1.211 + 1.212 +config HOLES_IN_ZONE 1.213 + bool 1.214 + default y if VIRTUAL_MEM_MAP 1.215 + 1.216 +config DISCONTIGMEM 1.217 + bool "Discontiguous memory support" 1.218 + depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP 1.219 + default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA 1.220 + help 1.221 + Say Y to support efficient handling of discontiguous physical memory, 1.222 + for architectures which are either NUMA (Non-Uniform Memory Access) 1.223 + or have huge holes in the physical address space for other reasons. 1.224 + See <file:Documentation/vm/numa> for more. 1.225 + 1.226 +config IA64_CYCLONE 1.227 + bool "Cyclone (EXA) Time Source support" 1.228 + help 1.229 + Say Y here to enable support for IBM EXA Cyclone time source. 1.230 + If you're unsure, answer N. 1.231 + 1.232 +config IOSAPIC 1.233 + bool 1.234 + depends on !IA64_HP_SIM 1.235 + default y 1.236 + 1.237 +config IA64_SGI_SN_SIM 1.238 + bool "SGI Medusa Simulator Support" 1.239 + depends on IA64_SGI_SN2 1.240 + help 1.241 + If you are compiling a kernel that will run under SGI's IA-64 1.242 + simulator (Medusa) then say Y, otherwise say N. 1.243 + 1.244 +config IA64_SGI_SN_XP 1.245 + tristate "Support communication between SGI SSIs" 1.246 + depends on MSPEC 1.247 + help 1.248 + An SGI machine can be divided into multiple Single System 1.249 + Images which act independently of each other and have 1.250 + hardware based memory protection from the others. Enabling 1.251 + this feature will allow for direct communication between SSIs 1.252 + based on a network adapter and DMA messaging. 1.253 + 1.254 +config FORCE_MAX_ZONEORDER 1.255 + int 1.256 + default "18" 1.257 + 1.258 +config SMP 1.259 + bool "Symmetric multi-processing support" 1.260 + help 1.261 + This enables support for systems with more than one CPU. If you have 1.262 + a system with only one CPU, say N. If you have a system with more 1.263 + than one CPU, say Y. 1.264 + 1.265 + If you say N here, the kernel will run on single and multiprocessor 1.266 + systems, but will use only one CPU of a multiprocessor system. If 1.267 + you say Y here, the kernel will run on many, but not all, 1.268 + single processor systems. On a single processor system, the kernel 1.269 + will run faster if you say N here. 1.270 + 1.271 + See also the <file:Documentation/smp.txt> and the SMP-HOWTO 1.272 + available at <http://www.tldp.org/docs.html#howto>. 1.273 + 1.274 + If you don't know what to do here, say N. 1.275 + 1.276 +config NR_CPUS 1.277 + int "Maximum number of CPUs (2-512)" 1.278 + range 2 512 1.279 + depends on SMP 1.280 + default "64" 1.281 + help 1.282 + You should set this to the number of CPUs in your system, but 1.283 + keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but 1.284 + only use 2 CPUs on a >2 CPU system. Setting this to a value larger 1.285 + than 64 will cause the use of a CPU mask array, causing a small 1.286 + performance hit. 1.287 + 1.288 +config HOTPLUG_CPU 1.289 + bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" 1.290 + depends on SMP && EXPERIMENTAL 1.291 + select HOTPLUG 1.292 + default n 1.293 + ---help--- 1.294 + Say Y here to experiment with turning CPUs off and on. CPUs 1.295 + can be controlled through /sys/devices/system/cpu/cpu#. 1.296 + Say N if you want to disable CPU hotplug. 1.297 + 1.298 +config SCHED_SMT 1.299 + bool "SMT scheduler support" 1.300 + depends on SMP 1.301 + default off 1.302 + help 1.303 + Improves the CPU scheduler's decision making when dealing with 1.304 + Intel IA64 chips with MultiThreading at a cost of slightly increased 1.305 + overhead in some places. If unsure say N here. 1.306 + 1.307 +config PREEMPT 1.308 + bool "Preemptible Kernel" 1.309 + help 1.310 + This option reduces the latency of the kernel when reacting to 1.311 + real-time or interactive events by allowing a low priority process to 1.312 + be preempted even if it is in kernel mode executing a system call. 1.313 + This allows applications to run more reliably even when the system is 1.314 + under load. 1.315 + 1.316 + Say Y here if you are building a kernel for a desktop, embedded 1.317 + or real-time system. Say N if you are unsure. 1.318 + 1.319 +config HAVE_DEC_LOCK 1.320 + bool 1.321 + depends on (SMP || PREEMPT) 1.322 + default y 1.323 + 1.324 +config IA32_SUPPORT 1.325 + bool "Support for Linux/x86 binaries" 1.326 + help 1.327 + IA-64 processors can execute IA-32 (X86) instructions. By 1.328 + saying Y here, the kernel will include IA-32 system call 1.329 + emulation support which makes it possible to transparently 1.330 + run IA-32 Linux binaries on an IA-64 Linux system. 1.331 + If in doubt, say Y. 1.332 + 1.333 +config COMPAT 1.334 + bool 1.335 + depends on IA32_SUPPORT 1.336 + default y 1.337 + 1.338 +config IA64_MCA_RECOVERY 1.339 + tristate "MCA recovery from errors other than TLB." 1.340 + 1.341 +config PERFMON 1.342 + bool "Performance monitor support" 1.343 + help 1.344 + Selects whether support for the IA-64 performance monitor hardware 1.345 + is included in the kernel. This makes some kernel data-structures a 1.346 + little bigger and slows down execution a bit, but it is generally 1.347 + a good idea to turn this on. If you're unsure, say Y. 1.348 + 1.349 +config IA64_PALINFO 1.350 + tristate "/proc/pal support" 1.351 + help 1.352 + If you say Y here, you are able to get PAL (Processor Abstraction 1.353 + Layer) information in /proc/pal. This contains useful information 1.354 + about the processors in your systems, such as cache and TLB sizes 1.355 + and the PAL firmware version in use. 1.356 + 1.357 + To use this option, you have to ensure that the "/proc file system 1.358 + support" (CONFIG_PROC_FS) is enabled, too. 1.359 + 1.360 +config ACPI_DEALLOCATE_IRQ 1.361 + bool 1.362 + depends on IOSAPIC && EXPERIMENTAL 1.363 + default y 1.364 + 1.365 +source "drivers/firmware/Kconfig" 1.366 + 1.367 +source "fs/Kconfig.binfmt" 1.368 + 1.369 +endmenu 1.370 + 1.371 +menu "Power management and ACPI" 1.372 + 1.373 +config PM 1.374 + bool "Power Management support" 1.375 + depends on !IA64_HP_SIM 1.376 + default y 1.377 + help 1.378 + "Power Management" means that parts of your computer are shut 1.379 + off or put into a power conserving "sleep" mode if they are not 1.380 + being used. There are two competing standards for doing this: APM 1.381 + and ACPI. If you want to use either one, say Y here and then also 1.382 + to the requisite support below. 1.383 + 1.384 + Power Management is most important for battery powered laptop 1.385 + computers; if you have a laptop, check out the Linux Laptop home 1.386 + page on the WWW at <http://www.linux-on-laptops.com/> and the 1.387 + Battery Powered Linux mini-HOWTO, available from 1.388 + <http://www.tldp.org/docs.html#howto>. 1.389 + 1.390 + Note that, even if you say N here, Linux on the x86 architecture 1.391 + will issue the hlt instruction if nothing is to be done, thereby 1.392 + sending the processor to sleep and saving power. 1.393 + 1.394 +config ACPI 1.395 + bool 1.396 + depends on !IA64_HP_SIM 1.397 + default y 1.398 + 1.399 +if !IA64_HP_SIM 1.400 + 1.401 +source "drivers/acpi/Kconfig" 1.402 + 1.403 +endif 1.404 + 1.405 +endmenu 1.406 + 1.407 +if !IA64_HP_SIM 1.408 + 1.409 +menu "Bus options (PCI, PCMCIA)" 1.410 + 1.411 +config PCI 1.412 + bool "PCI support" 1.413 + help 1.414 + Find out whether you have a PCI motherboard. PCI is the name of a 1.415 + bus system, i.e. the way the CPU talks to the other stuff inside 1.416 + your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or 1.417 + VESA. If you have PCI, say Y, otherwise N. 1.418 + 1.419 + The PCI-HOWTO, available from 1.420 + <http://www.tldp.org/docs.html#howto>, contains valuable 1.421 + information about which PCI hardware does work under Linux and which 1.422 + doesn't. 1.423 + 1.424 +config PCI_DOMAINS 1.425 + bool 1.426 + default PCI 1.427 + 1.428 +source "drivers/pci/Kconfig" 1.429 + 1.430 +source "drivers/pci/hotplug/Kconfig" 1.431 + 1.432 +source "drivers/pcmcia/Kconfig" 1.433 + 1.434 +endmenu 1.435 + 1.436 +endif 1.437 + 1.438 +source "drivers/Kconfig" 1.439 + 1.440 +source "fs/Kconfig" 1.441 + 1.442 +source "lib/Kconfig" 1.443 + 1.444 +# 1.445 +# Use the generic interrupt handling code in kernel/irq/: 1.446 +# 1.447 +config GENERIC_HARDIRQS 1.448 + bool 1.449 + default y 1.450 + 1.451 +config GENERIC_IRQ_PROBE 1.452 + bool 1.453 + default y 1.454 + 1.455 +source "arch/ia64/hp/sim/Kconfig" 1.456 + 1.457 +source "arch/ia64/oprofile/Kconfig" 1.458 + 1.459 +source "arch/ia64/Kconfig.debug" 1.460 + 1.461 +source "security/Kconfig" 1.462 + 1.463 +source "crypto/Kconfig"
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/Makefile Wed Sep 21 09:06:30 2005 -0600 2.3 @@ -0,0 +1,141 @@ 2.4 +# 2.5 +# ia64/Makefile 2.6 +# 2.7 +# This file is subject to the terms and conditions of the GNU General Public 2.8 +# License. See the file "COPYING" in the main directory of this archive 2.9 +# for more details. 2.10 +# 2.11 +# Copyright (C) 1998-2004 by David Mosberger-Tang <davidm@hpl.hp.com> 2.12 +# 2.13 + 2.14 +NM := $(CROSS_COMPILE)nm -B 2.15 +READELF := $(CROSS_COMPILE)readelf 2.16 + 2.17 +# following is temporary pending xen directory restructuring 2.18 +NOSTDINC_FLAGS += -Iinclude/asm-xen 2.19 + 2.20 +export AWK 2.21 + 2.22 +CHECKFLAGS += -m64 -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__ 2.23 + 2.24 +OBJCOPYFLAGS := --strip-all 2.25 +LDFLAGS_vmlinux := -static 2.26 +LDFLAGS_MODULE += -T $(srctree)/arch/ia64/module.lds 2.27 +AFLAGS_KERNEL := -mconstant-gp 2.28 +EXTRA := 2.29 + 2.30 +cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \ 2.31 + -falign-functions=32 -frename-registers -fno-optimize-sibling-calls 2.32 +CFLAGS_KERNEL := -mconstant-gp 2.33 + 2.34 +GCC_VERSION := $(call cc-version) 2.35 +GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)") 2.36 +CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)") 2.37 + 2.38 +ifeq ($(GAS_STATUS),buggy) 2.39 +$(error Sorry, you need a newer version of the assember, one that is built from \ 2.40 + a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \ 2.41 + static binary of such an assembler at: \ 2.42 + \ 2.43 + ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) 2.44 +endif 2.45 + 2.46 +ifneq ($(shell if [ $(GCC_VERSION) -lt 0300 ] ; then echo "bad"; fi ;),) 2.47 +$(error Sorry, your compiler is too old. GCC v2.96 is known to generate bad code.) 2.48 +endif 2.49 + 2.50 +ifeq ($(GCC_VERSION),0304) 2.51 + cflags-$(CONFIG_ITANIUM) += -mtune=merced 2.52 + cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley 2.53 +endif 2.54 + 2.55 +CFLAGS += $(cflags-y) 2.56 +head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o 2.57 + 2.58 +libs-y += arch/ia64/lib/ 2.59 +core-y += arch/ia64/kernel/ arch/ia64/mm/ 2.60 +core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/ 2.61 +core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ 2.62 +core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ 2.63 +core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ 2.64 +core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ 2.65 +core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ 2.66 +core-$(CONFIG_XEN) += arch/ia64/xen/ arch/ia64/hp/sim/ 2.67 + 2.68 +drivers-$(CONFIG_PCI) += arch/ia64/pci/ 2.69 +drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ 2.70 +drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ 2.71 +drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ 2.72 +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ 2.73 +drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ 2.74 + 2.75 +boot := arch/ia64/hp/sim/boot 2.76 + 2.77 +.PHONY: boot compressed check 2.78 + 2.79 +all: compressed unwcheck 2.80 + 2.81 +compressed: vmlinux.gz 2.82 + 2.83 +vmlinux.gz: vmlinux 2.84 + $(Q)$(MAKE) $(build)=$(boot) $@ 2.85 + 2.86 +unwcheck: vmlinux 2.87 + -$(Q)READELF=$(READELF) $(srctree)/arch/ia64/scripts/unwcheck.py $< 2.88 + 2.89 +archclean: 2.90 + $(Q)$(MAKE) $(clean)=$(boot) 2.91 + 2.92 +CLEAN_FILES += include/asm-ia64/.offsets.h.stamp vmlinux.gz bootloader 2.93 +CLEAN_FILES += include/asm-xen/xen-public include/asm-ia64/xen/asm-xsi-offsets.h 2.94 +CLEAN_FILES += include/asm-xen/linux-public/xenstored.h 2.95 +CLEAN_FILES += include/asm-xen/linux-public include/asm-xen/asm-ia64/hypervisor.h 2.96 + 2.97 +MRPROPER_FILES += include/asm-ia64/offsets.h 2.98 + 2.99 +prepare: include/asm-ia64/offsets.h 2.100 + 2.101 +arch/ia64/kernel/asm-offsets.s: include/asm include/linux/version.h include/config/MARKER 2.102 + 2.103 +include/asm-ia64/offsets.h: arch/ia64/kernel/asm-offsets.s 2.104 + $(call filechk,gen-asm-offsets) 2.105 + 2.106 +arch/ia64/kernel/asm-offsets.s: include/asm-ia64/.offsets.h.stamp 2.107 + 2.108 +XEN_PATH ?= $(srctree)/../xen-ia64-unstable.hg/ 2.109 +include/asm-ia64/.offsets.h.stamp: 2.110 + mkdir -p include/asm-ia64 2.111 + [ -s include/asm-ia64/offsets.h ] \ 2.112 + || echo "#define IA64_TASK_SIZE 0" > include/asm-ia64/offsets.h 2.113 + touch $@ 2.114 + [ -e include/asm-xen/asm ] \ 2.115 + || ln -s asm-ia64 include/asm-xen/asm 2.116 + [ -e include/asm-xen/xen-public ] \ 2.117 + || ln -s $(XEN_PATH)/xen/include/public \ 2.118 + include/asm-xen/xen-public 2.119 + [ -e include/asm-ia64/xen/asm-xsi-offsets.h ] \ 2.120 + || ln -s $(XEN_PATH)/xen/include/asm-ia64/asm-xsi-offsets.h \ 2.121 + include/asm-ia64/xen/asm-xsi-offsets.h 2.122 + [ -e include/asm-xen/linux-public ] \ 2.123 + || ln -s $(XEN_PATH)/linux-2.6-xen-sparse/include/asm-xen/linux-public \ 2.124 + include/asm-xen/linux-public 2.125 + [ -e include/asm-xen/linux-public/xenstored.h ] \ 2.126 + || ln -s $(XEN_PATH)/tools/xenstore/xenstored.h \ 2.127 + include/asm-xen/linux-public/xenstored.h 2.128 + [ -e include/asm-xen/asm-ia64/hypervisor.h ] \ 2.129 + || ln -s $(XEN_PATH)/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h \ 2.130 + include/asm-xen/asm-ia64/hypervisor.h 2.131 + 2.132 + 2.133 +boot: lib/lib.a vmlinux 2.134 + $(Q)$(MAKE) $(build)=$(boot) $@ 2.135 + 2.136 +install: vmlinux.gz 2.137 + sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" 2.138 + 2.139 +define archhelp 2.140 + echo '* compressed - Build compressed kernel image' 2.141 + echo ' install - Install compressed kernel image' 2.142 + echo ' boot - Build vmlinux and bootloader for Ski simulator' 2.143 + echo '* unwcheck - Check vmlinux for invalid unwind info' 2.144 +endef
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/linux-2.6-xen-sparse/arch/ia64/hp/sim/Makefile Wed Sep 21 09:06:30 2005 -0600 3.3 @@ -0,0 +1,18 @@ 3.4 +# 3.5 +# ia64/platform/hp/sim/Makefile 3.6 +# 3.7 +# Copyright (C) 2002 Hewlett-Packard Co. 3.8 +# David Mosberger-Tang <davidm@hpl.hp.com> 3.9 +# Copyright (C) 1999 Silicon Graphics, Inc. 3.10 +# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com) 3.11 +# 3.12 + 3.13 +obj-y := hpsim_irq.o hpsim_setup.o hpsim.o 3.14 +obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o 3.15 + 3.16 +obj-$(CONFIG_HP_SIMETH) += simeth.o 3.17 +obj-$(CONFIG_HP_SIMSERIAL) += simserial.o 3.18 +obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o 3.19 +obj-$(CONFIG_HP_SIMSCSI) += simscsi.o 3.20 +obj-$(CONFIG_XEN) += simserial.o 3.21 +obj-$(CONFIG_XEN) += hpsim_console.o
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/entry.S Wed Sep 21 09:06:30 2005 -0600 4.3 @@ -0,0 +1,1593 @@ 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 + /* 4.53 + * execve() is special because in case of success, we need to 4.54 + * setup a null register window frame. 4.55 + */ 4.56 +ENTRY(ia64_execve) 4.57 + /* 4.58 + * Allocate 8 input registers since ptrace() may clobber them 4.59 + */ 4.60 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.61 + alloc loc1=ar.pfs,8,2,4,0 4.62 + mov loc0=rp 4.63 + .body 4.64 + mov out0=in0 // filename 4.65 + ;; // stop bit between alloc and call 4.66 + mov out1=in1 // argv 4.67 + mov out2=in2 // envp 4.68 + add out3=16,sp // regs 4.69 + br.call.sptk.many rp=sys_execve 4.70 +.ret0: 4.71 +#ifdef CONFIG_IA32_SUPPORT 4.72 + /* 4.73 + * Check if we're returning to ia32 mode. If so, we need to restore ia32 registers 4.74 + * from pt_regs. 4.75 + */ 4.76 + adds r16=PT(CR_IPSR)+16,sp 4.77 + ;; 4.78 + ld8 r16=[r16] 4.79 +#endif 4.80 + cmp4.ge p6,p7=r8,r0 4.81 + mov ar.pfs=loc1 // restore ar.pfs 4.82 + sxt4 r8=r8 // return 64-bit result 4.83 + ;; 4.84 + stf.spill [sp]=f0 4.85 +(p6) cmp.ne pKStk,pUStk=r0,r0 // a successful execve() lands us in user-mode... 4.86 + mov rp=loc0 4.87 +(p6) mov ar.pfs=r0 // clear ar.pfs on success 4.88 +(p7) br.ret.sptk.many rp 4.89 + 4.90 + /* 4.91 + * In theory, we'd have to zap this state only to prevent leaking of 4.92 + * security sensitive state (e.g., if current->mm->dumpable is zero). However, 4.93 + * this executes in less than 20 cycles even on Itanium, so it's not worth 4.94 + * optimizing for...). 4.95 + */ 4.96 + mov ar.unat=0; mov ar.lc=0 4.97 + mov r4=0; mov f2=f0; mov b1=r0 4.98 + mov r5=0; mov f3=f0; mov b2=r0 4.99 + mov r6=0; mov f4=f0; mov b3=r0 4.100 + mov r7=0; mov f5=f0; mov b4=r0 4.101 + ldf.fill f12=[sp]; mov f13=f0; mov b5=r0 4.102 + ldf.fill f14=[sp]; ldf.fill f15=[sp]; mov f16=f0 4.103 + ldf.fill f17=[sp]; ldf.fill f18=[sp]; mov f19=f0 4.104 + ldf.fill f20=[sp]; ldf.fill f21=[sp]; mov f22=f0 4.105 + ldf.fill f23=[sp]; ldf.fill f24=[sp]; mov f25=f0 4.106 + ldf.fill f26=[sp]; ldf.fill f27=[sp]; mov f28=f0 4.107 + ldf.fill f29=[sp]; ldf.fill f30=[sp]; mov f31=f0 4.108 +#ifdef CONFIG_IA32_SUPPORT 4.109 + tbit.nz p6,p0=r16, IA64_PSR_IS_BIT 4.110 + movl loc0=ia64_ret_from_ia32_execve 4.111 + ;; 4.112 +(p6) mov rp=loc0 4.113 +#endif 4.114 + br.ret.sptk.many rp 4.115 +END(ia64_execve) 4.116 + 4.117 +/* 4.118 + * sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 parent_tidptr, u64 child_tidptr, 4.119 + * u64 tls) 4.120 + */ 4.121 +GLOBAL_ENTRY(sys_clone2) 4.122 + /* 4.123 + * Allocate 8 input registers since ptrace() may clobber them 4.124 + */ 4.125 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.126 + alloc r16=ar.pfs,8,2,6,0 4.127 + DO_SAVE_SWITCH_STACK 4.128 + adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp 4.129 + mov loc0=rp 4.130 + mov loc1=r16 // save ar.pfs across do_fork 4.131 + .body 4.132 + mov out1=in1 4.133 + mov out3=in2 4.134 + tbit.nz p6,p0=in0,CLONE_SETTLS_BIT 4.135 + mov out4=in3 // parent_tidptr: valid only w/CLONE_PARENT_SETTID 4.136 + ;; 4.137 +(p6) st8 [r2]=in5 // store TLS in r16 for copy_thread() 4.138 + mov out5=in4 // child_tidptr: valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID 4.139 + adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s 4.140 + mov out0=in0 // out0 = clone_flags 4.141 + br.call.sptk.many rp=do_fork 4.142 +.ret1: .restore sp 4.143 + adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack 4.144 + mov ar.pfs=loc1 4.145 + mov rp=loc0 4.146 + br.ret.sptk.many rp 4.147 +END(sys_clone2) 4.148 + 4.149 +/* 4.150 + * sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls) 4.151 + * Deprecated. Use sys_clone2() instead. 4.152 + */ 4.153 +GLOBAL_ENTRY(sys_clone) 4.154 + /* 4.155 + * Allocate 8 input registers since ptrace() may clobber them 4.156 + */ 4.157 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.158 + alloc r16=ar.pfs,8,2,6,0 4.159 + DO_SAVE_SWITCH_STACK 4.160 + adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp 4.161 + mov loc0=rp 4.162 + mov loc1=r16 // save ar.pfs across do_fork 4.163 + .body 4.164 + mov out1=in1 4.165 + mov out3=16 // stacksize (compensates for 16-byte scratch area) 4.166 + tbit.nz p6,p0=in0,CLONE_SETTLS_BIT 4.167 + mov out4=in2 // parent_tidptr: valid only w/CLONE_PARENT_SETTID 4.168 + ;; 4.169 +(p6) st8 [r2]=in4 // store TLS in r13 (tp) 4.170 + mov out5=in3 // child_tidptr: valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID 4.171 + adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s 4.172 + mov out0=in0 // out0 = clone_flags 4.173 + br.call.sptk.many rp=do_fork 4.174 +.ret2: .restore sp 4.175 + adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack 4.176 + mov ar.pfs=loc1 4.177 + mov rp=loc0 4.178 + br.ret.sptk.many rp 4.179 +END(sys_clone) 4.180 + 4.181 +/* 4.182 + * prev_task <- ia64_switch_to(struct task_struct *next) 4.183 + * With Ingo's new scheduler, interrupts are disabled when this routine gets 4.184 + * called. The code starting at .map relies on this. The rest of the code 4.185 + * doesn't care about the interrupt masking status. 4.186 + */ 4.187 +GLOBAL_ENTRY(__ia64_switch_to) 4.188 + .prologue 4.189 + alloc r16=ar.pfs,1,0,0,0 4.190 + DO_SAVE_SWITCH_STACK 4.191 + .body 4.192 + 4.193 + adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 4.194 + movl r25=init_task 4.195 + mov r27=IA64_KR(CURRENT_STACK) 4.196 + adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 4.197 + dep r20=0,in0,61,3 // physical address of "next" 4.198 + ;; 4.199 + st8 [r22]=sp // save kernel stack pointer of old task 4.200 + shr.u r26=r20,IA64_GRANULE_SHIFT 4.201 + cmp.eq p7,p6=r25,in0 4.202 + ;; 4.203 + /* 4.204 + * If we've already mapped this task's page, we can skip doing it again. 4.205 + */ 4.206 +(p6) cmp.eq p7,p6=r26,r27 4.207 +(p6) br.cond.dpnt .map 4.208 + ;; 4.209 +.done: 4.210 +(p6) ssm psr.ic // if we had to map, reenable the psr.ic bit FIRST!!! 4.211 + ;; 4.212 +(p6) srlz.d 4.213 + ld8 sp=[r21] // load kernel stack pointer of new task 4.214 + mov IA64_KR(CURRENT)=in0 // update "current" application register 4.215 + mov r8=r13 // return pointer to previously running task 4.216 + mov r13=in0 // set "current" pointer 4.217 + ;; 4.218 + DO_LOAD_SWITCH_STACK 4.219 + 4.220 +#ifdef CONFIG_SMP 4.221 + sync.i // ensure "fc"s done by this CPU are visible on other CPUs 4.222 +#endif 4.223 + br.ret.sptk.many rp // boogie on out in new context 4.224 + 4.225 +.map: 4.226 + rsm psr.ic // interrupts (psr.i) are already disabled here 4.227 + movl r25=PAGE_KERNEL 4.228 + ;; 4.229 + srlz.d 4.230 + or r23=r25,r20 // construct PA | page properties 4.231 + mov r25=IA64_GRANULE_SHIFT<<2 4.232 + ;; 4.233 + mov cr.itir=r25 4.234 + mov cr.ifa=in0 // VA of next task... 4.235 + ;; 4.236 + mov r25=IA64_TR_CURRENT_STACK 4.237 + mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped... 4.238 + ;; 4.239 + itr.d dtr[r25]=r23 // wire in new mapping... 4.240 + br.cond.sptk .done 4.241 +END(__ia64_switch_to) 4.242 + 4.243 +/* 4.244 + * Note that interrupts are enabled during save_switch_stack and load_switch_stack. This 4.245 + * means that we may get an interrupt with "sp" pointing to the new kernel stack while 4.246 + * ar.bspstore is still pointing to the old kernel backing store area. Since ar.rsc, 4.247 + * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts, this is not a 4.248 + * problem. Also, we don't need to specify unwind information for preserved registers 4.249 + * that are not modified in save_switch_stack as the right unwind information is already 4.250 + * specified at the call-site of save_switch_stack. 4.251 + */ 4.252 + 4.253 +/* 4.254 + * save_switch_stack: 4.255 + * - r16 holds ar.pfs 4.256 + * - b7 holds address to return to 4.257 + * - rp (b0) holds return address to save 4.258 + */ 4.259 +GLOBAL_ENTRY(save_switch_stack) 4.260 + .prologue 4.261 + .altrp b7 4.262 + flushrs // flush dirty regs to backing store (must be first in insn group) 4.263 + .save @priunat,r17 4.264 + mov r17=ar.unat // preserve caller's 4.265 + .body 4.266 +#ifdef CONFIG_ITANIUM 4.267 + adds r2=16+128,sp 4.268 + adds r3=16+64,sp 4.269 + adds r14=SW(R4)+16,sp 4.270 + ;; 4.271 + st8.spill [r14]=r4,16 // spill r4 4.272 + lfetch.fault.excl.nt1 [r3],128 4.273 + ;; 4.274 + lfetch.fault.excl.nt1 [r2],128 4.275 + lfetch.fault.excl.nt1 [r3],128 4.276 + ;; 4.277 + lfetch.fault.excl [r2] 4.278 + lfetch.fault.excl [r3] 4.279 + adds r15=SW(R5)+16,sp 4.280 +#else 4.281 + add r2=16+3*128,sp 4.282 + add r3=16,sp 4.283 + add r14=SW(R4)+16,sp 4.284 + ;; 4.285 + st8.spill [r14]=r4,SW(R6)-SW(R4) // spill r4 and prefetch offset 0x1c0 4.286 + lfetch.fault.excl.nt1 [r3],128 // prefetch offset 0x010 4.287 + ;; 4.288 + lfetch.fault.excl.nt1 [r3],128 // prefetch offset 0x090 4.289 + lfetch.fault.excl.nt1 [r2],128 // prefetch offset 0x190 4.290 + ;; 4.291 + lfetch.fault.excl.nt1 [r3] // prefetch offset 0x110 4.292 + lfetch.fault.excl.nt1 [r2] // prefetch offset 0x210 4.293 + adds r15=SW(R5)+16,sp 4.294 +#endif 4.295 + ;; 4.296 + st8.spill [r15]=r5,SW(R7)-SW(R5) // spill r5 4.297 + mov.m ar.rsc=0 // put RSE in mode: enforced lazy, little endian, pl 0 4.298 + add r2=SW(F2)+16,sp // r2 = &sw->f2 4.299 + ;; 4.300 + st8.spill [r14]=r6,SW(B0)-SW(R6) // spill r6 4.301 + mov.m r18=ar.fpsr // preserve fpsr 4.302 + add r3=SW(F3)+16,sp // r3 = &sw->f3 4.303 + ;; 4.304 + stf.spill [r2]=f2,32 4.305 + mov.m r19=ar.rnat 4.306 + mov r21=b0 4.307 + 4.308 + stf.spill [r3]=f3,32 4.309 + st8.spill [r15]=r7,SW(B2)-SW(R7) // spill r7 4.310 + mov r22=b1 4.311 + ;; 4.312 + // since we're done with the spills, read and save ar.unat: 4.313 + mov.m r29=ar.unat 4.314 + mov.m r20=ar.bspstore 4.315 + mov r23=b2 4.316 + stf.spill [r2]=f4,32 4.317 + stf.spill [r3]=f5,32 4.318 + mov r24=b3 4.319 + ;; 4.320 + st8 [r14]=r21,SW(B1)-SW(B0) // save b0 4.321 + st8 [r15]=r23,SW(B3)-SW(B2) // save b2 4.322 + mov r25=b4 4.323 + mov r26=b5 4.324 + ;; 4.325 + st8 [r14]=r22,SW(B4)-SW(B1) // save b1 4.326 + st8 [r15]=r24,SW(AR_PFS)-SW(B3) // save b3 4.327 + mov r21=ar.lc // I-unit 4.328 + stf.spill [r2]=f12,32 4.329 + stf.spill [r3]=f13,32 4.330 + ;; 4.331 + st8 [r14]=r25,SW(B5)-SW(B4) // save b4 4.332 + st8 [r15]=r16,SW(AR_LC)-SW(AR_PFS) // save ar.pfs 4.333 + stf.spill [r2]=f14,32 4.334 + stf.spill [r3]=f15,32 4.335 + ;; 4.336 + st8 [r14]=r26 // save b5 4.337 + st8 [r15]=r21 // save ar.lc 4.338 + stf.spill [r2]=f16,32 4.339 + stf.spill [r3]=f17,32 4.340 + ;; 4.341 + stf.spill [r2]=f18,32 4.342 + stf.spill [r3]=f19,32 4.343 + ;; 4.344 + stf.spill [r2]=f20,32 4.345 + stf.spill [r3]=f21,32 4.346 + ;; 4.347 + stf.spill [r2]=f22,32 4.348 + stf.spill [r3]=f23,32 4.349 + ;; 4.350 + stf.spill [r2]=f24,32 4.351 + stf.spill [r3]=f25,32 4.352 + ;; 4.353 + stf.spill [r2]=f26,32 4.354 + stf.spill [r3]=f27,32 4.355 + ;; 4.356 + stf.spill [r2]=f28,32 4.357 + stf.spill [r3]=f29,32 4.358 + ;; 4.359 + stf.spill [r2]=f30,SW(AR_UNAT)-SW(F30) 4.360 + stf.spill [r3]=f31,SW(PR)-SW(F31) 4.361 + add r14=SW(CALLER_UNAT)+16,sp 4.362 + ;; 4.363 + st8 [r2]=r29,SW(AR_RNAT)-SW(AR_UNAT) // save ar.unat 4.364 + st8 [r14]=r17,SW(AR_FPSR)-SW(CALLER_UNAT) // save caller_unat 4.365 + mov r21=pr 4.366 + ;; 4.367 + st8 [r2]=r19,SW(AR_BSPSTORE)-SW(AR_RNAT) // save ar.rnat 4.368 + st8 [r3]=r21 // save predicate registers 4.369 + ;; 4.370 + st8 [r2]=r20 // save ar.bspstore 4.371 + st8 [r14]=r18 // save fpsr 4.372 + mov ar.rsc=3 // put RSE back into eager mode, pl 0 4.373 + br.cond.sptk.many b7 4.374 +END(save_switch_stack) 4.375 + 4.376 +/* 4.377 + * load_switch_stack: 4.378 + * - "invala" MUST be done at call site (normally in DO_LOAD_SWITCH_STACK) 4.379 + * - b7 holds address to return to 4.380 + * - must not touch r8-r11 4.381 + */ 4.382 +GLOBAL_ENTRY(load_switch_stack) 4.383 + .prologue 4.384 + .altrp b7 4.385 + 4.386 + .body 4.387 + lfetch.fault.nt1 [sp] 4.388 + adds r2=SW(AR_BSPSTORE)+16,sp 4.389 + adds r3=SW(AR_UNAT)+16,sp 4.390 + mov ar.rsc=0 // put RSE into enforced lazy mode 4.391 + adds r14=SW(CALLER_UNAT)+16,sp 4.392 + adds r15=SW(AR_FPSR)+16,sp 4.393 + ;; 4.394 + ld8 r27=[r2],(SW(B0)-SW(AR_BSPSTORE)) // bspstore 4.395 + ld8 r29=[r3],(SW(B1)-SW(AR_UNAT)) // unat 4.396 + ;; 4.397 + ld8 r21=[r2],16 // restore b0 4.398 + ld8 r22=[r3],16 // restore b1 4.399 + ;; 4.400 + ld8 r23=[r2],16 // restore b2 4.401 + ld8 r24=[r3],16 // restore b3 4.402 + ;; 4.403 + ld8 r25=[r2],16 // restore b4 4.404 + ld8 r26=[r3],16 // restore b5 4.405 + ;; 4.406 + ld8 r16=[r2],(SW(PR)-SW(AR_PFS)) // ar.pfs 4.407 + ld8 r17=[r3],(SW(AR_RNAT)-SW(AR_LC)) // ar.lc 4.408 + ;; 4.409 + ld8 r28=[r2] // restore pr 4.410 + ld8 r30=[r3] // restore rnat 4.411 + ;; 4.412 + ld8 r18=[r14],16 // restore caller's unat 4.413 + ld8 r19=[r15],24 // restore fpsr 4.414 + ;; 4.415 + ldf.fill f2=[r14],32 4.416 + ldf.fill f3=[r15],32 4.417 + ;; 4.418 + ldf.fill f4=[r14],32 4.419 + ldf.fill f5=[r15],32 4.420 + ;; 4.421 + ldf.fill f12=[r14],32 4.422 + ldf.fill f13=[r15],32 4.423 + ;; 4.424 + ldf.fill f14=[r14],32 4.425 + ldf.fill f15=[r15],32 4.426 + ;; 4.427 + ldf.fill f16=[r14],32 4.428 + ldf.fill f17=[r15],32 4.429 + ;; 4.430 + ldf.fill f18=[r14],32 4.431 + ldf.fill f19=[r15],32 4.432 + mov b0=r21 4.433 + ;; 4.434 + ldf.fill f20=[r14],32 4.435 + ldf.fill f21=[r15],32 4.436 + mov b1=r22 4.437 + ;; 4.438 + ldf.fill f22=[r14],32 4.439 + ldf.fill f23=[r15],32 4.440 + mov b2=r23 4.441 + ;; 4.442 + mov ar.bspstore=r27 4.443 + mov ar.unat=r29 // establish unat holding the NaT bits for r4-r7 4.444 + mov b3=r24 4.445 + ;; 4.446 + ldf.fill f24=[r14],32 4.447 + ldf.fill f25=[r15],32 4.448 + mov b4=r25 4.449 + ;; 4.450 + ldf.fill f26=[r14],32 4.451 + ldf.fill f27=[r15],32 4.452 + mov b5=r26 4.453 + ;; 4.454 + ldf.fill f28=[r14],32 4.455 + ldf.fill f29=[r15],32 4.456 + mov ar.pfs=r16 4.457 + ;; 4.458 + ldf.fill f30=[r14],32 4.459 + ldf.fill f31=[r15],24 4.460 + mov ar.lc=r17 4.461 + ;; 4.462 + ld8.fill r4=[r14],16 4.463 + ld8.fill r5=[r15],16 4.464 + mov pr=r28,-1 4.465 + ;; 4.466 + ld8.fill r6=[r14],16 4.467 + ld8.fill r7=[r15],16 4.468 + 4.469 + mov ar.unat=r18 // restore caller's unat 4.470 + mov ar.rnat=r30 // must restore after bspstore but before rsc! 4.471 + mov ar.fpsr=r19 // restore fpsr 4.472 + mov ar.rsc=3 // put RSE back into eager mode, pl 0 4.473 + br.cond.sptk.many b7 4.474 +END(load_switch_stack) 4.475 + 4.476 +GLOBAL_ENTRY(__ia64_syscall) 4.477 + .regstk 6,0,0,0 4.478 + mov r15=in5 // put syscall number in place 4.479 + break __BREAK_SYSCALL 4.480 + movl r2=errno 4.481 + cmp.eq p6,p7=-1,r10 4.482 + ;; 4.483 +(p6) st4 [r2]=r8 4.484 +(p6) mov r8=-1 4.485 + br.ret.sptk.many rp 4.486 +END(__ia64_syscall) 4.487 + 4.488 +GLOBAL_ENTRY(execve) 4.489 + mov r15=__NR_execve // put syscall number in place 4.490 + break __BREAK_SYSCALL 4.491 + br.ret.sptk.many rp 4.492 +END(execve) 4.493 + 4.494 +GLOBAL_ENTRY(clone) 4.495 + mov r15=__NR_clone // put syscall number in place 4.496 + break __BREAK_SYSCALL 4.497 + br.ret.sptk.many rp 4.498 +END(clone) 4.499 + 4.500 + /* 4.501 + * Invoke a system call, but do some tracing before and after the call. 4.502 + * We MUST preserve the current register frame throughout this routine 4.503 + * because some system calls (such as ia64_execve) directly 4.504 + * manipulate ar.pfs. 4.505 + */ 4.506 +GLOBAL_ENTRY(__ia64_trace_syscall) 4.507 + PT_REGS_UNWIND_INFO(0) 4.508 + /* 4.509 + * We need to preserve the scratch registers f6-f11 in case the system 4.510 + * call is sigreturn. 4.511 + */ 4.512 + adds r16=PT(F6)+16,sp 4.513 + adds r17=PT(F7)+16,sp 4.514 + ;; 4.515 + stf.spill [r16]=f6,32 4.516 + stf.spill [r17]=f7,32 4.517 + ;; 4.518 + stf.spill [r16]=f8,32 4.519 + stf.spill [r17]=f9,32 4.520 + ;; 4.521 + stf.spill [r16]=f10 4.522 + stf.spill [r17]=f11 4.523 + br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args 4.524 + adds r16=PT(F6)+16,sp 4.525 + adds r17=PT(F7)+16,sp 4.526 + ;; 4.527 + ldf.fill f6=[r16],32 4.528 + ldf.fill f7=[r17],32 4.529 + ;; 4.530 + ldf.fill f8=[r16],32 4.531 + ldf.fill f9=[r17],32 4.532 + ;; 4.533 + ldf.fill f10=[r16] 4.534 + ldf.fill f11=[r17] 4.535 + // the syscall number may have changed, so re-load it and re-calculate the 4.536 + // syscall entry-point: 4.537 + adds r15=PT(R15)+16,sp // r15 = &pt_regs.r15 (syscall #) 4.538 + ;; 4.539 + ld8 r15=[r15] 4.540 + mov r3=NR_syscalls - 1 4.541 + ;; 4.542 + adds r15=-1024,r15 4.543 + movl r16=sys_call_table 4.544 + ;; 4.545 + shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) 4.546 + cmp.leu p6,p7=r15,r3 4.547 + ;; 4.548 +(p6) ld8 r20=[r20] // load address of syscall entry point 4.549 +(p7) movl r20=sys_ni_syscall 4.550 + ;; 4.551 + mov b6=r20 4.552 + br.call.sptk.many rp=b6 // do the syscall 4.553 +.strace_check_retval: 4.554 + cmp.lt p6,p0=r8,r0 // syscall failed? 4.555 + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 4.556 + adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 4.557 + mov r10=0 4.558 +(p6) br.cond.sptk strace_error // syscall failed -> 4.559 + ;; // avoid RAW on r10 4.560 +.strace_save_retval: 4.561 +.mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8 4.562 +.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 4.563 + br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value 4.564 +.ret3: br.cond.sptk .work_pending_syscall_end 4.565 + 4.566 +strace_error: 4.567 + ld8 r3=[r2] // load pt_regs.r8 4.568 + sub r9=0,r8 // negate return value to get errno value 4.569 + ;; 4.570 + cmp.ne p6,p0=r3,r0 // is pt_regs.r8!=0? 4.571 + adds r3=16,r2 // r3=&pt_regs.r10 4.572 + ;; 4.573 +(p6) mov r10=-1 4.574 +(p6) mov r8=r9 4.575 + br.cond.sptk .strace_save_retval 4.576 +END(__ia64_trace_syscall) 4.577 + 4.578 + /* 4.579 + * When traced and returning from sigreturn, we invoke syscall_trace but then 4.580 + * go straight to ia64_leave_kernel rather than ia64_leave_syscall. 4.581 + */ 4.582 +GLOBAL_ENTRY(ia64_strace_leave_kernel) 4.583 + PT_REGS_UNWIND_INFO(0) 4.584 +{ /* 4.585 + * Some versions of gas generate bad unwind info if the first instruction of a 4.586 + * procedure doesn't go into the first slot of a bundle. This is a workaround. 4.587 + */ 4.588 + nop.m 0 4.589 + nop.i 0 4.590 + br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value 4.591 +} 4.592 +.ret4: br.cond.sptk ia64_leave_kernel 4.593 +END(ia64_strace_leave_kernel) 4.594 + 4.595 +GLOBAL_ENTRY(ia64_ret_from_clone) 4.596 + PT_REGS_UNWIND_INFO(0) 4.597 +{ /* 4.598 + * Some versions of gas generate bad unwind info if the first instruction of a 4.599 + * procedure doesn't go into the first slot of a bundle. This is a workaround. 4.600 + */ 4.601 + nop.m 0 4.602 + nop.i 0 4.603 + /* 4.604 + * We need to call schedule_tail() to complete the scheduling process. 4.605 + * Called by ia64_switch_to() after do_fork()->copy_thread(). r8 contains the 4.606 + * address of the previously executing task. 4.607 + */ 4.608 + br.call.sptk.many rp=ia64_invoke_schedule_tail 4.609 +} 4.610 +.ret8: 4.611 + adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 4.612 + ;; 4.613 + ld4 r2=[r2] 4.614 + ;; 4.615 + mov r8=0 4.616 + and r2=_TIF_SYSCALL_TRACEAUDIT,r2 4.617 + ;; 4.618 + cmp.ne p6,p0=r2,r0 4.619 +(p6) br.cond.spnt .strace_check_retval 4.620 + ;; // added stop bits to prevent r8 dependency 4.621 +END(ia64_ret_from_clone) 4.622 + // fall through 4.623 +GLOBAL_ENTRY(ia64_ret_from_syscall) 4.624 + PT_REGS_UNWIND_INFO(0) 4.625 + cmp.ge p6,p7=r8,r0 // syscall executed successfully? 4.626 + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 4.627 + mov r10=r0 // clear error indication in r10 4.628 +(p7) br.cond.spnt handle_syscall_error // handle potential syscall failure 4.629 + ;; 4.630 + // don't fall through, ia64_leave_syscall may be #define'd 4.631 + br.cond.sptk.few ia64_leave_syscall 4.632 + ;; 4.633 +END(ia64_ret_from_syscall) 4.634 +/* 4.635 + * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't 4.636 + * need to switch to bank 0 and doesn't restore the scratch registers. 4.637 + * To avoid leaking kernel bits, the scratch registers are set to 4.638 + * the following known-to-be-safe values: 4.639 + * 4.640 + * r1: restored (global pointer) 4.641 + * r2: cleared 4.642 + * r3: 1 (when returning to user-level) 4.643 + * r8-r11: restored (syscall return value(s)) 4.644 + * r12: restored (user-level stack pointer) 4.645 + * r13: restored (user-level thread pointer) 4.646 + * r14: cleared 4.647 + * r15: restored (syscall #) 4.648 + * r16-r17: cleared 4.649 + * r18: user-level b6 4.650 + * r19: cleared 4.651 + * r20: user-level ar.fpsr 4.652 + * r21: user-level b0 4.653 + * r22: cleared 4.654 + * r23: user-level ar.bspstore 4.655 + * r24: user-level ar.rnat 4.656 + * r25: user-level ar.unat 4.657 + * r26: user-level ar.pfs 4.658 + * r27: user-level ar.rsc 4.659 + * r28: user-level ip 4.660 + * r29: user-level psr 4.661 + * r30: user-level cfm 4.662 + * r31: user-level pr 4.663 + * f6-f11: cleared 4.664 + * pr: restored (user-level pr) 4.665 + * b0: restored (user-level rp) 4.666 + * b6: restored 4.667 + * b7: cleared 4.668 + * ar.unat: restored (user-level ar.unat) 4.669 + * ar.pfs: restored (user-level ar.pfs) 4.670 + * ar.rsc: restored (user-level ar.rsc) 4.671 + * ar.rnat: restored (user-level ar.rnat) 4.672 + * ar.bspstore: restored (user-level ar.bspstore) 4.673 + * ar.fpsr: restored (user-level ar.fpsr) 4.674 + * ar.ccv: cleared 4.675 + * ar.csd: cleared 4.676 + * ar.ssd: cleared 4.677 + */ 4.678 +GLOBAL_ENTRY(__ia64_leave_syscall) 4.679 + PT_REGS_UNWIND_INFO(0) 4.680 + /* 4.681 + * work.need_resched etc. mustn't get changed by this CPU before it returns to 4.682 + * user- or fsys-mode, hence we disable interrupts early on. 4.683 + * 4.684 + * p6 controls whether current_thread_info()->flags needs to be check for 4.685 + * extra work. We always check for extra work when returning to user-level. 4.686 + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count 4.687 + * is 0. After extra work processing has been completed, execution 4.688 + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check 4.689 + * needs to be redone. 4.690 + */ 4.691 +#ifdef CONFIG_PREEMPT 4.692 + rsm psr.i // disable interrupts 4.693 + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall 4.694 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 4.695 + ;; 4.696 + .pred.rel.mutex pUStk,pKStk 4.697 +(pKStk) ld4 r21=[r20] // r21 <- preempt_count 4.698 +(pUStk) mov r21=0 // r21 <- 0 4.699 + ;; 4.700 + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) 4.701 +#else /* !CONFIG_PREEMPT */ 4.702 +(pUStk) rsm psr.i 4.703 + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall 4.704 +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk 4.705 +#endif 4.706 +.work_processed_syscall: 4.707 + adds r2=PT(LOADRS)+16,r12 4.708 + adds r3=PT(AR_BSPSTORE)+16,r12 4.709 + adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 4.710 + ;; 4.711 +(p6) ld4 r31=[r18] // load current_thread_info()->flags 4.712 + ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" 4.713 + mov b7=r0 // clear b7 4.714 + ;; 4.715 + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) 4.716 + ld8 r18=[r2],PT(R9)-PT(B6) // load b6 4.717 +(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? 4.718 + ;; 4.719 + mov r16=ar.bsp // M2 get existing backing store pointer 4.720 +(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? 4.721 +(p6) br.cond.spnt .work_pending_syscall 4.722 + ;; 4.723 + // start restoring the state saved on the kernel stack (struct pt_regs): 4.724 + ld8 r9=[r2],PT(CR_IPSR)-PT(R9) 4.725 + ld8 r11=[r3],PT(CR_IIP)-PT(R11) 4.726 + mov f6=f0 // clear f6 4.727 + ;; 4.728 + invala // M0|1 invalidate ALAT 4.729 + rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection 4.730 + mov f9=f0 // clear f9 4.731 + 4.732 + ld8 r29=[r2],16 // load cr.ipsr 4.733 + ld8 r28=[r3],16 // load cr.iip 4.734 + mov f8=f0 // clear f8 4.735 + ;; 4.736 + ld8 r30=[r2],16 // M0|1 load cr.ifs 4.737 + ld8 r25=[r3],16 // M0|1 load ar.unat 4.738 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs 4.739 + ;; 4.740 + ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs 4.741 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled 4.742 + mov f10=f0 // clear f10 4.743 + ;; 4.744 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 4.745 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc 4.746 + mov f11=f0 // clear f11 4.747 + ;; 4.748 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) 4.749 + ld8 r31=[r3],PT(R1)-PT(PR) // load predicates 4.750 +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 4.751 + ;; 4.752 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr 4.753 + ld8.fill r1=[r3],16 // load r1 4.754 +(pUStk) mov r17=1 4.755 + ;; 4.756 + srlz.d // M0 ensure interruption collection is off 4.757 + ld8.fill r13=[r3],16 4.758 + mov f7=f0 // clear f7 4.759 + ;; 4.760 + ld8.fill r12=[r2] // restore r12 (sp) 4.761 + mov.m ar.ssd=r0 // M2 clear ar.ssd 4.762 + mov r22=r0 // clear r22 4.763 + 4.764 + ld8.fill r15=[r3] // restore r15 4.765 +(pUStk) st1 [r14]=r17 4.766 + addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 4.767 + ;; 4.768 +(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 4.769 + mov.m ar.csd=r0 // M2 clear ar.csd 4.770 + mov b6=r18 // I0 restore b6 4.771 + ;; 4.772 + mov r14=r0 // clear r14 4.773 + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition 4.774 +(pKStk) br.cond.dpnt.many skip_rbs_switch 4.775 + 4.776 + mov.m ar.ccv=r0 // clear ar.ccv 4.777 +(pNonSys) br.cond.dpnt.many dont_preserve_current_frame 4.778 + br.cond.sptk.many rbs_switch 4.779 +END(__ia64_leave_syscall) 4.780 + 4.781 +#ifdef CONFIG_IA32_SUPPORT 4.782 +GLOBAL_ENTRY(ia64_ret_from_ia32_execve) 4.783 + PT_REGS_UNWIND_INFO(0) 4.784 + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 4.785 + adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 4.786 + ;; 4.787 + .mem.offset 0,0 4.788 + st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit 4.789 + .mem.offset 8,0 4.790 + st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit 4.791 + ;; 4.792 + // don't fall through, ia64_leave_kernel may be #define'd 4.793 + br.cond.sptk.few ia64_leave_kernel 4.794 + ;; 4.795 +END(ia64_ret_from_ia32_execve) 4.796 +#endif /* CONFIG_IA32_SUPPORT */ 4.797 +GLOBAL_ENTRY(__ia64_leave_kernel) 4.798 + PT_REGS_UNWIND_INFO(0) 4.799 + /* 4.800 + * work.need_resched etc. mustn't get changed by this CPU before it returns to 4.801 + * user- or fsys-mode, hence we disable interrupts early on. 4.802 + * 4.803 + * p6 controls whether current_thread_info()->flags needs to be check for 4.804 + * extra work. We always check for extra work when returning to user-level. 4.805 + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count 4.806 + * is 0. After extra work processing has been completed, execution 4.807 + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check 4.808 + * needs to be redone. 4.809 + */ 4.810 +#ifdef CONFIG_PREEMPT 4.811 + rsm psr.i // disable interrupts 4.812 + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel 4.813 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 4.814 + ;; 4.815 + .pred.rel.mutex pUStk,pKStk 4.816 +(pKStk) ld4 r21=[r20] // r21 <- preempt_count 4.817 +(pUStk) mov r21=0 // r21 <- 0 4.818 + ;; 4.819 + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) 4.820 +#else 4.821 +(pUStk) rsm psr.i 4.822 + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel 4.823 +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk 4.824 +#endif 4.825 +.work_processed_kernel: 4.826 + adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 4.827 + ;; 4.828 +(p6) ld4 r31=[r17] // load current_thread_info()->flags 4.829 + adds r21=PT(PR)+16,r12 4.830 + ;; 4.831 + 4.832 + lfetch [r21],PT(CR_IPSR)-PT(PR) 4.833 + adds r2=PT(B6)+16,r12 4.834 + adds r3=PT(R16)+16,r12 4.835 + ;; 4.836 + lfetch [r21] 4.837 + ld8 r28=[r2],8 // load b6 4.838 + adds r29=PT(R24)+16,r12 4.839 + 4.840 + ld8.fill r16=[r3],PT(AR_CSD)-PT(R16) 4.841 + adds r30=PT(AR_CCV)+16,r12 4.842 +(p6) and r19=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? 4.843 + ;; 4.844 + ld8.fill r24=[r29] 4.845 + ld8 r15=[r30] // load ar.ccv 4.846 +(p6) cmp4.ne.unc p6,p0=r19, r0 // any special work pending? 4.847 + ;; 4.848 + ld8 r29=[r2],16 // load b7 4.849 + ld8 r30=[r3],16 // load ar.csd 4.850 +(p6) br.cond.spnt .work_pending 4.851 + ;; 4.852 + ld8 r31=[r2],16 // load ar.ssd 4.853 + ld8.fill r8=[r3],16 4.854 + ;; 4.855 + ld8.fill r9=[r2],16 4.856 + ld8.fill r10=[r3],PT(R17)-PT(R10) 4.857 + ;; 4.858 + ld8.fill r11=[r2],PT(R18)-PT(R11) 4.859 + ld8.fill r17=[r3],16 4.860 + ;; 4.861 + ld8.fill r18=[r2],16 4.862 + ld8.fill r19=[r3],16 4.863 + ;; 4.864 + ld8.fill r20=[r2],16 4.865 + ld8.fill r21=[r3],16 4.866 + mov ar.csd=r30 4.867 + mov ar.ssd=r31 4.868 + ;; 4.869 + rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection 4.870 + invala // invalidate ALAT 4.871 + ;; 4.872 + ld8.fill r22=[r2],24 4.873 + ld8.fill r23=[r3],24 4.874 + mov b6=r28 4.875 + ;; 4.876 + ld8.fill r25=[r2],16 4.877 + ld8.fill r26=[r3],16 4.878 + mov b7=r29 4.879 + ;; 4.880 + ld8.fill r27=[r2],16 4.881 + ld8.fill r28=[r3],16 4.882 + ;; 4.883 + ld8.fill r29=[r2],16 4.884 + ld8.fill r30=[r3],24 4.885 + ;; 4.886 + ld8.fill r31=[r2],PT(F9)-PT(R31) 4.887 + adds r3=PT(F10)-PT(F6),r3 4.888 + ;; 4.889 + ldf.fill f9=[r2],PT(F6)-PT(F9) 4.890 + ldf.fill f10=[r3],PT(F8)-PT(F10) 4.891 + ;; 4.892 + ldf.fill f6=[r2],PT(F7)-PT(F6) 4.893 + ;; 4.894 + ldf.fill f7=[r2],PT(F11)-PT(F7) 4.895 + ldf.fill f8=[r3],32 4.896 + ;; 4.897 + srlz.i // ensure interruption collection is off 4.898 + mov ar.ccv=r15 4.899 + ;; 4.900 + ldf.fill f11=[r2] 4.901 + bsw.0 // switch back to bank 0 (no stop bit required beforehand...) 4.902 + ;; 4.903 +(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency) 4.904 + adds r16=PT(CR_IPSR)+16,r12 4.905 + adds r17=PT(CR_IIP)+16,r12 4.906 + 4.907 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled 4.908 + nop.i 0 4.909 + nop.i 0 4.910 + ;; 4.911 + ld8 r29=[r16],16 // load cr.ipsr 4.912 + ld8 r28=[r17],16 // load cr.iip 4.913 + ;; 4.914 + ld8 r30=[r16],16 // load cr.ifs 4.915 + ld8 r25=[r17],16 // load ar.unat 4.916 + ;; 4.917 + ld8 r26=[r16],16 // load ar.pfs 4.918 + ld8 r27=[r17],16 // load ar.rsc 4.919 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs 4.920 + ;; 4.921 + ld8 r24=[r16],16 // load ar.rnat (may be garbage) 4.922 + ld8 r23=[r17],16 // load ar.bspstore (may be garbage) 4.923 + ;; 4.924 + ld8 r31=[r16],16 // load predicates 4.925 + ld8 r21=[r17],16 // load b0 4.926 + ;; 4.927 + ld8 r19=[r16],16 // load ar.rsc value for "loadrs" 4.928 + ld8.fill r1=[r17],16 // load r1 4.929 + ;; 4.930 + ld8.fill r12=[r16],16 4.931 + ld8.fill r13=[r17],16 4.932 +(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 4.933 + ;; 4.934 + ld8 r20=[r16],16 // ar.fpsr 4.935 + ld8.fill r15=[r17],16 4.936 + ;; 4.937 + ld8.fill r14=[r16],16 4.938 + ld8.fill r2=[r17] 4.939 +(pUStk) mov r17=1 4.940 + ;; 4.941 + ld8.fill r3=[r16] 4.942 +(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack 4.943 + shr.u r18=r19,16 // get byte size of existing "dirty" partition 4.944 + ;; 4.945 + mov r16=ar.bsp // get existing backing store pointer 4.946 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 4.947 + ;; 4.948 + ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 4.949 +(pKStk) br.cond.dpnt skip_rbs_switch 4.950 + 4.951 + /* 4.952 + * Restore user backing store. 4.953 + * 4.954 + * NOTE: alloc, loadrs, and cover can't be predicated. 4.955 + */ 4.956 +(pNonSys) br.cond.dpnt dont_preserve_current_frame 4.957 + 4.958 +rbs_switch: 4.959 + cover // add current frame into dirty partition and set cr.ifs 4.960 + ;; 4.961 + mov r19=ar.bsp // get new backing store pointer 4.962 + sub r16=r16,r18 // krbs = old bsp - size of dirty partition 4.963 + cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs 4.964 + ;; 4.965 + sub r19=r19,r16 // calculate total byte size of dirty partition 4.966 + add r18=64,r18 // don't force in0-in7 into memory... 4.967 + ;; 4.968 + shl r19=r19,16 // shift size of dirty partition into loadrs position 4.969 + ;; 4.970 +dont_preserve_current_frame: 4.971 + /* 4.972 + * To prevent leaking bits between the kernel and user-space, 4.973 + * we must clear the stacked registers in the "invalid" partition here. 4.974 + * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium, 4.975 + * 5 registers/cycle on McKinley). 4.976 + */ 4.977 +# define pRecurse p6 4.978 +# define pReturn p7 4.979 +#ifdef CONFIG_ITANIUM 4.980 +# define Nregs 10 4.981 +#else 4.982 +# define Nregs 14 4.983 +#endif 4.984 + alloc loc0=ar.pfs,2,Nregs-2,2,0 4.985 + shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) 4.986 + sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize 4.987 + ;; 4.988 + mov ar.rsc=r19 // load ar.rsc to be used for "loadrs" 4.989 + shladd in0=loc1,3,r17 4.990 + mov in1=0 4.991 + ;; 4.992 + TEXT_ALIGN(32) 4.993 +rse_clear_invalid: 4.994 +#ifdef CONFIG_ITANIUM 4.995 + // cycle 0 4.996 + { .mii 4.997 + alloc loc0=ar.pfs,2,Nregs-2,2,0 4.998 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse 4.999 + add out0=-Nregs*8,in0 4.1000 +}{ .mfb 4.1001 + add out1=1,in1 // increment recursion count 4.1002 + nop.f 0 4.1003 + nop.b 0 // can't do br.call here because of alloc (WAW on CFM) 4.1004 + ;; 4.1005 +}{ .mfi // cycle 1 4.1006 + mov loc1=0 4.1007 + nop.f 0 4.1008 + mov loc2=0 4.1009 +}{ .mib 4.1010 + mov loc3=0 4.1011 + mov loc4=0 4.1012 +(pRecurse) br.call.sptk.many b0=rse_clear_invalid 4.1013 + 4.1014 +}{ .mfi // cycle 2 4.1015 + mov loc5=0 4.1016 + nop.f 0 4.1017 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret 4.1018 +}{ .mib 4.1019 + mov loc6=0 4.1020 + mov loc7=0 4.1021 +(pReturn) br.ret.sptk.many b0 4.1022 +} 4.1023 +#else /* !CONFIG_ITANIUM */ 4.1024 + alloc loc0=ar.pfs,2,Nregs-2,2,0 4.1025 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse 4.1026 + add out0=-Nregs*8,in0 4.1027 + add out1=1,in1 // increment recursion count 4.1028 + mov loc1=0 4.1029 + mov loc2=0 4.1030 + ;; 4.1031 + mov loc3=0 4.1032 + mov loc4=0 4.1033 + mov loc5=0 4.1034 + mov loc6=0 4.1035 + mov loc7=0 4.1036 +(pRecurse) br.call.sptk.few b0=rse_clear_invalid 4.1037 + ;; 4.1038 + mov loc8=0 4.1039 + mov loc9=0 4.1040 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret 4.1041 + mov loc10=0 4.1042 + mov loc11=0 4.1043 +(pReturn) br.ret.sptk.many b0 4.1044 +#endif /* !CONFIG_ITANIUM */ 4.1045 +# undef pRecurse 4.1046 +# undef pReturn 4.1047 + ;; 4.1048 + alloc r17=ar.pfs,0,0,0,0 // drop current register frame 4.1049 + ;; 4.1050 + loadrs 4.1051 + ;; 4.1052 +skip_rbs_switch: 4.1053 + mov ar.unat=r25 // M2 4.1054 +(pKStk) extr.u r22=r22,21,1 // I0 extract current value of psr.pp from r22 4.1055 +(pLvSys)mov r19=r0 // A clear r19 for leave_syscall, no-op otherwise 4.1056 + ;; 4.1057 +(pUStk) mov ar.bspstore=r23 // M2 4.1058 +(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp 4.1059 +(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise 4.1060 + ;; 4.1061 + mov cr.ipsr=r29 // M2 4.1062 + mov ar.pfs=r26 // I0 4.1063 +(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise 4.1064 + 4.1065 +(p9) mov cr.ifs=r30 // M2 4.1066 + mov b0=r21 // I0 4.1067 +(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise 4.1068 + 4.1069 + mov ar.fpsr=r20 // M2 4.1070 + mov cr.iip=r28 // M2 4.1071 + nop 0 4.1072 + ;; 4.1073 +(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode 4.1074 + nop 0 4.1075 +(pLvSys)mov r2=r0 4.1076 + 4.1077 + mov ar.rsc=r27 // M2 4.1078 + mov pr=r31,-1 // I0 4.1079 + rfi // B 4.1080 + 4.1081 + /* 4.1082 + * On entry: 4.1083 + * r20 = ¤t->thread_info->pre_count (if CONFIG_PREEMPT) 4.1084 + * r31 = current->thread_info->flags 4.1085 + * On exit: 4.1086 + * p6 = TRUE if work-pending-check needs to be redone 4.1087 + */ 4.1088 +.work_pending_syscall: 4.1089 + add r2=-8,r2 4.1090 + add r3=-8,r3 4.1091 + ;; 4.1092 + st8 [r2]=r8 4.1093 + st8 [r3]=r10 4.1094 +.work_pending: 4.1095 + tbit.nz p6,p0=r31,TIF_SIGDELAYED // signal delayed from MCA/INIT/NMI/PMI context? 4.1096 +(p6) br.cond.sptk.few .sigdelayed 4.1097 + ;; 4.1098 + tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? 4.1099 +(p6) br.cond.sptk.few .notify 4.1100 +#ifdef CONFIG_PREEMPT 4.1101 +(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 4.1102 + ;; 4.1103 +(pKStk) st4 [r20]=r21 4.1104 + ssm psr.i // enable interrupts 4.1105 +#endif 4.1106 + br.call.spnt.many rp=schedule 4.1107 +.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 4.1108 + rsm psr.i // disable interrupts 4.1109 + ;; 4.1110 +#ifdef CONFIG_PREEMPT 4.1111 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 4.1112 + ;; 4.1113 +(pKStk) st4 [r20]=r0 // preempt_count() <- 0 4.1114 +#endif 4.1115 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 4.1116 + br.cond.sptk.many .work_processed_kernel // re-check 4.1117 + 4.1118 +.notify: 4.1119 +(pUStk) br.call.spnt.many rp=notify_resume_user 4.1120 +.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 4.1121 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 4.1122 + br.cond.sptk.many .work_processed_kernel // don't re-check 4.1123 + 4.1124 +// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where 4.1125 +// it could not be delivered. Deliver it now. The signal might be for us and 4.1126 +// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed 4.1127 +// signal. 4.1128 + 4.1129 +.sigdelayed: 4.1130 + br.call.sptk.many rp=do_sigdelayed 4.1131 + cmp.eq p6,p0=r0,r0 // p6 <- 1, always re-check 4.1132 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 4.1133 + br.cond.sptk.many .work_processed_kernel // re-check 4.1134 + 4.1135 +.work_pending_syscall_end: 4.1136 + adds r2=PT(R8)+16,r12 4.1137 + adds r3=PT(R10)+16,r12 4.1138 + ;; 4.1139 + ld8 r8=[r2] 4.1140 + ld8 r10=[r3] 4.1141 + br.cond.sptk.many .work_processed_syscall // re-check 4.1142 + 4.1143 +END(__ia64_leave_kernel) 4.1144 + 4.1145 +ENTRY(handle_syscall_error) 4.1146 + /* 4.1147 + * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could 4.1148 + * lead us to mistake a negative return value as a failed syscall. Those syscall 4.1149 + * must deposit a non-zero value in pt_regs.r8 to indicate an error. If 4.1150 + * pt_regs.r8 is zero, we assume that the call completed successfully. 4.1151 + */ 4.1152 + PT_REGS_UNWIND_INFO(0) 4.1153 + ld8 r3=[r2] // load pt_regs.r8 4.1154 + ;; 4.1155 + cmp.eq p6,p7=r3,r0 // is pt_regs.r8==0? 4.1156 + ;; 4.1157 +(p7) mov r10=-1 4.1158 +(p7) sub r8=0,r8 // negate return value to get errno 4.1159 + br.cond.sptk ia64_leave_syscall 4.1160 +END(handle_syscall_error) 4.1161 + 4.1162 + /* 4.1163 + * Invoke schedule_tail(task) while preserving in0-in7, which may be needed 4.1164 + * in case a system call gets restarted. 4.1165 + */ 4.1166 +GLOBAL_ENTRY(ia64_invoke_schedule_tail) 4.1167 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.1168 + alloc loc1=ar.pfs,8,2,1,0 4.1169 + mov loc0=rp 4.1170 + mov out0=r8 // Address of previous task 4.1171 + ;; 4.1172 + br.call.sptk.many rp=schedule_tail 4.1173 +.ret11: mov ar.pfs=loc1 4.1174 + mov rp=loc0 4.1175 + br.ret.sptk.many rp 4.1176 +END(ia64_invoke_schedule_tail) 4.1177 + 4.1178 + /* 4.1179 + * Setup stack and call do_notify_resume_user(). Note that pSys and pNonSys need to 4.1180 + * be set up by the caller. We declare 8 input registers so the system call 4.1181 + * args get preserved, in case we need to restart a system call. 4.1182 + */ 4.1183 +GLOBAL_ENTRY(notify_resume_user) 4.1184 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.1185 + alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart! 4.1186 + mov r9=ar.unat 4.1187 + mov loc0=rp // save return address 4.1188 + mov out0=0 // there is no "oldset" 4.1189 + adds out1=8,sp // out1=&sigscratch->ar_pfs 4.1190 +(pSys) mov out2=1 // out2==1 => we're in a syscall 4.1191 + ;; 4.1192 +(pNonSys) mov out2=0 // out2==0 => not a syscall 4.1193 + .fframe 16 4.1194 + .spillsp ar.unat, 16 4.1195 + st8 [sp]=r9,-16 // allocate space for ar.unat and save it 4.1196 + st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch 4.1197 + .body 4.1198 + br.call.sptk.many rp=do_notify_resume_user 4.1199 +.ret15: .restore sp 4.1200 + adds sp=16,sp // pop scratch stack space 4.1201 + ;; 4.1202 + ld8 r9=[sp] // load new unat from sigscratch->scratch_unat 4.1203 + mov rp=loc0 4.1204 + ;; 4.1205 + mov ar.unat=r9 4.1206 + mov ar.pfs=loc1 4.1207 + br.ret.sptk.many rp 4.1208 +END(notify_resume_user) 4.1209 + 4.1210 +GLOBAL_ENTRY(sys_rt_sigsuspend) 4.1211 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 4.1212 + alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart! 4.1213 + mov r9=ar.unat 4.1214 + mov loc0=rp // save return address 4.1215 + mov out0=in0 // mask 4.1216 + mov out1=in1 // sigsetsize 4.1217 + adds out2=8,sp // out2=&sigscratch->ar_pfs 4.1218 + ;; 4.1219 + .fframe 16 4.1220 + .spillsp ar.unat, 16 4.1221 + st8 [sp]=r9,-16 // allocate space for ar.unat and save it 4.1222 + st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch 4.1223 + .body 4.1224 + br.call.sptk.many rp=ia64_rt_sigsuspend 4.1225 +.ret17: .restore sp 4.1226 + adds sp=16,sp // pop scratch stack space 4.1227 + ;; 4.1228 + ld8 r9=[sp] // load new unat from sw->caller_unat 4.1229 + mov rp=loc0 4.1230 + ;; 4.1231 + mov ar.unat=r9 4.1232 + mov ar.pfs=loc1 4.1233 + br.ret.sptk.many rp 4.1234 +END(sys_rt_sigsuspend) 4.1235 + 4.1236 +ENTRY(sys_rt_sigreturn) 4.1237 + PT_REGS_UNWIND_INFO(0) 4.1238 + /* 4.1239 + * Allocate 8 input registers since ptrace() may clobber them 4.1240 + */ 4.1241 + alloc r2=ar.pfs,8,0,1,0 4.1242 + .prologue 4.1243 + PT_REGS_SAVES(16) 4.1244 + adds sp=-16,sp 4.1245 + .body 4.1246 + cmp.eq pNonSys,pSys=r0,r0 // sigreturn isn't a normal syscall... 4.1247 + ;; 4.1248 + /* 4.1249 + * leave_kernel() restores f6-f11 from pt_regs, but since the streamlined 4.1250 + * syscall-entry path does not save them we save them here instead. Note: we 4.1251 + * don't need to save any other registers that are not saved by the stream-lined 4.1252 + * syscall path, because restore_sigcontext() restores them. 4.1253 + */ 4.1254 + adds r16=PT(F6)+32,sp 4.1255 + adds r17=PT(F7)+32,sp 4.1256 + ;; 4.1257 + stf.spill [r16]=f6,32 4.1258 + stf.spill [r17]=f7,32 4.1259 + ;; 4.1260 + stf.spill [r16]=f8,32 4.1261 + stf.spill [r17]=f9,32 4.1262 + ;; 4.1263 + stf.spill [r16]=f10 4.1264 + stf.spill [r17]=f11 4.1265 + adds out0=16,sp // out0 = &sigscratch 4.1266 + br.call.sptk.many rp=ia64_rt_sigreturn 4.1267 +.ret19: .restore sp 0 4.1268 + adds sp=16,sp 4.1269 + ;; 4.1270 + ld8 r9=[sp] // load new ar.unat 4.1271 + mov.sptk b7=r8,__ia64_leave_kernel 4.1272 + ;; 4.1273 + mov ar.unat=r9 4.1274 + br.many b7 4.1275 +END(sys_rt_sigreturn) 4.1276 + 4.1277 +GLOBAL_ENTRY(ia64_prepare_handle_unaligned) 4.1278 + .prologue 4.1279 + /* 4.1280 + * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 4.1281 + */ 4.1282 + mov r16=r0 4.1283 + DO_SAVE_SWITCH_STACK 4.1284 + br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt 4.1285 +.ret21: .body 4.1286 + DO_LOAD_SWITCH_STACK 4.1287 + br.cond.sptk.many rp // goes to ia64_leave_kernel 4.1288 +END(ia64_prepare_handle_unaligned) 4.1289 + 4.1290 + // 4.1291 + // unw_init_running(void (*callback)(info, arg), void *arg) 4.1292 + // 4.1293 +# define EXTRA_FRAME_SIZE ((UNW_FRAME_INFO_SIZE+15)&~15) 4.1294 + 4.1295 +GLOBAL_ENTRY(unw_init_running) 4.1296 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) 4.1297 + alloc loc1=ar.pfs,2,3,3,0 4.1298 + ;; 4.1299 + ld8 loc2=[in0],8 4.1300 + mov loc0=rp 4.1301 + mov r16=loc1 4.1302 + DO_SAVE_SWITCH_STACK 4.1303 + .body 4.1304 + 4.1305 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) 4.1306 + .fframe IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE 4.1307 + SWITCH_STACK_SAVES(EXTRA_FRAME_SIZE) 4.1308 + adds sp=-EXTRA_FRAME_SIZE,sp 4.1309 + .body 4.1310 + ;; 4.1311 + adds out0=16,sp // &info 4.1312 + mov out1=r13 // current 4.1313 + adds out2=16+EXTRA_FRAME_SIZE,sp // &switch_stack 4.1314 + br.call.sptk.many rp=unw_init_frame_info 4.1315 +1: adds out0=16,sp // &info 4.1316 + mov b6=loc2 4.1317 + mov loc2=gp // save gp across indirect function call 4.1318 + ;; 4.1319 + ld8 gp=[in0] 4.1320 + mov out1=in1 // arg 4.1321 + br.call.sptk.many rp=b6 // invoke the callback function 4.1322 +1: mov gp=loc2 // restore gp 4.1323 + 4.1324 + // For now, we don't allow changing registers from within 4.1325 + // unw_init_running; if we ever want to allow that, we'd 4.1326 + // have to do a load_switch_stack here: 4.1327 + .restore sp 4.1328 + adds sp=IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE,sp 4.1329 + 4.1330 + mov ar.pfs=loc1 4.1331 + mov rp=loc0 4.1332 + br.ret.sptk.many rp 4.1333 +END(unw_init_running) 4.1334 + 4.1335 + .rodata 4.1336 + .align 8 4.1337 + .globl sys_call_table 4.1338 +sys_call_table: 4.1339 + data8 sys_ni_syscall // This must be sys_ni_syscall! See ivt.S. 4.1340 + data8 sys_exit // 1025 4.1341 + data8 sys_read 4.1342 + data8 sys_write 4.1343 + data8 sys_open 4.1344 + data8 sys_close 4.1345 + data8 sys_creat // 1030 4.1346 + data8 sys_link 4.1347 + data8 sys_unlink 4.1348 + data8 ia64_execve 4.1349 + data8 sys_chdir 4.1350 + data8 sys_fchdir // 1035 4.1351 + data8 sys_utimes 4.1352 + data8 sys_mknod 4.1353 + data8 sys_chmod 4.1354 + data8 sys_chown 4.1355 + data8 sys_lseek // 1040 4.1356 + data8 sys_getpid 4.1357 + data8 sys_getppid 4.1358 + data8 sys_mount 4.1359 + data8 sys_umount 4.1360 + data8 sys_setuid // 1045 4.1361 + data8 sys_getuid 4.1362 + data8 sys_geteuid 4.1363 + data8 sys_ptrace 4.1364 + data8 sys_access 4.1365 + data8 sys_sync // 1050 4.1366 + data8 sys_fsync 4.1367 + data8 sys_fdatasync 4.1368 + data8 sys_kill 4.1369 + data8 sys_rename 4.1370 + data8 sys_mkdir // 1055 4.1371 + data8 sys_rmdir 4.1372 + data8 sys_dup 4.1373 + data8 sys_pipe 4.1374 + data8 sys_times 4.1375 + data8 ia64_brk // 1060 4.1376 + data8 sys_setgid 4.1377 + data8 sys_getgid 4.1378 + data8 sys_getegid 4.1379 + data8 sys_acct 4.1380 + data8 sys_ioctl // 1065 4.1381 + data8 sys_fcntl 4.1382 + data8 sys_umask 4.1383 + data8 sys_chroot 4.1384 + data8 sys_ustat 4.1385 + data8 sys_dup2 // 1070 4.1386 + data8 sys_setreuid 4.1387 + data8 sys_setregid 4.1388 + data8 sys_getresuid 4.1389 + data8 sys_setresuid 4.1390 + data8 sys_getresgid // 1075 4.1391 + data8 sys_setresgid 4.1392 + data8 sys_getgroups 4.1393 + data8 sys_setgroups 4.1394 + data8 sys_getpgid 4.1395 + data8 sys_setpgid // 1080 4.1396 + data8 sys_setsid 4.1397 + data8 sys_getsid 4.1398 + data8 sys_sethostname 4.1399 + data8 sys_setrlimit 4.1400 + data8 sys_getrlimit // 1085 4.1401 + data8 sys_getrusage 4.1402 + data8 sys_gettimeofday 4.1403 + data8 sys_settimeofday 4.1404 + data8 sys_select 4.1405 + data8 sys_poll // 1090 4.1406 + data8 sys_symlink 4.1407 + data8 sys_readlink 4.1408 + data8 sys_uselib 4.1409 + data8 sys_swapon 4.1410 + data8 sys_swapoff // 1095 4.1411 + data8 sys_reboot 4.1412 + data8 sys_truncate 4.1413 + data8 sys_ftruncate 4.1414 + data8 sys_fchmod 4.1415 + data8 sys_fchown // 1100 4.1416 + data8 ia64_getpriority 4.1417 + data8 sys_setpriority 4.1418 + data8 sys_statfs 4.1419 + data8 sys_fstatfs 4.1420 + data8 sys_gettid // 1105 4.1421 + data8 sys_semget 4.1422 + data8 sys_semop 4.1423 + data8 sys_semctl 4.1424 + data8 sys_msgget 4.1425 + data8 sys_msgsnd // 1110 4.1426 + data8 sys_msgrcv 4.1427 + data8 sys_msgctl 4.1428 + data8 sys_shmget 4.1429 + data8 sys_shmat 4.1430 + data8 sys_shmdt // 1115 4.1431 + data8 sys_shmctl 4.1432 + data8 sys_syslog 4.1433 + data8 sys_setitimer 4.1434 + data8 sys_getitimer 4.1435 + data8 sys_ni_syscall // 1120 /* was: ia64_oldstat */ 4.1436 + data8 sys_ni_syscall /* was: ia64_oldlstat */ 4.1437 + data8 sys_ni_syscall /* was: ia64_oldfstat */ 4.1438 + data8 sys_vhangup 4.1439 + data8 sys_lchown 4.1440 + data8 sys_remap_file_pages // 1125 4.1441 + data8 sys_wait4 4.1442 + data8 sys_sysinfo 4.1443 + data8 sys_clone 4.1444 + data8 sys_setdomainname 4.1445 + data8 sys_newuname // 1130 4.1446 + data8 sys_adjtimex 4.1447 + data8 sys_ni_syscall /* was: ia64_create_module */ 4.1448 + data8 sys_init_module 4.1449 + data8 sys_delete_module 4.1450 + data8 sys_ni_syscall // 1135 /* was: sys_get_kernel_syms */ 4.1451 + data8 sys_ni_syscall /* was: sys_query_module */ 4.1452 + data8 sys_quotactl 4.1453 + data8 sys_bdflush 4.1454 + data8 sys_sysfs 4.1455 + data8 sys_personality // 1140 4.1456 + data8 sys_ni_syscall // sys_afs_syscall 4.1457 + data8 sys_setfsuid 4.1458 + data8 sys_setfsgid 4.1459 + data8 sys_getdents 4.1460 + data8 sys_flock // 1145 4.1461 + data8 sys_readv 4.1462 + data8 sys_writev 4.1463 + data8 sys_pread64 4.1464 + data8 sys_pwrite64 4.1465 + data8 sys_sysctl // 1150 4.1466 + data8 sys_mmap 4.1467 + data8 sys_munmap 4.1468 + data8 sys_mlock 4.1469 + data8 sys_mlockall 4.1470 + data8 sys_mprotect // 1155 4.1471 + data8 ia64_mremap 4.1472 + data8 sys_msync 4.1473 + data8 sys_munlock 4.1474 + data8 sys_munlockall 4.1475 + data8 sys_sched_getparam // 1160 4.1476 + data8 sys_sched_setparam 4.1477 + data8 sys_sched_getscheduler 4.1478 + data8 sys_sched_setscheduler 4.1479 + data8 sys_sched_yield 4.1480 + data8 sys_sched_get_priority_max // 1165 4.1481 + data8 sys_sched_get_priority_min 4.1482 + data8 sys_sched_rr_get_interval 4.1483 + data8 sys_nanosleep 4.1484 + data8 sys_nfsservctl 4.1485 + data8 sys_prctl // 1170 4.1486 + data8 sys_getpagesize 4.1487 + data8 sys_mmap2 4.1488 + data8 sys_pciconfig_read 4.1489 + data8 sys_pciconfig_write 4.1490 + data8 sys_perfmonctl // 1175 4.1491 + data8 sys_sigaltstack 4.1492 + data8 sys_rt_sigaction 4.1493 + data8 sys_rt_sigpending 4.1494 + data8 sys_rt_sigprocmask 4.1495 + data8 sys_rt_sigqueueinfo // 1180 4.1496 + data8 sys_rt_sigreturn 4.1497 + data8 sys_rt_sigsuspend 4.1498 + data8 sys_rt_sigtimedwait 4.1499 + data8 sys_getcwd 4.1500 + data8 sys_capget // 1185 4.1501 + data8 sys_capset 4.1502 + data8 sys_sendfile64 4.1503 + data8 sys_ni_syscall // sys_getpmsg (STREAMS) 4.1504 + data8 sys_ni_syscall // sys_putpmsg (STREAMS) 4.1505 + data8 sys_socket // 1190 4.1506 + data8 sys_bind 4.1507 + data8 sys_connect 4.1508 + data8 sys_listen 4.1509 + data8 sys_accept 4.1510 + data8 sys_getsockname // 1195 4.1511 + data8 sys_getpeername 4.1512 + data8 sys_socketpair 4.1513 + data8 sys_send 4.1514 + data8 sys_sendto 4.1515 + data8 sys_recv // 1200 4.1516 + data8 sys_recvfrom 4.1517 + data8 sys_shutdown 4.1518 + data8 sys_setsockopt 4.1519 + data8 sys_getsockopt 4.1520 + data8 sys_sendmsg // 1205 4.1521 + data8 sys_recvmsg 4.1522 + data8 sys_pivot_root 4.1523 + data8 sys_mincore 4.1524 + data8 sys_madvise 4.1525 + data8 sys_newstat // 1210 4.1526 + data8 sys_newlstat 4.1527 + data8 sys_newfstat 4.1528 + data8 sys_clone2 4.1529 + data8 sys_getdents64 4.1530 + data8 sys_getunwind // 1215 4.1531 + data8 sys_readahead 4.1532 + data8 sys_setxattr 4.1533 + data8 sys_lsetxattr 4.1534 + data8 sys_fsetxattr 4.1535 + data8 sys_getxattr // 1220 4.1536 + data8 sys_lgetxattr 4.1537 + data8 sys_fgetxattr 4.1538 + data8 sys_listxattr 4.1539 + data8 sys_llistxattr 4.1540 + data8 sys_flistxattr // 1225 4.1541 + data8 sys_removexattr 4.1542 + data8 sys_lremovexattr 4.1543 + data8 sys_fremovexattr 4.1544 + data8 sys_tkill 4.1545 + data8 sys_futex // 1230 4.1546 + data8 sys_sched_setaffinity 4.1547 + data8 sys_sched_getaffinity 4.1548 + data8 sys_set_tid_address 4.1549 + data8 sys_fadvise64_64 4.1550 + data8 sys_tgkill // 1235 4.1551 + data8 sys_exit_group 4.1552 + data8 sys_lookup_dcookie 4.1553 + data8 sys_io_setup 4.1554 + data8 sys_io_destroy 4.1555 + data8 sys_io_getevents // 1240 4.1556 + data8 sys_io_submit 4.1557 + data8 sys_io_cancel 4.1558 + data8 sys_epoll_create 4.1559 + data8 sys_epoll_ctl 4.1560 + data8 sys_epoll_wait // 1245 4.1561 + data8 sys_restart_syscall 4.1562 + data8 sys_semtimedop 4.1563 + data8 sys_timer_create 4.1564 + data8 sys_timer_settime 4.1565 + data8 sys_timer_gettime // 1250 4.1566 + data8 sys_timer_getoverrun 4.1567 + data8 sys_timer_delete 4.1568 + data8 sys_clock_settime 4.1569 + data8 sys_clock_gettime 4.1570 + data8 sys_clock_getres // 1255 4.1571 + data8 sys_clock_nanosleep 4.1572 + data8 sys_fstatfs64 4.1573 + data8 sys_statfs64 4.1574 + data8 sys_mbind 4.1575 + data8 sys_get_mempolicy // 1260 4.1576 + data8 sys_set_mempolicy 4.1577 + data8 sys_mq_open 4.1578 + data8 sys_mq_unlink 4.1579 + data8 sys_mq_timedsend 4.1580 + data8 sys_mq_timedreceive // 1265 4.1581 + data8 sys_mq_notify 4.1582 + data8 sys_mq_getsetattr 4.1583 + data8 sys_ni_syscall // reserved for kexec_load 4.1584 + data8 sys_ni_syscall // reserved for vserver 4.1585 + data8 sys_waitid // 1270 4.1586 + data8 sys_add_key 4.1587 + data8 sys_request_key 4.1588 + data8 sys_keyctl 4.1589 + data8 sys_ni_syscall 4.1590 + data8 sys_ni_syscall // 1275 4.1591 + data8 sys_ni_syscall 4.1592 + data8 sys_ni_syscall 4.1593 + data8 sys_ni_syscall 4.1594 + data8 sys_ni_syscall 4.1595 + 4.1596 + .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/head.S Wed Sep 21 09:06:30 2005 -0600 5.3 @@ -0,0 +1,1224 @@ 5.4 +/* 5.5 + * Here is where the ball gets rolling as far as the kernel is concerned. 5.6 + * When control is transferred to _start, the bootload has already 5.7 + * loaded us to the correct address. All that's left to do here is 5.8 + * to set up the kernel's global pointer and jump to the kernel 5.9 + * entry point. 5.10 + * 5.11 + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co 5.12 + * David Mosberger-Tang <davidm@hpl.hp.com> 5.13 + * Stephane Eranian <eranian@hpl.hp.com> 5.14 + * Copyright (C) 1999 VA Linux Systems 5.15 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> 5.16 + * Copyright (C) 1999 Intel Corp. 5.17 + * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com> 5.18 + * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com> 5.19 + * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com> 5.20 + * -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2. 5.21 + * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com> 5.22 + * Support for CPU Hotplug 5.23 + */ 5.24 + 5.25 +#include <linux/config.h> 5.26 + 5.27 +#include <asm/asmmacro.h> 5.28 +#include <asm/fpu.h> 5.29 +#include <asm/kregs.h> 5.30 +#include <asm/mmu_context.h> 5.31 +#include <asm/offsets.h> 5.32 +#include <asm/pal.h> 5.33 +#include <asm/pgtable.h> 5.34 +#include <asm/processor.h> 5.35 +#include <asm/ptrace.h> 5.36 +#include <asm/system.h> 5.37 +#include <asm/mca_asm.h> 5.38 + 5.39 +#ifdef CONFIG_HOTPLUG_CPU 5.40 +#define SAL_PSR_BITS_TO_SET \ 5.41 + (IA64_PSR_AC | IA64_PSR_BN | IA64_PSR_MFH | IA64_PSR_MFL) 5.42 + 5.43 +#define SAVE_FROM_REG(src, ptr, dest) \ 5.44 + mov dest=src;; \ 5.45 + st8 [ptr]=dest,0x08 5.46 + 5.47 +#define RESTORE_REG(reg, ptr, _tmp) \ 5.48 + ld8 _tmp=[ptr],0x08;; \ 5.49 + mov reg=_tmp 5.50 + 5.51 +#define SAVE_BREAK_REGS(ptr, _idx, _breg, _dest)\ 5.52 + mov ar.lc=IA64_NUM_DBG_REGS-1;; \ 5.53 + mov _idx=0;; \ 5.54 +1: \ 5.55 + SAVE_FROM_REG(_breg[_idx], ptr, _dest);; \ 5.56 + add _idx=1,_idx;; \ 5.57 + br.cloop.sptk.many 1b 5.58 + 5.59 +#define RESTORE_BREAK_REGS(ptr, _idx, _breg, _tmp, _lbl)\ 5.60 + mov ar.lc=IA64_NUM_DBG_REGS-1;; \ 5.61 + mov _idx=0;; \ 5.62 +_lbl: RESTORE_REG(_breg[_idx], ptr, _tmp);; \ 5.63 + add _idx=1, _idx;; \ 5.64 + br.cloop.sptk.many _lbl 5.65 + 5.66 +#define SAVE_ONE_RR(num, _reg, _tmp) \ 5.67 + movl _tmp=(num<<61);; \ 5.68 + mov _reg=rr[_tmp] 5.69 + 5.70 +#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \ 5.71 + SAVE_ONE_RR(0,_r0, _tmp);; \ 5.72 + SAVE_ONE_RR(1,_r1, _tmp);; \ 5.73 + SAVE_ONE_RR(2,_r2, _tmp);; \ 5.74 + SAVE_ONE_RR(3,_r3, _tmp);; \ 5.75 + SAVE_ONE_RR(4,_r4, _tmp);; \ 5.76 + SAVE_ONE_RR(5,_r5, _tmp);; \ 5.77 + SAVE_ONE_RR(6,_r6, _tmp);; \ 5.78 + SAVE_ONE_RR(7,_r7, _tmp);; 5.79 + 5.80 +#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \ 5.81 + st8 [ptr]=_r0, 8;; \ 5.82 + st8 [ptr]=_r1, 8;; \ 5.83 + st8 [ptr]=_r2, 8;; \ 5.84 + st8 [ptr]=_r3, 8;; \ 5.85 + st8 [ptr]=_r4, 8;; \ 5.86 + st8 [ptr]=_r5, 8;; \ 5.87 + st8 [ptr]=_r6, 8;; \ 5.88 + st8 [ptr]=_r7, 8;; 5.89 + 5.90 +#define RESTORE_REGION_REGS(ptr, _idx1, _idx2, _tmp) \ 5.91 + mov ar.lc=0x08-1;; \ 5.92 + movl _idx1=0x00;; \ 5.93 +RestRR: \ 5.94 + dep.z _idx2=_idx1,61,3;; \ 5.95 + ld8 _tmp=[ptr],8;; \ 5.96 + mov rr[_idx2]=_tmp;; \ 5.97 + srlz.d;; \ 5.98 + add _idx1=1,_idx1;; \ 5.99 + br.cloop.sptk.few RestRR 5.100 + 5.101 +#define SET_AREA_FOR_BOOTING_CPU(reg1, reg2) \ 5.102 + movl reg1=sal_state_for_booting_cpu;; \ 5.103 + ld8 reg2=[reg1];; 5.104 + 5.105 +/* 5.106 + * Adjust region registers saved before starting to save 5.107 + * break regs and rest of the states that need to be preserved. 5.108 + */ 5.109 +#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(_reg1,_reg2,_pred) \ 5.110 + SAVE_FROM_REG(b0,_reg1,_reg2);; \ 5.111 + SAVE_FROM_REG(b1,_reg1,_reg2);; \ 5.112 + SAVE_FROM_REG(b2,_reg1,_reg2);; \ 5.113 + SAVE_FROM_REG(b3,_reg1,_reg2);; \ 5.114 + SAVE_FROM_REG(b4,_reg1,_reg2);; \ 5.115 + SAVE_FROM_REG(b5,_reg1,_reg2);; \ 5.116 + st8 [_reg1]=r1,0x08;; \ 5.117 + st8 [_reg1]=r12,0x08;; \ 5.118 + st8 [_reg1]=r13,0x08;; \ 5.119 + SAVE_FROM_REG(ar.fpsr,_reg1,_reg2);; \ 5.120 + SAVE_FROM_REG(ar.pfs,_reg1,_reg2);; \ 5.121 + SAVE_FROM_REG(ar.rnat,_reg1,_reg2);; \ 5.122 + SAVE_FROM_REG(ar.unat,_reg1,_reg2);; \ 5.123 + SAVE_FROM_REG(ar.bspstore,_reg1,_reg2);; \ 5.124 + SAVE_FROM_REG(cr.dcr,_reg1,_reg2);; \ 5.125 + SAVE_FROM_REG(cr.iva,_reg1,_reg2);; \ 5.126 + SAVE_FROM_REG(cr.pta,_reg1,_reg2);; \ 5.127 + SAVE_FROM_REG(cr.itv,_reg1,_reg2);; \ 5.128 + SAVE_FROM_REG(cr.pmv,_reg1,_reg2);; \ 5.129 + SAVE_FROM_REG(cr.cmcv,_reg1,_reg2);; \ 5.130 + SAVE_FROM_REG(cr.lrr0,_reg1,_reg2);; \ 5.131 + SAVE_FROM_REG(cr.lrr1,_reg1,_reg2);; \ 5.132 + st8 [_reg1]=r4,0x08;; \ 5.133 + st8 [_reg1]=r5,0x08;; \ 5.134 + st8 [_reg1]=r6,0x08;; \ 5.135 + st8 [_reg1]=r7,0x08;; \ 5.136 + st8 [_reg1]=_pred,0x08;; \ 5.137 + SAVE_FROM_REG(ar.lc, _reg1, _reg2);; \ 5.138 + stf.spill.nta [_reg1]=f2,16;; \ 5.139 + stf.spill.nta [_reg1]=f3,16;; \ 5.140 + stf.spill.nta [_reg1]=f4,16;; \ 5.141 + stf.spill.nta [_reg1]=f5,16;; \ 5.142 + stf.spill.nta [_reg1]=f16,16;; \ 5.143 + stf.spill.nta [_reg1]=f17,16;; \ 5.144 + stf.spill.nta [_reg1]=f18,16;; \ 5.145 + stf.spill.nta [_reg1]=f19,16;; \ 5.146 + stf.spill.nta [_reg1]=f20,16;; \ 5.147 + stf.spill.nta [_reg1]=f21,16;; \ 5.148 + stf.spill.nta [_reg1]=f22,16;; \ 5.149 + stf.spill.nta [_reg1]=f23,16;; \ 5.150 + stf.spill.nta [_reg1]=f24,16;; \ 5.151 + stf.spill.nta [_reg1]=f25,16;; \ 5.152 + stf.spill.nta [_reg1]=f26,16;; \ 5.153 + stf.spill.nta [_reg1]=f27,16;; \ 5.154 + stf.spill.nta [_reg1]=f28,16;; \ 5.155 + stf.spill.nta [_reg1]=f29,16;; \ 5.156 + stf.spill.nta [_reg1]=f30,16;; \ 5.157 + stf.spill.nta [_reg1]=f31,16;; 5.158 + 5.159 +#else 5.160 +#define SET_AREA_FOR_BOOTING_CPU(a1, a2) 5.161 +#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(a1,a2, a3) 5.162 +#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) 5.163 +#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) 5.164 +#endif 5.165 + 5.166 +#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \ 5.167 + movl _tmp1=(num << 61);; \ 5.168 + mov _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize << 2) | vhpt);; \ 5.169 + mov rr[_tmp1]=_tmp2 5.170 + 5.171 + .section __special_page_section,"ax" 5.172 + 5.173 + .global empty_zero_page 5.174 +empty_zero_page: 5.175 + .skip PAGE_SIZE 5.176 + 5.177 + .global swapper_pg_dir 5.178 +swapper_pg_dir: 5.179 + .skip PAGE_SIZE 5.180 + 5.181 + .rodata 5.182 +halt_msg: 5.183 + stringz "Halting kernel\n" 5.184 + 5.185 + .text 5.186 + 5.187 + .global start_ap 5.188 + 5.189 + /* 5.190 + * Start the kernel. When the bootloader passes control to _start(), r28 5.191 + * points to the address of the boot parameter area. Execution reaches 5.192 + * here in physical mode. 5.193 + */ 5.194 +GLOBAL_ENTRY(_start) 5.195 +start_ap: 5.196 + .prologue 5.197 + .save rp, r0 // terminate unwind chain with a NULL rp 5.198 + .body 5.199 + 5.200 + rsm psr.i | psr.ic 5.201 + ;; 5.202 + srlz.i 5.203 + ;; 5.204 + /* 5.205 + * Save the region registers, predicate before they get clobbered 5.206 + */ 5.207 + SAVE_REGION_REGS(r2, r8,r9,r10,r11,r12,r13,r14,r15); 5.208 + mov r25=pr;; 5.209 + 5.210 + /* 5.211 + * Initialize kernel region registers: 5.212 + * rr[0]: VHPT enabled, page size = PAGE_SHIFT 5.213 + * rr[1]: VHPT enabled, page size = PAGE_SHIFT 5.214 + * rr[2]: VHPT enabled, page size = PAGE_SHIFT 5.215 + * rr[3]: VHPT enabled, page size = PAGE_SHIFT 5.216 + * rr[4]: VHPT enabled, page size = PAGE_SHIFT 5.217 + * rr[5]: VHPT enabled, page size = PAGE_SHIFT 5.218 + * rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT 5.219 + * rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT 5.220 + * We initialize all of them to prevent inadvertently assuming 5.221 + * something about the state of address translation early in boot. 5.222 + */ 5.223 + SET_ONE_RR(0, PAGE_SHIFT, r2, r16, 1);; 5.224 + SET_ONE_RR(1, PAGE_SHIFT, r2, r16, 1);; 5.225 + SET_ONE_RR(2, PAGE_SHIFT, r2, r16, 1);; 5.226 + SET_ONE_RR(3, PAGE_SHIFT, r2, r16, 1);; 5.227 + SET_ONE_RR(4, PAGE_SHIFT, r2, r16, 1);; 5.228 + SET_ONE_RR(5, PAGE_SHIFT, r2, r16, 1);; 5.229 + SET_ONE_RR(6, IA64_GRANULE_SHIFT, r2, r16, 0);; 5.230 + SET_ONE_RR(7, IA64_GRANULE_SHIFT, r2, r16, 0);; 5.231 + /* 5.232 + * Now pin mappings into the TLB for kernel text and data 5.233 + */ 5.234 + mov r18=KERNEL_TR_PAGE_SHIFT<<2 5.235 + movl r17=KERNEL_START 5.236 + ;; 5.237 + mov cr.itir=r18 5.238 + mov cr.ifa=r17 5.239 + mov r16=IA64_TR_KERNEL 5.240 + mov r3=ip 5.241 + movl r18=PAGE_KERNEL 5.242 + ;; 5.243 + dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT 5.244 + ;; 5.245 + or r18=r2,r18 5.246 + ;; 5.247 + srlz.i 5.248 + ;; 5.249 + itr.i itr[r16]=r18 5.250 + ;; 5.251 + itr.d dtr[r16]=r18 5.252 + ;; 5.253 + srlz.i 5.254 + 5.255 + /* 5.256 + * Switch into virtual mode: 5.257 + */ 5.258 + movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \ 5.259 + |IA64_PSR_DI) 5.260 + ;; 5.261 + mov cr.ipsr=r16 5.262 + movl r17=1f 5.263 + ;; 5.264 + mov cr.iip=r17 5.265 + mov cr.ifs=r0 5.266 + ;; 5.267 + rfi 5.268 + ;; 5.269 +1: // now we are in virtual mode 5.270 + 5.271 + SET_AREA_FOR_BOOTING_CPU(r2, r16); 5.272 + 5.273 + STORE_REGION_REGS(r16, r8,r9,r10,r11,r12,r13,r14,r15); 5.274 + SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(r16,r17,r25) 5.275 + ;; 5.276 + 5.277 + // set IVT entry point---can't access I/O ports without it 5.278 + movl r3=ia64_ivt 5.279 + ;; 5.280 + mov cr.iva=r3 5.281 + movl r2=FPSR_DEFAULT 5.282 + ;; 5.283 + srlz.i 5.284 + movl gp=__gp 5.285 + 5.286 + mov ar.fpsr=r2 5.287 + ;; 5.288 + 5.289 +#define isAP p2 // are we an Application Processor? 5.290 +#define isBP p3 // are we the Bootstrap Processor? 5.291 + 5.292 +#ifdef CONFIG_SMP 5.293 + /* 5.294 + * Find the init_task for the currently booting CPU. At poweron, and in 5.295 + * UP mode, task_for_booting_cpu is NULL. 5.296 + */ 5.297 + movl r3=task_for_booting_cpu 5.298 + ;; 5.299 + ld8 r3=[r3] 5.300 + movl r2=init_task 5.301 + ;; 5.302 + cmp.eq isBP,isAP=r3,r0 5.303 + ;; 5.304 +(isAP) mov r2=r3 5.305 +#else 5.306 + movl r2=init_task 5.307 + cmp.eq isBP,isAP=r0,r0 5.308 +#endif 5.309 + ;; 5.310 + tpa r3=r2 // r3 == phys addr of task struct 5.311 + mov r16=-1 5.312 +(isBP) br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it 5.313 + 5.314 + // load mapping for stack (virtaddr in r2, physaddr in r3) 5.315 + rsm psr.ic 5.316 + movl r17=PAGE_KERNEL 5.317 + ;; 5.318 + srlz.d 5.319 + dep r18=0,r3,0,12 5.320 + ;; 5.321 + or r18=r17,r18 5.322 + dep r2=-1,r3,61,3 // IMVA of task 5.323 + ;; 5.324 + mov r17=rr[r2] 5.325 + shr.u r16=r3,IA64_GRANULE_SHIFT 5.326 + ;; 5.327 + dep r17=0,r17,8,24 5.328 + ;; 5.329 + mov cr.itir=r17 5.330 + mov cr.ifa=r2 5.331 + 5.332 + mov r19=IA64_TR_CURRENT_STACK 5.333 + ;; 5.334 + itr.d dtr[r19]=r18 5.335 + ;; 5.336 + ssm psr.ic 5.337 + srlz.d 5.338 + ;; 5.339 + 5.340 +.load_current: 5.341 + // load the "current" pointer (r13) and ar.k6 with the current task 5.342 + mov IA64_KR(CURRENT)=r2 // virtual address 5.343 + mov IA64_KR(CURRENT_STACK)=r16 5.344 + mov r13=r2 5.345 + /* 5.346 + * Reserve space at the top of the stack for "struct pt_regs". Kernel 5.347 + * threads don't store interesting values in that structure, but the space 5.348 + * still needs to be there because time-critical stuff such as the context 5.349 + * switching can be implemented more efficiently (for example, __switch_to() 5.350 + * always sets the psr.dfh bit of the task it is switching to). 5.351 + */ 5.352 + 5.353 + addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2 5.354 + addl r2=IA64_RBS_OFFSET,r2 // initialize the RSE 5.355 + mov ar.rsc=0 // place RSE in enforced lazy mode 5.356 + ;; 5.357 + loadrs // clear the dirty partition 5.358 + ;; 5.359 + mov ar.bspstore=r2 // establish the new RSE stack 5.360 + ;; 5.361 + mov ar.rsc=0x3 // place RSE in eager mode 5.362 + 5.363 +(isBP) dep r28=-1,r28,61,3 // make address virtual 5.364 +(isBP) movl r2=ia64_boot_param 5.365 + ;; 5.366 +(isBP) st8 [r2]=r28 // save the address of the boot param area passed by the bootloader 5.367 + 5.368 +#ifdef CONFIG_SMP 5.369 +(isAP) br.call.sptk.many rp=start_secondary 5.370 +.ret0: 5.371 +(isAP) br.cond.sptk self 5.372 +#endif 5.373 + 5.374 + // This is executed by the bootstrap processor (bsp) only: 5.375 + 5.376 +#ifdef CONFIG_XEN 5.377 + br.call.sptk.many rp=early_xen_setup 5.378 + ;; 5.379 +#endif 5.380 +#ifdef CONFIG_IA64_FW_EMU 5.381 + // initialize PAL & SAL emulator: 5.382 + br.call.sptk.many rp=sys_fw_init 5.383 +.ret1: 5.384 +#endif 5.385 + br.call.sptk.many rp=start_kernel 5.386 +.ret2: addl r3=@ltoff(halt_msg),gp 5.387 + ;; 5.388 + alloc r2=ar.pfs,8,0,2,0 5.389 + ;; 5.390 + ld8 out0=[r3] 5.391 + br.call.sptk.many b0=console_print 5.392 + 5.393 +self: hint @pause 5.394 + br.sptk.many self // endless loop 5.395 +END(_start) 5.396 + 5.397 +GLOBAL_ENTRY(ia64_save_debug_regs) 5.398 + alloc r16=ar.pfs,1,0,0,0 5.399 + mov r20=ar.lc // preserve ar.lc 5.400 + mov ar.lc=IA64_NUM_DBG_REGS-1 5.401 + mov r18=0 5.402 + add r19=IA64_NUM_DBG_REGS*8,in0 5.403 + ;; 5.404 +1: mov r16=dbr[r18] 5.405 +#ifdef CONFIG_ITANIUM 5.406 + ;; 5.407 + srlz.d 5.408 +#endif 5.409 + mov r17=ibr[r18] 5.410 + add r18=1,r18 5.411 + ;; 5.412 + st8.nta [in0]=r16,8 5.413 + st8.nta [r19]=r17,8 5.414 + br.cloop.sptk.many 1b 5.415 + ;; 5.416 + mov ar.lc=r20 // restore ar.lc 5.417 + br.ret.sptk.many rp 5.418 +END(ia64_save_debug_regs) 5.419 + 5.420 +GLOBAL_ENTRY(ia64_load_debug_regs) 5.421 + alloc r16=ar.pfs,1,0,0,0 5.422 + lfetch.nta [in0] 5.423 + mov r20=ar.lc // preserve ar.lc 5.424 + add r19=IA64_NUM_DBG_REGS*8,in0 5.425 + mov ar.lc=IA64_NUM_DBG_REGS-1 5.426 + mov r18=-1 5.427 + ;; 5.428 +1: ld8.nta r16=[in0],8 5.429 + ld8.nta r17=[r19],8 5.430 + add r18=1,r18 5.431 + ;; 5.432 + mov dbr[r18]=r16 5.433 +#ifdef CONFIG_ITANIUM 5.434 + ;; 5.435 + srlz.d // Errata 132 (NoFix status) 5.436 +#endif 5.437 + mov ibr[r18]=r17 5.438 + br.cloop.sptk.many 1b 5.439 + ;; 5.440 + mov ar.lc=r20 // restore ar.lc 5.441 + br.ret.sptk.many rp 5.442 +END(ia64_load_debug_regs) 5.443 + 5.444 +GLOBAL_ENTRY(__ia64_save_fpu) 5.445 + alloc r2=ar.pfs,1,4,0,0 5.446 + adds loc0=96*16-16,in0 5.447 + adds loc1=96*16-16-128,in0 5.448 + ;; 5.449 + stf.spill.nta [loc0]=f127,-256 5.450 + stf.spill.nta [loc1]=f119,-256 5.451 + ;; 5.452 + stf.spill.nta [loc0]=f111,-256 5.453 + stf.spill.nta [loc1]=f103,-256 5.454 + ;; 5.455 + stf.spill.nta [loc0]=f95,-256 5.456 + stf.spill.nta [loc1]=f87,-256 5.457 + ;; 5.458 + stf.spill.nta [loc0]=f79,-256 5.459 + stf.spill.nta [loc1]=f71,-256 5.460 + ;; 5.461 + stf.spill.nta [loc0]=f63,-256 5.462 + stf.spill.nta [loc1]=f55,-256 5.463 + adds loc2=96*16-32,in0 5.464 + ;; 5.465 + stf.spill.nta [loc0]=f47,-256 5.466 + stf.spill.nta [loc1]=f39,-256 5.467 + adds loc3=96*16-32-128,in0 5.468 + ;; 5.469 + stf.spill.nta [loc2]=f126,-256 5.470 + stf.spill.nta [loc3]=f118,-256 5.471 + ;; 5.472 + stf.spill.nta [loc2]=f110,-256 5.473 + stf.spill.nta [loc3]=f102,-256 5.474 + ;; 5.475 + stf.spill.nta [loc2]=f94,-256 5.476 + stf.spill.nta [loc3]=f86,-256 5.477 + ;; 5.478 + stf.spill.nta [loc2]=f78,-256 5.479 + stf.spill.nta [loc3]=f70,-256 5.480 + ;; 5.481 + stf.spill.nta [loc2]=f62,-256 5.482 + stf.spill.nta [loc3]=f54,-256 5.483 + adds loc0=96*16-48,in0 5.484 + ;; 5.485 + stf.spill.nta [loc2]=f46,-256 5.486 + stf.spill.nta [loc3]=f38,-256 5.487 + adds loc1=96*16-48-128,in0 5.488 + ;; 5.489 + stf.spill.nta [loc0]=f125,-256 5.490 + stf.spill.nta [loc1]=f117,-256 5.491 + ;; 5.492 + stf.spill.nta [loc0]=f109,-256 5.493 + stf.spill.nta [loc1]=f101,-256 5.494 + ;; 5.495 + stf.spill.nta [loc0]=f93,-256 5.496 + stf.spill.nta [loc1]=f85,-256 5.497 + ;; 5.498 + stf.spill.nta [loc0]=f77,-256 5.499 + stf.spill.nta [loc1]=f69,-256 5.500 + ;; 5.501 + stf.spill.nta [loc0]=f61,-256 5.502 + stf.spill.nta [loc1]=f53,-256 5.503 + adds loc2=96*16-64,in0 5.504 + ;; 5.505 + stf.spill.nta [loc0]=f45,-256 5.506 + stf.spill.nta [loc1]=f37,-256 5.507 + adds loc3=96*16-64-128,in0 5.508 + ;; 5.509 + stf.spill.nta [loc2]=f124,-256 5.510 + stf.spill.nta [loc3]=f116,-256 5.511 + ;; 5.512 + stf.spill.nta [loc2]=f108,-256 5.513 + stf.spill.nta [loc3]=f100,-256 5.514 + ;; 5.515 + stf.spill.nta [loc2]=f92,-256 5.516 + stf.spill.nta [loc3]=f84,-256 5.517 + ;; 5.518 + stf.spill.nta [loc2]=f76,-256 5.519 + stf.spill.nta [loc3]=f68,-256 5.520 + ;; 5.521 + stf.spill.nta [loc2]=f60,-256 5.522 + stf.spill.nta [loc3]=f52,-256 5.523 + adds loc0=96*16-80,in0 5.524 + ;; 5.525 + stf.spill.nta [loc2]=f44,-256 5.526 + stf.spill.nta [loc3]=f36,-256 5.527 + adds loc1=96*16-80-128,in0 5.528 + ;; 5.529 + stf.spill.nta [loc0]=f123,-256 5.530 + stf.spill.nta [loc1]=f115,-256 5.531 + ;; 5.532 + stf.spill.nta [loc0]=f107,-256 5.533 + stf.spill.nta [loc1]=f99,-256 5.534 + ;; 5.535 + stf.spill.nta [loc0]=f91,-256 5.536 + stf.spill.nta [loc1]=f83,-256 5.537 + ;; 5.538 + stf.spill.nta [loc0]=f75,-256 5.539 + stf.spill.nta [loc1]=f67,-256 5.540 + ;; 5.541 + stf.spill.nta [loc0]=f59,-256 5.542 + stf.spill.nta [loc1]=f51,-256 5.543 + adds loc2=96*16-96,in0 5.544 + ;; 5.545 + stf.spill.nta [loc0]=f43,-256 5.546 + stf.spill.nta [loc1]=f35,-256 5.547 + adds loc3=96*16-96-128,in0 5.548 + ;; 5.549 + stf.spill.nta [loc2]=f122,-256 5.550 + stf.spill.nta [loc3]=f114,-256 5.551 + ;; 5.552 + stf.spill.nta [loc2]=f106,-256 5.553 + stf.spill.nta [loc3]=f98,-256 5.554 + ;; 5.555 + stf.spill.nta [loc2]=f90,-256 5.556 + stf.spill.nta [loc3]=f82,-256 5.557 + ;; 5.558 + stf.spill.nta [loc2]=f74,-256 5.559 + stf.spill.nta [loc3]=f66,-256 5.560 + ;; 5.561 + stf.spill.nta [loc2]=f58,-256 5.562 + stf.spill.nta [loc3]=f50,-256 5.563 + adds loc0=96*16-112,in0 5.564 + ;; 5.565 + stf.spill.nta [loc2]=f42,-256 5.566 + stf.spill.nta [loc3]=f34,-256 5.567 + adds loc1=96*16-112-128,in0 5.568 + ;; 5.569 + stf.spill.nta [loc0]=f121,-256 5.570 + stf.spill.nta [loc1]=f113,-256 5.571 + ;; 5.572 + stf.spill.nta [loc0]=f105,-256 5.573 + stf.spill.nta [loc1]=f97,-256 5.574 + ;; 5.575 + stf.spill.nta [loc0]=f89,-256 5.576 + stf.spill.nta [loc1]=f81,-256 5.577 + ;; 5.578 + stf.spill.nta [loc0]=f73,-256 5.579 + stf.spill.nta [loc1]=f65,-256 5.580 + ;; 5.581 + stf.spill.nta [loc0]=f57,-256 5.582 + stf.spill.nta [loc1]=f49,-256 5.583 + adds loc2=96*16-128,in0 5.584 + ;; 5.585 + stf.spill.nta [loc0]=f41,-256 5.586 + stf.spill.nta [loc1]=f33,-256 5.587 + adds loc3=96*16-128-128,in0 5.588 + ;; 5.589 + stf.spill.nta [loc2]=f120,-256 5.590 + stf.spill.nta [loc3]=f112,-256 5.591 + ;; 5.592 + stf.spill.nta [loc2]=f104,-256 5.593 + stf.spill.nta [loc3]=f96,-256 5.594 + ;; 5.595 + stf.spill.nta [loc2]=f88,-256 5.596 + stf.spill.nta [loc3]=f80,-256 5.597 + ;; 5.598 + stf.spill.nta [loc2]=f72,-256 5.599 + stf.spill.nta [loc3]=f64,-256 5.600 + ;; 5.601 + stf.spill.nta [loc2]=f56,-256 5.602 + stf.spill.nta [loc3]=f48,-256 5.603 + ;; 5.604 + stf.spill.nta [loc2]=f40 5.605 + stf.spill.nta [loc3]=f32 5.606 + br.ret.sptk.many rp 5.607 +END(__ia64_save_fpu) 5.608 + 5.609 +GLOBAL_ENTRY(__ia64_load_fpu) 5.610 + alloc r2=ar.pfs,1,2,0,0 5.611 + adds r3=128,in0 5.612 + adds r14=256,in0 5.613 + adds r15=384,in0 5.614 + mov loc0=512 5.615 + mov loc1=-1024+16 5.616 + ;; 5.617 + ldf.fill.nta f32=[in0],loc0 5.618 + ldf.fill.nta f40=[ r3],loc0 5.619 + ldf.fill.nta f48=[r14],loc0 5.620 + ldf.fill.nta f56=[r15],loc0 5.621 + ;; 5.622 + ldf.fill.nta f64=[in0],loc0 5.623 + ldf.fill.nta f72=[ r3],loc0 5.624 + ldf.fill.nta f80=[r14],loc0 5.625 + ldf.fill.nta f88=[r15],loc0 5.626 + ;; 5.627 + ldf.fill.nta f96=[in0],loc1 5.628 + ldf.fill.nta f104=[ r3],loc1 5.629 + ldf.fill.nta f112=[r14],loc1 5.630 + ldf.fill.nta f120=[r15],loc1 5.631 + ;; 5.632 + ldf.fill.nta f33=[in0],loc0 5.633 + ldf.fill.nta f41=[ r3],loc0 5.634 + ldf.fill.nta f49=[r14],loc0 5.635 + ldf.fill.nta f57=[r15],loc0 5.636 + ;; 5.637 + ldf.fill.nta f65=[in0],loc0 5.638 + ldf.fill.nta f73=[ r3],loc0 5.639 + ldf.fill.nta f81=[r14],loc0 5.640 + ldf.fill.nta f89=[r15],loc0 5.641 + ;; 5.642 + ldf.fill.nta f97=[in0],loc1 5.643 + ldf.fill.nta f105=[ r3],loc1 5.644 + ldf.fill.nta f113=[r14],loc1 5.645 + ldf.fill.nta f121=[r15],loc1 5.646 + ;; 5.647 + ldf.fill.nta f34=[in0],loc0 5.648 + ldf.fill.nta f42=[ r3],loc0 5.649 + ldf.fill.nta f50=[r14],loc0 5.650 + ldf.fill.nta f58=[r15],loc0 5.651 + ;; 5.652 + ldf.fill.nta f66=[in0],loc0 5.653 + ldf.fill.nta f74=[ r3],loc0 5.654 + ldf.fill.nta f82=[r14],loc0 5.655 + ldf.fill.nta f90=[r15],loc0 5.656 + ;; 5.657 + ldf.fill.nta f98=[in0],loc1 5.658 + ldf.fill.nta f106=[ r3],loc1 5.659 + ldf.fill.nta f114=[r14],loc1 5.660 + ldf.fill.nta f122=[r15],loc1 5.661 + ;; 5.662 + ldf.fill.nta f35=[in0],loc0 5.663 + ldf.fill.nta f43=[ r3],loc0 5.664 + ldf.fill.nta f51=[r14],loc0 5.665 + ldf.fill.nta f59=[r15],loc0 5.666 + ;; 5.667 + ldf.fill.nta f67=[in0],loc0 5.668 + ldf.fill.nta f75=[ r3],loc0 5.669 + ldf.fill.nta f83=[r14],loc0 5.670 + ldf.fill.nta f91=[r15],loc0 5.671 + ;; 5.672 + ldf.fill.nta f99=[in0],loc1 5.673 + ldf.fill.nta f107=[ r3],loc1 5.674 + ldf.fill.nta f115=[r14],loc1 5.675 + ldf.fill.nta f123=[r15],loc1 5.676 + ;; 5.677 + ldf.fill.nta f36=[in0],loc0 5.678 + ldf.fill.nta f44=[ r3],loc0 5.679 + ldf.fill.nta f52=[r14],loc0 5.680 + ldf.fill.nta f60=[r15],loc0 5.681 + ;; 5.682 + ldf.fill.nta f68=[in0],loc0 5.683 + ldf.fill.nta f76=[ r3],loc0 5.684 + ldf.fill.nta f84=[r14],loc0 5.685 + ldf.fill.nta f92=[r15],loc0 5.686 + ;; 5.687 + ldf.fill.nta f100=[in0],loc1 5.688 + ldf.fill.nta f108=[ r3],loc1 5.689 + ldf.fill.nta f116=[r14],loc1 5.690 + ldf.fill.nta f124=[r15],loc1 5.691 + ;; 5.692 + ldf.fill.nta f37=[in0],loc0 5.693 + ldf.fill.nta f45=[ r3],loc0 5.694 + ldf.fill.nta f53=[r14],loc0 5.695 + ldf.fill.nta f61=[r15],loc0 5.696 + ;; 5.697 + ldf.fill.nta f69=[in0],loc0 5.698 + ldf.fill.nta f77=[ r3],loc0 5.699 + ldf.fill.nta f85=[r14],loc0 5.700 + ldf.fill.nta f93=[r15],loc0 5.701 + ;; 5.702 + ldf.fill.nta f101=[in0],loc1 5.703 + ldf.fill.nta f109=[ r3],loc1 5.704 + ldf.fill.nta f117=[r14],loc1 5.705 + ldf.fill.nta f125=[r15],loc1 5.706 + ;; 5.707 + ldf.fill.nta f38 =[in0],loc0 5.708 + ldf.fill.nta f46 =[ r3],loc0 5.709 + ldf.fill.nta f54 =[r14],loc0 5.710 + ldf.fill.nta f62 =[r15],loc0 5.711 + ;; 5.712 + ldf.fill.nta f70 =[in0],loc0 5.713 + ldf.fill.nta f78 =[ r3],loc0 5.714 + ldf.fill.nta f86 =[r14],loc0 5.715 + ldf.fill.nta f94 =[r15],loc0 5.716 + ;; 5.717 + ldf.fill.nta f102=[in0],loc1 5.718 + ldf.fill.nta f110=[ r3],loc1 5.719 + ldf.fill.nta f118=[r14],loc1 5.720 + ldf.fill.nta f126=[r15],loc1 5.721 + ;; 5.722 + ldf.fill.nta f39 =[in0],loc0 5.723 + ldf.fill.nta f47 =[ r3],loc0 5.724 + ldf.fill.nta f55 =[r14],loc0 5.725 + ldf.fill.nta f63 =[r15],loc0 5.726 + ;; 5.727 + ldf.fill.nta f71 =[in0],loc0 5.728 + ldf.fill.nta f79 =[ r3],loc0 5.729 + ldf.fill.nta f87 =[r14],loc0 5.730 + ldf.fill.nta f95 =[r15],loc0 5.731 + ;; 5.732 + ldf.fill.nta f103=[in0] 5.733 + ldf.fill.nta f111=[ r3] 5.734 + ldf.fill.nta f119=[r14] 5.735 + ldf.fill.nta f127=[r15] 5.736 + br.ret.sptk.many rp 5.737 +END(__ia64_load_fpu) 5.738 + 5.739 +GLOBAL_ENTRY(__ia64_init_fpu) 5.740 + stf.spill [sp]=f0 // M3 5.741 + mov f32=f0 // F 5.742 + nop.b 0 5.743 + 5.744 + ldfps f33,f34=[sp] // M0 5.745 + ldfps f35,f36=[sp] // M1 5.746 + mov f37=f0 // F 5.747 + ;; 5.748 + 5.749 + setf.s f38=r0 // M2 5.750 + setf.s f39=r0 // M3 5.751 + mov f40=f0 // F 5.752 + 5.753 + ldfps f41,f42=[sp] // M0 5.754 + ldfps f43,f44=[sp] // M1 5.755 + mov f45=f0 // F 5.756 + 5.757 + setf.s f46=r0 // M2 5.758 + setf.s f47=r0 // M3 5.759 + mov f48=f0 // F 5.760 + 5.761 + ldfps f49,f50=[sp] // M0 5.762 + ldfps f51,f52=[sp] // M1 5.763 + mov f53=f0 // F 5.764 + 5.765 + setf.s f54=r0 // M2 5.766 + setf.s f55=r0 // M3 5.767 + mov f56=f0 // F 5.768 + 5.769 + ldfps f57,f58=[sp] // M0 5.770 + ldfps f59,f60=[sp] // M1 5.771 + mov f61=f0 // F 5.772 + 5.773 + setf.s f62=r0 // M2 5.774 + setf.s f63=r0 // M3 5.775 + mov f64=f0 // F 5.776 + 5.777 + ldfps f65,f66=[sp] // M0 5.778 + ldfps f67,f68=[sp] // M1 5.779 + mov f69=f0 // F 5.780 + 5.781 + setf.s f70=r0 // M2 5.782 + setf.s f71=r0 // M3 5.783 + mov f72=f0 // F 5.784 + 5.785 + ldfps f73,f74=[sp] // M0 5.786 + ldfps f75,f76=[sp] // M1 5.787 + mov f77=f0 // F 5.788 + 5.789 + setf.s f78=r0 // M2 5.790 + setf.s f79=r0 // M3 5.791 + mov f80=f0 // F 5.792 + 5.793 + ldfps f81,f82=[sp] // M0 5.794 + ldfps f83,f84=[sp] // M1 5.795 + mov f85=f0 // F 5.796 + 5.797 + setf.s f86=r0 // M2 5.798 + setf.s f87=r0 // M3 5.799 + mov f88=f0 // F 5.800 + 5.801 + /* 5.802 + * When the instructions are cached, it would be faster to initialize 5.803 + * the remaining registers with simply mov instructions (F-unit). 5.804 + * This gets the time down to ~29 cycles. However, this would use up 5.805 + * 33 bundles, whereas continuing with the above pattern yields 5.806 + * 10 bundles and ~30 cycles. 5.807 + */ 5.808 + 5.809 + ldfps f89,f90=[sp] // M0 5.810 + ldfps f91,f92=[sp] // M1 5.811 + mov f93=f0 // F 5.812 + 5.813 + setf.s f94=r0 // M2 5.814 + setf.s f95=r0 // M3 5.815 + mov f96=f0 // F 5.816 + 5.817 + ldfps f97,f98=[sp] // M0 5.818 + ldfps f99,f100=[sp] // M1 5.819 + mov f101=f0 // F 5.820 + 5.821 + setf.s f102=r0 // M2 5.822 + setf.s f103=r0 // M3 5.823 + mov f104=f0 // F 5.824 + 5.825 + ldfps f105,f106=[sp] // M0 5.826 + ldfps f107,f108=[sp] // M1 5.827 + mov f109=f0 // F 5.828 + 5.829 + setf.s f110=r0 // M2 5.830 + setf.s f111=r0 // M3 5.831 + mov f112=f0 // F 5.832 + 5.833 + ldfps f113,f114=[sp] // M0 5.834 + ldfps f115,f116=[sp] // M1 5.835 + mov f117=f0 // F 5.836 + 5.837 + setf.s f118=r0 // M2 5.838 + setf.s f119=r0 // M3 5.839 + mov f120=f0 // F 5.840 + 5.841 + ldfps f121,f122=[sp] // M0 5.842 + ldfps f123,f124=[sp] // M1 5.843 + mov f125=f0 // F 5.844 + 5.845 + setf.s f126=r0 // M2 5.846 + setf.s f127=r0 // M3 5.847 + br.ret.sptk.many rp // F 5.848 +END(__ia64_init_fpu) 5.849 + 5.850 +/* 5.851 + * Switch execution mode from virtual to physical 5.852 + * 5.853 + * Inputs: 5.854 + * r16 = new psr to establish 5.855 + * Output: 5.856 + * r19 = old virtual address of ar.bsp 5.857 + * r20 = old virtual address of sp 5.858 + * 5.859 + * Note: RSE must already be in enforced lazy mode 5.860 + */ 5.861 +GLOBAL_ENTRY(ia64_switch_mode_phys) 5.862 + { 5.863 + alloc r2=ar.pfs,0,0,0,0 5.864 + rsm psr.i | psr.ic // disable interrupts and interrupt collection 5.865 + mov r15=ip 5.866 + } 5.867 + ;; 5.868 + { 5.869 + flushrs // must be first insn in group 5.870 + srlz.i 5.871 + } 5.872 + ;; 5.873 + mov cr.ipsr=r16 // set new PSR 5.874 + add r3=1f-ia64_switch_mode_phys,r15 5.875 + 5.876 + mov r19=ar.bsp 5.877 + mov r20=sp 5.878 + mov r14=rp // get return address into a general register 5.879 + ;; 5.880 + 5.881 + // going to physical mode, use tpa to translate virt->phys 5.882 + tpa r17=r19 5.883 + tpa r3=r3 5.884 + tpa sp=sp 5.885 + tpa r14=r14 5.886 + ;; 5.887 + 5.888 + mov r18=ar.rnat // save ar.rnat 5.889 + mov ar.bspstore=r17 // this steps on ar.rnat 5.890 + mov cr.iip=r3 5.891 + mov cr.ifs=r0 5.892 + ;; 5.893 + mov ar.rnat=r18 // restore ar.rnat 5.894 + rfi // must be last insn in group 5.895 + ;; 5.896 +1: mov rp=r14 5.897 + br.ret.sptk.many rp 5.898 +END(ia64_switch_mode_phys) 5.899 + 5.900 +/* 5.901 + * Switch execution mode from physical to virtual 5.902 + * 5.903 + * Inputs: 5.904 + * r16 = new psr to establish 5.905 + * r19 = new bspstore to establish 5.906 + * r20 = new sp to establish 5.907 + * 5.908 + * Note: RSE must already be in enforced lazy mode 5.909 + */ 5.910 +GLOBAL_ENTRY(ia64_switch_mode_virt) 5.911 + { 5.912 + alloc r2=ar.pfs,0,0,0,0 5.913 + rsm psr.i | psr.ic // disable interrupts and interrupt collection 5.914 + mov r15=ip 5.915 + } 5.916 + ;; 5.917 + { 5.918 + flushrs // must be first insn in group 5.919 + srlz.i 5.920 + } 5.921 + ;; 5.922 + mov cr.ipsr=r16 // set new PSR 5.923 + add r3=1f-ia64_switch_mode_virt,r15 5.924 + 5.925 + mov r14=rp // get return address into a general register 5.926 + ;; 5.927 + 5.928 + // going to virtual 5.929 + // - for code addresses, set upper bits of addr to KERNEL_START 5.930 + // - for stack addresses, copy from input argument 5.931 + movl r18=KERNEL_START 5.932 + dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT 5.933 + dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT 5.934 + mov sp=r20 5.935 + ;; 5.936 + or r3=r3,r18 5.937 + or r14=r14,r18 5.938 + ;; 5.939 + 5.940 + mov r18=ar.rnat // save ar.rnat 5.941 + mov ar.bspstore=r19 // this steps on ar.rnat 5.942 + mov cr.iip=r3 5.943 + mov cr.ifs=r0 5.944 + ;; 5.945 + mov ar.rnat=r18 // restore ar.rnat 5.946 + rfi // must be last insn in group 5.947 + ;; 5.948 +1: mov rp=r14 5.949 + br.ret.sptk.many rp 5.950 +END(ia64_switch_mode_virt) 5.951 + 5.952 +GLOBAL_ENTRY(ia64_delay_loop) 5.953 + .prologue 5.954 +{ nop 0 // work around GAS unwind info generation bug... 5.955 + .save ar.lc,r2 5.956 + mov r2=ar.lc 5.957 + .body 5.958 + ;; 5.959 + mov ar.lc=r32 5.960 +} 5.961 + ;; 5.962 + // force loop to be 32-byte aligned (GAS bug means we cannot use .align 5.963 + // inside function body without corrupting unwind info). 5.964 +{ nop 0 } 5.965 +1: br.cloop.sptk.few 1b 5.966 + ;; 5.967 + mov ar.lc=r2 5.968 + br.ret.sptk.many rp 5.969 +END(ia64_delay_loop) 5.970 + 5.971 +/* 5.972 + * Return a CPU-local timestamp in nano-seconds. This timestamp is 5.973 + * NOT synchronized across CPUs its return value must never be 5.974 + * compared against the values returned on another CPU. The usage in 5.975 + * kernel/sched.c ensures that. 5.976 + * 5.977 + * The return-value of sched_clock() is NOT supposed to wrap-around. 5.978 + * If it did, it would cause some scheduling hiccups (at the worst). 5.979 + * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even 5.980 + * that would happen only once every 5+ years. 5.981 + * 5.982 + * The code below basically calculates: 5.983 + * 5.984 + * (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT 5.985 + * 5.986 + * except that the multiplication and the shift are done with 128-bit 5.987 + * intermediate precision so that we can produce a full 64-bit result. 5.988 + */ 5.989 +GLOBAL_ENTRY(sched_clock) 5.990 + addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 5.991 + mov.m r9=ar.itc // fetch cycle-counter (35 cyc) 5.992 + ;; 5.993 + ldf8 f8=[r8] 5.994 + ;; 5.995 + setf.sig f9=r9 // certain to stall, so issue it _after_ ldf8... 5.996 + ;; 5.997 + xmpy.lu f10=f9,f8 // calculate low 64 bits of 128-bit product (4 cyc) 5.998 + xmpy.hu f11=f9,f8 // calculate high 64 bits of 128-bit product 5.999 + ;; 5.1000 + getf.sig r8=f10 // (5 cyc) 5.1001 + getf.sig r9=f11 5.1002 + ;; 5.1003 + shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT 5.1004 + br.ret.sptk.many rp 5.1005 +END(sched_clock) 5.1006 + 5.1007 +GLOBAL_ENTRY(start_kernel_thread) 5.1008 + .prologue 5.1009 + .save rp, r0 // this is the end of the call-chain 5.1010 + .body 5.1011 + alloc r2 = ar.pfs, 0, 0, 2, 0 5.1012 + mov out0 = r9 5.1013 + mov out1 = r11;; 5.1014 + br.call.sptk.many rp = kernel_thread_helper;; 5.1015 + mov out0 = r8 5.1016 + br.call.sptk.many rp = sys_exit;; 5.1017 +1: br.sptk.few 1b // not reached 5.1018 +END(start_kernel_thread) 5.1019 + 5.1020 +#ifdef CONFIG_IA64_BRL_EMU 5.1021 + 5.1022 +/* 5.1023 + * Assembly routines used by brl_emu.c to set preserved register state. 5.1024 + */ 5.1025 + 5.1026 +#define SET_REG(reg) \ 5.1027 + GLOBAL_ENTRY(ia64_set_##reg); \ 5.1028 + alloc r16=ar.pfs,1,0,0,0; \ 5.1029 + mov reg=r32; \ 5.1030 + ;; \ 5.1031 + br.ret.sptk.many rp; \ 5.1032 + END(ia64_set_##reg) 5.1033 + 5.1034 +SET_REG(b1); 5.1035 +SET_REG(b2); 5.1036 +SET_REG(b3); 5.1037 +SET_REG(b4); 5.1038 +SET_REG(b5); 5.1039 + 5.1040 +#endif /* CONFIG_IA64_BRL_EMU */ 5.1041 + 5.1042 +#ifdef CONFIG_SMP 5.1043 + /* 5.1044 + * This routine handles spinlock contention. It uses a non-standard calling 5.1045 + * convention to avoid converting leaf routines into interior routines. Because 5.1046 + * of this special convention, there are several restrictions: 5.1047 + * 5.1048 + * - do not use gp relative variables, this code is called from the kernel 5.1049 + * and from modules, r1 is undefined. 5.1050 + * - do not use stacked registers, the caller owns them. 5.1051 + * - do not use the scratch stack space, the caller owns it. 5.1052 + * - do not use any registers other than the ones listed below 5.1053 + * 5.1054 + * Inputs: 5.1055 + * ar.pfs - saved CFM of caller 5.1056 + * ar.ccv - 0 (and available for use) 5.1057 + * r27 - flags from spin_lock_irqsave or 0. Must be preserved. 5.1058 + * r28 - available for use. 5.1059 + * r29 - available for use. 5.1060 + * r30 - available for use. 5.1061 + * r31 - address of lock, available for use. 5.1062 + * b6 - return address 5.1063 + * p14 - available for use. 5.1064 + * p15 - used to track flag status. 5.1065 + * 5.1066 + * If you patch this code to use more registers, do not forget to update 5.1067 + * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h. 5.1068 + */ 5.1069 + 5.1070 +#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 5.1071 + 5.1072 +GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4) 5.1073 + .prologue 5.1074 + .save ar.pfs, r0 // this code effectively has a zero frame size 5.1075 + .save rp, r28 5.1076 + .body 5.1077 + nop 0 5.1078 + tbit.nz p15,p0=r27,IA64_PSR_I_BIT 5.1079 + .restore sp // pop existing prologue after next insn 5.1080 + mov b6 = r28 5.1081 + .prologue 5.1082 + .save ar.pfs, r0 5.1083 + .altrp b6 5.1084 + .body 5.1085 + ;; 5.1086 +(p15) ssm psr.i // reenable interrupts if they were on 5.1087 + // DavidM says that srlz.d is slow and is not required in this case 5.1088 +.wait: 5.1089 + // exponential backoff, kdb, lockmeter etc. go in here 5.1090 + hint @pause 5.1091 + ld4 r30=[r31] // don't use ld4.bias; if it's contended, we won't write the word 5.1092 + nop 0 5.1093 + ;; 5.1094 + cmp4.ne p14,p0=r30,r0 5.1095 +(p14) br.cond.sptk.few .wait 5.1096 +(p15) rsm psr.i // disable interrupts if we reenabled them 5.1097 + br.cond.sptk.few b6 // lock is now free, try to acquire 5.1098 + .global ia64_spinlock_contention_pre3_4_end // for kernprof 5.1099 +ia64_spinlock_contention_pre3_4_end: 5.1100 +END(ia64_spinlock_contention_pre3_4) 5.1101 + 5.1102 +#else 5.1103 + 5.1104 +GLOBAL_ENTRY(ia64_spinlock_contention) 5.1105 + .prologue 5.1106 + .altrp b6 5.1107 + .body 5.1108 + tbit.nz p15,p0=r27,IA64_PSR_I_BIT 5.1109 + ;; 5.1110 +.wait: 5.1111 +(p15) ssm psr.i // reenable interrupts if they were on 5.1112 + // DavidM says that srlz.d is slow and is not required in this case 5.1113 +.wait2: 5.1114 + // exponential backoff, kdb, lockmeter etc. go in here 5.1115 + hint @pause 5.1116 + ld4 r30=[r31] // don't use ld4.bias; if it's contended, we won't write the word 5.1117 + ;; 5.1118 + cmp4.ne p14,p0=r30,r0 5.1119 + mov r30 = 1 5.1120 +(p14) br.cond.sptk.few .wait2 5.1121 +(p15) rsm psr.i // disable interrupts if we reenabled them 5.1122 + ;; 5.1123 + cmpxchg4.acq r30=[r31], r30, ar.ccv 5.1124 + ;; 5.1125 + cmp4.ne p14,p0=r0,r30 5.1126 +(p14) br.cond.sptk.few .wait 5.1127 + 5.1128 + br.ret.sptk.many b6 // lock is now taken 5.1129 +END(ia64_spinlock_contention) 5.1130 + 5.1131 +#endif 5.1132 + 5.1133 +#ifdef CONFIG_HOTPLUG_CPU 5.1134 +GLOBAL_ENTRY(ia64_jump_to_sal) 5.1135 + alloc r16=ar.pfs,1,0,0,0;; 5.1136 + rsm psr.i | psr.ic 5.1137 +{ 5.1138 + flushrs 5.1139 + srlz.i 5.1140 +} 5.1141 + tpa r25=in0 5.1142 + movl r18=tlb_purge_done;; 5.1143 + DATA_VA_TO_PA(r18);; 5.1144 + mov b1=r18 // Return location 5.1145 + movl r18=ia64_do_tlb_purge;; 5.1146 + DATA_VA_TO_PA(r18);; 5.1147 + mov b2=r18 // doing tlb_flush work 5.1148 + mov ar.rsc=0 // Put RSE in enforced lazy, LE mode 5.1149 + movl r17=1f;; 5.1150 + DATA_VA_TO_PA(r17);; 5.1151 + mov cr.iip=r17 5.1152 + movl r16=SAL_PSR_BITS_TO_SET;; 5.1153 + mov cr.ipsr=r16 5.1154 + mov cr.ifs=r0;; 5.1155 + rfi;; 5.1156 +1: 5.1157 + /* 5.1158 + * Invalidate all TLB data/inst 5.1159 + */ 5.1160 + br.sptk.many b2;; // jump to tlb purge code 5.1161 + 5.1162 +tlb_purge_done: 5.1163 + RESTORE_REGION_REGS(r25, r17,r18,r19);; 5.1164 + RESTORE_REG(b0, r25, r17);; 5.1165 + RESTORE_REG(b1, r25, r17);; 5.1166 + RESTORE_REG(b2, r25, r17);; 5.1167 + RESTORE_REG(b3, r25, r17);; 5.1168 + RESTORE_REG(b4, r25, r17);; 5.1169 + RESTORE_REG(b5, r25, r17);; 5.1170 + ld8 r1=[r25],0x08;; 5.1171 + ld8 r12=[r25],0x08;; 5.1172 + ld8 r13=[r25],0x08;; 5.1173 + RESTORE_REG(ar.fpsr, r25, r17);; 5.1174 + RESTORE_REG(ar.pfs, r25, r17);; 5.1175 + RESTORE_REG(ar.rnat, r25, r17);; 5.1176 + RESTORE_REG(ar.unat, r25, r17);; 5.1177 + RESTORE_REG(ar.bspstore, r25, r17);; 5.1178 + RESTORE_REG(cr.dcr, r25, r17);; 5.1179 + RESTORE_REG(cr.iva, r25, r17);; 5.1180 + RESTORE_REG(cr.pta, r25, r17);; 5.1181 + RESTORE_REG(cr.itv, r25, r17);; 5.1182 + RESTORE_REG(cr.pmv, r25, r17);; 5.1183 + RESTORE_REG(cr.cmcv, r25, r17);; 5.1184 + RESTORE_REG(cr.lrr0, r25, r17);; 5.1185 + RESTORE_REG(cr.lrr1, r25, r17);; 5.1186 + ld8 r4=[r25],0x08;; 5.1187 + ld8 r5=[r25],0x08;; 5.1188 + ld8 r6=[r25],0x08;; 5.1189 + ld8 r7=[r25],0x08;; 5.1190 + ld8 r17=[r25],0x08;; 5.1191 + mov pr=r17,-1;; 5.1192 + RESTORE_REG(ar.lc, r25, r17);; 5.1193 + /* 5.1194 + * Now Restore floating point regs 5.1195 + */ 5.1196 + ldf.fill.nta f2=[r25],16;; 5.1197 + ldf.fill.nta f3=[r25],16;; 5.1198 + ldf.fill.nta f4=[r25],16;; 5.1199 + ldf.fill.nta f5=[r25],16;; 5.1200 + ldf.fill.nta f16=[r25],16;; 5.1201 + ldf.fill.nta f17=[r25],16;; 5.1202 + ldf.fill.nta f18=[r25],16;; 5.1203 + ldf.fill.nta f19=[r25],16;; 5.1204 + ldf.fill.nta f20=[r25],16;; 5.1205 + ldf.fill.nta f21=[r25],16;; 5.1206 + ldf.fill.nta f22=[r25],16;; 5.1207 + ldf.fill.nta f23=[r25],16;; 5.1208 + ldf.fill.nta f24=[r25],16;; 5.1209 + ldf.fill.nta f25=[r25],16;; 5.1210 + ldf.fill.nta f26=[r25],16;; 5.1211 + ldf.fill.nta f27=[r25],16;; 5.1212 + ldf.fill.nta f28=[r25],16;; 5.1213 + ldf.fill.nta f29=[r25],16;; 5.1214 + ldf.fill.nta f30=[r25],16;; 5.1215 + ldf.fill.nta f31=[r25],16;; 5.1216 + 5.1217 + /* 5.1218 + * Now that we have done all the register restores 5.1219 + * we are now ready for the big DIVE to SAL Land 5.1220 + */ 5.1221 + ssm psr.ic;; 5.1222 + srlz.d;; 5.1223 + br.ret.sptk.many b0;; 5.1224 +END(ia64_jump_to_sal) 5.1225 +#endif /* CONFIG_HOTPLUG_CPU */ 5.1226 + 5.1227 +#endif /* CONFIG_SMP */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/pal.S Wed Sep 21 09:06:30 2005 -0600 6.3 @@ -0,0 +1,303 @@ 6.4 +/* 6.5 + * PAL Firmware support 6.6 + * IA-64 Processor Programmers Reference Vol 2 6.7 + * 6.8 + * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> 6.9 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> 6.10 + * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co 6.11 + * David Mosberger <davidm@hpl.hp.com> 6.12 + * Stephane Eranian <eranian@hpl.hp.com> 6.13 + * 6.14 + * 05/22/2000 eranian Added support for stacked register calls 6.15 + * 05/24/2000 eranian Added support for physical mode static calls 6.16 + */ 6.17 + 6.18 +#include <asm/asmmacro.h> 6.19 +#include <asm/processor.h> 6.20 + 6.21 + .data 6.22 + .globl pal_entry_point 6.23 +pal_entry_point: 6.24 + data8 ia64_pal_default_handler 6.25 + .text 6.26 + 6.27 +/* 6.28 + * Set the PAL entry point address. This could be written in C code, but we do it here 6.29 + * to keep it all in one module (besides, it's so trivial that it's 6.30 + * not a big deal). 6.31 + * 6.32 + * in0 Address of the PAL entry point (text address, NOT a function descriptor). 6.33 + */ 6.34 +GLOBAL_ENTRY(ia64_pal_handler_init) 6.35 + alloc r3=ar.pfs,1,0,0,0 6.36 + movl r2=pal_entry_point 6.37 + ;; 6.38 + st8 [r2]=in0 6.39 + br.ret.sptk.many rp 6.40 +END(ia64_pal_handler_init) 6.41 + 6.42 +/* 6.43 + * Default PAL call handler. This needs to be coded in assembly because it uses 6.44 + * the static calling convention, i.e., the RSE may not be used and calls are 6.45 + * done via "br.cond" (not "br.call"). 6.46 + */ 6.47 +GLOBAL_ENTRY(ia64_pal_default_handler) 6.48 + mov r8=-1 6.49 + br.cond.sptk.many rp 6.50 +END(ia64_pal_default_handler) 6.51 + 6.52 +/* 6.53 + * Make a PAL call using the static calling convention. 6.54 + * 6.55 + * in0 Index of PAL service 6.56 + * in1 - in3 Remaining PAL arguments 6.57 + * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic 6.58 + * 6.59 + */ 6.60 +GLOBAL_ENTRY(__ia64_pal_call_static) 6.61 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) 6.62 + alloc loc1 = ar.pfs,5,5,0,0 6.63 + movl loc2 = pal_entry_point 6.64 +1: { 6.65 + mov r28 = in0 6.66 + mov r29 = in1 6.67 + mov r8 = ip 6.68 + } 6.69 + ;; 6.70 + ld8 loc2 = [loc2] // loc2 <- entry point 6.71 + tbit.nz p6,p7 = in4, 0 6.72 + adds r8 = 1f-1b,r8 6.73 + mov loc4=ar.rsc // save RSE configuration 6.74 + ;; 6.75 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 6.76 + mov loc3 = psr 6.77 + mov loc0 = rp 6.78 + .body 6.79 + mov r30 = in2 6.80 + 6.81 +(p6) rsm psr.i | psr.ic 6.82 + mov r31 = in3 6.83 + mov b7 = loc2 6.84 + 6.85 +(p7) rsm psr.i 6.86 + ;; 6.87 +(p6) srlz.i 6.88 + mov rp = r8 6.89 + br.cond.sptk.many b7 6.90 +1: mov psr.l = loc3 6.91 + mov ar.rsc = loc4 // restore RSE configuration 6.92 + mov ar.pfs = loc1 6.93 + mov rp = loc0 6.94 + ;; 6.95 + srlz.d // seralize restoration of psr.l 6.96 + br.ret.sptk.many b0 6.97 +END(__ia64_pal_call_static) 6.98 + 6.99 +/* 6.100 + * Make a PAL call using the stacked registers calling convention. 6.101 + * 6.102 + * Inputs: 6.103 + * in0 Index of PAL service 6.104 + * in2 - in3 Remaning PAL arguments 6.105 + */ 6.106 +GLOBAL_ENTRY(ia64_pal_call_stacked) 6.107 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) 6.108 + alloc loc1 = ar.pfs,4,4,4,0 6.109 + movl loc2 = pal_entry_point 6.110 + 6.111 + mov r28 = in0 // Index MUST be copied to r28 6.112 + mov out0 = in0 // AND in0 of PAL function 6.113 + mov loc0 = rp 6.114 + .body 6.115 + ;; 6.116 + ld8 loc2 = [loc2] // loc2 <- entry point 6.117 + mov out1 = in1 6.118 + mov out2 = in2 6.119 + mov out3 = in3 6.120 + mov loc3 = psr 6.121 + ;; 6.122 + rsm psr.i 6.123 + mov b7 = loc2 6.124 + ;; 6.125 + br.call.sptk.many rp=b7 // now make the call 6.126 +.ret0: mov psr.l = loc3 6.127 + mov ar.pfs = loc1 6.128 + mov rp = loc0 6.129 + ;; 6.130 + srlz.d // serialize restoration of psr.l 6.131 + br.ret.sptk.many b0 6.132 +END(ia64_pal_call_stacked) 6.133 + 6.134 +/* 6.135 + * Make a physical mode PAL call using the static registers calling convention. 6.136 + * 6.137 + * Inputs: 6.138 + * in0 Index of PAL service 6.139 + * in2 - in3 Remaning PAL arguments 6.140 + * 6.141 + * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel. 6.142 + * So we don't need to clear them. 6.143 + */ 6.144 +#define PAL_PSR_BITS_TO_CLEAR \ 6.145 + (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \ 6.146 + IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ 6.147 + IA64_PSR_DFL | IA64_PSR_DFH) 6.148 + 6.149 +#define PAL_PSR_BITS_TO_SET \ 6.150 + (IA64_PSR_BN) 6.151 + 6.152 + 6.153 +GLOBAL_ENTRY(ia64_pal_call_phys_static) 6.154 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) 6.155 + alloc loc1 = ar.pfs,4,7,0,0 6.156 + movl loc2 = pal_entry_point 6.157 +1: { 6.158 + mov r28 = in0 // copy procedure index 6.159 + mov r8 = ip // save ip to compute branch 6.160 + mov loc0 = rp // save rp 6.161 + } 6.162 + .body 6.163 + ;; 6.164 + ld8 loc2 = [loc2] // loc2 <- entry point 6.165 + mov r29 = in1 // first argument 6.166 + mov r30 = in2 // copy arg2 6.167 + mov r31 = in3 // copy arg3 6.168 + ;; 6.169 + mov loc3 = psr // save psr 6.170 + adds r8 = 1f-1b,r8 // calculate return address for call 6.171 + ;; 6.172 + mov loc4=ar.rsc // save RSE configuration 6.173 + dep.z loc2=loc2,0,61 // convert pal entry point to physical 6.174 + tpa r8=r8 // convert rp to physical 6.175 + ;; 6.176 + mov b7 = loc2 // install target to branch reg 6.177 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 6.178 + movl r16=PAL_PSR_BITS_TO_CLEAR 6.179 + movl r17=PAL_PSR_BITS_TO_SET 6.180 + ;; 6.181 + or loc3=loc3,r17 // add in psr the bits to set 6.182 + ;; 6.183 + andcm r16=loc3,r16 // removes bits to clear from psr 6.184 + br.call.sptk.many rp=ia64_switch_mode_phys 6.185 +.ret1: mov rp = r8 // install return address (physical) 6.186 + mov loc5 = r19 6.187 + mov loc6 = r20 6.188 + br.cond.sptk.many b7 6.189 +1: 6.190 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 6.191 + mov r16=loc3 // r16= original psr 6.192 + mov r19=loc5 6.193 + mov r20=loc6 6.194 + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode 6.195 +.ret2: 6.196 + mov psr.l = loc3 // restore init PSR 6.197 + 6.198 + mov ar.pfs = loc1 6.199 + mov rp = loc0 6.200 + ;; 6.201 + mov ar.rsc=loc4 // restore RSE configuration 6.202 + srlz.d // seralize restoration of psr.l 6.203 + br.ret.sptk.many b0 6.204 +END(ia64_pal_call_phys_static) 6.205 + 6.206 +/* 6.207 + * Make a PAL call using the stacked registers in physical mode. 6.208 + * 6.209 + * Inputs: 6.210 + * in0 Index of PAL service 6.211 + * in2 - in3 Remaning PAL arguments 6.212 + */ 6.213 +GLOBAL_ENTRY(ia64_pal_call_phys_stacked) 6.214 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) 6.215 + alloc loc1 = ar.pfs,5,7,4,0 6.216 + movl loc2 = pal_entry_point 6.217 +1: { 6.218 + mov r28 = in0 // copy procedure index 6.219 + mov loc0 = rp // save rp 6.220 + } 6.221 + .body 6.222 + ;; 6.223 + ld8 loc2 = [loc2] // loc2 <- entry point 6.224 + mov out0 = in0 // first argument 6.225 + mov out1 = in1 // copy arg2 6.226 + mov out2 = in2 // copy arg3 6.227 + mov out3 = in3 // copy arg3 6.228 + ;; 6.229 + mov loc3 = psr // save psr 6.230 + ;; 6.231 + mov loc4=ar.rsc // save RSE configuration 6.232 + dep.z loc2=loc2,0,61 // convert pal entry point to physical 6.233 + ;; 6.234 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 6.235 + movl r16=PAL_PSR_BITS_TO_CLEAR 6.236 + movl r17=PAL_PSR_BITS_TO_SET 6.237 + ;; 6.238 + or loc3=loc3,r17 // add in psr the bits to set 6.239 + mov b7 = loc2 // install target to branch reg 6.240 + ;; 6.241 + andcm r16=loc3,r16 // removes bits to clear from psr 6.242 + br.call.sptk.many rp=ia64_switch_mode_phys 6.243 +.ret6: 6.244 + mov loc5 = r19 6.245 + mov loc6 = r20 6.246 + br.call.sptk.many rp=b7 // now make the call 6.247 +.ret7: 6.248 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 6.249 + mov r16=loc3 // r16= original psr 6.250 + mov r19=loc5 6.251 + mov r20=loc6 6.252 + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode 6.253 + 6.254 +.ret8: mov psr.l = loc3 // restore init PSR 6.255 + mov ar.pfs = loc1 6.256 + mov rp = loc0 6.257 + ;; 6.258 + mov ar.rsc=loc4 // restore RSE configuration 6.259 + srlz.d // seralize restoration of psr.l 6.260 + br.ret.sptk.many b0 6.261 +END(ia64_pal_call_phys_stacked) 6.262 + 6.263 +/* 6.264 + * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15). 6.265 + * 6.266 + * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch 6.267 + * regs fp-low partition. 6.268 + * 6.269 + * Inputs: 6.270 + * in0 Address of stack storage for fp regs 6.271 + */ 6.272 +GLOBAL_ENTRY(ia64_save_scratch_fpregs) 6.273 + alloc r3=ar.pfs,1,0,0,0 6.274 + add r2=16,in0 6.275 + ;; 6.276 + stf.spill [in0] = f10,32 6.277 + stf.spill [r2] = f11,32 6.278 + ;; 6.279 + stf.spill [in0] = f12,32 6.280 + stf.spill [r2] = f13,32 6.281 + ;; 6.282 + stf.spill [in0] = f14,32 6.283 + stf.spill [r2] = f15,32 6.284 + br.ret.sptk.many rp 6.285 +END(ia64_save_scratch_fpregs) 6.286 + 6.287 +/* 6.288 + * Load scratch fp scratch regs (fp10-fp15) 6.289 + * 6.290 + * Inputs: 6.291 + * in0 Address of stack storage for fp regs 6.292 + */ 6.293 +GLOBAL_ENTRY(ia64_load_scratch_fpregs) 6.294 + alloc r3=ar.pfs,1,0,0,0 6.295 + add r2=16,in0 6.296 + ;; 6.297 + ldf.fill f10 = [in0],32 6.298 + ldf.fill f11 = [r2],32 6.299 + ;; 6.300 + ldf.fill f12 = [in0],32 6.301 + ldf.fill f13 = [r2],32 6.302 + ;; 6.303 + ldf.fill f14 = [in0],32 6.304 + ldf.fill f15 = [r2],32 6.305 + br.ret.sptk.many rp 6.306 +END(ia64_load_scratch_fpregs)
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Wed Sep 21 09:06:30 2005 -0600 7.3 @@ -0,0 +1,792 @@ 7.4 +/* 7.5 + * Architecture-specific setup. 7.6 + * 7.7 + * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co 7.8 + * David Mosberger-Tang <davidm@hpl.hp.com> 7.9 + * Stephane Eranian <eranian@hpl.hp.com> 7.10 + * Copyright (C) 2000, 2004 Intel Corp 7.11 + * Rohit Seth <rohit.seth@intel.com> 7.12 + * Suresh Siddha <suresh.b.siddha@intel.com> 7.13 + * Gordon Jin <gordon.jin@intel.com> 7.14 + * Copyright (C) 1999 VA Linux Systems 7.15 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> 7.16 + * 7.17 + * 12/26/04 S.Siddha, G.Jin, R.Seth 7.18 + * Add multi-threading and multi-core detection 7.19 + * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo(). 7.20 + * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map 7.21 + * 03/31/00 R.Seth cpu_initialized and current->processor fixes 7.22 + * 02/04/00 D.Mosberger some more get_cpuinfo fixes... 7.23 + * 02/01/00 R.Seth fixed get_cpuinfo for SMP 7.24 + * 01/07/99 S.Eranian added the support for command line argument 7.25 + * 06/24/99 W.Drummond added boot_cpu_data. 7.26 + */ 7.27 +#include <linux/config.h> 7.28 +#include <linux/module.h> 7.29 +#include <linux/init.h> 7.30 + 7.31 +#include <linux/acpi.h> 7.32 +#include <linux/bootmem.h> 7.33 +#include <linux/console.h> 7.34 +#include <linux/delay.h> 7.35 +#include <linux/kernel.h> 7.36 +#include <linux/reboot.h> 7.37 +#include <linux/sched.h> 7.38 +#include <linux/seq_file.h> 7.39 +#include <linux/string.h> 7.40 +#include <linux/threads.h> 7.41 +#include <linux/tty.h> 7.42 +#include <linux/serial.h> 7.43 +#include <linux/serial_core.h> 7.44 +#include <linux/efi.h> 7.45 +#include <linux/initrd.h> 7.46 + 7.47 +#include <asm/ia32.h> 7.48 +#include <asm/machvec.h> 7.49 +#include <asm/mca.h> 7.50 +#include <asm/meminit.h> 7.51 +#include <asm/page.h> 7.52 +#include <asm/patch.h> 7.53 +#include <asm/pgtable.h> 7.54 +#include <asm/processor.h> 7.55 +#include <asm/sal.h> 7.56 +#include <asm/sections.h> 7.57 +#include <asm/serial.h> 7.58 +#include <asm/setup.h> 7.59 +#include <asm/smp.h> 7.60 +#include <asm/system.h> 7.61 +#include <asm/unistd.h> 7.62 + 7.63 +#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) 7.64 +# error "struct cpuinfo_ia64 too big!" 7.65 +#endif 7.66 + 7.67 +#ifdef CONFIG_SMP 7.68 +unsigned long __per_cpu_offset[NR_CPUS]; 7.69 +EXPORT_SYMBOL(__per_cpu_offset); 7.70 +#endif 7.71 + 7.72 +DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); 7.73 +DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); 7.74 +DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); 7.75 +unsigned long ia64_cycles_per_usec; 7.76 +struct ia64_boot_param *ia64_boot_param; 7.77 +struct screen_info screen_info; 7.78 + 7.79 +unsigned long ia64_max_cacheline_size; 7.80 +unsigned long ia64_iobase; /* virtual address for I/O accesses */ 7.81 +EXPORT_SYMBOL(ia64_iobase); 7.82 +struct io_space io_space[MAX_IO_SPACES]; 7.83 +EXPORT_SYMBOL(io_space); 7.84 +unsigned int num_io_spaces; 7.85 + 7.86 +/* 7.87 + * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This 7.88 + * mask specifies a mask of address bits that must be 0 in order for two buffers to be 7.89 + * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start 7.90 + * address of the second buffer must be aligned to (merge_mask+1) in order to be 7.91 + * mergeable). By default, we assume there is no I/O MMU which can merge physically 7.92 + * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu 7.93 + * page-size of 2^64. 7.94 + */ 7.95 +unsigned long ia64_max_iommu_merge_mask = ~0UL; 7.96 +EXPORT_SYMBOL(ia64_max_iommu_merge_mask); 7.97 + 7.98 +/* 7.99 + * We use a special marker for the end of memory and it uses the extra (+1) slot 7.100 + */ 7.101 +struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1]; 7.102 +int num_rsvd_regions; 7.103 + 7.104 + 7.105 +/* 7.106 + * Filter incoming memory segments based on the primitive map created from the boot 7.107 + * parameters. Segments contained in the map are removed from the memory ranges. A 7.108 + * caller-specified function is called with the memory ranges that remain after filtering. 7.109 + * This routine does not assume the incoming segments are sorted. 7.110 + */ 7.111 +int 7.112 +filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) 7.113 +{ 7.114 + unsigned long range_start, range_end, prev_start; 7.115 + void (*func)(unsigned long, unsigned long, int); 7.116 + int i; 7.117 + 7.118 +#if IGNORE_PFN0 7.119 + if (start == PAGE_OFFSET) { 7.120 + printk(KERN_WARNING "warning: skipping physical page 0\n"); 7.121 + start += PAGE_SIZE; 7.122 + if (start >= end) return 0; 7.123 + } 7.124 +#endif 7.125 + /* 7.126 + * lowest possible address(walker uses virtual) 7.127 + */ 7.128 + prev_start = PAGE_OFFSET; 7.129 + func = arg; 7.130 + 7.131 + for (i = 0; i < num_rsvd_regions; ++i) { 7.132 + range_start = max(start, prev_start); 7.133 + range_end = min(end, rsvd_region[i].start); 7.134 + 7.135 + if (range_start < range_end) 7.136 + call_pernode_memory(__pa(range_start), range_end - range_start, func); 7.137 + 7.138 + /* nothing more available in this segment */ 7.139 + if (range_end == end) return 0; 7.140 + 7.141 + prev_start = rsvd_region[i].end; 7.142 + } 7.143 + /* end of memory marker allows full processing inside loop body */ 7.144 + return 0; 7.145 +} 7.146 + 7.147 +static void 7.148 +sort_regions (struct rsvd_region *rsvd_region, int max) 7.149 +{ 7.150 + int j; 7.151 + 7.152 + /* simple bubble sorting */ 7.153 + while (max--) { 7.154 + for (j = 0; j < max; ++j) { 7.155 + if (rsvd_region[j].start > rsvd_region[j+1].start) { 7.156 + struct rsvd_region tmp; 7.157 + tmp = rsvd_region[j]; 7.158 + rsvd_region[j] = rsvd_region[j + 1]; 7.159 + rsvd_region[j + 1] = tmp; 7.160 + } 7.161 + } 7.162 + } 7.163 +} 7.164 + 7.165 +/** 7.166 + * reserve_memory - setup reserved memory areas 7.167 + * 7.168 + * Setup the reserved memory areas set aside for the boot parameters, 7.169 + * initrd, etc. There are currently %IA64_MAX_RSVD_REGIONS defined, 7.170 + * see include/asm-ia64/meminit.h if you need to define more. 7.171 + */ 7.172 +void 7.173 +reserve_memory (void) 7.174 +{ 7.175 + int n = 0; 7.176 + 7.177 + /* 7.178 + * none of the entries in this table overlap 7.179 + */ 7.180 + rsvd_region[n].start = (unsigned long) ia64_boot_param; 7.181 + rsvd_region[n].end = rsvd_region[n].start + sizeof(*ia64_boot_param); 7.182 + n++; 7.183 + 7.184 + rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->efi_memmap); 7.185 + rsvd_region[n].end = rsvd_region[n].start + ia64_boot_param->efi_memmap_size; 7.186 + n++; 7.187 + 7.188 + rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->command_line); 7.189 + rsvd_region[n].end = (rsvd_region[n].start 7.190 + + strlen(__va(ia64_boot_param->command_line)) + 1); 7.191 + n++; 7.192 + 7.193 + rsvd_region[n].start = (unsigned long) ia64_imva((void *)KERNEL_START); 7.194 + rsvd_region[n].end = (unsigned long) ia64_imva(_end); 7.195 + n++; 7.196 + 7.197 +#ifdef CONFIG_BLK_DEV_INITRD 7.198 + if (ia64_boot_param->initrd_start) { 7.199 + rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start); 7.200 + rsvd_region[n].end = rsvd_region[n].start + ia64_boot_param->initrd_size; 7.201 + n++; 7.202 + } 7.203 +#endif 7.204 + 7.205 + /* end of memory marker */ 7.206 + rsvd_region[n].start = ~0UL; 7.207 + rsvd_region[n].end = ~0UL; 7.208 + n++; 7.209 + 7.210 + num_rsvd_regions = n; 7.211 + 7.212 + sort_regions(rsvd_region, num_rsvd_regions); 7.213 +} 7.214 + 7.215 +/** 7.216 + * find_initrd - get initrd parameters from the boot parameter structure 7.217 + * 7.218 + * Grab the initrd start and end from the boot parameter struct given us by 7.219 + * the boot loader. 7.220 + */ 7.221 +void 7.222 +find_initrd (void) 7.223 +{ 7.224 +#ifdef CONFIG_BLK_DEV_INITRD 7.225 + if (ia64_boot_param->initrd_start) { 7.226 + initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start); 7.227 + initrd_end = initrd_start+ia64_boot_param->initrd_size; 7.228 + 7.229 + printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", 7.230 + initrd_start, ia64_boot_param->initrd_size); 7.231 + } 7.232 +#endif 7.233 +} 7.234 + 7.235 +static void __init 7.236 +io_port_init (void) 7.237 +{ 7.238 + extern unsigned long ia64_iobase; 7.239 + unsigned long phys_iobase; 7.240 + 7.241 + /* 7.242 + * Set `iobase' to the appropriate address in region 6 (uncached access range). 7.243 + * 7.244 + * The EFI memory map is the "preferred" location to get the I/O port space base, 7.245 + * rather the relying on AR.KR0. This should become more clear in future SAL 7.246 + * specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is 7.247 + * found in the memory map. 7.248 + */ 7.249 + phys_iobase = efi_get_iobase(); 7.250 + if (phys_iobase) 7.251 + /* set AR.KR0 since this is all we use it for anyway */ 7.252 + ia64_set_kr(IA64_KR_IO_BASE, phys_iobase); 7.253 + else { 7.254 + phys_iobase = ia64_get_kr(IA64_KR_IO_BASE); 7.255 + printk(KERN_INFO "No I/O port range found in EFI memory map, falling back " 7.256 + "to AR.KR0\n"); 7.257 + printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase); 7.258 + } 7.259 + ia64_iobase = (unsigned long) ioremap(phys_iobase, 0); 7.260 + 7.261 + /* setup legacy IO port space */ 7.262 + io_space[0].mmio_base = ia64_iobase; 7.263 + io_space[0].sparse = 1; 7.264 + num_io_spaces = 1; 7.265 +} 7.266 + 7.267 +/** 7.268 + * early_console_setup - setup debugging console 7.269 + * 7.270 + * Consoles started here require little enough setup that we can start using 7.271 + * them very early in the boot process, either right after the machine 7.272 + * vector initialization, or even before if the drivers can detect their hw. 7.273 + * 7.274 + * Returns non-zero if a console couldn't be setup. 7.275 + */ 7.276 +static inline int __init 7.277 +early_console_setup (char *cmdline) 7.278 +{ 7.279 +#ifdef CONFIG_XEN 7.280 + if (!early_xen_console_setup(cmdline)) return 0; 7.281 +#endif 7.282 +#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE 7.283 + { 7.284 + extern int sn_serial_console_early_setup(void); 7.285 + if (!sn_serial_console_early_setup()) 7.286 + return 0; 7.287 + } 7.288 +#endif 7.289 +#ifdef CONFIG_EFI_PCDP 7.290 + if (!efi_setup_pcdp_console(cmdline)) 7.291 + return 0; 7.292 +#endif 7.293 +#ifdef CONFIG_SERIAL_8250_CONSOLE 7.294 + if (!early_serial_console_init(cmdline)) 7.295 + return 0; 7.296 +#endif 7.297 + 7.298 + return -1; 7.299 +} 7.300 + 7.301 +static inline void 7.302 +mark_bsp_online (void) 7.303 +{ 7.304 +#ifdef CONFIG_SMP 7.305 + /* If we register an early console, allow CPU 0 to printk */ 7.306 + cpu_set(smp_processor_id(), cpu_online_map); 7.307 +#endif 7.308 +} 7.309 + 7.310 +#ifdef CONFIG_SMP 7.311 +static void 7.312 +check_for_logical_procs (void) 7.313 +{ 7.314 + pal_logical_to_physical_t info; 7.315 + s64 status; 7.316 + 7.317 + status = ia64_pal_logical_to_phys(0, &info); 7.318 + if (status == -1) { 7.319 + printk(KERN_INFO "No logical to physical processor mapping " 7.320 + "available\n"); 7.321 + return; 7.322 + } 7.323 + if (status) { 7.324 + printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", 7.325 + status); 7.326 + return; 7.327 + } 7.328 + /* 7.329 + * Total number of siblings that BSP has. Though not all of them 7.330 + * may have booted successfully. The correct number of siblings 7.331 + * booted is in info.overview_num_log. 7.332 + */ 7.333 + smp_num_siblings = info.overview_tpc; 7.334 + smp_num_cpucores = info.overview_cpp; 7.335 +} 7.336 +#endif 7.337 + 7.338 +void __init 7.339 +setup_arch (char **cmdline_p) 7.340 +{ 7.341 + unw_init(); 7.342 + 7.343 + ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); 7.344 + 7.345 + *cmdline_p = __va(ia64_boot_param->command_line); 7.346 + strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE); 7.347 + 7.348 + efi_init(); 7.349 + io_port_init(); 7.350 + 7.351 +#ifdef CONFIG_IA64_GENERIC 7.352 + { 7.353 + const char *mvec_name = strstr (*cmdline_p, "machvec="); 7.354 + char str[64]; 7.355 + 7.356 + if (mvec_name) { 7.357 + const char *end; 7.358 + size_t len; 7.359 + 7.360 + mvec_name += 8; 7.361 + end = strchr (mvec_name, ' '); 7.362 + if (end) 7.363 + len = end - mvec_name; 7.364 + else 7.365 + len = strlen (mvec_name); 7.366 + len = min(len, sizeof (str) - 1); 7.367 + strncpy (str, mvec_name, len); 7.368 + str[len] = '\0'; 7.369 + mvec_name = str; 7.370 + } else 7.371 + mvec_name = acpi_get_sysname(); 7.372 + machvec_init(mvec_name); 7.373 + } 7.374 +#endif 7.375 + 7.376 + if (early_console_setup(*cmdline_p) == 0) 7.377 + mark_bsp_online(); 7.378 + 7.379 +#ifdef CONFIG_ACPI_BOOT 7.380 + /* Initialize the ACPI boot-time table parser */ 7.381 + acpi_table_init(); 7.382 +# ifdef CONFIG_ACPI_NUMA 7.383 + acpi_numa_init(); 7.384 +# endif 7.385 +#else 7.386 +# ifdef CONFIG_SMP 7.387 + smp_build_cpu_map(); /* happens, e.g., with the Ski simulator */ 7.388 +# endif 7.389 +#endif /* CONFIG_APCI_BOOT */ 7.390 + 7.391 + find_memory(); 7.392 + 7.393 + /* process SAL system table: */ 7.394 + ia64_sal_init(efi.sal_systab); 7.395 + 7.396 +#ifdef CONFIG_SMP 7.397 + cpu_physical_id(0) = hard_smp_processor_id(); 7.398 + 7.399 + cpu_set(0, cpu_sibling_map[0]); 7.400 + cpu_set(0, cpu_core_map[0]); 7.401 + 7.402 + check_for_logical_procs(); 7.403 + if (smp_num_cpucores > 1) 7.404 + printk(KERN_INFO 7.405 + "cpu package is Multi-Core capable: number of cores=%d\n", 7.406 + smp_num_cpucores); 7.407 + if (smp_num_siblings > 1) 7.408 + printk(KERN_INFO 7.409 + "cpu package is Multi-Threading capable: number of siblings=%d\n", 7.410 + smp_num_siblings); 7.411 +#endif 7.412 + 7.413 + cpu_init(); /* initialize the bootstrap CPU */ 7.414 + 7.415 +#ifdef CONFIG_ACPI_BOOT 7.416 + acpi_boot_init(); 7.417 +#endif 7.418 + 7.419 +#ifdef CONFIG_VT 7.420 + if (!conswitchp) { 7.421 +# if defined(CONFIG_DUMMY_CONSOLE) 7.422 + conswitchp = &dummy_con; 7.423 +# endif 7.424 +# if defined(CONFIG_VGA_CONSOLE) 7.425 + /* 7.426 + * Non-legacy systems may route legacy VGA MMIO range to system 7.427 + * memory. vga_con probes the MMIO hole, so memory looks like 7.428 + * a VGA device to it. The EFI memory map can tell us if it's 7.429 + * memory so we can avoid this problem. 7.430 + */ 7.431 + if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY) 7.432 + conswitchp = &vga_con; 7.433 +# endif 7.434 + } 7.435 +#endif 7.436 + 7.437 + /* enable IA-64 Machine Check Abort Handling unless disabled */ 7.438 + if (!strstr(saved_command_line, "nomca")) 7.439 + ia64_mca_init(); 7.440 + 7.441 + platform_setup(cmdline_p); 7.442 + paging_init(); 7.443 +} 7.444 + 7.445 +/* 7.446 + * Display cpu info for all cpu's. 7.447 + */ 7.448 +static int 7.449 +show_cpuinfo (struct seq_file *m, void *v) 7.450 +{ 7.451 +#ifdef CONFIG_SMP 7.452 +# define lpj c->loops_per_jiffy 7.453 +# define cpunum c->cpu 7.454 +#else 7.455 +# define lpj loops_per_jiffy 7.456 +# define cpunum 0 7.457 +#endif 7.458 + static struct { 7.459 + unsigned long mask; 7.460 + const char *feature_name; 7.461 + } feature_bits[] = { 7.462 + { 1UL << 0, "branchlong" }, 7.463 + { 1UL << 1, "spontaneous deferral"}, 7.464 + { 1UL << 2, "16-byte atomic ops" } 7.465 + }; 7.466 + char family[32], features[128], *cp, sep; 7.467 + struct cpuinfo_ia64 *c = v; 7.468 + unsigned long mask; 7.469 + int i; 7.470 + 7.471 + mask = c->features; 7.472 + 7.473 + switch (c->family) { 7.474 + case 0x07: memcpy(family, "Itanium", 8); break; 7.475 + case 0x1f: memcpy(family, "Itanium 2", 10); break; 7.476 + default: sprintf(family, "%u", c->family); break; 7.477 + } 7.478 + 7.479 + /* build the feature string: */ 7.480 + memcpy(features, " standard", 10); 7.481 + cp = features; 7.482 + sep = 0; 7.483 + for (i = 0; i < (int) ARRAY_SIZE(feature_bits); ++i) { 7.484 + if (mask & feature_bits[i].mask) { 7.485 + if (sep) 7.486 + *cp++ = sep; 7.487 + sep = ','; 7.488 + *cp++ = ' '; 7.489 + strcpy(cp, feature_bits[i].feature_name); 7.490 + cp += strlen(feature_bits[i].feature_name); 7.491 + mask &= ~feature_bits[i].mask; 7.492 + } 7.493 + } 7.494 + if (mask) { 7.495 + /* print unknown features as a hex value: */ 7.496 + if (sep) 7.497 + *cp++ = sep; 7.498 + sprintf(cp, " 0x%lx", mask); 7.499 + } 7.500 + 7.501 + seq_printf(m, 7.502 + "processor : %d\n" 7.503 + "vendor : %s\n" 7.504 + "arch : IA-64\n" 7.505 + "family : %s\n" 7.506 + "model : %u\n" 7.507 + "revision : %u\n" 7.508 + "archrev : %u\n" 7.509 + "features :%s\n" /* don't change this---it _is_ right! */ 7.510 + "cpu number : %lu\n" 7.511 + "cpu regs : %u\n" 7.512 + "cpu MHz : %lu.%06lu\n" 7.513 + "itc MHz : %lu.%06lu\n" 7.514 + "BogoMIPS : %lu.%02lu\n", 7.515 + cpunum, c->vendor, family, c->model, c->revision, c->archrev, 7.516 + features, c->ppn, c->number, 7.517 + c->proc_freq / 1000000, c->proc_freq % 1000000, 7.518 + c->itc_freq / 1000000, c->itc_freq % 1000000, 7.519 + lpj*HZ/500000, (lpj*HZ/5000) % 100); 7.520 +#ifdef CONFIG_SMP 7.521 + seq_printf(m, "siblings : %u\n", c->num_log); 7.522 + if (c->threads_per_core > 1 || c->cores_per_socket > 1) 7.523 + seq_printf(m, 7.524 + "physical id: %u\n" 7.525 + "core id : %u\n" 7.526 + "thread id : %u\n", 7.527 + c->socket_id, c->core_id, c->thread_id); 7.528 +#endif 7.529 + seq_printf(m,"\n"); 7.530 + 7.531 + return 0; 7.532 +} 7.533 + 7.534 +static void * 7.535 +c_start (struct seq_file *m, loff_t *pos) 7.536 +{ 7.537 +#ifdef CONFIG_SMP 7.538 + while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map)) 7.539 + ++*pos; 7.540 +#endif 7.541 + return *pos < NR_CPUS ? cpu_data(*pos) : NULL; 7.542 +} 7.543 + 7.544 +static void * 7.545 +c_next (struct seq_file *m, void *v, loff_t *pos) 7.546 +{ 7.547 + ++*pos; 7.548 + return c_start(m, pos); 7.549 +} 7.550 + 7.551 +static void 7.552 +c_stop (struct seq_file *m, void *v) 7.553 +{ 7.554 +} 7.555 + 7.556 +struct seq_operations cpuinfo_op = { 7.557 + .start = c_start, 7.558 + .next = c_next, 7.559 + .stop = c_stop, 7.560 + .show = show_cpuinfo 7.561 +}; 7.562 + 7.563 +void 7.564 +identify_cpu (struct cpuinfo_ia64 *c) 7.565 +{ 7.566 + union { 7.567 + unsigned long bits[5]; 7.568 + struct { 7.569 + /* id 0 & 1: */ 7.570 + char vendor[16]; 7.571 + 7.572 + /* id 2 */ 7.573 + u64 ppn; /* processor serial number */ 7.574 + 7.575 + /* id 3: */ 7.576 + unsigned number : 8; 7.577 + unsigned revision : 8; 7.578 + unsigned model : 8; 7.579 + unsigned family : 8; 7.580 + unsigned archrev : 8; 7.581 + unsigned reserved : 24; 7.582 + 7.583 + /* id 4: */ 7.584 + u64 features; 7.585 + } field; 7.586 + } cpuid; 7.587 + pal_vm_info_1_u_t vm1; 7.588 + pal_vm_info_2_u_t vm2; 7.589 + pal_status_t status; 7.590 + unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */ 7.591 + int i; 7.592 + 7.593 + for (i = 0; i < 5; ++i) 7.594 + cpuid.bits[i] = ia64_get_cpuid(i); 7.595 + 7.596 + memcpy(c->vendor, cpuid.field.vendor, 16); 7.597 +#ifdef CONFIG_SMP 7.598 + c->cpu = smp_processor_id(); 7.599 + 7.600 + /* below default values will be overwritten by identify_siblings() 7.601 + * for Multi-Threading/Multi-Core capable cpu's 7.602 + */ 7.603 + c->threads_per_core = c->cores_per_socket = c->num_log = 1; 7.604 + c->socket_id = -1; 7.605 + 7.606 + identify_siblings(c); 7.607 +#endif 7.608 + c->ppn = cpuid.field.ppn; 7.609 + c->number = cpuid.field.number; 7.610 + c->revision = cpuid.field.revision; 7.611 + c->model = cpuid.field.model; 7.612 + c->family = cpuid.field.family; 7.613 + c->archrev = cpuid.field.archrev; 7.614 + c->features = cpuid.field.features; 7.615 + 7.616 + status = ia64_pal_vm_summary(&vm1, &vm2); 7.617 + if (status == PAL_STATUS_SUCCESS) { 7.618 + impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb; 7.619 + phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size; 7.620 + } 7.621 + c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1)); 7.622 + c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); 7.623 +} 7.624 + 7.625 +void 7.626 +setup_per_cpu_areas (void) 7.627 +{ 7.628 + /* start_kernel() requires this... */ 7.629 +} 7.630 + 7.631 +static void 7.632 +get_max_cacheline_size (void) 7.633 +{ 7.634 + unsigned long line_size, max = 1; 7.635 + u64 l, levels, unique_caches; 7.636 + pal_cache_config_info_t cci; 7.637 + s64 status; 7.638 + 7.639 + status = ia64_pal_cache_summary(&levels, &unique_caches); 7.640 + if (status != 0) { 7.641 + printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", 7.642 + __FUNCTION__, status); 7.643 + max = SMP_CACHE_BYTES; 7.644 + goto out; 7.645 + } 7.646 + 7.647 + for (l = 0; l < levels; ++l) { 7.648 + status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2, 7.649 + &cci); 7.650 + if (status != 0) { 7.651 + printk(KERN_ERR 7.652 + "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n", 7.653 + __FUNCTION__, l, status); 7.654 + max = SMP_CACHE_BYTES; 7.655 + } 7.656 + line_size = 1 << cci.pcci_line_size; 7.657 + if (line_size > max) 7.658 + max = line_size; 7.659 + } 7.660 + out: 7.661 + if (max > ia64_max_cacheline_size) 7.662 + ia64_max_cacheline_size = max; 7.663 +} 7.664 + 7.665 +/* 7.666 + * cpu_init() initializes state that is per-CPU. This function acts 7.667 + * as a 'CPU state barrier', nothing should get across. 7.668 + */ 7.669 +void 7.670 +cpu_init (void) 7.671 +{ 7.672 + extern void __devinit ia64_mmu_init (void *); 7.673 + unsigned long num_phys_stacked; 7.674 + pal_vm_info_2_u_t vmi; 7.675 + unsigned int max_ctx; 7.676 + struct cpuinfo_ia64 *cpu_info; 7.677 + void *cpu_data; 7.678 + 7.679 + cpu_data = per_cpu_init(); 7.680 + 7.681 + /* 7.682 + * We set ar.k3 so that assembly code in MCA handler can compute 7.683 + * physical addresses of per cpu variables with a simple: 7.684 + * phys = ar.k3 + &per_cpu_var 7.685 + */ 7.686 + ia64_set_kr(IA64_KR_PER_CPU_DATA, 7.687 + ia64_tpa(cpu_data) - (long) __per_cpu_start); 7.688 + 7.689 + get_max_cacheline_size(); 7.690 + 7.691 + /* 7.692 + * We can't pass "local_cpu_data" to identify_cpu() because we haven't called 7.693 + * ia64_mmu_init() yet. And we can't call ia64_mmu_init() first because it 7.694 + * depends on the data returned by identify_cpu(). We break the dependency by 7.695 + * accessing cpu_data() through the canonical per-CPU address. 7.696 + */ 7.697 + cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start); 7.698 + identify_cpu(cpu_info); 7.699 + 7.700 +#ifdef CONFIG_MCKINLEY 7.701 + { 7.702 +# define FEATURE_SET 16 7.703 + struct ia64_pal_retval iprv; 7.704 + 7.705 + if (cpu_info->family == 0x1f) { 7.706 + PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0); 7.707 + if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80)) 7.708 + PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES, 7.709 + (iprv.v1 | 0x80), FEATURE_SET, 0); 7.710 + } 7.711 + } 7.712 +#endif 7.713 + 7.714 + /* Clear the stack memory reserved for pt_regs: */ 7.715 + memset(ia64_task_regs(current), 0, sizeof(struct pt_regs)); 7.716 + 7.717 + ia64_set_kr(IA64_KR_FPU_OWNER, 0); 7.718 + 7.719 + /* 7.720 + * Initialize the page-table base register to a global 7.721 + * directory with all zeroes. This ensure that we can handle 7.722 + * TLB-misses to user address-space even before we created the 7.723 + * first user address-space. This may happen, e.g., due to 7.724 + * aggressive use of lfetch.fault. 7.725 + */ 7.726 + ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); 7.727 + 7.728 + /* 7.729 + * Initialize default control register to defer speculative faults except 7.730 + * for those arising from TLB misses, which are not deferred. The 7.731 + * kernel MUST NOT depend on a particular setting of these bits (in other words, 7.732 + * the kernel must have recovery code for all speculative accesses). Turn on 7.733 + * dcr.lc as per recommendation by the architecture team. Most IA-32 apps 7.734 + * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll 7.735 + * be fine). 7.736 + */ 7.737 + ia64_setreg(_IA64_REG_CR_DCR, ( IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR 7.738 + | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC)); 7.739 + atomic_inc(&init_mm.mm_count); 7.740 + current->active_mm = &init_mm; 7.741 + if (current->mm) 7.742 + BUG(); 7.743 + 7.744 + ia64_mmu_init(ia64_imva(cpu_data)); 7.745 + ia64_mca_cpu_init(ia64_imva(cpu_data)); 7.746 + 7.747 +#ifdef CONFIG_IA32_SUPPORT 7.748 + ia32_cpu_init(); 7.749 +#endif 7.750 + 7.751 + /* Clear ITC to eliminiate sched_clock() overflows in human time. */ 7.752 + ia64_set_itc(0); 7.753 + 7.754 + /* disable all local interrupt sources: */ 7.755 + ia64_set_itv(1 << 16); 7.756 + ia64_set_lrr0(1 << 16); 7.757 + ia64_set_lrr1(1 << 16); 7.758 + ia64_setreg(_IA64_REG_CR_PMV, 1 << 16); 7.759 + ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16); 7.760 + 7.761 + /* clear TPR & XTP to enable all interrupt classes: */ 7.762 + ia64_setreg(_IA64_REG_CR_TPR, 0); 7.763 +#ifdef CONFIG_SMP 7.764 + normal_xtp(); 7.765 +#endif 7.766 + 7.767 + /* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */ 7.768 + if (ia64_pal_vm_summary(NULL, &vmi) == 0) 7.769 + max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1; 7.770 + else { 7.771 + printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n"); 7.772 + max_ctx = (1U << 15) - 1; /* use architected minimum */ 7.773 + } 7.774 + while (max_ctx < ia64_ctx.max_ctx) { 7.775 + unsigned int old = ia64_ctx.max_ctx; 7.776 + if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old) 7.777 + break; 7.778 + } 7.779 + 7.780 + if (ia64_pal_rse_info(&num_phys_stacked, NULL) != 0) { 7.781 + printk(KERN_WARNING "cpu_init: PAL RSE info failed; assuming 96 physical " 7.782 + "stacked regs\n"); 7.783 + num_phys_stacked = 96; 7.784 + } 7.785 + /* size of physical stacked register partition plus 8 bytes: */ 7.786 + __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; 7.787 + platform_cpu_init(); 7.788 +} 7.789 + 7.790 +void 7.791 +check_bugs (void) 7.792 +{ 7.793 + ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, 7.794 + (unsigned long) __end___mckinley_e9_bundles); 7.795 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile Wed Sep 21 09:06:30 2005 -0600 8.3 @@ -0,0 +1,5 @@ 8.4 +# 8.5 +# Makefile for Xen components 8.6 +# 8.7 + 8.8 +obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o xenconsole.o
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S Wed Sep 21 09:06:30 2005 -0600 9.3 @@ -0,0 +1,268 @@ 9.4 +/* 9.5 + * Support routines for Xen hypercalls 9.6 + * 9.7 + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com> 9.8 + */ 9.9 + 9.10 +#include <linux/config.h> 9.11 +#include <asm/processor.h> 9.12 +#include <asm/asmmacro.h> 9.13 + 9.14 +GLOBAL_ENTRY(xen_get_ivr) 9.15 + movl r8=running_on_xen;; 9.16 + ld4 r8=[r8];; 9.17 + cmp.eq p7,p0=r8,r0;; 9.18 +(p7) mov r8=cr.ivr;; 9.19 +(p7) br.ret.sptk.many rp 9.20 + ;; 9.21 + movl r9=XSI_PSR_IC 9.22 + ;; 9.23 + ld8 r10=[r9] 9.24 + ;; 9.25 + st8 [r9]=r0 9.26 + ;; 9.27 + XEN_HYPER_GET_IVR 9.28 + ;; 9.29 + st8 [r9]=r10 9.30 + br.ret.sptk.many rp 9.31 + ;; 9.32 +END(xen_get_ivr) 9.33 + 9.34 +GLOBAL_ENTRY(xen_get_tpr) 9.35 + movl r8=running_on_xen;; 9.36 + ld4 r8=[r8];; 9.37 + cmp.eq p7,p0=r8,r0;; 9.38 +(p7) mov r8=cr.tpr;; 9.39 +(p7) br.ret.sptk.many rp 9.40 + ;; 9.41 + movl r9=XSI_PSR_IC 9.42 + ;; 9.43 + ld8 r10=[r9] 9.44 + ;; 9.45 + st8 [r9]=r0 9.46 + ;; 9.47 + XEN_HYPER_GET_TPR 9.48 + ;; 9.49 + st8 [r9]=r10 9.50 + br.ret.sptk.many rp 9.51 + ;; 9.52 +END(xen_get_tpr) 9.53 + 9.54 +GLOBAL_ENTRY(xen_set_tpr) 9.55 + movl r8=running_on_xen;; 9.56 + ld4 r8=[r8];; 9.57 + cmp.eq p7,p0=r8,r0;; 9.58 +(p7) mov cr.tpr=r32;; 9.59 +(p7) br.ret.sptk.many rp 9.60 + ;; 9.61 + movl r9=XSI_PSR_IC 9.62 + mov r8=r32 9.63 + ;; 9.64 + ld8 r10=[r9] 9.65 + ;; 9.66 + st8 [r9]=r0 9.67 + ;; 9.68 + XEN_HYPER_SET_TPR 9.69 + ;; 9.70 + st8 [r9]=r10 9.71 + br.ret.sptk.many rp 9.72 + ;; 9.73 +END(xen_set_tpr) 9.74 + 9.75 +GLOBAL_ENTRY(xen_eoi) 9.76 + movl r8=running_on_xen;; 9.77 + ld4 r8=[r8];; 9.78 + cmp.eq p7,p0=r8,r0;; 9.79 +(p7) mov cr.eoi=r0;; 9.80 +(p7) br.ret.sptk.many rp 9.81 + ;; 9.82 + movl r9=XSI_PSR_IC 9.83 + mov r8=r32 9.84 + ;; 9.85 + ld8 r10=[r9] 9.86 + ;; 9.87 + st8 [r9]=r0 9.88 + ;; 9.89 + XEN_HYPER_EOI 9.90 + ;; 9.91 + st8 [r9]=r10 9.92 + br.ret.sptk.many rp 9.93 + ;; 9.94 +END(xen_eoi) 9.95 + 9.96 +GLOBAL_ENTRY(xen_thash) 9.97 + movl r8=running_on_xen;; 9.98 + ld4 r8=[r8];; 9.99 + cmp.eq p7,p0=r8,r0;; 9.100 +(p7) thash r8=r32;; 9.101 +(p7) br.ret.sptk.many rp 9.102 + ;; 9.103 + movl r9=XSI_PSR_IC 9.104 + mov r8=r32 9.105 + ;; 9.106 + ld8 r10=[r9] 9.107 + ;; 9.108 + st8 [r9]=r0 9.109 + ;; 9.110 + XEN_HYPER_THASH 9.111 + ;; 9.112 + st8 [r9]=r10 9.113 + ;; 9.114 + br.ret.sptk.many rp 9.115 + ;; 9.116 +END(xen_thash) 9.117 + 9.118 +GLOBAL_ENTRY(xen_set_itm) 9.119 + movl r8=running_on_xen;; 9.120 + ld4 r8=[r8];; 9.121 + cmp.eq p7,p0=r8,r0;; 9.122 +(p7) mov cr.itm=r32;; 9.123 +(p7) br.ret.sptk.many rp 9.124 + ;; 9.125 + movl r9=XSI_PSR_IC 9.126 + mov r8=r32 9.127 + ;; 9.128 + ld8 r10=[r9] 9.129 + ;; 9.130 + st8 [r9]=r0 9.131 + ;; 9.132 + XEN_HYPER_SET_ITM 9.133 + ;; 9.134 + st8 [r9]=r10 9.135 + ;; 9.136 + br.ret.sptk.many rp 9.137 + ;; 9.138 +END(xen_set_itm) 9.139 + 9.140 +GLOBAL_ENTRY(xen_ptcga) 9.141 + movl r8=running_on_xen;; 9.142 + ld4 r8=[r8];; 9.143 + cmp.eq p7,p0=r8,r0;; 9.144 +(p7) ptc.ga r32,r33;; 9.145 +(p7) br.ret.sptk.many rp 9.146 + ;; 9.147 + movl r11=XSI_PSR_IC 9.148 + mov r8=r32 9.149 + mov r9=r33 9.150 + ;; 9.151 + ld8 r10=[r11] 9.152 + ;; 9.153 + st8 [r11]=r0 9.154 + ;; 9.155 + XEN_HYPER_PTC_GA 9.156 + ;; 9.157 + st8 [r11]=r10 9.158 + ;; 9.159 + br.ret.sptk.many rp 9.160 + ;; 9.161 +END(xen_ptcga) 9.162 + 9.163 +GLOBAL_ENTRY(xen_get_rr) 9.164 + movl r8=running_on_xen;; 9.165 + ld4 r8=[r8];; 9.166 + cmp.eq p7,p0=r8,r0;; 9.167 +(p7) mov r8=rr[r32];; 9.168 +(p7) br.ret.sptk.many rp 9.169 + ;; 9.170 + movl r9=XSI_PSR_IC 9.171 + mov r8=r32 9.172 + ;; 9.173 + ld8 r10=[r9] 9.174 + ;; 9.175 + st8 [r9]=r0 9.176 + ;; 9.177 + XEN_HYPER_GET_RR 9.178 + ;; 9.179 + st8 [r9]=r10 9.180 + ;; 9.181 + br.ret.sptk.many rp 9.182 + ;; 9.183 +END(xen_get_rr) 9.184 + 9.185 +GLOBAL_ENTRY(xen_set_rr) 9.186 + movl r8=running_on_xen;; 9.187 + ld4 r8=[r8];; 9.188 + cmp.eq p7,p0=r8,r0;; 9.189 +(p7) mov rr[r32]=r33;; 9.190 +(p7) br.ret.sptk.many rp 9.191 + ;; 9.192 + movl r11=XSI_PSR_IC 9.193 + mov r8=r32 9.194 + mov r9=r33 9.195 + ;; 9.196 + ld8 r10=[r11] 9.197 + ;; 9.198 + st8 [r11]=r0 9.199 + ;; 9.200 + XEN_HYPER_SET_RR 9.201 + ;; 9.202 + st8 [r11]=r10 9.203 + ;; 9.204 + br.ret.sptk.many rp 9.205 + ;; 9.206 +END(xen_set_rr) 9.207 + 9.208 +GLOBAL_ENTRY(xen_fc) 9.209 + movl r8=running_on_xen;; 9.210 + ld4 r8=[r8];; 9.211 + cmp.eq p7,p0=r8,r0;; 9.212 +(p7) fc r32;; 9.213 +(p7) br.ret.sptk.many rp 9.214 + ;; 9.215 + ptc.e r96 // this is a "privified" fc r32 9.216 + ;; 9.217 + br.ret.sptk.many rp 9.218 +END(xen_fc) 9.219 + 9.220 +GLOBAL_ENTRY(xen_get_cpuid) 9.221 + movl r8=running_on_xen;; 9.222 + ld4 r8=[r8];; 9.223 + cmp.eq p7,p0=r8,r0;; 9.224 +(p7) mov r8=cpuid[r32];; 9.225 +(p7) br.ret.sptk.many rp 9.226 + ;; 9.227 + mov r72=rr[r32] // this is a "privified" mov r8=cpuid[r32] 9.228 + ;; 9.229 + br.ret.sptk.many rp 9.230 +END(xen_get_cpuid) 9.231 + 9.232 +GLOBAL_ENTRY(xen_get_pmd) 9.233 + movl r8=running_on_xen;; 9.234 + ld4 r8=[r8];; 9.235 + cmp.eq p7,p0=r8,r0;; 9.236 +(p7) mov r8=pmd[r32];; 9.237 +(p7) br.ret.sptk.many rp 9.238 + ;; 9.239 + mov r72=pmc[r32] // this is a "privified" mov r8=pmd[r32] 9.240 + ;; 9.241 + br.ret.sptk.many rp 9.242 +END(xen_get_pmd) 9.243 + 9.244 +#ifdef CONFIG_IA32_SUPPORT 9.245 +GLOBAL_ENTRY(xen_get_eflag) 9.246 + movl r8=running_on_xen;; 9.247 + ld4 r8=[r8];; 9.248 + cmp.eq p7,p0=r8,r0;; 9.249 +(p7) mov r8=ar24;; 9.250 +(p7) br.ret.sptk.many rp 9.251 + ;; 9.252 + mov ar24=r72 // this is a "privified" mov r8=ar.eflg 9.253 + ;; 9.254 + br.ret.sptk.many rp 9.255 +END(xen_get_eflag) 9.256 +// some bits aren't set if pl!=0, see SDM vol1 3.1.8 9.257 +GLOBAL_ENTRY(xen_set_eflag) 9.258 + movl r8=running_on_xen;; 9.259 + ld4 r8=[r8];; 9.260 + cmp.eq p7,p0=r8,r0;; 9.261 +(p7) mov ar24=r32 9.262 +(p7) br.ret.sptk.many rp 9.263 + ;; 9.264 + // FIXME: this remains no-op'd because it generates 9.265 + // a privileged register (general exception) trap rather than 9.266 + // a privileged operation fault 9.267 + //mov ar24=r32 9.268 + ;; 9.269 + br.ret.sptk.many rp 9.270 +END(xen_get_eflag) 9.271 +#endif
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenconsole.c Wed Sep 21 09:06:30 2005 -0600 10.3 @@ -0,0 +1,18 @@ 10.4 +#include <linux/config.h> 10.5 +#include <linux/console.h> 10.6 + 10.7 +int 10.8 +early_xen_console_setup (char *cmdline) 10.9 +{ 10.10 +#ifdef CONFIG_XEN 10.11 +#ifndef CONFIG_IA64_HP_SIM 10.12 + extern int running_on_xen; 10.13 + if (running_on_xen) { 10.14 + extern struct console hpsim_cons; 10.15 + register_console(&hpsim_cons); 10.16 + return 0; 10.17 + } 10.18 +#endif 10.19 +#endif 10.20 + return -1; 10.21 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Wed Sep 21 09:06:30 2005 -0600 11.3 @@ -0,0 +1,860 @@ 11.4 +/* 11.5 + * ia64/xen/entry.S 11.6 + * 11.7 + * Alternate kernel routines for Xen. Heavily leveraged from 11.8 + * ia64/kernel/entry.S 11.9 + * 11.10 + * Copyright (C) 2005 Hewlett-Packard Co 11.11 + * Dan Magenheimer <dan.magenheimer@.hp.com> 11.12 + */ 11.13 + 11.14 +#include <linux/config.h> 11.15 + 11.16 +#include <asm/asmmacro.h> 11.17 +#include <asm/cache.h> 11.18 +#include <asm/errno.h> 11.19 +#include <asm/kregs.h> 11.20 +#include <asm/offsets.h> 11.21 +#include <asm/pgtable.h> 11.22 +#include <asm/percpu.h> 11.23 +#include <asm/processor.h> 11.24 +#include <asm/thread_info.h> 11.25 +#include <asm/unistd.h> 11.26 + 11.27 +#ifdef CONFIG_XEN 11.28 +#include "xenminstate.h" 11.29 +#else 11.30 +#include "minstate.h" 11.31 +#endif 11.32 + 11.33 +/* 11.34 + * prev_task <- ia64_switch_to(struct task_struct *next) 11.35 + * With Ingo's new scheduler, interrupts are disabled when this routine gets 11.36 + * called. The code starting at .map relies on this. The rest of the code 11.37 + * doesn't care about the interrupt masking status. 11.38 + */ 11.39 +#ifdef CONFIG_XEN 11.40 +GLOBAL_ENTRY(xen_switch_to) 11.41 + .prologue 11.42 + alloc r16=ar.pfs,1,0,0,0 11.43 + movl r22=running_on_xen;; 11.44 + ld4 r22=[r22];; 11.45 + cmp.eq p7,p0=r22,r0 11.46 +(p7) br.cond.sptk.many __ia64_switch_to;; 11.47 +#else 11.48 +GLOBAL_ENTRY(ia64_switch_to) 11.49 + .prologue 11.50 + alloc r16=ar.pfs,1,0,0,0 11.51 +#endif 11.52 + .prologue 11.53 + alloc r16=ar.pfs,1,0,0,0 11.54 + DO_SAVE_SWITCH_STACK 11.55 + .body 11.56 + 11.57 + adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 11.58 + movl r25=init_task 11.59 +#ifdef CONFIG_XEN 11.60 + movl r27=XSI_KR0+(IA64_KR_CURRENT_STACK*8) 11.61 + ;; 11.62 + ld8 r27=[r27] 11.63 +#else 11.64 + mov r27=IA64_KR(CURRENT_STACK) 11.65 +#endif 11.66 + adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 11.67 + dep r20=0,in0,61,3 // physical address of "next" 11.68 + ;; 11.69 + st8 [r22]=sp // save kernel stack pointer of old task 11.70 + shr.u r26=r20,IA64_GRANULE_SHIFT 11.71 + cmp.eq p7,p6=r25,in0 11.72 + ;; 11.73 + /* 11.74 + * If we've already mapped this task's page, we can skip doing it again. 11.75 + */ 11.76 +(p6) cmp.eq p7,p6=r26,r27 11.77 +(p6) br.cond.dpnt .map 11.78 + ;; 11.79 +.done: 11.80 +#ifdef CONFIG_XEN 11.81 + movl r27=XSI_PSR_IC 11.82 + mov r8=1 11.83 + ;; 11.84 +(p6) st4 [r27]=r8 11.85 + ;; 11.86 +#else 11.87 +(p6) ssm psr.ic // if we had to map, reenable the psr.ic bit FIRST!!! 11.88 + ;; 11.89 +(p6) srlz.d 11.90 +#endif 11.91 + ld8 sp=[r21] // load kernel stack pointer of new task 11.92 +#ifdef CONFIG_XEN 11.93 + movl r8=XSI_KR0+(IA64_KR_CURRENT*8) 11.94 + ;; 11.95 + st8 [r8]=in0 11.96 +#else 11.97 + mov IA64_KR(CURRENT)=in0 // update "current" application register 11.98 +#endif 11.99 + mov r8=r13 // return pointer to previously running task 11.100 + mov r13=in0 // set "current" pointer 11.101 + ;; 11.102 + DO_LOAD_SWITCH_STACK 11.103 + 11.104 +#ifdef CONFIG_SMP 11.105 + sync.i // ensure "fc"s done by this CPU are visible on other CPUs 11.106 +#endif 11.107 + br.ret.sptk.many rp // boogie on out in new context 11.108 + 11.109 +.map: 11.110 +#ifdef CONFIG_XEN 11.111 + movl r27=XSI_PSR_IC 11.112 + ;; 11.113 + st4 [r27]=r0 11.114 +#else 11.115 + rsm psr.ic // interrupts (psr.i) are already disabled here 11.116 +#endif 11.117 + movl r25=PAGE_KERNEL 11.118 + ;; 11.119 + srlz.d 11.120 + or r23=r25,r20 // construct PA | page properties 11.121 + mov r25=IA64_GRANULE_SHIFT<<2 11.122 + ;; 11.123 +#ifdef CONFIG_XEN 11.124 + movl r8=XSI_ITIR 11.125 + ;; 11.126 + st8 [r8]=r25 11.127 + ;; 11.128 + movl r8=XSI_IFA 11.129 + ;; 11.130 + st8 [r8]=in0 // VA of next task... 11.131 + ;; 11.132 + mov r25=IA64_TR_CURRENT_STACK 11.133 + movl r8=XSI_KR0+(IA64_KR_CURRENT_STACK*8) 11.134 + ;; 11.135 + st8 [r8]=r26 11.136 +#else 11.137 + mov cr.itir=r25 11.138 + mov cr.ifa=in0 // VA of next task... 11.139 + ;; 11.140 + mov r25=IA64_TR_CURRENT_STACK 11.141 + mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped... 11.142 +#endif 11.143 + ;; 11.144 + itr.d dtr[r25]=r23 // wire in new mapping... 11.145 + br.cond.sptk .done 11.146 +#ifdef CONFIG_XEN 11.147 +END(xen_switch_to) 11.148 +#else 11.149 +END(ia64_switch_to) 11.150 +#endif 11.151 + 11.152 + /* 11.153 + * Invoke a system call, but do some tracing before and after the call. 11.154 + * We MUST preserve the current register frame throughout this routine 11.155 + * because some system calls (such as ia64_execve) directly 11.156 + * manipulate ar.pfs. 11.157 + */ 11.158 +#ifdef CONFIG_XEN 11.159 +GLOBAL_ENTRY(xen_trace_syscall) 11.160 + PT_REGS_UNWIND_INFO(0) 11.161 + movl r16=running_on_xen;; 11.162 + ld4 r16=[r16];; 11.163 + cmp.eq p7,p0=r16,r0 11.164 +(p7) br.cond.sptk.many __ia64_trace_syscall;; 11.165 +#else 11.166 +GLOBAL_ENTRY(ia64_trace_syscall) 11.167 + PT_REGS_UNWIND_INFO(0) 11.168 +#endif 11.169 + /* 11.170 + * We need to preserve the scratch registers f6-f11 in case the system 11.171 + * call is sigreturn. 11.172 + */ 11.173 + adds r16=PT(F6)+16,sp 11.174 + adds r17=PT(F7)+16,sp 11.175 + ;; 11.176 + stf.spill [r16]=f6,32 11.177 + stf.spill [r17]=f7,32 11.178 + ;; 11.179 + stf.spill [r16]=f8,32 11.180 + stf.spill [r17]=f9,32 11.181 + ;; 11.182 + stf.spill [r16]=f10 11.183 + stf.spill [r17]=f11 11.184 + br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args 11.185 + adds r16=PT(F6)+16,sp 11.186 + adds r17=PT(F7)+16,sp 11.187 + ;; 11.188 + ldf.fill f6=[r16],32 11.189 + ldf.fill f7=[r17],32 11.190 + ;; 11.191 + ldf.fill f8=[r16],32 11.192 + ldf.fill f9=[r17],32 11.193 + ;; 11.194 + ldf.fill f10=[r16] 11.195 + ldf.fill f11=[r17] 11.196 + // the syscall number may have changed, so re-load it and re-calculate the 11.197 + // syscall entry-point: 11.198 + adds r15=PT(R15)+16,sp // r15 = &pt_regs.r15 (syscall #) 11.199 + ;; 11.200 + ld8 r15=[r15] 11.201 + mov r3=NR_syscalls - 1 11.202 + ;; 11.203 + adds r15=-1024,r15 11.204 + movl r16=sys_call_table 11.205 + ;; 11.206 + shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) 11.207 + cmp.leu p6,p7=r15,r3 11.208 + ;; 11.209 +(p6) ld8 r20=[r20] // load address of syscall entry point 11.210 +(p7) movl r20=sys_ni_syscall 11.211 + ;; 11.212 + mov b6=r20 11.213 + br.call.sptk.many rp=b6 // do the syscall 11.214 +.strace_check_retval: 11.215 + cmp.lt p6,p0=r8,r0 // syscall failed? 11.216 + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 11.217 + adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 11.218 + mov r10=0 11.219 +(p6) br.cond.sptk strace_error // syscall failed -> 11.220 + ;; // avoid RAW on r10 11.221 +.strace_save_retval: 11.222 +.mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8 11.223 +.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 11.224 + br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value 11.225 +.ret3: br.cond.sptk .work_pending_syscall_end 11.226 + 11.227 +strace_error: 11.228 + ld8 r3=[r2] // load pt_regs.r8 11.229 + sub r9=0,r8 // negate return value to get errno value 11.230 + ;; 11.231 + cmp.ne p6,p0=r3,r0 // is pt_regs.r8!=0? 11.232 + adds r3=16,r2 // r3=&pt_regs.r10 11.233 + ;; 11.234 +(p6) mov r10=-1 11.235 +(p6) mov r8=r9 11.236 + br.cond.sptk .strace_save_retval 11.237 +#ifdef CONFIG_XEN 11.238 +END(xen_trace_syscall) 11.239 +#else 11.240 +END(ia64_trace_syscall) 11.241 +#endif 11.242 + 11.243 +/* 11.244 + * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't 11.245 + * need to switch to bank 0 and doesn't restore the scratch registers. 11.246 + * To avoid leaking kernel bits, the scratch registers are set to 11.247 + * the following known-to-be-safe values: 11.248 + * 11.249 + * r1: restored (global pointer) 11.250 + * r2: cleared 11.251 + * r3: 1 (when returning to user-level) 11.252 + * r8-r11: restored (syscall return value(s)) 11.253 + * r12: restored (user-level stack pointer) 11.254 + * r13: restored (user-level thread pointer) 11.255 + * r14: cleared 11.256 + * r15: restored (syscall #) 11.257 + * r16-r17: cleared 11.258 + * r18: user-level b6 11.259 + * r19: cleared 11.260 + * r20: user-level ar.fpsr 11.261 + * r21: user-level b0 11.262 + * r22: cleared 11.263 + * r23: user-level ar.bspstore 11.264 + * r24: user-level ar.rnat 11.265 + * r25: user-level ar.unat 11.266 + * r26: user-level ar.pfs 11.267 + * r27: user-level ar.rsc 11.268 + * r28: user-level ip 11.269 + * r29: user-level psr 11.270 + * r30: user-level cfm 11.271 + * r31: user-level pr 11.272 + * f6-f11: cleared 11.273 + * pr: restored (user-level pr) 11.274 + * b0: restored (user-level rp) 11.275 + * b6: restored 11.276 + * b7: cleared 11.277 + * ar.unat: restored (user-level ar.unat) 11.278 + * ar.pfs: restored (user-level ar.pfs) 11.279 + * ar.rsc: restored (user-level ar.rsc) 11.280 + * ar.rnat: restored (user-level ar.rnat) 11.281 + * ar.bspstore: restored (user-level ar.bspstore) 11.282 + * ar.fpsr: restored (user-level ar.fpsr) 11.283 + * ar.ccv: cleared 11.284 + * ar.csd: cleared 11.285 + * ar.ssd: cleared 11.286 + */ 11.287 +#ifdef CONFIG_XEN 11.288 +GLOBAL_ENTRY(xen_leave_syscall) 11.289 + PT_REGS_UNWIND_INFO(0) 11.290 + movl r22=running_on_xen;; 11.291 + ld4 r22=[r22];; 11.292 + cmp.eq p7,p0=r22,r0 11.293 +(p7) br.cond.sptk.many __ia64_leave_syscall;; 11.294 +#else 11.295 +ENTRY(ia64_leave_syscall) 11.296 + PT_REGS_UNWIND_INFO(0) 11.297 +#endif 11.298 + /* 11.299 + * work.need_resched etc. mustn't get changed by this CPU before it returns to 11.300 + * user- or fsys-mode, hence we disable interrupts early on. 11.301 + * 11.302 + * p6 controls whether current_thread_info()->flags needs to be check for 11.303 + * extra work. We always check for extra work when returning to user-level. 11.304 + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count 11.305 + * is 0. After extra work processing has been completed, execution 11.306 + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check 11.307 + * needs to be redone. 11.308 + */ 11.309 +#ifdef CONFIG_PREEMPT 11.310 + rsm psr.i // disable interrupts 11.311 + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall 11.312 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 11.313 + ;; 11.314 + .pred.rel.mutex pUStk,pKStk 11.315 +(pKStk) ld4 r21=[r20] // r21 <- preempt_count 11.316 +(pUStk) mov r21=0 // r21 <- 0 11.317 + ;; 11.318 + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) 11.319 +#else /* !CONFIG_PREEMPT */ 11.320 +#ifdef CONFIG_XEN 11.321 + movl r2=XSI_PSR_I 11.322 + ;; 11.323 +(pUStk) st4 [r2]=r0 11.324 +#else 11.325 +(pUStk) rsm psr.i 11.326 +#endif 11.327 + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall 11.328 +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk 11.329 +#endif 11.330 +.work_processed_syscall: 11.331 + adds r2=PT(LOADRS)+16,r12 11.332 + adds r3=PT(AR_BSPSTORE)+16,r12 11.333 + adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 11.334 + ;; 11.335 +(p6) ld4 r31=[r18] // load current_thread_info()->flags 11.336 + ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" 11.337 + mov b7=r0 // clear b7 11.338 + ;; 11.339 + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) 11.340 + ld8 r18=[r2],PT(R9)-PT(B6) // load b6 11.341 +(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? 11.342 + ;; 11.343 + mov r16=ar.bsp // M2 get existing backing store pointer 11.344 +(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? 11.345 +(p6) br.cond.spnt .work_pending_syscall 11.346 + ;; 11.347 + // start restoring the state saved on the kernel stack (struct pt_regs): 11.348 + ld8 r9=[r2],PT(CR_IPSR)-PT(R9) 11.349 + ld8 r11=[r3],PT(CR_IIP)-PT(R11) 11.350 + mov f6=f0 // clear f6 11.351 + ;; 11.352 + invala // M0|1 invalidate ALAT 11.353 +#ifdef CONFIG_XEN 11.354 + movl r29=XSI_PSR_IC 11.355 + ;; 11.356 + st8 [r29]=r0 // note: clears both vpsr.i and vpsr.ic! 11.357 + ;; 11.358 +#else 11.359 + rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection 11.360 +#endif 11.361 + mov f9=f0 // clear f9 11.362 + 11.363 + ld8 r29=[r2],16 // load cr.ipsr 11.364 + ld8 r28=[r3],16 // load cr.iip 11.365 + mov f8=f0 // clear f8 11.366 + ;; 11.367 + ld8 r30=[r2],16 // M0|1 load cr.ifs 11.368 + mov.m ar.ssd=r0 // M2 clear ar.ssd 11.369 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs 11.370 + ;; 11.371 + ld8 r25=[r3],16 // M0|1 load ar.unat 11.372 + mov.m ar.csd=r0 // M2 clear ar.csd 11.373 + mov r22=r0 // clear r22 11.374 + ;; 11.375 + ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs 11.376 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled 11.377 + mov f10=f0 // clear f10 11.378 + ;; 11.379 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 11.380 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc 11.381 + mov f11=f0 // clear f11 11.382 + ;; 11.383 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) 11.384 + ld8 r31=[r3],PT(R1)-PT(PR) // load predicates 11.385 +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 11.386 + ;; 11.387 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr 11.388 + ld8.fill r1=[r3],16 // load r1 11.389 +(pUStk) mov r17=1 11.390 + ;; 11.391 + srlz.d // M0 ensure interruption collection is off 11.392 + ld8.fill r13=[r3],16 11.393 + mov f7=f0 // clear f7 11.394 + ;; 11.395 + ld8.fill r12=[r2] // restore r12 (sp) 11.396 + ld8.fill r15=[r3] // restore r15 11.397 + addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 11.398 + ;; 11.399 +(pUStk) ld4 r3=[r3] // r3 = cpu_data->phys_stacked_size_p8 11.400 +(pUStk) st1 [r14]=r17 11.401 + mov b6=r18 // I0 restore b6 11.402 + ;; 11.403 + mov r14=r0 // clear r14 11.404 + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition 11.405 +(pKStk) br.cond.dpnt.many skip_rbs_switch 11.406 + 11.407 + mov.m ar.ccv=r0 // clear ar.ccv 11.408 +(pNonSys) br.cond.dpnt.many dont_preserve_current_frame 11.409 + br.cond.sptk.many rbs_switch 11.410 +#ifdef CONFIG_XEN 11.411 +END(xen_leave_syscall) 11.412 +#else 11.413 +END(ia64_leave_syscall) 11.414 +#endif 11.415 + 11.416 +#ifdef CONFIG_XEN 11.417 +GLOBAL_ENTRY(xen_leave_kernel) 11.418 + PT_REGS_UNWIND_INFO(0) 11.419 + movl r22=running_on_xen;; 11.420 + ld4 r22=[r22];; 11.421 + cmp.eq p7,p0=r22,r0 11.422 +(p7) br.cond.sptk.many __ia64_leave_kernel;; 11.423 +#else 11.424 +GLOBAL_ENTRY(ia64_leave_kernel) 11.425 + PT_REGS_UNWIND_INFO(0) 11.426 +#endif 11.427 + /* 11.428 + * work.need_resched etc. mustn't get changed by this CPU before it returns to 11.429 + * user- or fsys-mode, hence we disable interrupts early on. 11.430 + * 11.431 + * p6 controls whether current_thread_info()->flags needs to be check for 11.432 + * extra work. We always check for extra work when returning to user-level. 11.433 + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count 11.434 + * is 0. After extra work processing has been completed, execution 11.435 + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check 11.436 + * needs to be redone. 11.437 + */ 11.438 +#ifdef CONFIG_PREEMPT 11.439 + rsm psr.i // disable interrupts 11.440 + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel 11.441 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 11.442 + ;; 11.443 + .pred.rel.mutex pUStk,pKStk 11.444 +(pKStk) ld4 r21=[r20] // r21 <- preempt_count 11.445 +(pUStk) mov r21=0 // r21 <- 0 11.446 + ;; 11.447 + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) 11.448 +#else 11.449 +#ifdef CONFIG_XEN 11.450 +(pUStk) movl r17=XSI_PSR_I 11.451 + ;; 11.452 +(pUStk) st4 [r17]=r0 11.453 + ;; 11.454 +#else 11.455 +(pUStk) rsm psr.i 11.456 +#endif 11.457 + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel 11.458 +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk 11.459 +#endif 11.460 +.work_processed_kernel: 11.461 + adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 11.462 + ;; 11.463 +(p6) ld4 r31=[r17] // load current_thread_info()->flags 11.464 + adds r21=PT(PR)+16,r12 11.465 + ;; 11.466 + 11.467 + lfetch [r21],PT(CR_IPSR)-PT(PR) 11.468 + adds r2=PT(B6)+16,r12 11.469 + adds r3=PT(R16)+16,r12 11.470 + ;; 11.471 + lfetch [r21] 11.472 + ld8 r28=[r2],8 // load b6 11.473 + adds r29=PT(R24)+16,r12 11.474 + 11.475 + ld8.fill r16=[r3],PT(AR_CSD)-PT(R16) 11.476 + adds r30=PT(AR_CCV)+16,r12 11.477 +(p6) and r19=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? 11.478 + ;; 11.479 + ld8.fill r24=[r29] 11.480 + ld8 r15=[r30] // load ar.ccv 11.481 +(p6) cmp4.ne.unc p6,p0=r19, r0 // any special work pending? 11.482 + ;; 11.483 + ld8 r29=[r2],16 // load b7 11.484 + ld8 r30=[r3],16 // load ar.csd 11.485 +(p6) br.cond.spnt .work_pending 11.486 + ;; 11.487 + ld8 r31=[r2],16 // load ar.ssd 11.488 + ld8.fill r8=[r3],16 11.489 + ;; 11.490 + ld8.fill r9=[r2],16 11.491 + ld8.fill r10=[r3],PT(R17)-PT(R10) 11.492 + ;; 11.493 + ld8.fill r11=[r2],PT(R18)-PT(R11) 11.494 + ld8.fill r17=[r3],16 11.495 + ;; 11.496 + ld8.fill r18=[r2],16 11.497 + ld8.fill r19=[r3],16 11.498 + ;; 11.499 + ld8.fill r20=[r2],16 11.500 + ld8.fill r21=[r3],16 11.501 + mov ar.csd=r30 11.502 + mov ar.ssd=r31 11.503 + ;; 11.504 +#ifdef CONFIG_XEN 11.505 + movl r22=XSI_PSR_IC 11.506 + ;; 11.507 + st8 [r22]=r0 // note: clears both vpsr.i and vpsr.ic! 11.508 + ;; 11.509 +#else 11.510 + rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection 11.511 +#endif 11.512 + invala // invalidate ALAT 11.513 + ;; 11.514 + ld8.fill r22=[r2],24 11.515 + ld8.fill r23=[r3],24 11.516 + mov b6=r28 11.517 + ;; 11.518 + ld8.fill r25=[r2],16 11.519 + ld8.fill r26=[r3],16 11.520 + mov b7=r29 11.521 + ;; 11.522 + ld8.fill r27=[r2],16 11.523 + ld8.fill r28=[r3],16 11.524 + ;; 11.525 + ld8.fill r29=[r2],16 11.526 + ld8.fill r30=[r3],24 11.527 + ;; 11.528 + ld8.fill r31=[r2],PT(F9)-PT(R31) 11.529 + adds r3=PT(F10)-PT(F6),r3 11.530 + ;; 11.531 + ldf.fill f9=[r2],PT(F6)-PT(F9) 11.532 + ldf.fill f10=[r3],PT(F8)-PT(F10) 11.533 + ;; 11.534 + ldf.fill f6=[r2],PT(F7)-PT(F6) 11.535 + ;; 11.536 + ldf.fill f7=[r2],PT(F11)-PT(F7) 11.537 + ldf.fill f8=[r3],32 11.538 + ;; 11.539 + srlz.i // ensure interruption collection is off 11.540 + mov ar.ccv=r15 11.541 + ;; 11.542 + ldf.fill f11=[r2] 11.543 +#ifdef CONFIG_XEN 11.544 + ;; 11.545 + // r16-r31 all now hold bank1 values 11.546 + movl r2=XSI_BANK1_R16 11.547 + movl r3=XSI_BANK1_R16+8 11.548 + ;; 11.549 + st8.spill [r2]=r16,16 11.550 + st8.spill [r3]=r17,16 11.551 + ;; 11.552 + st8.spill [r2]=r18,16 11.553 + st8.spill [r3]=r19,16 11.554 + ;; 11.555 + st8.spill [r2]=r20,16 11.556 + st8.spill [r3]=r21,16 11.557 + ;; 11.558 + st8.spill [r2]=r22,16 11.559 + st8.spill [r3]=r23,16 11.560 + ;; 11.561 + st8.spill [r2]=r24,16 11.562 + st8.spill [r3]=r25,16 11.563 + ;; 11.564 + st8.spill [r2]=r26,16 11.565 + st8.spill [r3]=r27,16 11.566 + ;; 11.567 + st8.spill [r2]=r28,16 11.568 + st8.spill [r3]=r29,16 11.569 + ;; 11.570 + st8.spill [r2]=r30,16 11.571 + st8.spill [r3]=r31,16 11.572 + ;; 11.573 + movl r2=XSI_BANKNUM;; 11.574 + st4 [r2]=r0; 11.575 +#else 11.576 + bsw.0 // switch back to bank 0 (no stop bit required beforehand...) 11.577 +#endif 11.578 + ;; 11.579 +#ifdef CONFIG_XEN 11.580 +(pUStk) movl r18=XSI_KR0+(IA64_KR_CURRENT*8) 11.581 + ;; 11.582 +(pUStk) ld8 r18=[r18] 11.583 + ;; 11.584 +#else 11.585 +(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency) 11.586 +#endif 11.587 + adds r16=PT(CR_IPSR)+16,r12 11.588 + adds r17=PT(CR_IIP)+16,r12 11.589 + 11.590 +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled 11.591 + nop.i 0 11.592 + nop.i 0 11.593 + ;; 11.594 + ld8 r29=[r16],16 // load cr.ipsr 11.595 + ld8 r28=[r17],16 // load cr.iip 11.596 + ;; 11.597 + ld8 r30=[r16],16 // load cr.ifs 11.598 + ld8 r25=[r17],16 // load ar.unat 11.599 + ;; 11.600 + ld8 r26=[r16],16 // load ar.pfs 11.601 + ld8 r27=[r17],16 // load ar.rsc 11.602 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs 11.603 + ;; 11.604 + ld8 r24=[r16],16 // load ar.rnat (may be garbage) 11.605 + ld8 r23=[r17],16 // load ar.bspstore (may be garbage) 11.606 + ;; 11.607 + ld8 r31=[r16],16 // load predicates 11.608 + ld8 r21=[r17],16 // load b0 11.609 + ;; 11.610 + ld8 r19=[r16],16 // load ar.rsc value for "loadrs" 11.611 + ld8.fill r1=[r17],16 // load r1 11.612 + ;; 11.613 + ld8.fill r12=[r16],16 11.614 + ld8.fill r13=[r17],16 11.615 +(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 11.616 + ;; 11.617 + ld8 r20=[r16],16 // ar.fpsr 11.618 + ld8.fill r15=[r17],16 11.619 + ;; 11.620 + ld8.fill r14=[r16],16 11.621 + ld8.fill r2=[r17] 11.622 +(pUStk) mov r17=1 11.623 + ;; 11.624 + ld8.fill r3=[r16] 11.625 +(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack 11.626 + shr.u r18=r19,16 // get byte size of existing "dirty" partition 11.627 + ;; 11.628 + mov r16=ar.bsp // get existing backing store pointer 11.629 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 11.630 + ;; 11.631 + ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 11.632 +(pKStk) br.cond.dpnt skip_rbs_switch 11.633 + 11.634 + /* 11.635 + * Restore user backing store. 11.636 + * 11.637 + * NOTE: alloc, loadrs, and cover can't be predicated. 11.638 + */ 11.639 +(pNonSys) br.cond.dpnt dont_preserve_current_frame 11.640 + 11.641 +rbs_switch: 11.642 +#ifdef CONFIG_XEN 11.643 + XEN_HYPER_COVER; 11.644 +#else 11.645 + cover // add current frame into dirty partition and set cr.ifs 11.646 +#endif 11.647 + ;; 11.648 + mov r19=ar.bsp // get new backing store pointer 11.649 + sub r16=r16,r18 // krbs = old bsp - size of dirty partition 11.650 + cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs 11.651 + ;; 11.652 + sub r19=r19,r16 // calculate total byte size of dirty partition 11.653 + add r18=64,r18 // don't force in0-in7 into memory... 11.654 + ;; 11.655 + shl r19=r19,16 // shift size of dirty partition into loadrs position 11.656 + ;; 11.657 +dont_preserve_current_frame: 11.658 + /* 11.659 + * To prevent leaking bits between the kernel and user-space, 11.660 + * we must clear the stacked registers in the "invalid" partition here. 11.661 + * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium, 11.662 + * 5 registers/cycle on McKinley). 11.663 + */ 11.664 +# define pRecurse p6 11.665 +# define pReturn p7 11.666 +#ifdef CONFIG_ITANIUM 11.667 +# define Nregs 10 11.668 +#else 11.669 +# define Nregs 14 11.670 +#endif 11.671 + alloc loc0=ar.pfs,2,Nregs-2,2,0 11.672 + shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) 11.673 + sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize 11.674 + ;; 11.675 + mov ar.rsc=r19 // load ar.rsc to be used for "loadrs" 11.676 + shladd in0=loc1,3,r17 11.677 + mov in1=0 11.678 + ;; 11.679 + TEXT_ALIGN(32) 11.680 +rse_clear_invalid: 11.681 +#ifdef CONFIG_ITANIUM 11.682 + // cycle 0 11.683 + { .mii 11.684 + alloc loc0=ar.pfs,2,Nregs-2,2,0 11.685 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse 11.686 + add out0=-Nregs*8,in0 11.687 +}{ .mfb 11.688 + add out1=1,in1 // increment recursion count 11.689 + nop.f 0 11.690 + nop.b 0 // can't do br.call here because of alloc (WAW on CFM) 11.691 + ;; 11.692 +}{ .mfi // cycle 1 11.693 + mov loc1=0 11.694 + nop.f 0 11.695 + mov loc2=0 11.696 +}{ .mib 11.697 + mov loc3=0 11.698 + mov loc4=0 11.699 +(pRecurse) br.call.sptk.many b0=rse_clear_invalid 11.700 + 11.701 +}{ .mfi // cycle 2 11.702 + mov loc5=0 11.703 + nop.f 0 11.704 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret 11.705 +}{ .mib 11.706 + mov loc6=0 11.707 + mov loc7=0 11.708 +(pReturn) br.ret.sptk.many b0 11.709 +} 11.710 +#else /* !CONFIG_ITANIUM */ 11.711 + alloc loc0=ar.pfs,2,Nregs-2,2,0 11.712 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse 11.713 + add out0=-Nregs*8,in0 11.714 + add out1=1,in1 // increment recursion count 11.715 + mov loc1=0 11.716 + mov loc2=0 11.717 + ;; 11.718 + mov loc3=0 11.719 + mov loc4=0 11.720 + mov loc5=0 11.721 + mov loc6=0 11.722 + mov loc7=0 11.723 +(pRecurse) br.call.sptk.few b0=rse_clear_invalid 11.724 + ;; 11.725 + mov loc8=0 11.726 + mov loc9=0 11.727 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret 11.728 + mov loc10=0 11.729 + mov loc11=0 11.730 +(pReturn) br.ret.sptk.many b0 11.731 +#endif /* !CONFIG_ITANIUM */ 11.732 +# undef pRecurse 11.733 +# undef pReturn 11.734 + ;; 11.735 + alloc r17=ar.pfs,0,0,0,0 // drop current register frame 11.736 + ;; 11.737 + loadrs 11.738 + ;; 11.739 +skip_rbs_switch: 11.740 + mov ar.unat=r25 // M2 11.741 +(pKStk) extr.u r22=r22,21,1 // I0 extract current value of psr.pp from r22 11.742 +(pLvSys)mov r19=r0 // A clear r19 for leave_syscall, no-op otherwise 11.743 + ;; 11.744 +(pUStk) mov ar.bspstore=r23 // M2 11.745 +(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp 11.746 +(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise 11.747 + ;; 11.748 +#ifdef CONFIG_XEN 11.749 + movl r25=XSI_IPSR 11.750 + ;; 11.751 + st8[r25]=r29,XSI_IFS-XSI_IPSR 11.752 + ;; 11.753 +#else 11.754 + mov cr.ipsr=r29 // M2 11.755 +#endif 11.756 + mov ar.pfs=r26 // I0 11.757 +(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise 11.758 + 11.759 +#ifdef CONFIG_XEN 11.760 +(p9) st8 [r25]=r30 11.761 + ;; 11.762 + adds r25=XSI_IIP-XSI_IFS,r25 11.763 + ;; 11.764 +#else 11.765 +(p9) mov cr.ifs=r30 // M2 11.766 +#endif 11.767 + mov b0=r21 // I0 11.768 +(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise 11.769 + 11.770 + mov ar.fpsr=r20 // M2 11.771 +#ifdef CONFIG_XEN 11.772 + st8 [r25]=r28 11.773 +#else 11.774 + mov cr.iip=r28 // M2 11.775 +#endif 11.776 + nop 0 11.777 + ;; 11.778 +(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode 11.779 + nop 0 11.780 +(pLvSys)mov r2=r0 11.781 + 11.782 + mov ar.rsc=r27 // M2 11.783 + mov pr=r31,-1 // I0 11.784 +#ifdef CONFIG_XEN 11.785 + ;; 11.786 + XEN_HYPER_RFI; 11.787 +#else 11.788 + rfi // B 11.789 +#endif 11.790 + 11.791 + /* 11.792 + * On entry: 11.793 + * r20 = ¤t->thread_info->pre_count (if CONFIG_PREEMPT) 11.794 + * r31 = current->thread_info->flags 11.795 + * On exit: 11.796 + * p6 = TRUE if work-pending-check needs to be redone 11.797 + */ 11.798 +.work_pending_syscall: 11.799 + add r2=-8,r2 11.800 + add r3=-8,r3 11.801 + ;; 11.802 + st8 [r2]=r8 11.803 + st8 [r3]=r10 11.804 +.work_pending: 11.805 + tbit.nz p6,p0=r31,TIF_SIGDELAYED // signal delayed from MCA/INIT/NMI/PMI context? 11.806 +(p6) br.cond.sptk.few .sigdelayed 11.807 + ;; 11.808 + tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? 11.809 +(p6) br.cond.sptk.few .notify 11.810 +#ifdef CONFIG_PREEMPT 11.811 +(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 11.812 + ;; 11.813 +(pKStk) st4 [r20]=r21 11.814 + ssm psr.i // enable interrupts 11.815 +#endif 11.816 + br.call.spnt.many rp=schedule 11.817 +.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 11.818 +#ifdef CONFIG_XEN 11.819 + movl r2=XSI_PSR_I 11.820 + ;; 11.821 + st4 [r2]=r0 11.822 +#else 11.823 + rsm psr.i // disable interrupts 11.824 +#endif 11.825 + ;; 11.826 +#ifdef CONFIG_PREEMPT 11.827 +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 11.828 + ;; 11.829 +(pKStk) st4 [r20]=r0 // preempt_count() <- 0 11.830 +#endif 11.831 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 11.832 + br.cond.sptk.many .work_processed_kernel // re-check 11.833 + 11.834 +.notify: 11.835 +(pUStk) br.call.spnt.many rp=notify_resume_user 11.836 +.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 11.837 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 11.838 + br.cond.sptk.many .work_processed_kernel // don't re-check 11.839 + 11.840 +// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where 11.841 +// it could not be delivered. Deliver it now. The signal might be for us and 11.842 +// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed 11.843 +// signal. 11.844 + 11.845 +.sigdelayed: 11.846 + br.call.sptk.many rp=do_sigdelayed 11.847 + cmp.eq p6,p0=r0,r0 // p6 <- 1, always re-check 11.848 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end 11.849 + br.cond.sptk.many .work_processed_kernel // re-check 11.850 + 11.851 +.work_pending_syscall_end: 11.852 + adds r2=PT(R8)+16,r12 11.853 + adds r3=PT(R10)+16,r12 11.854 + ;; 11.855 + ld8 r8=[r2] 11.856 + ld8 r10=[r3] 11.857 + br.cond.sptk.many .work_processed_syscall // re-check 11.858 + 11.859 +#ifdef CONFIG_XEN 11.860 +END(xen_leave_kernel) 11.861 +#else 11.862 +END(ia64_leave_kernel) 11.863 +#endif
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenhpski.c Wed Sep 21 09:06:30 2005 -0600 12.3 @@ -0,0 +1,19 @@ 12.4 + 12.5 +extern unsigned long xen_get_cpuid(int); 12.6 + 12.7 +int 12.8 +running_on_sim(void) 12.9 +{ 12.10 + int i; 12.11 + long cpuid[6]; 12.12 + 12.13 + for (i = 0; i < 5; ++i) 12.14 + cpuid[i] = xen_get_cpuid(i); 12.15 + if ((cpuid[0] & 0xff) != 'H') return 0; 12.16 + if ((cpuid[3] & 0xff) != 0x4) return 0; 12.17 + if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0; 12.18 + if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0; 12.19 + if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0; 12.20 + return 1; 12.21 +} 12.22 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S Wed Sep 21 09:06:30 2005 -0600 13.3 @@ -0,0 +1,2015 @@ 13.4 +/* 13.5 + * arch/ia64/xen/ivt.S 13.6 + * 13.7 + * Copyright (C) 2005 Hewlett-Packard Co 13.8 + * Dan Magenheimer <dan.magenheimer@hp.com> 13.9 + */ 13.10 +/* 13.11 + * This file defines the interruption vector table used by the CPU. 13.12 + * It does not include one entry per possible cause of interruption. 13.13 + * 13.14 + * The first 20 entries of the table contain 64 bundles each while the 13.15 + * remaining 48 entries contain only 16 bundles each. 13.16 + * 13.17 + * The 64 bundles are used to allow inlining the whole handler for critical 13.18 + * interruptions like TLB misses. 13.19 + * 13.20 + * For each entry, the comment is as follows: 13.21 + * 13.22 + * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) 13.23 + * entry offset ----/ / / / / 13.24 + * entry number ---------/ / / / 13.25 + * size of the entry -------------/ / / 13.26 + * vector name -------------------------------------/ / 13.27 + * interruptions triggering this vector ----------------------/ 13.28 + * 13.29 + * The table is 32KB in size and must be aligned on 32KB boundary. 13.30 + * (The CPU ignores the 15 lower bits of the address) 13.31 + * 13.32 + * Table is based upon EAS2.6 (Oct 1999) 13.33 + */ 13.34 + 13.35 +#include <linux/config.h> 13.36 + 13.37 +#include <asm/asmmacro.h> 13.38 +#include <asm/break.h> 13.39 +#include <asm/ia32.h> 13.40 +#include <asm/kregs.h> 13.41 +#include <asm/offsets.h> 13.42 +#include <asm/pgtable.h> 13.43 +#include <asm/processor.h> 13.44 +#include <asm/ptrace.h> 13.45 +#include <asm/system.h> 13.46 +#include <asm/thread_info.h> 13.47 +#include <asm/unistd.h> 13.48 +#include <asm/errno.h> 13.49 + 13.50 +#ifdef CONFIG_XEN 13.51 +#define ia64_ivt xen_ivt 13.52 +#endif 13.53 + 13.54 +#if 1 13.55 +# define PSR_DEFAULT_BITS psr.ac 13.56 +#else 13.57 +# define PSR_DEFAULT_BITS 0 13.58 +#endif 13.59 + 13.60 +#if 0 13.61 + /* 13.62 + * This lets you track the last eight faults that occurred on the CPU. Make sure ar.k2 isn't 13.63 + * needed for something else before enabling this... 13.64 + */ 13.65 +# define DBG_FAULT(i) mov r16=ar.k2;; shl r16=r16,8;; add r16=(i),r16;;mov ar.k2=r16 13.66 +#else 13.67 +# define DBG_FAULT(i) 13.68 +#endif 13.69 + 13.70 +#define MINSTATE_VIRT /* needed by minstate.h */ 13.71 +#include "xenminstate.h" 13.72 + 13.73 +#define FAULT(n) \ 13.74 + mov r31=pr; \ 13.75 + mov r19=n;; /* prepare to save predicates */ \ 13.76 + br.sptk.many dispatch_to_fault_handler 13.77 + 13.78 + .section .text.ivt,"ax" 13.79 + 13.80 + .align 32768 // align on 32KB boundary 13.81 + .global ia64_ivt 13.82 +ia64_ivt: 13.83 +///////////////////////////////////////////////////////////////////////////////////////// 13.84 +// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47) 13.85 +ENTRY(vhpt_miss) 13.86 + DBG_FAULT(0) 13.87 + /* 13.88 + * The VHPT vector is invoked when the TLB entry for the virtual page table 13.89 + * is missing. This happens only as a result of a previous 13.90 + * (the "original") TLB miss, which may either be caused by an instruction 13.91 + * fetch or a data access (or non-access). 13.92 + * 13.93 + * What we do here is normal TLB miss handing for the _original_ miss, followed 13.94 + * by inserting the TLB entry for the virtual page table page that the VHPT 13.95 + * walker was attempting to access. The latter gets inserted as long 13.96 + * as both L1 and L2 have valid mappings for the faulting address. 13.97 + * The TLB entry for the original miss gets inserted only if 13.98 + * the L3 entry indicates that the page is present. 13.99 + * 13.100 + * do_page_fault gets invoked in the following cases: 13.101 + * - the faulting virtual address uses unimplemented address bits 13.102 + * - the faulting virtual address has no L1, L2, or L3 mapping 13.103 + */ 13.104 +#ifdef CONFIG_XEN 13.105 + movl r16=XSI_IFA 13.106 + ;; 13.107 + ld8 r16=[r16] 13.108 +#ifdef CONFIG_HUGETLB_PAGE 13.109 + movl r18=PAGE_SHIFT 13.110 + movl r25=XSI_ITIR 13.111 + ;; 13.112 + ld8 r25=[r25] 13.113 +#endif 13.114 + ;; 13.115 +#else 13.116 + mov r16=cr.ifa // get address that caused the TLB miss 13.117 +#ifdef CONFIG_HUGETLB_PAGE 13.118 + movl r18=PAGE_SHIFT 13.119 + mov r25=cr.itir 13.120 +#endif 13.121 +#endif 13.122 + ;; 13.123 +#ifdef CONFIG_XEN 13.124 + XEN_HYPER_RSM_PSR_DT; 13.125 +#else 13.126 + rsm psr.dt // use physical addressing for data 13.127 +#endif 13.128 + mov r31=pr // save the predicate registers 13.129 +#ifdef CONFIG_XEN 13.130 + movl r19=XSI_KR0+(IA64_KR_PT_BASE*8) // get the page table base address 13.131 + ;; 13.132 + ld8 r19=[r19] 13.133 +#else 13.134 + mov r19=IA64_KR(PT_BASE) // get page table base address 13.135 +#endif 13.136 + shl r21=r16,3 // shift bit 60 into sign bit 13.137 + shr.u r17=r16,61 // get the region number into r17 13.138 + ;; 13.139 + shr r22=r21,3 13.140 +#ifdef CONFIG_HUGETLB_PAGE 13.141 + extr.u r26=r25,2,6 13.142 + ;; 13.143 + cmp.ne p8,p0=r18,r26 13.144 + sub r27=r26,r18 13.145 + ;; 13.146 +(p8) dep r25=r18,r25,2,6 13.147 +(p8) shr r22=r22,r27 13.148 +#endif 13.149 + ;; 13.150 + cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? 13.151 + shr.u r18=r22,PGDIR_SHIFT // get bits 33-63 of the faulting address 13.152 + ;; 13.153 +(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place 13.154 + 13.155 + srlz.d 13.156 + LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir 13.157 + 13.158 + .pred.rel "mutex", p6, p7 13.159 +(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT 13.160 +(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 13.161 + ;; 13.162 +(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 13.163 +(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) 13.164 + cmp.eq p7,p6=0,r21 // unused address bits all zeroes? 13.165 + shr.u r18=r22,PMD_SHIFT // shift L2 index into position 13.166 + ;; 13.167 + ld8 r17=[r17] // fetch the L1 entry (may be 0) 13.168 + ;; 13.169 +(p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? 13.170 + dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry 13.171 + ;; 13.172 +(p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) 13.173 + shr.u r19=r22,PAGE_SHIFT // shift L3 index into position 13.174 + ;; 13.175 +(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? 13.176 + dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry 13.177 + ;; 13.178 +#ifdef CONFIG_XEN 13.179 +(p7) ld8 r18=[r21] // read the L3 PTE 13.180 + movl r19=XSI_ISR 13.181 + ;; 13.182 + ld8 r19=[r19] 13.183 + ;; 13.184 +(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? 13.185 + movl r22=XSI_IHA 13.186 + ;; 13.187 + ld8 r22=[r22] 13.188 + ;; 13.189 +#else 13.190 +(p7) ld8 r18=[r21] // read the L3 PTE 13.191 + mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss 13.192 + ;; 13.193 +(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? 13.194 + mov r22=cr.iha // get the VHPT address that caused the TLB miss 13.195 + ;; // avoid RAW on p7 13.196 +#endif 13.197 +(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? 13.198 + dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address 13.199 + ;; 13.200 +(p10) itc.i r18 // insert the instruction TLB entry 13.201 +(p11) itc.d r18 // insert the data TLB entry 13.202 +(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) 13.203 +#ifdef CONFIG_XEN 13.204 + ;; 13.205 + movl r24=XSI_IFA 13.206 + ;; 13.207 + st8 [r24]=r22 13.208 + ;; 13.209 +#else 13.210 + mov cr.ifa=r22 13.211 +#endif 13.212 + 13.213 +#ifdef CONFIG_HUGETLB_PAGE 13.214 +(p8) mov cr.itir=r25 // change to default page-size for VHPT 13.215 +#endif 13.216 + 13.217 + /* 13.218 + * Now compute and insert the TLB entry for the virtual page table. We never 13.219 + * execute in a page table page so there is no need to set the exception deferral 13.220 + * bit. 13.221 + */ 13.222 + adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 13.223 + ;; 13.224 +#ifdef CONFIG_XEN 13.225 +(p7) mov r25=r8 13.226 +(p7) mov r8=r24 13.227 + ;; 13.228 +(p7) XEN_HYPER_ITC_D 13.229 + ;; 13.230 +(p7) mov r8=r25 13.231 + ;; 13.232 +#else 13.233 +(p7) itc.d r24 13.234 +#endif 13.235 + ;; 13.236 +#ifdef CONFIG_SMP 13.237 + /* 13.238 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.239 + * cannot possibly affect the following loads: 13.240 + */ 13.241 + dv_serialize_data 13.242 + 13.243 + /* 13.244 + * Re-check L2 and L3 pagetable. If they changed, we may have received a ptc.g 13.245 + * between reading the pagetable and the "itc". If so, flush the entry we 13.246 + * inserted and retry. 13.247 + */ 13.248 + ld8 r25=[r21] // read L3 PTE again 13.249 + ld8 r26=[r17] // read L2 entry again 13.250 + ;; 13.251 + cmp.ne p6,p7=r26,r20 // did L2 entry change 13.252 + mov r27=PAGE_SHIFT<<2 13.253 + ;; 13.254 +(p6) ptc.l r22,r27 // purge PTE page translation 13.255 +(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L3 PTE change 13.256 + ;; 13.257 +(p6) ptc.l r16,r27 // purge translation 13.258 +#endif 13.259 + 13.260 + mov pr=r31,-1 // restore predicate registers 13.261 +#ifdef CONFIG_XEN 13.262 + XEN_HYPER_RFI; 13.263 +#else 13.264 + rfi 13.265 +#endif 13.266 +END(vhpt_miss) 13.267 + 13.268 + .org ia64_ivt+0x400 13.269 +///////////////////////////////////////////////////////////////////////////////////////// 13.270 +// 0x0400 Entry 1 (size 64 bundles) ITLB (21) 13.271 +ENTRY(itlb_miss) 13.272 + DBG_FAULT(1) 13.273 + /* 13.274 + * The ITLB handler accesses the L3 PTE via the virtually mapped linear 13.275 + * page table. If a nested TLB miss occurs, we switch into physical 13.276 + * mode, walk the page table, and then re-execute the L3 PTE read 13.277 + * and go on normally after that. 13.278 + */ 13.279 +#ifdef CONFIG_XEN 13.280 + movl r16=XSI_IFA 13.281 + ;; 13.282 + ld8 r16=[r16] 13.283 +#else 13.284 + mov r16=cr.ifa // get virtual address 13.285 +#endif 13.286 + mov r29=b0 // save b0 13.287 + mov r31=pr // save predicates 13.288 +.itlb_fault: 13.289 +#ifdef CONFIG_XEN 13.290 + movl r17=XSI_IHA 13.291 + ;; 13.292 + ld8 r17=[r17] // get virtual address of L3 PTE 13.293 +#else 13.294 + mov r17=cr.iha // get virtual address of L3 PTE 13.295 +#endif 13.296 + movl r30=1f // load nested fault continuation point 13.297 + ;; 13.298 +1: ld8 r18=[r17] // read L3 PTE 13.299 + ;; 13.300 + mov b0=r29 13.301 + tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? 13.302 +(p6) br.cond.spnt page_fault 13.303 + ;; 13.304 +#ifdef CONFIG_XEN 13.305 + mov r19=r8 13.306 + mov r8=r18 13.307 + ;; 13.308 + XEN_HYPER_ITC_I 13.309 + ;; 13.310 + mov r8=r19 13.311 +#else 13.312 + itc.i r18 13.313 +#endif 13.314 + ;; 13.315 +#ifdef CONFIG_SMP 13.316 + /* 13.317 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.318 + * cannot possibly affect the following loads: 13.319 + */ 13.320 + dv_serialize_data 13.321 + 13.322 + ld8 r19=[r17] // read L3 PTE again and see if same 13.323 + mov r20=PAGE_SHIFT<<2 // setup page size for purge 13.324 + ;; 13.325 + cmp.ne p7,p0=r18,r19 13.326 + ;; 13.327 +(p7) ptc.l r16,r20 13.328 +#endif 13.329 + mov pr=r31,-1 13.330 +#ifdef CONFIG_XEN 13.331 + XEN_HYPER_RFI; 13.332 +#else 13.333 + rfi 13.334 +#endif 13.335 +END(itlb_miss) 13.336 + 13.337 + .org ia64_ivt+0x0800 13.338 +///////////////////////////////////////////////////////////////////////////////////////// 13.339 +// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) 13.340 +ENTRY(dtlb_miss) 13.341 + DBG_FAULT(2) 13.342 + /* 13.343 + * The DTLB handler accesses the L3 PTE via the virtually mapped linear 13.344 + * page table. If a nested TLB miss occurs, we switch into physical 13.345 + * mode, walk the page table, and then re-execute the L3 PTE read 13.346 + * and go on normally after that. 13.347 + */ 13.348 +#ifdef CONFIG_XEN 13.349 + movl r16=XSI_IFA 13.350 + ;; 13.351 + ld8 r16=[r16] 13.352 +#else 13.353 + mov r16=cr.ifa // get virtual address 13.354 +#endif 13.355 + mov r29=b0 // save b0 13.356 + mov r31=pr // save predicates 13.357 +dtlb_fault: 13.358 +#ifdef CONFIG_XEN 13.359 + movl r17=XSI_IHA 13.360 + ;; 13.361 + ld8 r17=[r17] // get virtual address of L3 PTE 13.362 +#else 13.363 + mov r17=cr.iha // get virtual address of L3 PTE 13.364 +#endif 13.365 + movl r30=1f // load nested fault continuation point 13.366 + ;; 13.367 +1: ld8 r18=[r17] // read L3 PTE 13.368 + ;; 13.369 + mov b0=r29 13.370 + tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? 13.371 +(p6) br.cond.spnt page_fault 13.372 + ;; 13.373 +#ifdef CONFIG_XEN 13.374 + mov r19=r8 13.375 + mov r8=r18 13.376 + ;; 13.377 + XEN_HYPER_ITC_D 13.378 + ;; 13.379 + mov r8=r19 13.380 + ;; 13.381 +#else 13.382 + itc.d r18 13.383 +#endif 13.384 + ;; 13.385 +#ifdef CONFIG_SMP 13.386 + /* 13.387 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.388 + * cannot possibly affect the following loads: 13.389 + */ 13.390 + dv_serialize_data 13.391 + 13.392 + ld8 r19=[r17] // read L3 PTE again and see if same 13.393 + mov r20=PAGE_SHIFT<<2 // setup page size for purge 13.394 + ;; 13.395 + cmp.ne p7,p0=r18,r19 13.396 + ;; 13.397 +(p7) ptc.l r16,r20 13.398 +#endif 13.399 + mov pr=r31,-1 13.400 +#ifdef CONFIG_XEN 13.401 + XEN_HYPER_RFI; 13.402 +#else 13.403 + rfi 13.404 +#endif 13.405 +END(dtlb_miss) 13.406 + 13.407 + .org ia64_ivt+0x0c00 13.408 +///////////////////////////////////////////////////////////////////////////////////////// 13.409 +// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) 13.410 +ENTRY(alt_itlb_miss) 13.411 + DBG_FAULT(3) 13.412 +#ifdef CONFIG_XEN 13.413 + movl r31=XSI_IPSR 13.414 + ;; 13.415 + ld8 r21=[r31],XSI_IFA-XSI_IPSR // get ipsr, point to ifa 13.416 + movl r17=PAGE_KERNEL 13.417 + ;; 13.418 + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 13.419 + ;; 13.420 + ld8 r16=[r31] // get ifa 13.421 + mov r31=pr 13.422 + ;; 13.423 +#else 13.424 + mov r16=cr.ifa // get address that caused the TLB miss 13.425 + movl r17=PAGE_KERNEL 13.426 + mov r21=cr.ipsr 13.427 + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 13.428 + mov r31=pr 13.429 + ;; 13.430 +#endif 13.431 +#ifdef CONFIG_DISABLE_VHPT 13.432 + shr.u r22=r16,61 // get the region number into r21 13.433 + ;; 13.434 + cmp.gt p8,p0=6,r22 // user mode 13.435 + ;; 13.436 +#ifndef CONFIG_XEN 13.437 +(p8) thash r17=r16 13.438 + ;; 13.439 +(p8) mov cr.iha=r17 13.440 +#endif 13.441 +(p8) mov r29=b0 // save b0 13.442 +(p8) br.cond.dptk .itlb_fault 13.443 +#endif 13.444 + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl 13.445 + and r19=r19,r16 // clear ed, reserved bits, and PTE control bits 13.446 + shr.u r18=r16,57 // move address bit 61 to bit 4 13.447 + ;; 13.448 + andcm r18=0x10,r18 // bit 4=~address-bit(61) 13.449 + cmp.ne p8,p0=r0,r23 // psr.cpl != 0? 13.450 + or r19=r17,r19 // insert PTE control bits into r19 13.451 + ;; 13.452 + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 13.453 +(p8) br.cond.spnt page_fault 13.454 + ;; 13.455 +#ifdef CONFIG_XEN 13.456 + mov r18=r8 13.457 + mov r8=r19 13.458 + ;; 13.459 + XEN_HYPER_ITC_I 13.460 + ;; 13.461 + mov r8=r18 13.462 + ;; 13.463 + mov pr=r31,-1 13.464 + ;; 13.465 + XEN_HYPER_RFI; 13.466 +#else 13.467 + itc.i r19 // insert the TLB entry 13.468 + mov pr=r31,-1 13.469 + rfi 13.470 +#endif 13.471 +END(alt_itlb_miss) 13.472 + 13.473 + .org ia64_ivt+0x1000 13.474 +///////////////////////////////////////////////////////////////////////////////////////// 13.475 +// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) 13.476 +ENTRY(alt_dtlb_miss) 13.477 + DBG_FAULT(4) 13.478 +#ifdef CONFIG_XEN 13.479 + movl r31=XSI_IPSR 13.480 + ;; 13.481 + ld8 r21=[r31],XSI_ISR-XSI_IPSR // get ipsr, point to isr 13.482 + movl r17=PAGE_KERNEL 13.483 + ;; 13.484 + ld8 r20=[r31],XSI_IFA-XSI_ISR // get isr, point to ifa 13.485 + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 13.486 + ;; 13.487 + ld8 r16=[r31] // get ifa 13.488 + mov r31=pr 13.489 + ;; 13.490 +#else 13.491 + mov r16=cr.ifa // get address that caused the TLB miss 13.492 + movl r17=PAGE_KERNEL 13.493 + mov r20=cr.isr 13.494 + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) 13.495 + mov r21=cr.ipsr 13.496 + mov r31=pr 13.497 + ;; 13.498 +#endif 13.499 +#ifdef CONFIG_DISABLE_VHPT 13.500 + shr.u r22=r16,61 // get the region number into r21 13.501 + ;; 13.502 + cmp.gt p8,p0=6,r22 // access to region 0-5 13.503 + ;; 13.504 +#ifndef CONFIG_XEN 13.505 +(p8) thash r17=r16 13.506 + ;; 13.507 +(p8) mov cr.iha=r17 13.508 +#endif 13.509 +(p8) mov r29=b0 // save b0 13.510 +(p8) br.cond.dptk dtlb_fault 13.511 +#endif 13.512 + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl 13.513 + and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field 13.514 + tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? 13.515 + shr.u r18=r16,57 // move address bit 61 to bit 4 13.516 + and r19=r19,r16 // clear ed, reserved bits, and PTE control bits 13.517 + tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? 13.518 + ;; 13.519 + andcm r18=0x10,r18 // bit 4=~address-bit(61) 13.520 + cmp.ne p8,p0=r0,r23 13.521 +(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field 13.522 +(p8) br.cond.spnt page_fault 13.523 + 13.524 + dep r21=-1,r21,IA64_PSR_ED_BIT,1 13.525 + or r19=r19,r17 // insert PTE control bits into r19 13.526 + ;; 13.527 + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 13.528 +(p6) mov cr.ipsr=r21 13.529 + ;; 13.530 +#ifdef CONFIG_XEN 13.531 +(p7) mov r18=r8 13.532 +(p7) mov r8=r19 13.533 + ;; 13.534 +(p7) XEN_HYPER_ITC_D 13.535 + ;; 13.536 +(p7) mov r8=r18 13.537 + ;; 13.538 + mov pr=r31,-1 13.539 + ;; 13.540 + XEN_HYPER_RFI; 13.541 +#else 13.542 +(p7) itc.d r19 // insert the TLB entry 13.543 + mov pr=r31,-1 13.544 + rfi 13.545 +#endif 13.546 +END(alt_dtlb_miss) 13.547 + 13.548 + .org ia64_ivt+0x1400 13.549 +///////////////////////////////////////////////////////////////////////////////////////// 13.550 +// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) 13.551 +ENTRY(nested_dtlb_miss) 13.552 + /* 13.553 + * In the absence of kernel bugs, we get here when the virtually mapped linear 13.554 + * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction 13.555 + * Access-bit, or Data Access-bit faults). If the DTLB entry for the virtual page 13.556 + * table is missing, a nested TLB miss fault is triggered and control is 13.557 + * transferred to this point. When this happens, we lookup the pte for the 13.558 + * faulting address by walking the page table in physical mode and return to the 13.559 + * continuation point passed in register r30 (or call page_fault if the address is 13.560 + * not mapped). 13.561 + * 13.562 + * Input: r16: faulting address 13.563 + * r29: saved b0 13.564 + * r30: continuation address 13.565 + * r31: saved pr 13.566 + * 13.567 + * Output: r17: physical address of L3 PTE of faulting address 13.568 + * r29: saved b0 13.569 + * r30: continuation address 13.570 + * r31: saved pr 13.571 + * 13.572 + * Clobbered: b0, r18, r19, r21, psr.dt (cleared) 13.573 + */ 13.574 +#ifdef CONFIG_XEN 13.575 + XEN_HYPER_RSM_PSR_DT; 13.576 +#else 13.577 + rsm psr.dt // switch to using physical data addressing 13.578 +#endif 13.579 +#ifdef CONFIG_XEN 13.580 + movl r19=XSI_KR0+(IA64_KR_PT_BASE*8) // get the page table base address 13.581 + ;; 13.582 + ld8 r19=[r19] 13.583 +#else 13.584 + mov r19=IA64_KR(PT_BASE) // get the page table base address 13.585 +#endif 13.586 + shl r21=r16,3 // shift bit 60 into sign bit 13.587 + ;; 13.588 + shr.u r17=r16,61 // get the region number into r17 13.589 + ;; 13.590 + cmp.eq p6,p7=5,r17 // is faulting address in region 5? 13.591 + shr.u r18=r16,PGDIR_SHIFT // get bits 33-63 of faulting address 13.592 + ;; 13.593 +(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place 13.594 + 13.595 + srlz.d 13.596 + LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir 13.597 + 13.598 + .pred.rel "mutex", p6, p7 13.599 +(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT 13.600 +(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 13.601 + ;; 13.602 +(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 13.603 +(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) 13.604 + cmp.eq p7,p6=0,r21 // unused address bits all zeroes? 13.605 + shr.u r18=r16,PMD_SHIFT // shift L2 index into position 13.606 + ;; 13.607 + ld8 r17=[r17] // fetch the L1 entry (may be 0) 13.608 + ;; 13.609 +(p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? 13.610 + dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry 13.611 + ;; 13.612 +(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) 13.613 + shr.u r19=r16,PAGE_SHIFT // shift L3 index into position 13.614 + ;; 13.615 +(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? 13.616 + dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry 13.617 +(p6) br.cond.spnt page_fault 13.618 + mov b0=r30 13.619 + br.sptk.many b0 // return to continuation point 13.620 +END(nested_dtlb_miss) 13.621 + 13.622 + .org ia64_ivt+0x1800 13.623 +///////////////////////////////////////////////////////////////////////////////////////// 13.624 +// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) 13.625 +ENTRY(ikey_miss) 13.626 + DBG_FAULT(6) 13.627 + FAULT(6) 13.628 +END(ikey_miss) 13.629 + 13.630 + //----------------------------------------------------------------------------------- 13.631 + // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) 13.632 +ENTRY(page_fault) 13.633 +#ifdef CONFIG_XEN 13.634 + XEN_HYPER_SSM_PSR_DT; 13.635 +#else 13.636 + ssm psr.dt 13.637 + ;; 13.638 + srlz.i 13.639 +#endif 13.640 + ;; 13.641 + SAVE_MIN_WITH_COVER 13.642 + alloc r15=ar.pfs,0,0,3,0 13.643 +#ifdef CONFIG_XEN 13.644 + movl r3=XSI_ISR 13.645 + ;; 13.646 + ld8 out1=[r3],XSI_IFA-XSI_ISR // get vcr.isr, point to ifa 13.647 + ;; 13.648 + ld8 out0=[r3] // get vcr.ifa 13.649 + mov r14=1 13.650 + ;; 13.651 + add r3=XSI_PSR_IC-XSI_IFA, r3 // point to vpsr.ic 13.652 + ;; 13.653 + st4 [r3]=r14 // vpsr.ic = 1 13.654 + adds r3=8,r2 // set up second base pointer 13.655 + ;; 13.656 +#else 13.657 + mov out0=cr.ifa 13.658 + mov out1=cr.isr 13.659 + adds r3=8,r2 // set up second base pointer 13.660 + ;; 13.661 + ssm psr.ic | PSR_DEFAULT_BITS 13.662 + ;; 13.663 + srlz.i // guarantee that interruption collectin is on 13.664 + ;; 13.665 +#endif 13.666 +#ifdef CONFIG_XEN 13.667 + br.cond.sptk.many xen_page_fault 13.668 + ;; 13.669 +done_xen_page_fault: 13.670 +#endif 13.671 +(p15) ssm psr.i // restore psr.i 13.672 + movl r14=ia64_leave_kernel 13.673 + ;; 13.674 + SAVE_REST 13.675 + mov rp=r14 13.676 + ;; 13.677 + adds out2=16,r12 // out2 = pointer to pt_regs 13.678 + br.call.sptk.many b6=ia64_do_page_fault // ignore return address 13.679 +END(page_fault) 13.680 + 13.681 + .org ia64_ivt+0x1c00 13.682 +///////////////////////////////////////////////////////////////////////////////////////// 13.683 +// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) 13.684 +ENTRY(dkey_miss) 13.685 + DBG_FAULT(7) 13.686 + FAULT(7) 13.687 +#ifdef CONFIG_XEN 13.688 + // Leaving this code inline above results in an IVT section overflow 13.689 + // There is no particular reason for this code to be here... 13.690 +xen_page_fault: 13.691 +(p15) movl r3=XSI_PSR_I 13.692 + ;; 13.693 +(p15) st4 [r3]=r14,XSI_PEND-XSI_PSR_I // if (p15) vpsr.i = 1 13.694 + mov r14=r0 13.695 + ;; 13.696 +(p15) ld4 r14=[r3] // if (pending_interrupts) 13.697 + adds r3=8,r2 // re-set up second base pointer 13.698 + ;; 13.699 +(p15) cmp.ne p15,p0=r14,r0 13.700 + ;; 13.701 + br.cond.sptk.many done_xen_page_fault 13.702 + ;; 13.703 +#endif 13.704 +END(dkey_miss) 13.705 + 13.706 + .org ia64_ivt+0x2000 13.707 +///////////////////////////////////////////////////////////////////////////////////////// 13.708 +// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) 13.709 +ENTRY(dirty_bit) 13.710 + DBG_FAULT(8) 13.711 + /* 13.712 + * What we do here is to simply turn on the dirty bit in the PTE. We need to 13.713 + * update both the page-table and the TLB entry. To efficiently access the PTE, 13.714 + * we address it through the virtual page table. Most likely, the TLB entry for 13.715 + * the relevant virtual page table page is still present in the TLB so we can 13.716 + * normally do this without additional TLB misses. In case the necessary virtual 13.717 + * page table TLB entry isn't present, we take a nested TLB miss hit where we look 13.718 + * up the physical address of the L3 PTE and then continue at label 1 below. 13.719 + */ 13.720 +#ifdef CONFIG_XEN 13.721 + movl r16=XSI_IFA 13.722 + ;; 13.723 + ld8 r16=[r16] 13.724 + ;; 13.725 +#else 13.726 + mov r16=cr.ifa // get the address that caused the fault 13.727 +#endif 13.728 + movl r30=1f // load continuation point in case of nested fault 13.729 + ;; 13.730 +#ifdef CONFIG_XEN 13.731 +#if 1 13.732 + mov r18=r8; 13.733 + mov r8=r16; 13.734 + XEN_HYPER_THASH;; 13.735 + mov r17=r8; 13.736 + mov r8=r18;; 13.737 +#else 13.738 + tak r17=r80 // "privified" thash 13.739 +#endif 13.740 +#else 13.741 + thash r17=r16 // compute virtual address of L3 PTE 13.742 +#endif 13.743 + mov r29=b0 // save b0 in case of nested fault 13.744 + mov r31=pr // save pr 13.745 +#ifdef CONFIG_SMP 13.746 + mov r28=ar.ccv // save ar.ccv 13.747 + ;; 13.748 +1: ld8 r18=[r17] 13.749 + ;; // avoid RAW on r18 13.750 + mov ar.ccv=r18 // set compare value for cmpxchg 13.751 + or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits 13.752 + ;; 13.753 + cmpxchg8.acq r26=[r17],r25,ar.ccv 13.754 + mov r24=PAGE_SHIFT<<2 13.755 + ;; 13.756 + cmp.eq p6,p7=r26,r18 13.757 + ;; 13.758 +(p6) itc.d r25 // install updated PTE 13.759 + ;; 13.760 + /* 13.761 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.762 + * cannot possibly affect the following loads: 13.763 + */ 13.764 + dv_serialize_data 13.765 + 13.766 + ld8 r18=[r17] // read PTE again 13.767 + ;; 13.768 + cmp.eq p6,p7=r18,r25 // is it same as the newly installed 13.769 + ;; 13.770 +(p7) ptc.l r16,r24 13.771 + mov b0=r29 // restore b0 13.772 + mov ar.ccv=r28 13.773 +#else 13.774 + ;; 13.775 +1: ld8 r18=[r17] 13.776 + ;; // avoid RAW on r18 13.777 + or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits 13.778 + mov b0=r29 // restore b0 13.779 + ;; 13.780 + st8 [r17]=r18 // store back updated PTE 13.781 + itc.d r18 // install updated PTE 13.782 +#endif 13.783 + mov pr=r31,-1 // restore pr 13.784 +#ifdef CONFIG_XEN 13.785 + XEN_HYPER_RFI; 13.786 +#else 13.787 + rfi 13.788 +#endif 13.789 +END(dirty_bit) 13.790 + 13.791 + .org ia64_ivt+0x2400 13.792 +///////////////////////////////////////////////////////////////////////////////////////// 13.793 +// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) 13.794 +ENTRY(iaccess_bit) 13.795 + DBG_FAULT(9) 13.796 + // Like Entry 8, except for instruction access 13.797 +#ifdef CONFIG_XEN 13.798 + movl r16=XSI_IFA 13.799 + ;; 13.800 + ld8 r16=[r16] 13.801 + ;; 13.802 +#else 13.803 + mov r16=cr.ifa // get the address that caused the fault 13.804 +#endif 13.805 + movl r30=1f // load continuation point in case of nested fault 13.806 + mov r31=pr // save predicates 13.807 +#ifdef CONFIG_ITANIUM 13.808 + /* 13.809 + * Erratum 10 (IFA may contain incorrect address) has "NoFix" status. 13.810 + */ 13.811 + mov r17=cr.ipsr 13.812 + ;; 13.813 + mov r18=cr.iip 13.814 + tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set? 13.815 + ;; 13.816 +(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa 13.817 +#endif /* CONFIG_ITANIUM */ 13.818 + ;; 13.819 +#ifdef CONFIG_XEN 13.820 +#if 1 13.821 + mov r18=r8; 13.822 + mov r8=r16; 13.823 + XEN_HYPER_THASH;; 13.824 + mov r17=r8; 13.825 + mov r8=r18;; 13.826 +#else 13.827 + tak r17=r80 // "privified" thash 13.828 +#endif 13.829 +#else 13.830 + thash r17=r16 // compute virtual address of L3 PTE 13.831 +#endif 13.832 + mov r29=b0 // save b0 in case of nested fault) 13.833 +#ifdef CONFIG_SMP 13.834 + mov r28=ar.ccv // save ar.ccv 13.835 + ;; 13.836 +1: ld8 r18=[r17] 13.837 + ;; 13.838 + mov ar.ccv=r18 // set compare value for cmpxchg 13.839 + or r25=_PAGE_A,r18 // set the accessed bit 13.840 + ;; 13.841 + cmpxchg8.acq r26=[r17],r25,ar.ccv 13.842 + mov r24=PAGE_SHIFT<<2 13.843 + ;; 13.844 + cmp.eq p6,p7=r26,r18 13.845 + ;; 13.846 +(p6) itc.i r25 // install updated PTE 13.847 + ;; 13.848 + /* 13.849 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.850 + * cannot possibly affect the following loads: 13.851 + */ 13.852 + dv_serialize_data 13.853 + 13.854 + ld8 r18=[r17] // read PTE again 13.855 + ;; 13.856 + cmp.eq p6,p7=r18,r25 // is it same as the newly installed 13.857 + ;; 13.858 +(p7) ptc.l r16,r24 13.859 + mov b0=r29 // restore b0 13.860 + mov ar.ccv=r28 13.861 +#else /* !CONFIG_SMP */ 13.862 + ;; 13.863 +1: ld8 r18=[r17] 13.864 + ;; 13.865 + or r18=_PAGE_A,r18 // set the accessed bit 13.866 + mov b0=r29 // restore b0 13.867 + ;; 13.868 + st8 [r17]=r18 // store back updated PTE 13.869 + itc.i r18 // install updated PTE 13.870 +#endif /* !CONFIG_SMP */ 13.871 + mov pr=r31,-1 13.872 +#ifdef CONFIG_XEN 13.873 + XEN_HYPER_RFI; 13.874 +#else 13.875 + rfi 13.876 +#endif 13.877 +END(iaccess_bit) 13.878 + 13.879 + .org ia64_ivt+0x2800 13.880 +///////////////////////////////////////////////////////////////////////////////////////// 13.881 +// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) 13.882 +ENTRY(daccess_bit) 13.883 + DBG_FAULT(10) 13.884 + // Like Entry 8, except for data access 13.885 +#ifdef CONFIG_XEN 13.886 + movl r16=XSI_IFA 13.887 + ;; 13.888 + ld8 r16=[r16] 13.889 + ;; 13.890 +#else 13.891 + mov r16=cr.ifa // get the address that caused the fault 13.892 +#endif 13.893 + movl r30=1f // load continuation point in case of nested fault 13.894 + ;; 13.895 +#ifdef CONFIG_XEN 13.896 +#if 1 13.897 + mov r18=r8; 13.898 + mov r8=r16; 13.899 + XEN_HYPER_THASH;; 13.900 + mov r17=r8; 13.901 + mov r8=r18;; 13.902 +#else 13.903 + tak r17=r80 // "privified" thash 13.904 +#endif 13.905 +#else 13.906 + thash r17=r16 // compute virtual address of L3 PTE 13.907 +#endif 13.908 + mov r31=pr 13.909 + mov r29=b0 // save b0 in case of nested fault) 13.910 +#ifdef CONFIG_SMP 13.911 + mov r28=ar.ccv // save ar.ccv 13.912 + ;; 13.913 +1: ld8 r18=[r17] 13.914 + ;; // avoid RAW on r18 13.915 + mov ar.ccv=r18 // set compare value for cmpxchg 13.916 + or r25=_PAGE_A,r18 // set the dirty bit 13.917 + ;; 13.918 + cmpxchg8.acq r26=[r17],r25,ar.ccv 13.919 + mov r24=PAGE_SHIFT<<2 13.920 + ;; 13.921 + cmp.eq p6,p7=r26,r18 13.922 + ;; 13.923 +(p6) itc.d r25 // install updated PTE 13.924 + /* 13.925 + * Tell the assemblers dependency-violation checker that the above "itc" instructions 13.926 + * cannot possibly affect the following loads: 13.927 + */ 13.928 + dv_serialize_data 13.929 + ;; 13.930 + ld8 r18=[r17] // read PTE again 13.931 + ;; 13.932 + cmp.eq p6,p7=r18,r25 // is it same as the newly installed 13.933 + ;; 13.934 +(p7) ptc.l r16,r24 13.935 + mov ar.ccv=r28 13.936 +#else 13.937 + ;; 13.938 +1: ld8 r18=[r17] 13.939 + ;; // avoid RAW on r18 13.940 + or r18=_PAGE_A,r18 // set the accessed bit 13.941 + ;; 13.942 + st8 [r17]=r18 // store back updated PTE 13.943 + itc.d r18 // install updated PTE 13.944 +#endif 13.945 + mov b0=r29 // restore b0 13.946 + mov pr=r31,-1 13.947 +#ifdef CONFIG_XEN 13.948 + XEN_HYPER_RFI; 13.949 +#else 13.950 + rfi 13.951 +#endif 13.952 +END(daccess_bit) 13.953 + 13.954 + .org ia64_ivt+0x2c00 13.955 +///////////////////////////////////////////////////////////////////////////////////////// 13.956 +// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) 13.957 +ENTRY(break_fault) 13.958 + /* 13.959 + * The streamlined system call entry/exit paths only save/restore the initial part 13.960 + * of pt_regs. This implies that the callers of system-calls must adhere to the 13.961 + * normal procedure calling conventions. 13.962 + * 13.963 + * Registers to be saved & restored: 13.964 + * CR registers: cr.ipsr, cr.iip, cr.ifs 13.965 + * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr 13.966 + * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15 13.967 + * Registers to be restored only: 13.968 + * r8-r11: output value from the system call. 13.969 + * 13.970 + * During system call exit, scratch registers (including r15) are modified/cleared 13.971 + * to prevent leaking bits from kernel to user level. 13.972 + */ 13.973 + DBG_FAULT(11) 13.974 +#ifdef CONFIG_XEN 13.975 + movl r31=XSI_IPSR 13.976 + ;; 13.977 + ld8 r29=[r31],XSI_IIP-XSI_IPSR // get ipsr, point to iip 13.978 + mov r18=__IA64_BREAK_SYSCALL 13.979 + mov r21=ar.fpsr 13.980 + ;; 13.981 + ld8 r28=[r31],XSI_IIM-XSI_IIP // get iip, point to iim 13.982 + mov r19=b6 13.983 + mov r25=ar.unat 13.984 + ;; 13.985 + ld8 r17=[r31] // get iim 13.986 + mov r27=ar.rsc 13.987 + mov r26=ar.pfs 13.988 + ;; 13.989 + adds r31=(XSI_KR0+(IA64_KR_CURRENT*8))-XSI_IIM,r31 13.990 + ;; 13.991 + ld8 r16=[r31] // r16 = current task 13.992 +#else 13.993 + mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. 13.994 + mov r17=cr.iim 13.995 + mov r18=__IA64_BREAK_SYSCALL 13.996 + mov r21=ar.fpsr 13.997 + mov r29=cr.ipsr 13.998 + mov r19=b6 13.999 + mov r25=ar.unat 13.1000 + mov r27=ar.rsc 13.1001 + mov r26=ar.pfs 13.1002 + mov r28=cr.iip 13.1003 +#endif 13.1004 + mov r31=pr // prepare to save predicates 13.1005 + mov r20=r1 13.1006 + ;; 13.1007 + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 13.1008 + cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) 13.1009 +(p7) br.cond.spnt non_syscall 13.1010 + ;; 13.1011 + ld1 r17=[r16] // load current->thread.on_ustack flag 13.1012 + st1 [r16]=r0 // clear current->thread.on_ustack flag 13.1013 + add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT 13.1014 + ;; 13.1015 + invala 13.1016 + 13.1017 + /* adjust return address so we skip over the break instruction: */ 13.1018 + 13.1019 + extr.u r8=r29,41,2 // extract ei field from cr.ipsr 13.1020 + ;; 13.1021 + cmp.eq p6,p7=2,r8 // isr.ei==2? 13.1022 + mov r2=r1 // setup r2 for ia64_syscall_setup 13.1023 + ;; 13.1024 +(p6) mov r8=0 // clear ei to 0 13.1025 +(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped 13.1026 +(p7) adds r8=1,r8 // increment ei to next slot 13.1027 + ;; 13.1028 + cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? 13.1029 + dep r29=r8,r29,41,2 // insert new ei into cr.ipsr 13.1030 + ;; 13.1031 + 13.1032 + // switch from user to kernel RBS: 13.1033 + MINSTATE_START_SAVE_MIN_VIRT 13.1034 + br.call.sptk.many b7=ia64_syscall_setup 13.1035 + ;; 13.1036 +#ifdef CONFIG_XEN 13.1037 + mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;; 13.1038 +#else 13.1039 + MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 13.1040 +#endif 13.1041 +#ifdef CONFIG_XEN 13.1042 + movl r3=XSI_PSR_IC 13.1043 + mov r16=1 13.1044 + ;; 13.1045 +#if 1 13.1046 + st4 [r3]=r16,XSI_PSR_I-XSI_PSR_IC // vpsr.ic = 1 13.1047 + ;; 13.1048 +(p15) st4 [r3]=r16,XSI_PEND-XSI_PSR_I // if (p15) vpsr.i = 1 13.1049 + mov r16=r0 13.1050 + ;; 13.1051 +(p15) ld4 r16=[r3] // if (pending_interrupts) 13.1052 + ;; 13.1053 + cmp.ne p6,p0=r16,r0 13.1054 + ;; 13.1055 +(p6) ssm psr.i // do a real ssm psr.i 13.1056 + ;; 13.1057 +#else 13.1058 +// st4 [r3]=r16,XSI_PSR_I-XSI_PSR_IC // vpsr.ic = 1 13.1059 + adds r3=XSI_PSR_I-XSI_PSR_IC,r3 // SKIP vpsr.ic = 1 13.1060 + ;; 13.1061 +(p15) st4 [r3]=r16,XSI_PEND-XSI_PSR_I // if (p15) vpsr.i = 1 13.1062 + mov r16=r0 13.1063 + ;; 13.1064 +(p15) ld4 r16=[r3] // if (pending_interrupts) 13.1065 + ;; 13.1066 + cmp.ne p6,p0=r16,r0 13.1067 + ;; 13.1068 +//(p6) ssm psr.i // do a real ssm psr.i 13.1069 +//(p6) XEN_HYPER_SSM_I; 13.1070 +(p6) break 0x7; 13.1071 + ;; 13.1072 +#endif 13.1073 + mov r3=NR_syscalls - 1 13.1074 + ;; 13.1075 +#else 13.1076 + ssm psr.ic | PSR_DEFAULT_BITS 13.1077 + ;; 13.1078 + srlz.i // guarantee that interruption collection is on 13.1079 + mov r3=NR_syscalls - 1 13.1080 + ;; 13.1081 +(p15) ssm psr.i // restore psr.i 13.1082 +#endif 13.1083 + // p10==true means out registers are more than 8 or r15's Nat is true 13.1084 +(p10) br.cond.spnt.many ia64_ret_from_syscall 13.1085 + ;; 13.1086 + movl r16=sys_call_table 13.1087 + 13.1088 + adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 13.1089 + movl r2=ia64_ret_from_syscall 13.1090 + ;; 13.1091 + shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) 13.1092 + cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? 13.1093 + mov rp=r2 // set the real return addr 13.1094 + ;; 13.1095 +(p6) ld8 r20=[r20] // load address of syscall entry point 13.1096 +(p7) movl r20=sys_ni_syscall 13.1097 + 13.1098 + add r2=TI_FLAGS+IA64_TASK_SIZE,r13 13.1099 + ;; 13.1100 + ld4 r2=[r2] // r2 = current_thread_info()->flags 13.1101 + ;; 13.1102 + and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit 13.1103 + ;; 13.1104 + cmp.eq p8,p0=r2,r0 13.1105 + mov b6=r20 13.1106 + ;; 13.1107 +(p8) br.call.sptk.many b6=b6 // ignore this return addr 13.1108 + br.cond.sptk ia64_trace_syscall 13.1109 + // NOT REACHED 13.1110 +END(break_fault) 13.1111 + 13.1112 + .org ia64_ivt+0x3000 13.1113 +///////////////////////////////////////////////////////////////////////////////////////// 13.1114 +// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) 13.1115 +ENTRY(interrupt) 13.1116 + DBG_FAULT(12) 13.1117 + mov r31=pr // prepare to save predicates 13.1118 + ;; 13.1119 + SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 13.1120 +#ifdef CONFIG_XEN 13.1121 + movl r3=XSI_PSR_IC 13.1122 + mov r14=1 13.1123 + ;; 13.1124 + st4 [r3]=r14 13.1125 +#else 13.1126 + ssm psr.ic | PSR_DEFAULT_BITS 13.1127 +#endif 13.1128 + ;; 13.1129 + adds r3=8,r2 // set up second base pointer for SAVE_REST 13.1130 + srlz.i // ensure everybody knows psr.ic is back on 13.1131 + ;; 13.1132 + SAVE_REST 13.1133 + ;; 13.1134 + alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group 13.1135 +#ifdef CONFIG_XEN 13.1136 + ;; 13.1137 + br.call.sptk.many rp=xen_get_ivr 13.1138 + ;; 13.1139 + mov out0=r8 // pass cr.ivr as first arg 13.1140 +#else 13.1141 + mov out0=cr.ivr // pass cr.ivr as first arg 13.1142 +#endif 13.1143 + add out1=16,sp // pass pointer to pt_regs as second arg 13.1144 + ;; 13.1145 + srlz.d // make sure we see the effect of cr.ivr 13.1146 + movl r14=ia64_leave_kernel 13.1147 + ;; 13.1148 + mov rp=r14 13.1149 + br.call.sptk.many b6=ia64_handle_irq 13.1150 +END(interrupt) 13.1151 + 13.1152 + .org ia64_ivt+0x3400 13.1153 +///////////////////////////////////////////////////////////////////////////////////////// 13.1154 +// 0x3400 Entry 13 (size 64 bundles) Reserved 13.1155 + DBG_FAULT(13) 13.1156 + FAULT(13) 13.1157 + 13.1158 + .org ia64_ivt+0x3800 13.1159 +///////////////////////////////////////////////////////////////////////////////////////// 13.1160 +// 0x3800 Entry 14 (size 64 bundles) Reserved 13.1161 + DBG_FAULT(14) 13.1162 + FAULT(14) 13.1163 + 13.1164 + /* 13.1165 + * There is no particular reason for this code to be here, other than that 13.1166 + * there happens to be space here that would go unused otherwise. If this 13.1167 + * fault ever gets "unreserved", simply moved the following code to a more 13.1168 + * suitable spot... 13.1169 + * 13.1170 + * ia64_syscall_setup() is a separate subroutine so that it can 13.1171 + * allocate stacked registers so it can safely demine any 13.1172 + * potential NaT values from the input registers. 13.1173 + * 13.1174 + * On entry: 13.1175 + * - executing on bank 0 or bank 1 register set (doesn't matter) 13.1176 + * - r1: stack pointer 13.1177 + * - r2: current task pointer 13.1178 + * - r3: preserved 13.1179 + * - r11: original contents (saved ar.pfs to be saved) 13.1180 + * - r12: original contents (sp to be saved) 13.1181 + * - r13: original contents (tp to be saved) 13.1182 + * - r15: original contents (syscall # to be saved) 13.1183 + * - r18: saved bsp (after switching to kernel stack) 13.1184 + * - r19: saved b6 13.1185 + * - r20: saved r1 (gp) 13.1186 + * - r21: saved ar.fpsr 13.1187 + * - r22: kernel's register backing store base (krbs_base) 13.1188 + * - r23: saved ar.bspstore 13.1189 + * - r24: saved ar.rnat 13.1190 + * - r25: saved ar.unat 13.1191 + * - r26: saved ar.pfs 13.1192 + * - r27: saved ar.rsc 13.1193 + * - r28: saved cr.iip 13.1194 + * - r29: saved cr.ipsr 13.1195 + * - r31: saved pr 13.1196 + * - b0: original contents (to be saved) 13.1197 + * On exit: 13.1198 + * - executing on bank 1 registers 13.1199 + * - psr.ic enabled, interrupts restored 13.1200 + * - p10: TRUE if syscall is invoked with more than 8 out 13.1201 + * registers or r15's Nat is true 13.1202 + * - r1: kernel's gp 13.1203 + * - r3: preserved (same as on entry) 13.1204 + * - r8: -EINVAL if p10 is true 13.1205 + * - r12: points to kernel stack 13.1206 + * - r13: points to current task 13.1207 + * - p15: TRUE if interrupts need to be re-enabled 13.1208 + * - ar.fpsr: set to kernel settings 13.1209 + */ 13.1210 +#ifndef CONFIG_XEN 13.1211 +GLOBAL_ENTRY(ia64_syscall_setup) 13.1212 +#if PT(B6) != 0 13.1213 +# error This code assumes that b6 is the first field in pt_regs. 13.1214 +#endif 13.1215 + st8 [r1]=r19 // save b6 13.1216 + add r16=PT(CR_IPSR),r1 // initialize first base pointer 13.1217 + add r17=PT(R11),r1 // initialize second base pointer 13.1218 + ;; 13.1219 + alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable 13.1220 + st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr 13.1221 + tnat.nz p8,p0=in0 13.1222 + 13.1223 + st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11 13.1224 + tnat.nz p9,p0=in1 13.1225 +(pKStk) mov r18=r0 // make sure r18 isn't NaT 13.1226 + ;; 13.1227 + 13.1228 + st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs 13.1229 + st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip 13.1230 + mov r28=b0 // save b0 (2 cyc) 13.1231 + ;; 13.1232 + 13.1233 + st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat 13.1234 + dep r19=0,r19,38,26 // clear all bits but 0..37 [I0] 13.1235 +(p8) mov in0=-1 13.1236 + ;; 13.1237 + 13.1238 + st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs 13.1239 + extr.u r11=r19,7,7 // I0 // get sol of ar.pfs 13.1240 + and r8=0x7f,r19 // A // get sof of ar.pfs 13.1241 + 13.1242 + st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc 13.1243 + tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0 13.1244 +(p9) mov in1=-1 13.1245 + ;; 13.1246 + 13.1247 +(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8 13.1248 + tnat.nz p10,p0=in2 13.1249 + add r11=8,r11 13.1250 + ;; 13.1251 +(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field 13.1252 +(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field 13.1253 + tnat.nz p11,p0=in3 13.1254 + ;; 13.1255 +(p10) mov in2=-1 13.1256 + tnat.nz p12,p0=in4 // [I0] 13.1257 +(p11) mov in3=-1 13.1258 + ;; 13.1259 +(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat 13.1260 +(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore 13.1261 + shl r18=r18,16 // compute ar.rsc to be used for "loadrs" 13.1262 + ;; 13.1263 + st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates 13.1264 + st8 [r17]=r28,PT(R1)-PT(B0) // save b0 13.1265 + tnat.nz p13,p0=in5 // [I0] 13.1266 + ;; 13.1267 + st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs" 13.1268 + st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1 13.1269 +(p12) mov in4=-1 13.1270 + ;; 13.1271 + 13.1272 +.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12 13.1273 +.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13 13.1274 +(p13) mov in5=-1 13.1275 + ;; 13.1276 + st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr 13.1277 + tnat.nz p14,p0=in6 13.1278 + cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 13.1279 + ;; 13.1280 + stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) 13.1281 +(p9) tnat.nz p10,p0=r15 13.1282 + adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) 13.1283 + 13.1284 + st8.spill [r17]=r15 // save r15 13.1285 + tnat.nz p8,p0=in7 13.1286 + nop.i 0 13.1287 + 13.1288 + mov r13=r2 // establish `current' 13.1289 + movl r1=__gp // establish kernel global pointer 13.1290 + ;; 13.1291 +(p14) mov in6=-1 13.1292 +(p8) mov in7=-1 13.1293 + nop.i 0 13.1294 + 13.1295 + cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 13.1296 + movl r17=FPSR_DEFAULT 13.1297 + ;; 13.1298 + mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value 13.1299 +(p10) mov r8=-EINVAL 13.1300 + br.ret.sptk.many b7 13.1301 +END(ia64_syscall_setup) 13.1302 +#endif 13.1303 + 13.1304 + .org ia64_ivt+0x3c00 13.1305 +///////////////////////////////////////////////////////////////////////////////////////// 13.1306 +// 0x3c00 Entry 15 (size 64 bundles) Reserved 13.1307 + DBG_FAULT(15) 13.1308 + FAULT(15) 13.1309 + 13.1310 + /* 13.1311 + * Squatting in this space ... 13.1312 + * 13.1313 + * This special case dispatcher for illegal operation faults allows preserved 13.1314 + * registers to be modified through a callback function (asm only) that is handed 13.1315 + * back from the fault handler in r8. Up to three arguments can be passed to the 13.1316 + * callback function by returning an aggregate with the callback as its first 13.1317 + * element, followed by the arguments. 13.1318 + */ 13.1319 +ENTRY(dispatch_illegal_op_fault) 13.1320 + SAVE_MIN_WITH_COVER 13.1321 + ssm psr.ic | PSR_DEFAULT_BITS 13.1322 + ;; 13.1323 + srlz.i // guarantee that interruption collection is on 13.1324 + ;; 13.1325 +(p15) ssm psr.i // restore psr.i 13.1326 + adds r3=8,r2 // set up second base pointer for SAVE_REST 13.1327 + ;; 13.1328 + alloc r14=ar.pfs,0,0,1,0 // must be first in insn group 13.1329 + mov out0=ar.ec 13.1330 + ;; 13.1331 + SAVE_REST 13.1332 + ;; 13.1333 + br.call.sptk.many rp=ia64_illegal_op_fault 13.1334 +.ret0: ;; 13.1335 + alloc r14=ar.pfs,0,0,3,0 // must be first in insn group 13.1336 + mov out0=r9 13.1337 + mov out1=r10 13.1338 + mov out2=r11 13.1339 + movl r15=ia64_leave_kernel 13.1340 + ;; 13.1341 + mov rp=r15 13.1342 + mov b6=r8 13.1343 + ;; 13.1344 + cmp.ne p6,p0=0,r8 13.1345 +(p6) br.call.dpnt.many b6=b6 // call returns to ia64_leave_kernel 13.1346 + br.sptk.many ia64_leave_kernel 13.1347 +END(dispatch_illegal_op_fault) 13.1348 + 13.1349 + .org ia64_ivt+0x4000 13.1350 +///////////////////////////////////////////////////////////////////////////////////////// 13.1351 +// 0x4000 Entry 16 (size 64 bundles) Reserved 13.1352 + DBG_FAULT(16) 13.1353 + FAULT(16) 13.1354 + 13.1355 + .org ia64_ivt+0x4400 13.1356 +///////////////////////////////////////////////////////////////////////////////////////// 13.1357 +// 0x4400 Entry 17 (size 64 bundles) Reserved 13.1358 + DBG_FAULT(17) 13.1359 + FAULT(17) 13.1360 + 13.1361 +ENTRY(non_syscall) 13.1362 + SAVE_MIN_WITH_COVER 13.1363 + 13.1364 + // There is no particular reason for this code to be here, other than that 13.1365 + // there happens to be space here that would go unused otherwise. If this 13.1366 + // fault ever gets "unreserved", simply moved the following code to a more 13.1367 + // suitable spot... 13.1368 + 13.1369 + alloc r14=ar.pfs,0,0,2,0 13.1370 + mov out0=cr.iim 13.1371 + add out1=16,sp 13.1372 + adds r3=8,r2 // set up second base pointer for SAVE_REST 13.1373 + 13.1374 + ssm psr.ic | PSR_DEFAULT_BITS 13.1375 + ;; 13.1376 + srlz.i // guarantee that interruption collection is on 13.1377 + ;; 13.1378 +(p15) ssm psr.i // restore psr.i 13.1379 + movl r15=ia64_leave_kernel 13.1380 + ;; 13.1381 + SAVE_REST 13.1382 + mov rp=r15 13.1383 + ;; 13.1384 + br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr 13.1385 +END(non_syscall) 13.1386 + 13.1387 + .org ia64_ivt+0x4800 13.1388 +///////////////////////////////////////////////////////////////////////////////////////// 13.1389 +// 0x4800 Entry 18 (size 64 bundles) Reserved 13.1390 + DBG_FAULT(18) 13.1391 + FAULT(18) 13.1392 + 13.1393 + /* 13.1394 + * There is no particular reason for this code to be here, other than that 13.1395 + * there happens to be space here that would go unused otherwise. If this 13.1396 + * fault ever gets "unreserved", simply moved the following code to a more 13.1397 + * suitable spot... 13.1398 + */ 13.1399 + 13.1400 +ENTRY(dispatch_unaligned_handler) 13.1401 + SAVE_MIN_WITH_COVER 13.1402 + ;; 13.1403 + alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) 13.1404 + mov out0=cr.ifa 13.1405 + adds out1=16,sp 13.1406 + 13.1407 + ssm psr.ic | PSR_DEFAULT_BITS 13.1408 + ;; 13.1409 + srlz.i // guarantee that interruption collection is on 13.1410 + ;; 13.1411 +(p15) ssm psr.i // restore psr.i 13.1412 + adds r3=8,r2 // set up second base pointer 13.1413 + ;; 13.1414 + SAVE_REST 13.1415 + movl r14=ia64_leave_kernel 13.1416 + ;; 13.1417 + mov rp=r14 13.1418 + br.sptk.many ia64_prepare_handle_unaligned 13.1419 +END(dispatch_unaligned_handler) 13.1420 + 13.1421 + .org ia64_ivt+0x4c00 13.1422 +///////////////////////////////////////////////////////////////////////////////////////// 13.1423 +// 0x4c00 Entry 19 (size 64 bundles) Reserved 13.1424 + DBG_FAULT(19) 13.1425 + FAULT(19) 13.1426 + 13.1427 + /* 13.1428 + * There is no particular reason for this code to be here, other than that 13.1429 + * there happens to be space here that would go unused otherwise. If this 13.1430 + * fault ever gets "unreserved", simply moved the following code to a more 13.1431 + * suitable spot... 13.1432 + */ 13.1433 + 13.1434 +ENTRY(dispatch_to_fault_handler) 13.1435 + /* 13.1436 + * Input: 13.1437 + * psr.ic: off 13.1438 + * r19: fault vector number (e.g., 24 for General Exception) 13.1439 + * r31: contains saved predicates (pr) 13.1440 + */ 13.1441 + SAVE_MIN_WITH_COVER_R19 13.1442 + alloc r14=ar.pfs,0,0,5,0 13.1443 + mov out0=r15 13.1444 + mov out1=cr.isr 13.1445 + mov out2=cr.ifa 13.1446 + mov out3=cr.iim 13.1447 + mov out4=cr.itir 13.1448 + ;; 13.1449 + ssm psr.ic | PSR_DEFAULT_BITS 13.1450 + ;; 13.1451 + srlz.i // guarantee that interruption collection is on 13.1452 + ;; 13.1453 +(p15) ssm psr.i // restore psr.i 13.1454 + adds r3=8,r2 // set up second base pointer for SAVE_REST 13.1455 + ;; 13.1456 + SAVE_REST 13.1457 + movl r14=ia64_leave_kernel 13.1458 + ;; 13.1459 + mov rp=r14 13.1460 + br.call.sptk.many b6=ia64_fault 13.1461 +END(dispatch_to_fault_handler) 13.1462 + 13.1463 +// 13.1464 +// --- End of long entries, Beginning of short entries 13.1465 +// 13.1466 + 13.1467 + .org ia64_ivt+0x5000 13.1468 +///////////////////////////////////////////////////////////////////////////////////////// 13.1469 +// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) 13.1470 +ENTRY(page_not_present) 13.1471 + DBG_FAULT(20) 13.1472 + mov r16=cr.ifa 13.1473 + rsm psr.dt 13.1474 + /* 13.1475 + * The Linux page fault handler doesn't expect non-present pages to be in 13.1476 + * the TLB. Flush the existing entry now, so we meet that expectation. 13.1477 + */ 13.1478 + mov r17=PAGE_SHIFT<<2 13.1479 + ;; 13.1480 + ptc.l r16,r17 13.1481 + ;; 13.1482 + mov r31=pr 13.1483 + srlz.d 13.1484 + br.sptk.many page_fault 13.1485 +END(page_not_present) 13.1486 + 13.1487 + .org ia64_ivt+0x5100 13.1488 +///////////////////////////////////////////////////////////////////////////////////////// 13.1489 +// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) 13.1490 +ENTRY(key_permission) 13.1491 + DBG_FAULT(21) 13.1492 + mov r16=cr.ifa 13.1493 + rsm psr.dt 13.1494 + mov r31=pr 13.1495 + ;; 13.1496 + srlz.d 13.1497 + br.sptk.many page_fault 13.1498 +END(key_permission) 13.1499 + 13.1500 + .org ia64_ivt+0x5200 13.1501 +///////////////////////////////////////////////////////////////////////////////////////// 13.1502 +// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) 13.1503 +ENTRY(iaccess_rights) 13.1504 + DBG_FAULT(22) 13.1505 + mov r16=cr.ifa 13.1506 + rsm psr.dt 13.1507 + mov r31=pr 13.1508 + ;; 13.1509 + srlz.d 13.1510 + br.sptk.many page_fault 13.1511 +END(iaccess_rights) 13.1512 + 13.1513 + .org ia64_ivt+0x5300 13.1514 +///////////////////////////////////////////////////////////////////////////////////////// 13.1515 +// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) 13.1516 +ENTRY(daccess_rights) 13.1517 + DBG_FAULT(23) 13.1518 +#ifdef CONFIG_XEN 13.1519 + movl r16=XSI_IFA 13.1520 + ;; 13.1521 + ld8 r16=[r16] 13.1522 + ;; 13.1523 + XEN_HYPER_RSM_PSR_DT; 13.1524 +#else 13.1525 + mov r16=cr.ifa 13.1526 + rsm psr.dt 13.1527 +#endif 13.1528 + mov r31=pr 13.1529 + ;; 13.1530 + srlz.d 13.1531 + br.sptk.many page_fault 13.1532 +END(daccess_rights) 13.1533 + 13.1534 + .org ia64_ivt+0x5400 13.1535 +///////////////////////////////////////////////////////////////////////////////////////// 13.1536 +// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) 13.1537 +ENTRY(general_exception) 13.1538 + DBG_FAULT(24) 13.1539 + mov r16=cr.isr 13.1540 + mov r31=pr 13.1541 + ;; 13.1542 + cmp4.eq p6,p0=0,r16 13.1543 +(p6) br.sptk.many dispatch_illegal_op_fault 13.1544 + ;; 13.1545 + mov r19=24 // fault number 13.1546 + br.sptk.many dispatch_to_fault_handler 13.1547 +END(general_exception) 13.1548 + 13.1549 + .org ia64_ivt+0x5500 13.1550 +///////////////////////////////////////////////////////////////////////////////////////// 13.1551 +// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) 13.1552 +ENTRY(disabled_fp_reg) 13.1553 + DBG_FAULT(25) 13.1554 + rsm psr.dfh // ensure we can access fph 13.1555 + ;; 13.1556 + srlz.d 13.1557 + mov r31=pr 13.1558 + mov r19=25 13.1559 + br.sptk.many dispatch_to_fault_handler 13.1560 +END(disabled_fp_reg) 13.1561 + 13.1562 + .org ia64_ivt+0x5600 13.1563 +///////////////////////////////////////////////////////////////////////////////////////// 13.1564 +// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) 13.1565 +ENTRY(nat_consumption) 13.1566 + DBG_FAULT(26) 13.1567 + FAULT(26) 13.1568 +END(nat_consumption) 13.1569 + 13.1570 + .org ia64_ivt+0x5700 13.1571 +///////////////////////////////////////////////////////////////////////////////////////// 13.1572 +// 0x5700 Entry 27 (size 16 bundles) Speculation (40) 13.1573 +ENTRY(speculation_vector) 13.1574 + DBG_FAULT(27) 13.1575 + /* 13.1576 + * A [f]chk.[as] instruction needs to take the branch to the recovery code but 13.1577 + * this part of the architecture is not implemented in hardware on some CPUs, such 13.1578 + * as Itanium. Thus, in general we need to emulate the behavior. IIM contains 13.1579 + * the relative target (not yet sign extended). So after sign extending it we 13.1580 + * simply add it to IIP. We also need to reset the EI field of the IPSR to zero, 13.1581 + * i.e., the slot to restart into. 13.1582 + * 13.1583 + * cr.imm contains zero_ext(imm21) 13.1584 + */ 13.1585 + mov r18=cr.iim 13.1586 + ;; 13.1587 + mov r17=cr.iip 13.1588 + shl r18=r18,43 // put sign bit in position (43=64-21) 13.1589 + ;; 13.1590 + 13.1591 + mov r16=cr.ipsr 13.1592 + shr r18=r18,39 // sign extend (39=43-4) 13.1593 + ;; 13.1594 + 13.1595 + add r17=r17,r18 // now add the offset 13.1596 + ;; 13.1597 + mov cr.iip=r17 13.1598 + dep r16=0,r16,41,2 // clear EI 13.1599 + ;; 13.1600 + 13.1601 + mov cr.ipsr=r16 13.1602 + ;; 13.1603 + 13.1604 +#ifdef CONFIG_XEN 13.1605 + XEN_HYPER_RFI; 13.1606 +#else 13.1607 + rfi 13.1608 +#endif 13.1609 +END(speculation_vector) 13.1610 + 13.1611 + .org ia64_ivt+0x5800 13.1612 +///////////////////////////////////////////////////////////////////////////////////////// 13.1613 +// 0x5800 Entry 28 (size 16 bundles) Reserved 13.1614 + DBG_FAULT(28) 13.1615 + FAULT(28) 13.1616 + 13.1617 + .org ia64_ivt+0x5900 13.1618 +///////////////////////////////////////////////////////////////////////////////////////// 13.1619 +// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) 13.1620 +ENTRY(debug_vector) 13.1621 + DBG_FAULT(29) 13.1622 + FAULT(29) 13.1623 +END(debug_vector) 13.1624 + 13.1625 + .org ia64_ivt+0x5a00 13.1626 +///////////////////////////////////////////////////////////////////////////////////////// 13.1627 +// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) 13.1628 +ENTRY(unaligned_access) 13.1629 + DBG_FAULT(30) 13.1630 + mov r16=cr.ipsr 13.1631 + mov r31=pr // prepare to save predicates 13.1632 + ;; 13.1633 + br.sptk.many dispatch_unaligned_handler 13.1634 +END(unaligned_access) 13.1635 + 13.1636 + .org ia64_ivt+0x5b00 13.1637 +///////////////////////////////////////////////////////////////////////////////////////// 13.1638 +// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) 13.1639 +ENTRY(unsupported_data_reference) 13.1640 + DBG_FAULT(31) 13.1641 + FAULT(31) 13.1642 +END(unsupported_data_reference) 13.1643 + 13.1644 + .org ia64_ivt+0x5c00 13.1645 +///////////////////////////////////////////////////////////////////////////////////////// 13.1646 +// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64) 13.1647 +ENTRY(floating_point_fault) 13.1648 + DBG_FAULT(32) 13.1649 + FAULT(32) 13.1650 +END(floating_point_fault) 13.1651 + 13.1652 + .org ia64_ivt+0x5d00 13.1653 +///////////////////////////////////////////////////////////////////////////////////////// 13.1654 +// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) 13.1655 +ENTRY(floating_point_trap) 13.1656 + DBG_FAULT(33) 13.1657 + FAULT(33) 13.1658 +END(floating_point_trap) 13.1659 + 13.1660 + .org ia64_ivt+0x5e00 13.1661 +///////////////////////////////////////////////////////////////////////////////////////// 13.1662 +// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) 13.1663 +ENTRY(lower_privilege_trap) 13.1664 + DBG_FAULT(34) 13.1665 + FAULT(34) 13.1666 +END(lower_privilege_trap) 13.1667 + 13.1668 + .org ia64_ivt+0x5f00 13.1669 +///////////////////////////////////////////////////////////////////////////////////////// 13.1670 +// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) 13.1671 +ENTRY(taken_branch_trap) 13.1672 + DBG_FAULT(35) 13.1673 + FAULT(35) 13.1674 +END(taken_branch_trap) 13.1675 + 13.1676 + .org ia64_ivt+0x6000 13.1677 +///////////////////////////////////////////////////////////////////////////////////////// 13.1678 +// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) 13.1679 +ENTRY(single_step_trap) 13.1680 + DBG_FAULT(36) 13.1681 + FAULT(36) 13.1682 +END(single_step_trap) 13.1683 + 13.1684 + .org ia64_ivt+0x6100 13.1685 +///////////////////////////////////////////////////////////////////////////////////////// 13.1686 +// 0x6100 Entry 37 (size 16 bundles) Reserved 13.1687 + DBG_FAULT(37) 13.1688 + FAULT(37) 13.1689 + 13.1690 + .org ia64_ivt+0x6200 13.1691 +///////////////////////////////////////////////////////////////////////////////////////// 13.1692 +// 0x6200 Entry 38 (size 16 bundles) Reserved 13.1693 + DBG_FAULT(38) 13.1694 + FAULT(38) 13.1695 + 13.1696 + .org ia64_ivt+0x6300 13.1697 +///////////////////////////////////////////////////////////////////////////////////////// 13.1698 +// 0x6300 Entry 39 (size 16 bundles) Reserved 13.1699 + DBG_FAULT(39) 13.1700 + FAULT(39) 13.1701 + 13.1702 + .org ia64_ivt+0x6400 13.1703 +///////////////////////////////////////////////////////////////////////////////////////// 13.1704 +// 0x6400 Entry 40 (size 16 bundles) Reserved 13.1705 + DBG_FAULT(40) 13.1706 + FAULT(40) 13.1707 + 13.1708 + .org ia64_ivt+0x6500 13.1709 +///////////////////////////////////////////////////////////////////////////////////////// 13.1710 +// 0x6500 Entry 41 (size 16 bundles) Reserved 13.1711 + DBG_FAULT(41) 13.1712 + FAULT(41) 13.1713 + 13.1714 + .org ia64_ivt+0x6600 13.1715 +///////////////////////////////////////////////////////////////////////////////////////// 13.1716 +// 0x6600 Entry 42 (size 16 bundles) Reserved 13.1717 + DBG_FAULT(42) 13.1718 + FAULT(42) 13.1719 + 13.1720 + .org ia64_ivt+0x6700 13.1721 +///////////////////////////////////////////////////////////////////////////////////////// 13.1722 +// 0x6700 Entry 43 (size 16 bundles) Reserved 13.1723 + DBG_FAULT(43) 13.1724 + FAULT(43) 13.1725 + 13.1726 + .org ia64_ivt+0x6800 13.1727 +///////////////////////////////////////////////////////////////////////////////////////// 13.1728 +// 0x6800 Entry 44 (size 16 bundles) Reserved 13.1729 + DBG_FAULT(44) 13.1730 + FAULT(44) 13.1731 + 13.1732 + .org ia64_ivt+0x6900 13.1733 +///////////////////////////////////////////////////////////////////////////////////////// 13.1734 +// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) 13.1735 +ENTRY(ia32_exception) 13.1736 + DBG_FAULT(45) 13.1737 + FAULT(45) 13.1738 +END(ia32_exception) 13.1739 + 13.1740 + .org ia64_ivt+0x6a00 13.1741 +///////////////////////////////////////////////////////////////////////////////////////// 13.1742 +// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) 13.1743 +ENTRY(ia32_intercept) 13.1744 + DBG_FAULT(46) 13.1745 +#ifdef CONFIG_IA32_SUPPORT 13.1746 + mov r31=pr 13.1747 + mov r16=cr.isr 13.1748 + ;; 13.1749 + extr.u r17=r16,16,8 // get ISR.code 13.1750 + mov r18=ar.eflag 13.1751 + mov r19=cr.iim // old eflag value 13.1752 + ;; 13.1753 + cmp.ne p6,p0=2,r17 13.1754 +(p6) br.cond.spnt 1f // not a system flag fault 13.1755 + xor r16=r18,r19 13.1756 + ;; 13.1757 + extr.u r17=r16,18,1 // get the eflags.ac bit 13.1758 + ;; 13.1759 + cmp.eq p6,p0=0,r17 13.1760 +(p6) br.cond.spnt 1f // eflags.ac bit didn't change 13.1761 + ;; 13.1762 + mov pr=r31,-1 // restore predicate registers 13.1763 +#ifdef CONFIG_XEN 13.1764 + XEN_HYPER_RFI; 13.1765 +#else 13.1766 + rfi 13.1767 +#endif 13.1768 + 13.1769 +1: 13.1770 +#endif // CONFIG_IA32_SUPPORT 13.1771 + FAULT(46) 13.1772 +END(ia32_intercept) 13.1773 + 13.1774 + .org ia64_ivt+0x6b00 13.1775 +///////////////////////////////////////////////////////////////////////////////////////// 13.1776 +// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) 13.1777 +ENTRY(ia32_interrupt) 13.1778 + DBG_FAULT(47) 13.1779 +#ifdef CONFIG_IA32_SUPPORT 13.1780 + mov r31=pr 13.1781 + br.sptk.many dispatch_to_ia32_handler 13.1782 +#else 13.1783 + FAULT(47) 13.1784 +#endif 13.1785 +END(ia32_interrupt) 13.1786 + 13.1787 + .org ia64_ivt+0x6c00 13.1788 +///////////////////////////////////////////////////////////////////////////////////////// 13.1789 +// 0x6c00 Entry 48 (size 16 bundles) Reserved 13.1790 + DBG_FAULT(48) 13.1791 + FAULT(48) 13.1792 + 13.1793 + .org ia64_ivt+0x6d00 13.1794 +///////////////////////////////////////////////////////////////////////////////////////// 13.1795 +// 0x6d00 Entry 49 (size 16 bundles) Reserved 13.1796 + DBG_FAULT(49) 13.1797 + FAULT(49) 13.1798 + 13.1799 + .org ia64_ivt+0x6e00 13.1800 +///////////////////////////////////////////////////////////////////////////////////////// 13.1801 +// 0x6e00 Entry 50 (size 16 bundles) Reserved 13.1802 + DBG_FAULT(50) 13.1803 + FAULT(50) 13.1804 + 13.1805 + .org ia64_ivt+0x6f00 13.1806 +///////////////////////////////////////////////////////////////////////////////////////// 13.1807 +// 0x6f00 Entry 51 (size 16 bundles) Reserved 13.1808 + DBG_FAULT(51) 13.1809 + FAULT(51) 13.1810 + 13.1811 + .org ia64_ivt+0x7000 13.1812 +///////////////////////////////////////////////////////////////////////////////////////// 13.1813 +// 0x7000 Entry 52 (size 16 bundles) Reserved 13.1814 + DBG_FAULT(52) 13.1815 + FAULT(52) 13.1816 + 13.1817 + .org ia64_ivt+0x7100 13.1818 +///////////////////////////////////////////////////////////////////////////////////////// 13.1819 +// 0x7100 Entry 53 (size 16 bundles) Reserved 13.1820 + DBG_FAULT(53) 13.1821 + FAULT(53) 13.1822 + 13.1823 + .org ia64_ivt+0x7200 13.1824 +///////////////////////////////////////////////////////////////////////////////////////// 13.1825 +// 0x7200 Entry 54 (size 16 bundles) Reserved 13.1826 + DBG_FAULT(54) 13.1827 + FAULT(54) 13.1828 + 13.1829 + .org ia64_ivt+0x7300 13.1830 +///////////////////////////////////////////////////////////////////////////////////////// 13.1831 +// 0x7300 Entry 55 (size 16 bundles) Reserved 13.1832 + DBG_FAULT(55) 13.1833 + FAULT(55) 13.1834 + 13.1835 + .org ia64_ivt+0x7400 13.1836 +///////////////////////////////////////////////////////////////////////////////////////// 13.1837 +// 0x7400 Entry 56 (size 16 bundles) Reserved 13.1838 + DBG_FAULT(56) 13.1839 + FAULT(56) 13.1840 + 13.1841 + .org ia64_ivt+0x7500 13.1842 +///////////////////////////////////////////////////////////////////////////////////////// 13.1843 +// 0x7500 Entry 57 (size 16 bundles) Reserved 13.1844 + DBG_FAULT(57) 13.1845 + FAULT(57) 13.1846 + 13.1847 + .org ia64_ivt+0x7600 13.1848 +///////////////////////////////////////////////////////////////////////////////////////// 13.1849 +// 0x7600 Entry 58 (size 16 bundles) Reserved 13.1850 + DBG_FAULT(58) 13.1851 + FAULT(58) 13.1852 + 13.1853 + .org ia64_ivt+0x7700 13.1854 +///////////////////////////////////////////////////////////////////////////////////////// 13.1855 +// 0x7700 Entry 59 (size 16 bundles) Reserved 13.1856 + DBG_FAULT(59) 13.1857 + FAULT(59) 13.1858 + 13.1859 + .org ia64_ivt+0x7800 13.1860 +///////////////////////////////////////////////////////////////////////////////////////// 13.1861 +// 0x7800 Entry 60 (size 16 bundles) Reserved 13.1862 + DBG_FAULT(60) 13.1863 + FAULT(60) 13.1864 + 13.1865 + .org ia64_ivt+0x7900 13.1866 +///////////////////////////////////////////////////////////////////////////////////////// 13.1867 +// 0x7900 Entry 61 (size 16 bundles) Reserved 13.1868 + DBG_FAULT(61) 13.1869 + FAULT(61) 13.1870 + 13.1871 + .org ia64_ivt+0x7a00 13.1872 +///////////////////////////////////////////////////////////////////////////////////////// 13.1873 +// 0x7a00 Entry 62 (size 16 bundles) Reserved 13.1874 + DBG_FAULT(62) 13.1875 + FAULT(62) 13.1876 + 13.1877 + .org ia64_ivt+0x7b00 13.1878 +///////////////////////////////////////////////////////////////////////////////////////// 13.1879 +// 0x7b00 Entry 63 (size 16 bundles) Reserved 13.1880 + DBG_FAULT(63) 13.1881 + FAULT(63) 13.1882 + 13.1883 + .org ia64_ivt+0x7c00 13.1884 +///////////////////////////////////////////////////////////////////////////////////////// 13.1885 +// 0x7c00 Entry 64 (size 16 bundles) Reserved 13.1886 + DBG_FAULT(64) 13.1887 + FAULT(64) 13.1888 + 13.1889 + .org ia64_ivt+0x7d00 13.1890 +///////////////////////////////////////////////////////////////////////////////////////// 13.1891 +// 0x7d00 Entry 65 (size 16 bundles) Reserved 13.1892 + DBG_FAULT(65) 13.1893 + FAULT(65) 13.1894 + 13.1895 + .org ia64_ivt+0x7e00 13.1896 +///////////////////////////////////////////////////////////////////////////////////////// 13.1897 +// 0x7e00 Entry 66 (size 16 bundles) Reserved 13.1898 + DBG_FAULT(66) 13.1899 + FAULT(66) 13.1900 + 13.1901 +#ifdef CONFIG_XEN 13.1902 + /* 13.1903 + * There is no particular reason for this code to be here, other than that 13.1904 + * there happens to be space here that would go unused otherwise. If this 13.1905 + * fault ever gets "unreserved", simply moved the following code to a more 13.1906 + * suitable spot... 13.1907 + */ 13.1908 + 13.1909 +GLOBAL_ENTRY(xen_bsw1) 13.1910 + /* FIXME: THIS CODE IS NOT NaT SAFE! */ 13.1911 + movl r30=XSI_BANKNUM; 13.1912 + mov r31=1;; 13.1913 + st4 [r30]=r31; 13.1914 + movl r30=XSI_BANK1_R16; 13.1915 + movl r31=XSI_BANK1_R16+8;; 13.1916 + ld8 r16=[r30],16; ld8 r17=[r31],16;; 13.1917 + ld8 r18=[r30],16; ld8 r19=[r31],16;; 13.1918 + ld8 r20=[r30],16; ld8 r21=[r31],16;; 13.1919 + ld8 r22=[r30],16; ld8 r23=[r31],16;; 13.1920 + ld8 r24=[r30],16; ld8 r25=[r31],16;; 13.1921 + ld8 r26=[r30],16; ld8 r27=[r31],16;; 13.1922 + ld8 r28=[r30],16; ld8 r29=[r31],16;; 13.1923 + ld8 r30=[r30]; ld8 r31=[r31];; 13.1924 + br.ret.sptk.many b0 13.1925 +#endif 13.1926 + 13.1927 + .org ia64_ivt+0x7f00 13.1928 +///////////////////////////////////////////////////////////////////////////////////////// 13.1929 +// 0x7f00 Entry 67 (size 16 bundles) Reserved 13.1930 + DBG_FAULT(67) 13.1931 + FAULT(67) 13.1932 + 13.1933 +#ifdef CONFIG_IA32_SUPPORT 13.1934 + 13.1935 + /* 13.1936 + * There is no particular reason for this code to be here, other than that 13.1937 + * there happens to be space here that would go unused otherwise. If this 13.1938 + * fault ever gets "unreserved", simply moved the following code to a more 13.1939 + * suitable spot... 13.1940 + */ 13.1941 + 13.1942 + // IA32 interrupt entry point 13.1943 + 13.1944 +ENTRY(dispatch_to_ia32_handler) 13.1945 + SAVE_MIN 13.1946 + ;; 13.1947 + mov r14=cr.isr 13.1948 + ssm psr.ic | PSR_DEFAULT_BITS 13.1949 + ;; 13.1950 + srlz.i // guarantee that interruption collection is on 13.1951 + ;; 13.1952 +(p15) ssm psr.i 13.1953 + adds r3=8,r2 // Base pointer for SAVE_REST 13.1954 + ;; 13.1955 + SAVE_REST 13.1956 + ;; 13.1957 + mov r15=0x80 13.1958 + shr r14=r14,16 // Get interrupt number 13.1959 + ;; 13.1960 + cmp.ne p6,p0=r14,r15 13.1961 +(p6) br.call.dpnt.many b6=non_ia32_syscall 13.1962 + 13.1963 + adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp // 16 byte hole per SW conventions 13.1964 + adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp 13.1965 + ;; 13.1966 + cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 13.1967 + ld8 r8=[r14] // get r8 13.1968 + ;; 13.1969 + st8 [r15]=r8 // save original EAX in r1 (IA32 procs don't use the GP) 13.1970 + ;; 13.1971 + alloc r15=ar.pfs,0,0,6,0 // must first in an insn group 13.1972 + ;; 13.1973 + ld4 r8=[r14],8 // r8 == eax (syscall number) 13.1974 + mov r15=IA32_NR_syscalls 13.1975 + ;; 13.1976 + cmp.ltu.unc p6,p7=r8,r15 13.1977 + ld4 out1=[r14],8 // r9 == ecx 13.1978 + ;; 13.1979 + ld4 out2=[r14],8 // r10 == edx 13.1980 + ;; 13.1981 + ld4 out0=[r14] // r11 == ebx 13.1982 + adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp 13.1983 + ;; 13.1984 + ld4 out5=[r14],PT(R14)-PT(R13) // r13 == ebp 13.1985 + ;; 13.1986 + ld4 out3=[r14],PT(R15)-PT(R14) // r14 == esi 13.1987 + adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 13.1988 + ;; 13.1989 + ld4 out4=[r14] // r15 == edi 13.1990 + movl r16=ia32_syscall_table 13.1991 + ;; 13.1992 +(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number 13.1993 + ld4 r2=[r2] // r2 = current_thread_info()->flags 13.1994 + ;; 13.1995 + ld8 r16=[r16] 13.1996 + and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit 13.1997 + ;; 13.1998 + mov b6=r16 13.1999 + movl r15=ia32_ret_from_syscall 13.2000 + cmp.eq p8,p0=r2,r0 13.2001 + ;; 13.2002 + mov rp=r15 13.2003 +(p8) br.call.sptk.many b6=b6 13.2004 + br.cond.sptk ia32_trace_syscall 13.2005 + 13.2006 +non_ia32_syscall: 13.2007 + alloc r15=ar.pfs,0,0,2,0 13.2008 + mov out0=r14 // interrupt # 13.2009 + add out1=16,sp // pointer to pt_regs 13.2010 + ;; // avoid WAW on CFM 13.2011 + br.call.sptk.many rp=ia32_bad_interrupt 13.2012 +.ret1: movl r15=ia64_leave_kernel 13.2013 + ;; 13.2014 + mov rp=r15 13.2015 + br.ret.sptk.many rp 13.2016 +END(dispatch_to_ia32_handler) 13.2017 + 13.2018 +#endif /* CONFIG_IA32_SUPPORT */
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenminstate.h Wed Sep 21 09:06:30 2005 -0600 14.3 @@ -0,0 +1,371 @@ 14.4 +#include <linux/config.h> 14.5 + 14.6 +#include <asm/cache.h> 14.7 + 14.8 +#ifdef CONFIG_XEN 14.9 +#include "../kernel/entry.h" 14.10 +#else 14.11 +#include "entry.h" 14.12 +#endif 14.13 + 14.14 +/* 14.15 + * For ivt.s we want to access the stack virtually so we don't have to disable translation 14.16 + * on interrupts. 14.17 + * 14.18 + * On entry: 14.19 + * r1: pointer to current task (ar.k6) 14.20 + */ 14.21 +#define MINSTATE_START_SAVE_MIN_VIRT \ 14.22 +(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ 14.23 + ;; \ 14.24 +(pUStk) mov.m r24=ar.rnat; \ 14.25 +(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ 14.26 +(pKStk) mov r1=sp; /* get sp */ \ 14.27 + ;; \ 14.28 +(pUStk) lfetch.fault.excl.nt1 [r22]; \ 14.29 +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ 14.30 +(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ 14.31 + ;; \ 14.32 +(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ 14.33 +(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ 14.34 + ;; \ 14.35 +(pUStk) mov r18=ar.bsp; \ 14.36 +(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ 14.37 + 14.38 +#define MINSTATE_END_SAVE_MIN_VIRT \ 14.39 + bsw.1; /* switch back to bank 1 (must be last in insn group) */ \ 14.40 + ;; 14.41 + 14.42 +/* 14.43 + * For mca_asm.S we want to access the stack physically since the state is saved before we 14.44 + * go virtual and don't want to destroy the iip or ipsr. 14.45 + */ 14.46 +#define MINSTATE_START_SAVE_MIN_PHYS \ 14.47 +(pKStk) mov r3=IA64_KR(PER_CPU_DATA);; \ 14.48 +(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ 14.49 +(pKStk) ld8 r3 = [r3];; \ 14.50 +(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ 14.51 +(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ 14.52 +(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ 14.53 +(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ 14.54 + ;; \ 14.55 +(pUStk) mov r24=ar.rnat; \ 14.56 +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ 14.57 +(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ 14.58 +(pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ 14.59 + ;; \ 14.60 +(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ 14.61 +(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ 14.62 + ;; \ 14.63 +(pUStk) mov r18=ar.bsp; \ 14.64 +(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ 14.65 + 14.66 +#define MINSTATE_END_SAVE_MIN_PHYS \ 14.67 + dep r12=-1,r12,61,3; /* make sp a kernel virtual address */ \ 14.68 + ;; 14.69 + 14.70 +#ifdef MINSTATE_VIRT 14.71 +# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT) 14.72 +# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_VIRT 14.73 +# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_VIRT 14.74 +#endif 14.75 + 14.76 +#ifdef MINSTATE_PHYS 14.77 +# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT);; tpa reg=reg 14.78 +# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_PHYS 14.79 +# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_PHYS 14.80 +#endif 14.81 + 14.82 +/* 14.83 + * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves 14.84 + * the minimum state necessary that allows us to turn psr.ic back 14.85 + * on. 14.86 + * 14.87 + * Assumed state upon entry: 14.88 + * psr.ic: off 14.89 + * r31: contains saved predicates (pr) 14.90 + * 14.91 + * Upon exit, the state is as follows: 14.92 + * psr.ic: off 14.93 + * r2 = points to &pt_regs.r16 14.94 + * r8 = contents of ar.ccv 14.95 + * r9 = contents of ar.csd 14.96 + * r10 = contents of ar.ssd 14.97 + * r11 = FPSR_DEFAULT 14.98 + * r12 = kernel sp (kernel virtual address) 14.99 + * r13 = points to current task_struct (kernel virtual address) 14.100 + * p15 = TRUE if psr.i is set in cr.ipsr 14.101 + * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15: 14.102 + * preserved 14.103 + * CONFIG_XEN note: p6/p7 are not preserved 14.104 + * 14.105 + * Note that psr.ic is NOT turned on by this macro. This is so that 14.106 + * we can pass interruption state as arguments to a handler. 14.107 + */ 14.108 +#ifdef CONFIG_XEN 14.109 +#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ 14.110 + /*MINSTATE_GET_CURRENT(r16); /* M (or M;;I) */ \ 14.111 + movl r16=XSI_KR0+(IA64_KR_CURRENT*8);; \ 14.112 + ld8 r16=[r16];; \ 14.113 + mov r27=ar.rsc; /* M */ \ 14.114 + mov r20=r1; /* A */ \ 14.115 + mov r25=ar.unat; /* M */ \ 14.116 + /* mov r29=cr.ipsr; /* M */ \ 14.117 + movl r29=XSI_IPSR;; \ 14.118 + ld8 r29=[r29];; \ 14.119 + mov r26=ar.pfs; /* I */ \ 14.120 + /* mov r28=cr.iip; /* M */ \ 14.121 + movl r28=XSI_IIP;; \ 14.122 + ld8 r28=[r28];; \ 14.123 + mov r21=ar.fpsr; /* M */ \ 14.124 + COVER; /* B;; (or nothing) */ \ 14.125 + ;; \ 14.126 + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \ 14.127 + ;; \ 14.128 + ld1 r17=[r16]; /* load current->thread.on_ustack flag */ \ 14.129 + st1 [r16]=r0; /* clear current->thread.on_ustack flag */ \ 14.130 + adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 \ 14.131 + /* switch from user to kernel RBS: */ \ 14.132 + ;; \ 14.133 + invala; /* M */ \ 14.134 + /* SAVE_IFS; /* see xen special handling below */ \ 14.135 + cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? */ \ 14.136 + ;; \ 14.137 + MINSTATE_START_SAVE_MIN \ 14.138 + adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \ 14.139 + adds r16=PT(CR_IPSR),r1; \ 14.140 + ;; \ 14.141 + lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ 14.142 + st8 [r16]=r29; /* save cr.ipsr */ \ 14.143 + ;; \ 14.144 + lfetch.fault.excl.nt1 [r17]; \ 14.145 + tbit.nz p15,p0=r29,IA64_PSR_I_BIT; \ 14.146 + mov r29=b0 \ 14.147 + ;; \ 14.148 + adds r16=PT(R8),r1; /* initialize first base pointer */ \ 14.149 + adds r17=PT(R9),r1; /* initialize second base pointer */ \ 14.150 +(pKStk) mov r18=r0; /* make sure r18 isn't NaT */ \ 14.151 + ;; \ 14.152 +.mem.offset 0,0; st8.spill [r16]=r8,16; \ 14.153 +.mem.offset 8,0; st8.spill [r17]=r9,16; \ 14.154 + ;; \ 14.155 +.mem.offset 0,0; st8.spill [r16]=r10,24; \ 14.156 +.mem.offset 8,0; st8.spill [r17]=r11,24; \ 14.157 + ;; \ 14.158 + /* xen special handling for possibly lazy cover */ \ 14.159 + movl r8=XSI_INCOMPL_REGFR; \ 14.160 + ;; \ 14.161 + ld4 r30=[r8]; \ 14.162 + ;; \ 14.163 + cmp.eq p6,p7=r30,r0; \ 14.164 + ;; /* not sure if this stop bit is necessary */ \ 14.165 +(p6) adds r8=XSI_PRECOVER_IFS-XSI_INCOMPL_REGFR,r8; \ 14.166 +(p7) adds r8=XSI_IFS-XSI_INCOMPL_REGFR,r8; \ 14.167 + ;; \ 14.168 + ld8 r30=[r8]; \ 14.169 + ;; \ 14.170 + st8 [r16]=r28,16; /* save cr.iip */ \ 14.171 + st8 [r17]=r30,16; /* save cr.ifs */ \ 14.172 +(pUStk) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ \ 14.173 + mov r8=ar.ccv; \ 14.174 + mov r9=ar.csd; \ 14.175 + mov r10=ar.ssd; \ 14.176 + movl r11=FPSR_DEFAULT; /* L-unit */ \ 14.177 + ;; \ 14.178 + st8 [r16]=r25,16; /* save ar.unat */ \ 14.179 + st8 [r17]=r26,16; /* save ar.pfs */ \ 14.180 + shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ 14.181 + ;; \ 14.182 + st8 [r16]=r27,16; /* save ar.rsc */ \ 14.183 +(pUStk) st8 [r17]=r24,16; /* save ar.rnat */ \ 14.184 +(pKStk) adds r17=16,r17; /* skip over ar_rnat field */ \ 14.185 + ;; /* avoid RAW on r16 & r17 */ \ 14.186 +(pUStk) st8 [r16]=r23,16; /* save ar.bspstore */ \ 14.187 + st8 [r17]=r31,16; /* save predicates */ \ 14.188 +(pKStk) adds r16=16,r16; /* skip over ar_bspstore field */ \ 14.189 + ;; \ 14.190 + st8 [r16]=r29,16; /* save b0 */ \ 14.191 + st8 [r17]=r18,16; /* save ar.rsc value for "loadrs" */ \ 14.192 + cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \ 14.193 + ;; \ 14.194 +.mem.offset 0,0; st8.spill [r16]=r20,16; /* save original r1 */ \ 14.195 +.mem.offset 8,0; st8.spill [r17]=r12,16; \ 14.196 + adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \ 14.197 + ;; \ 14.198 +.mem.offset 0,0; st8.spill [r16]=r13,16; \ 14.199 +.mem.offset 8,0; st8.spill [r17]=r21,16; /* save ar.fpsr */ \ 14.200 + /* mov r13=IA64_KR(CURRENT); /* establish `current' */ \ 14.201 + movl r21=XSI_KR0+(IA64_KR_CURRENT*8);; \ 14.202 + ld8 r13=[r21];; \ 14.203 + ;; \ 14.204 +.mem.offset 0,0; st8.spill [r16]=r15,16; \ 14.205 +.mem.offset 8,0; st8.spill [r17]=r14,16; \ 14.206 + ;; \ 14.207 +.mem.offset 0,0; st8.spill [r16]=r2,16; \ 14.208 +.mem.offset 8,0; st8.spill [r17]=r3,16; \ 14.209 + ;; \ 14.210 + EXTRA; \ 14.211 + mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2; \ 14.212 + adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ 14.213 + ;; \ 14.214 + movl r1=__gp; /* establish kernel global pointer */ \ 14.215 + ;; \ 14.216 + /* MINSTATE_END_SAVE_MIN */ 14.217 +#else 14.218 +#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ 14.219 + MINSTATE_GET_CURRENT(r16); /* M (or M;;I) */ \ 14.220 + mov r27=ar.rsc; /* M */ \ 14.221 + mov r20=r1; /* A */ \ 14.222 + mov r25=ar.unat; /* M */ \ 14.223 + mov r29=cr.ipsr; /* M */ \ 14.224 + mov r26=ar.pfs; /* I */ \ 14.225 + mov r28=cr.iip; /* M */ \ 14.226 + mov r21=ar.fpsr; /* M */ \ 14.227 + COVER; /* B;; (or nothing) */ \ 14.228 + ;; \ 14.229 + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \ 14.230 + ;; \ 14.231 + ld1 r17=[r16]; /* load current->thread.on_ustack flag */ \ 14.232 + st1 [r16]=r0; /* clear current->thread.on_ustack flag */ \ 14.233 + adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 \ 14.234 + /* switch from user to kernel RBS: */ \ 14.235 + ;; \ 14.236 + invala; /* M */ \ 14.237 + SAVE_IFS; \ 14.238 + cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? */ \ 14.239 + ;; \ 14.240 + MINSTATE_START_SAVE_MIN \ 14.241 + adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \ 14.242 + adds r16=PT(CR_IPSR),r1; \ 14.243 + ;; \ 14.244 + lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ 14.245 + st8 [r16]=r29; /* save cr.ipsr */ \ 14.246 + ;; \ 14.247 + lfetch.fault.excl.nt1 [r17]; \ 14.248 + tbit.nz p15,p0=r29,IA64_PSR_I_BIT; \ 14.249 + mov r29=b0 \ 14.250 + ;; \ 14.251 + adds r16=PT(R8),r1; /* initialize first base pointer */ \ 14.252 + adds r17=PT(R9),r1; /* initialize second base pointer */ \ 14.253 +(pKStk) mov r18=r0; /* make sure r18 isn't NaT */ \ 14.254 + ;; \ 14.255 +.mem.offset 0,0; st8.spill [r16]=r8,16; \ 14.256 +.mem.offset 8,0; st8.spill [r17]=r9,16; \ 14.257 + ;; \ 14.258 +.mem.offset 0,0; st8.spill [r16]=r10,24; \ 14.259 +.mem.offset 8,0; st8.spill [r17]=r11,24; \ 14.260 + ;; \ 14.261 + st8 [r16]=r28,16; /* save cr.iip */ \ 14.262 + st8 [r17]=r30,16; /* save cr.ifs */ \ 14.263 +(pUStk) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ \ 14.264 + mov r8=ar.ccv; \ 14.265 + mov r9=ar.csd; \ 14.266 + mov r10=ar.ssd; \ 14.267 + movl r11=FPSR_DEFAULT; /* L-unit */ \ 14.268 + ;; \ 14.269 + st8 [r16]=r25,16; /* save ar.unat */ \ 14.270 + st8 [r17]=r26,16; /* save ar.pfs */ \ 14.271 + shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ 14.272 + ;; \ 14.273 + st8 [r16]=r27,16; /* save ar.rsc */ \ 14.274 +(pUStk) st8 [r17]=r24,16; /* save ar.rnat */ \ 14.275 +(pKStk) adds r17=16,r17; /* skip over ar_rnat field */ \ 14.276 + ;; /* avoid RAW on r16 & r17 */ \ 14.277 +(pUStk) st8 [r16]=r23,16; /* save ar.bspstore */ \ 14.278 + st8 [r17]=r31,16; /* save predicates */ \ 14.279 +(pKStk) adds r16=16,r16; /* skip over ar_bspstore field */ \ 14.280 + ;; \ 14.281 + st8 [r16]=r29,16; /* save b0 */ \ 14.282 + st8 [r17]=r18,16; /* save ar.rsc value for "loadrs" */ \ 14.283 + cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \ 14.284 + ;; \ 14.285 +.mem.offset 0,0; st8.spill [r16]=r20,16; /* save original r1 */ \ 14.286 +.mem.offset 8,0; st8.spill [r17]=r12,16; \ 14.287 + adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \ 14.288 + ;; \ 14.289 +.mem.offset 0,0; st8.spill [r16]=r13,16; \ 14.290 +.mem.offset 8,0; st8.spill [r17]=r21,16; /* save ar.fpsr */ \ 14.291 + mov r13=IA64_KR(CURRENT); /* establish `current' */ \ 14.292 + ;; \ 14.293 +.mem.offset 0,0; st8.spill [r16]=r15,16; \ 14.294 +.mem.offset 8,0; st8.spill [r17]=r14,16; \ 14.295 + ;; \ 14.296 +.mem.offset 0,0; st8.spill [r16]=r2,16; \ 14.297 +.mem.offset 8,0; st8.spill [r17]=r3,16; \ 14.298 + adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ 14.299 + ;; \ 14.300 + EXTRA; \ 14.301 + movl r1=__gp; /* establish kernel global pointer */ \ 14.302 + ;; \ 14.303 + MINSTATE_END_SAVE_MIN 14.304 +#endif 14.305 + 14.306 +/* 14.307 + * SAVE_REST saves the remainder of pt_regs (with psr.ic on). 14.308 + * 14.309 + * Assumed state upon entry: 14.310 + * psr.ic: on 14.311 + * r2: points to &pt_regs.r16 14.312 + * r3: points to &pt_regs.r17 14.313 + * r8: contents of ar.ccv 14.314 + * r9: contents of ar.csd 14.315 + * r10: contents of ar.ssd 14.316 + * r11: FPSR_DEFAULT 14.317 + * 14.318 + * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST. 14.319 + */ 14.320 +#define SAVE_REST \ 14.321 +.mem.offset 0,0; st8.spill [r2]=r16,16; \ 14.322 +.mem.offset 8,0; st8.spill [r3]=r17,16; \ 14.323 + ;; \ 14.324 +.mem.offset 0,0; st8.spill [r2]=r18,16; \ 14.325 +.mem.offset 8,0; st8.spill [r3]=r19,16; \ 14.326 + ;; \ 14.327 +.mem.offset 0,0; st8.spill [r2]=r20,16; \ 14.328 +.mem.offset 8,0; st8.spill [r3]=r21,16; \ 14.329 + mov r18=b6; \ 14.330 + ;; \ 14.331 +.mem.offset 0,0; st8.spill [r2]=r22,16; \ 14.332 +.mem.offset 8,0; st8.spill [r3]=r23,16; \ 14.333 + mov r19=b7; \ 14.334 + ;; \ 14.335 +.mem.offset 0,0; st8.spill [r2]=r24,16; \ 14.336 +.mem.offset 8,0; st8.spill [r3]=r25,16; \ 14.337 + ;; \ 14.338 +.mem.offset 0,0; st8.spill [r2]=r26,16; \ 14.339 +.mem.offset 8,0; st8.spill [r3]=r27,16; \ 14.340 + ;; \ 14.341 +.mem.offset 0,0; st8.spill [r2]=r28,16; \ 14.342 +.mem.offset 8,0; st8.spill [r3]=r29,16; \ 14.343 + ;; \ 14.344 +.mem.offset 0,0; st8.spill [r2]=r30,16; \ 14.345 +.mem.offset 8,0; st8.spill [r3]=r31,32; \ 14.346 + ;; \ 14.347 + mov ar.fpsr=r11; /* M-unit */ \ 14.348 + st8 [r2]=r8,8; /* ar.ccv */ \ 14.349 + adds r24=PT(B6)-PT(F7),r3; \ 14.350 + ;; \ 14.351 + stf.spill [r2]=f6,32; \ 14.352 + stf.spill [r3]=f7,32; \ 14.353 + ;; \ 14.354 + stf.spill [r2]=f8,32; \ 14.355 + stf.spill [r3]=f9,32; \ 14.356 + ;; \ 14.357 + stf.spill [r2]=f10; \ 14.358 + stf.spill [r3]=f11; \ 14.359 + adds r25=PT(B7)-PT(F11),r3; \ 14.360 + ;; \ 14.361 + st8 [r24]=r18,16; /* b6 */ \ 14.362 + st8 [r25]=r19,16; /* b7 */ \ 14.363 + ;; \ 14.364 + st8 [r24]=r9; /* ar.csd */ \ 14.365 + st8 [r25]=r10; /* ar.ssd */ \ 14.366 + ;; 14.367 + 14.368 +#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover, mov r30=cr.ifs,) 14.369 +#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19) 14.370 +#ifdef CONFIG_XEN 14.371 +#define SAVE_MIN break 0;; /* FIXME: non-cover version only for ia32 support? */ 14.372 +#else 14.373 +#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, ) 14.374 +#endif
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S Wed Sep 21 09:06:30 2005 -0600 15.3 @@ -0,0 +1,73 @@ 15.4 +/* 15.5 + * ia64/xen/xenpal.S 15.6 + * 15.7 + * Alternate PAL routines for Xen. Heavily leveraged from 15.8 + * ia64/kernel/pal.S 15.9 + * 15.10 + * Copyright (C) 2005 Hewlett-Packard Co 15.11 + * Dan Magenheimer <dan.magenheimer@.hp.com> 15.12 + */ 15.13 + 15.14 +#include <asm/asmmacro.h> 15.15 +#include <asm/processor.h> 15.16 + 15.17 +GLOBAL_ENTRY(xen_pal_call_static) 15.18 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) 15.19 + alloc loc1 = ar.pfs,5,5,0,0 15.20 +#ifdef CONFIG_XEN 15.21 + movl r22=running_on_xen;; 15.22 + ld4 r22=[r22];; 15.23 + cmp.eq p7,p0=r22,r0 15.24 +(p7) br.cond.spnt.many __ia64_pal_call_static;; 15.25 +#endif 15.26 + movl loc2 = pal_entry_point 15.27 +1: { 15.28 + mov r28 = in0 15.29 + mov r29 = in1 15.30 + mov r8 = ip 15.31 + } 15.32 + ;; 15.33 + ld8 loc2 = [loc2] // loc2 <- entry point 15.34 + tbit.nz p6,p7 = in4, 0 15.35 + adds r8 = 1f-1b,r8 15.36 + mov loc4=ar.rsc // save RSE configuration 15.37 + ;; 15.38 + mov ar.rsc=0 // put RSE in enforced lazy, LE mode 15.39 + mov loc3 = psr 15.40 + mov loc0 = rp 15.41 + .body 15.42 + mov r30 = in2 15.43 + 15.44 +#ifdef CONFIG_XEN 15.45 + // this is low priority for paravirtualization, but is called 15.46 + // from the idle loop so confuses privop counting 15.47 + movl r31=XSI_PSR_IC 15.48 + ;; 15.49 +(p6) st8 [r31]=r0 15.50 + ;; 15.51 +(p7) adds r31=XSI_PSR_I-XSI_PSR_IC,r31 15.52 + ;; 15.53 +(p7) st4 [r31]=r0 15.54 + ;; 15.55 + mov r31 = in3 15.56 + mov b7 = loc2 15.57 + ;; 15.58 +#else 15.59 +(p6) rsm psr.i | psr.ic 15.60 + mov r31 = in3 15.61 + mov b7 = loc2 15.62 + 15.63 +(p7) rsm psr.i 15.64 + ;; 15.65 +(p6) srlz.i 15.66 +#endif 15.67 + mov rp = r8 15.68 + br.cond.sptk.many b7 15.69 +1: mov psr.l = loc3 15.70 + mov ar.rsc = loc4 // restore RSE configuration 15.71 + mov ar.pfs = loc1 15.72 + mov rp = loc0 15.73 + ;; 15.74 + srlz.d // seralize restoration of psr.l 15.75 + br.ret.sptk.many b0 15.76 +END(xen_pal_call_static)
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xensetup.S Wed Sep 21 09:06:30 2005 -0600 16.3 @@ -0,0 +1,27 @@ 16.4 +/* 16.5 + * Support routines for Xen 16.6 + * 16.7 + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com> 16.8 + */ 16.9 + 16.10 +#include <linux/config.h> 16.11 +#include <asm/processor.h> 16.12 +#include <asm/asmmacro.h> 16.13 + 16.14 + .data 16.15 + .align 8 16.16 + .globl running_on_xen 16.17 +running_on_xen: 16.18 + data4 0 16.19 + 16.20 + .text 16.21 +GLOBAL_ENTRY(early_xen_setup) 16.22 + mov r8=cr.dcr;; 16.23 + extr.u r8=r8,63,1 16.24 + movl r9=running_on_xen;; 16.25 + st4 [r9]=r8;; 16.26 + cmp.ne p7,p0=r8,r0;; 16.27 +(p7) movl r10=xen_ivt;; 16.28 +(p7) mov cr.iva=r10 16.29 + br.ret.sptk.many rp;; 16.30 +END(xen_init)
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/linux-2.6-xen-sparse/drivers/acpi/motherboard.c Wed Sep 21 09:06:30 2005 -0600 17.3 @@ -0,0 +1,178 @@ 17.4 +/* 17.5 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17.6 + * This program is free software; you can redistribute it and/or modify 17.7 + * it under the terms of the GNU General Public License as published by 17.8 + * the Free Software Foundation; either version 2 of the License, or (at 17.9 + * your option) any later version. 17.10 + * 17.11 + * This program is distributed in the hope that it will be useful, but 17.12 + * WITHOUT ANY WARRANTY; without even the implied warranty of 17.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17.14 + * General Public License for more details. 17.15 + * 17.16 + * You should have received a copy of the GNU General Public License along 17.17 + * with this program; if not, write to the Free Software Foundation, Inc., 17.18 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 17.19 + * 17.20 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17.21 + */ 17.22 + 17.23 +/* Purpose: Prevent PCMCIA cards from using motherboard resources. */ 17.24 + 17.25 +#include <linux/kernel.h> 17.26 +#include <linux/init.h> 17.27 +#include <linux/types.h> 17.28 +#include <linux/pci.h> 17.29 +#include <linux/ioport.h> 17.30 +#include <asm/io.h> 17.31 + 17.32 +#include <acpi/acpi_bus.h> 17.33 +#include <acpi/acpi_drivers.h> 17.34 + 17.35 +#define _COMPONENT ACPI_SYSTEM_COMPONENT 17.36 +ACPI_MODULE_NAME ("acpi_motherboard") 17.37 + 17.38 +/* Dell use PNP0C01 instead of PNP0C02 */ 17.39 +#define ACPI_MB_HID1 "PNP0C01" 17.40 +#define ACPI_MB_HID2 "PNP0C02" 17.41 + 17.42 +/** 17.43 + * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved 17.44 + * Doesn't care about the failure of 'request_region', since other may reserve 17.45 + * the io ports as well 17.46 + */ 17.47 +#define IS_RESERVED_ADDR(base, len) \ 17.48 + (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ 17.49 + && ((base) + (len) > PCIBIOS_MIN_IO)) 17.50 + 17.51 +/* 17.52 + * Clearing the flag (IORESOURCE_BUSY) allows drivers to use 17.53 + * the io ports if they really know they can use it, while 17.54 + * still preventing hotplug PCI devices from using it. 17.55 + */ 17.56 + 17.57 +static acpi_status 17.58 +acpi_reserve_io_ranges (struct acpi_resource *res, void *data) 17.59 +{ 17.60 + struct resource *requested_res = NULL; 17.61 + 17.62 + ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges"); 17.63 + 17.64 + if (res->id == ACPI_RSTYPE_IO) { 17.65 + struct acpi_resource_io *io_res = &res->data.io; 17.66 + 17.67 + if (io_res->min_base_address != io_res->max_base_address) 17.68 + return_VALUE(AE_OK); 17.69 + if (IS_RESERVED_ADDR(io_res->min_base_address, io_res->range_length)) { 17.70 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", 17.71 + io_res->min_base_address, 17.72 + io_res->min_base_address + io_res->range_length)); 17.73 + requested_res = request_region(io_res->min_base_address, 17.74 + io_res->range_length, "motherboard"); 17.75 + } 17.76 + } else if (res->id == ACPI_RSTYPE_FIXED_IO) { 17.77 + struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io; 17.78 + 17.79 + if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) { 17.80 + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n", 17.81 + fixed_io_res->base_address, 17.82 + fixed_io_res->base_address + fixed_io_res->range_length)); 17.83 + requested_res = request_region(fixed_io_res->base_address, 17.84 + fixed_io_res->range_length, "motherboard"); 17.85 + } 17.86 + } else { 17.87 + /* Memory mapped IO? */ 17.88 + } 17.89 + 17.90 + if (requested_res) 17.91 + requested_res->flags &= ~IORESOURCE_BUSY; 17.92 + return_VALUE(AE_OK); 17.93 +} 17.94 + 17.95 +static int acpi_motherboard_add (struct acpi_device *device) 17.96 +{ 17.97 + if (!device) 17.98 + return -EINVAL; 17.99 + acpi_walk_resources(device->handle, METHOD_NAME__CRS, 17.100 + acpi_reserve_io_ranges, NULL); 17.101 + 17.102 + return 0; 17.103 +} 17.104 + 17.105 +static struct acpi_driver acpi_motherboard_driver1 = { 17.106 + .name = "motherboard", 17.107 + .class = "", 17.108 + .ids = ACPI_MB_HID1, 17.109 + .ops = { 17.110 + .add = acpi_motherboard_add, 17.111 + }, 17.112 +}; 17.113 + 17.114 +static struct acpi_driver acpi_motherboard_driver2 = { 17.115 + .name = "motherboard", 17.116 + .class = "", 17.117 + .ids = ACPI_MB_HID2, 17.118 + .ops = { 17.119 + .add = acpi_motherboard_add, 17.120 + }, 17.121 +}; 17.122 + 17.123 +static void __init 17.124 +acpi_reserve_resources (void) 17.125 +{ 17.126 + if (!acpi_gbl_FADT) return; 17.127 + if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) 17.128 + request_region(acpi_gbl_FADT->xpm1a_evt_blk.address, 17.129 + acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK"); 17.130 + 17.131 + if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) 17.132 + request_region(acpi_gbl_FADT->xpm1b_evt_blk.address, 17.133 + acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK"); 17.134 + 17.135 + if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) 17.136 + request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address, 17.137 + acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK"); 17.138 + 17.139 + if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) 17.140 + request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address, 17.141 + acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK"); 17.142 + 17.143 + if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4) 17.144 + request_region(acpi_gbl_FADT->xpm_tmr_blk.address, 17.145 + 4, "PM_TMR"); 17.146 + 17.147 + if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len) 17.148 + request_region(acpi_gbl_FADT->xpm2_cnt_blk.address, 17.149 + acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK"); 17.150 + 17.151 + /* Length of GPE blocks must be a non-negative multiple of 2 */ 17.152 + 17.153 + if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len && 17.154 + !(acpi_gbl_FADT->gpe0_blk_len & 0x1)) 17.155 + request_region(acpi_gbl_FADT->xgpe0_blk.address, 17.156 + acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK"); 17.157 + 17.158 + if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len && 17.159 + !(acpi_gbl_FADT->gpe1_blk_len & 0x1)) 17.160 + request_region(acpi_gbl_FADT->xgpe1_blk.address, 17.161 + acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK"); 17.162 +} 17.163 + 17.164 +static int __init acpi_motherboard_init(void) 17.165 +{ 17.166 + acpi_bus_register_driver(&acpi_motherboard_driver1); 17.167 + acpi_bus_register_driver(&acpi_motherboard_driver2); 17.168 + /* 17.169 + * Guarantee motherboard IO reservation first 17.170 + * This module must run after scan.c 17.171 + */ 17.172 + if (!acpi_disabled) 17.173 + acpi_reserve_resources (); 17.174 + return 0; 17.175 +} 17.176 + 17.177 +/** 17.178 + * Reserve motherboard resources after PCI claim BARs, 17.179 + * but before PCI assign resources for uninitialized PCI devices 17.180 + */ 17.181 +fs_initcall(acpi_motherboard_init);
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/gcc_intrin.h Wed Sep 21 09:06:30 2005 -0600 18.3 @@ -0,0 +1,603 @@ 18.4 +#ifndef _ASM_IA64_GCC_INTRIN_H 18.5 +#define _ASM_IA64_GCC_INTRIN_H 18.6 +/* 18.7 + * 18.8 + * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com> 18.9 + * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com> 18.10 + */ 18.11 + 18.12 +#include <linux/compiler.h> 18.13 + 18.14 +/* define this macro to get some asm stmts included in 'c' files */ 18.15 +#define ASM_SUPPORTED 18.16 + 18.17 +/* Optimization barrier */ 18.18 +/* The "volatile" is due to gcc bugs */ 18.19 +#define ia64_barrier() asm volatile ("":::"memory") 18.20 + 18.21 +#define ia64_stop() asm volatile (";;"::) 18.22 + 18.23 +#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum)) 18.24 + 18.25 +#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum)) 18.26 + 18.27 +extern void ia64_bad_param_for_setreg (void); 18.28 +extern void ia64_bad_param_for_getreg (void); 18.29 + 18.30 +register unsigned long ia64_r13 asm ("r13") __attribute_used__; 18.31 + 18.32 +#define __ia64_setreg(regnum, val) \ 18.33 +({ \ 18.34 + switch (regnum) { \ 18.35 + case _IA64_REG_PSR_L: \ 18.36 + asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \ 18.37 + break; \ 18.38 + case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \ 18.39 + asm volatile ("mov ar%0=%1" :: \ 18.40 + "i" (regnum - _IA64_REG_AR_KR0), \ 18.41 + "r"(val): "memory"); \ 18.42 + break; \ 18.43 + case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \ 18.44 + asm volatile ("mov cr%0=%1" :: \ 18.45 + "i" (regnum - _IA64_REG_CR_DCR), \ 18.46 + "r"(val): "memory" ); \ 18.47 + break; \ 18.48 + case _IA64_REG_SP: \ 18.49 + asm volatile ("mov r12=%0" :: \ 18.50 + "r"(val): "memory"); \ 18.51 + break; \ 18.52 + case _IA64_REG_GP: \ 18.53 + asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \ 18.54 + break; \ 18.55 + default: \ 18.56 + ia64_bad_param_for_setreg(); \ 18.57 + break; \ 18.58 + } \ 18.59 +}) 18.60 + 18.61 +#define __ia64_getreg(regnum) \ 18.62 +({ \ 18.63 + __u64 ia64_intri_res; \ 18.64 + \ 18.65 + switch (regnum) { \ 18.66 + case _IA64_REG_GP: \ 18.67 + asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \ 18.68 + break; \ 18.69 + case _IA64_REG_IP: \ 18.70 + asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \ 18.71 + break; \ 18.72 + case _IA64_REG_PSR: \ 18.73 + asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \ 18.74 + break; \ 18.75 + case _IA64_REG_TP: /* for current() */ \ 18.76 + ia64_intri_res = ia64_r13; \ 18.77 + break; \ 18.78 + case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \ 18.79 + asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \ 18.80 + : "i"(regnum - _IA64_REG_AR_KR0)); \ 18.81 + break; \ 18.82 + case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \ 18.83 + asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \ 18.84 + : "i" (regnum - _IA64_REG_CR_DCR)); \ 18.85 + break; \ 18.86 + case _IA64_REG_SP: \ 18.87 + asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \ 18.88 + break; \ 18.89 + default: \ 18.90 + ia64_bad_param_for_getreg(); \ 18.91 + break; \ 18.92 + } \ 18.93 + ia64_intri_res; \ 18.94 +}) 18.95 + 18.96 +#define ia64_hint_pause 0 18.97 + 18.98 +#define __ia64_hint(mode) \ 18.99 +({ \ 18.100 + switch (mode) { \ 18.101 + case ia64_hint_pause: \ 18.102 + asm volatile ("hint @pause" ::: "memory"); \ 18.103 + break; \ 18.104 + } \ 18.105 +}) 18.106 + 18.107 + 18.108 +/* Integer values for mux1 instruction */ 18.109 +#define ia64_mux1_brcst 0 18.110 +#define ia64_mux1_mix 8 18.111 +#define ia64_mux1_shuf 9 18.112 +#define ia64_mux1_alt 10 18.113 +#define ia64_mux1_rev 11 18.114 + 18.115 +#define ia64_mux1(x, mode) \ 18.116 +({ \ 18.117 + __u64 ia64_intri_res; \ 18.118 + \ 18.119 + switch (mode) { \ 18.120 + case ia64_mux1_brcst: \ 18.121 + asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \ 18.122 + break; \ 18.123 + case ia64_mux1_mix: \ 18.124 + asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \ 18.125 + break; \ 18.126 + case ia64_mux1_shuf: \ 18.127 + asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \ 18.128 + break; \ 18.129 + case ia64_mux1_alt: \ 18.130 + asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \ 18.131 + break; \ 18.132 + case ia64_mux1_rev: \ 18.133 + asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \ 18.134 + break; \ 18.135 + } \ 18.136 + ia64_intri_res; \ 18.137 +}) 18.138 + 18.139 +#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 18.140 +# define ia64_popcnt(x) __builtin_popcountl(x) 18.141 +#else 18.142 +# define ia64_popcnt(x) \ 18.143 + ({ \ 18.144 + __u64 ia64_intri_res; \ 18.145 + asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \ 18.146 + \ 18.147 + ia64_intri_res; \ 18.148 + }) 18.149 +#endif 18.150 + 18.151 +#define ia64_getf_exp(x) \ 18.152 +({ \ 18.153 + long ia64_intri_res; \ 18.154 + \ 18.155 + asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \ 18.156 + \ 18.157 + ia64_intri_res; \ 18.158 +}) 18.159 + 18.160 +#define ia64_shrp(a, b, count) \ 18.161 +({ \ 18.162 + __u64 ia64_intri_res; \ 18.163 + asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \ 18.164 + ia64_intri_res; \ 18.165 +}) 18.166 + 18.167 +#define ia64_ldfs(regnum, x) \ 18.168 +({ \ 18.169 + register double __f__ asm ("f"#regnum); \ 18.170 + asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \ 18.171 +}) 18.172 + 18.173 +#define ia64_ldfd(regnum, x) \ 18.174 +({ \ 18.175 + register double __f__ asm ("f"#regnum); \ 18.176 + asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \ 18.177 +}) 18.178 + 18.179 +#define ia64_ldfe(regnum, x) \ 18.180 +({ \ 18.181 + register double __f__ asm ("f"#regnum); \ 18.182 + asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \ 18.183 +}) 18.184 + 18.185 +#define ia64_ldf8(regnum, x) \ 18.186 +({ \ 18.187 + register double __f__ asm ("f"#regnum); \ 18.188 + asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \ 18.189 +}) 18.190 + 18.191 +#define ia64_ldf_fill(regnum, x) \ 18.192 +({ \ 18.193 + register double __f__ asm ("f"#regnum); \ 18.194 + asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \ 18.195 +}) 18.196 + 18.197 +#define ia64_stfs(x, regnum) \ 18.198 +({ \ 18.199 + register double __f__ asm ("f"#regnum); \ 18.200 + asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ 18.201 +}) 18.202 + 18.203 +#define ia64_stfd(x, regnum) \ 18.204 +({ \ 18.205 + register double __f__ asm ("f"#regnum); \ 18.206 + asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ 18.207 +}) 18.208 + 18.209 +#define ia64_stfe(x, regnum) \ 18.210 +({ \ 18.211 + register double __f__ asm ("f"#regnum); \ 18.212 + asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ 18.213 +}) 18.214 + 18.215 +#define ia64_stf8(x, regnum) \ 18.216 +({ \ 18.217 + register double __f__ asm ("f"#regnum); \ 18.218 + asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ 18.219 +}) 18.220 + 18.221 +#define ia64_stf_spill(x, regnum) \ 18.222 +({ \ 18.223 + register double __f__ asm ("f"#regnum); \ 18.224 + asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ 18.225 +}) 18.226 + 18.227 +#define ia64_fetchadd4_acq(p, inc) \ 18.228 +({ \ 18.229 + \ 18.230 + __u64 ia64_intri_res; \ 18.231 + asm volatile ("fetchadd4.acq %0=[%1],%2" \ 18.232 + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ 18.233 + : "memory"); \ 18.234 + \ 18.235 + ia64_intri_res; \ 18.236 +}) 18.237 + 18.238 +#define ia64_fetchadd4_rel(p, inc) \ 18.239 +({ \ 18.240 + __u64 ia64_intri_res; \ 18.241 + asm volatile ("fetchadd4.rel %0=[%1],%2" \ 18.242 + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ 18.243 + : "memory"); \ 18.244 + \ 18.245 + ia64_intri_res; \ 18.246 +}) 18.247 + 18.248 +#define ia64_fetchadd8_acq(p, inc) \ 18.249 +({ \ 18.250 + \ 18.251 + __u64 ia64_intri_res; \ 18.252 + asm volatile ("fetchadd8.acq %0=[%1],%2" \ 18.253 + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ 18.254 + : "memory"); \ 18.255 + \ 18.256 + ia64_intri_res; \ 18.257 +}) 18.258 + 18.259 +#define ia64_fetchadd8_rel(p, inc) \ 18.260 +({ \ 18.261 + __u64 ia64_intri_res; \ 18.262 + asm volatile ("fetchadd8.rel %0=[%1],%2" \ 18.263 + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ 18.264 + : "memory"); \ 18.265 + \ 18.266 + ia64_intri_res; \ 18.267 +}) 18.268 + 18.269 +#define ia64_xchg1(ptr,x) \ 18.270 +({ \ 18.271 + __u64 ia64_intri_res; \ 18.272 + asm volatile ("xchg1 %0=[%1],%2" \ 18.273 + : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \ 18.274 + ia64_intri_res; \ 18.275 +}) 18.276 + 18.277 +#define ia64_xchg2(ptr,x) \ 18.278 +({ \ 18.279 + __u64 ia64_intri_res; \ 18.280 + asm volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \ 18.281 + : "r" (ptr), "r" (x) : "memory"); \ 18.282 + ia64_intri_res; \ 18.283 +}) 18.284 + 18.285 +#define ia64_xchg4(ptr,x) \ 18.286 +({ \ 18.287 + __u64 ia64_intri_res; \ 18.288 + asm volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \ 18.289 + : "r" (ptr), "r" (x) : "memory"); \ 18.290 + ia64_intri_res; \ 18.291 +}) 18.292 + 18.293 +#define ia64_xchg8(ptr,x) \ 18.294 +({ \ 18.295 + __u64 ia64_intri_res; \ 18.296 + asm volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \ 18.297 + : "r" (ptr), "r" (x) : "memory"); \ 18.298 + ia64_intri_res; \ 18.299 +}) 18.300 + 18.301 +#define ia64_cmpxchg1_acq(ptr, new, old) \ 18.302 +({ \ 18.303 + __u64 ia64_intri_res; \ 18.304 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.305 + asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \ 18.306 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.307 + ia64_intri_res; \ 18.308 +}) 18.309 + 18.310 +#define ia64_cmpxchg1_rel(ptr, new, old) \ 18.311 +({ \ 18.312 + __u64 ia64_intri_res; \ 18.313 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.314 + asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \ 18.315 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.316 + ia64_intri_res; \ 18.317 +}) 18.318 + 18.319 +#define ia64_cmpxchg2_acq(ptr, new, old) \ 18.320 +({ \ 18.321 + __u64 ia64_intri_res; \ 18.322 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.323 + asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \ 18.324 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.325 + ia64_intri_res; \ 18.326 +}) 18.327 + 18.328 +#define ia64_cmpxchg2_rel(ptr, new, old) \ 18.329 +({ \ 18.330 + __u64 ia64_intri_res; \ 18.331 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.332 + \ 18.333 + asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \ 18.334 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.335 + ia64_intri_res; \ 18.336 +}) 18.337 + 18.338 +#define ia64_cmpxchg4_acq(ptr, new, old) \ 18.339 +({ \ 18.340 + __u64 ia64_intri_res; \ 18.341 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.342 + asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \ 18.343 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.344 + ia64_intri_res; \ 18.345 +}) 18.346 + 18.347 +#define ia64_cmpxchg4_rel(ptr, new, old) \ 18.348 +({ \ 18.349 + __u64 ia64_intri_res; \ 18.350 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.351 + asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \ 18.352 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.353 + ia64_intri_res; \ 18.354 +}) 18.355 + 18.356 +#define ia64_cmpxchg8_acq(ptr, new, old) \ 18.357 +({ \ 18.358 + __u64 ia64_intri_res; \ 18.359 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.360 + asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \ 18.361 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.362 + ia64_intri_res; \ 18.363 +}) 18.364 + 18.365 +#define ia64_cmpxchg8_rel(ptr, new, old) \ 18.366 +({ \ 18.367 + __u64 ia64_intri_res; \ 18.368 + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ 18.369 + \ 18.370 + asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \ 18.371 + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ 18.372 + ia64_intri_res; \ 18.373 +}) 18.374 + 18.375 +#define ia64_mf() asm volatile ("mf" ::: "memory") 18.376 +#define ia64_mfa() asm volatile ("mf.a" ::: "memory") 18.377 + 18.378 +#define ia64_invala() asm volatile ("invala" ::: "memory") 18.379 + 18.380 +#define __ia64_thash(addr) \ 18.381 +({ \ 18.382 + __u64 ia64_intri_res; \ 18.383 + asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \ 18.384 + ia64_intri_res; \ 18.385 +}) 18.386 + 18.387 +#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory") 18.388 +#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory"); 18.389 + 18.390 +#ifdef HAVE_SERIALIZE_DIRECTIVE 18.391 +# define ia64_dv_serialize_data() asm volatile (".serialize.data"); 18.392 +# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction"); 18.393 +#else 18.394 +# define ia64_dv_serialize_data() 18.395 +# define ia64_dv_serialize_instruction() 18.396 +#endif 18.397 + 18.398 +#define ia64_nop(x) asm volatile ("nop %0"::"i"(x)); 18.399 + 18.400 +#define __ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory") 18.401 + 18.402 +#define __ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory") 18.403 + 18.404 + 18.405 +#define __ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \ 18.406 + :: "r"(trnum), "r"(addr) : "memory") 18.407 + 18.408 +#define __ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \ 18.409 + :: "r"(trnum), "r"(addr) : "memory") 18.410 + 18.411 +#define __ia64_tpa(addr) \ 18.412 +({ \ 18.413 + __u64 ia64_pa; \ 18.414 + asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \ 18.415 + ia64_pa; \ 18.416 +}) 18.417 + 18.418 +#define __ia64_set_dbr(index, val) \ 18.419 + asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory") 18.420 + 18.421 +#define __ia64_set_ibr(index, val) \ 18.422 + asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory") 18.423 + 18.424 +#define __ia64_set_pkr(index, val) \ 18.425 + asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory") 18.426 + 18.427 +#define __ia64_set_pmc(index, val) \ 18.428 + asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory") 18.429 + 18.430 +#define __ia64_set_pmd(index, val) \ 18.431 + asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory") 18.432 + 18.433 +#define __ia64_set_rr(index, val) \ 18.434 + asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory"); 18.435 + 18.436 +#define __ia64_get_cpuid(index) \ 18.437 +({ \ 18.438 + __u64 ia64_intri_res; \ 18.439 + asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \ 18.440 + ia64_intri_res; \ 18.441 +}) 18.442 + 18.443 +#define __ia64_get_dbr(index) \ 18.444 +({ \ 18.445 + __u64 ia64_intri_res; \ 18.446 + asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 18.447 + ia64_intri_res; \ 18.448 +}) 18.449 + 18.450 +#define __ia64_get_ibr(index) \ 18.451 +({ \ 18.452 + __u64 ia64_intri_res; \ 18.453 + asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 18.454 + ia64_intri_res; \ 18.455 +}) 18.456 + 18.457 +#define __ia64_get_pkr(index) \ 18.458 +({ \ 18.459 + __u64 ia64_intri_res; \ 18.460 + asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 18.461 + ia64_intri_res; \ 18.462 +}) 18.463 + 18.464 +#define __ia64_get_pmc(index) \ 18.465 +({ \ 18.466 + __u64 ia64_intri_res; \ 18.467 + asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 18.468 + ia64_intri_res; \ 18.469 +}) 18.470 + 18.471 + 18.472 +#define __ia64_get_pmd(index) \ 18.473 +({ \ 18.474 + __u64 ia64_intri_res; \ 18.475 + asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ 18.476 + ia64_intri_res; \ 18.477 +}) 18.478 + 18.479 +#define __ia64_get_rr(index) \ 18.480 +({ \ 18.481 + __u64 ia64_intri_res; \ 18.482 + asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \ 18.483 + ia64_intri_res; \ 18.484 +}) 18.485 + 18.486 +#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory") 18.487 + 18.488 + 18.489 +#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory") 18.490 + 18.491 +#define __ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory") 18.492 +#define __ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory") 18.493 +#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory") 18.494 +#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory") 18.495 + 18.496 +#define __ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr)) 18.497 + 18.498 +#define __ia64_ptcga(addr, size) \ 18.499 +do { \ 18.500 + asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \ 18.501 + ia64_dv_serialize_data(); \ 18.502 +} while (0) 18.503 + 18.504 +#define __ia64_ptcl(addr, size) \ 18.505 +do { \ 18.506 + asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory"); \ 18.507 + ia64_dv_serialize_data(); \ 18.508 +} while (0) 18.509 + 18.510 +#define __ia64_ptri(addr, size) \ 18.511 + asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory") 18.512 + 18.513 +#define __ia64_ptrd(addr, size) \ 18.514 + asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory") 18.515 + 18.516 +/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */ 18.517 + 18.518 +#define ia64_lfhint_none 0 18.519 +#define ia64_lfhint_nt1 1 18.520 +#define ia64_lfhint_nt2 2 18.521 +#define ia64_lfhint_nta 3 18.522 + 18.523 +#define ia64_lfetch(lfhint, y) \ 18.524 +({ \ 18.525 + switch (lfhint) { \ 18.526 + case ia64_lfhint_none: \ 18.527 + asm volatile ("lfetch [%0]" : : "r"(y)); \ 18.528 + break; \ 18.529 + case ia64_lfhint_nt1: \ 18.530 + asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \ 18.531 + break; \ 18.532 + case ia64_lfhint_nt2: \ 18.533 + asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \ 18.534 + break; \ 18.535 + case ia64_lfhint_nta: \ 18.536 + asm volatile ("lfetch.nta [%0]" : : "r"(y)); \ 18.537 + break; \ 18.538 + } \ 18.539 +}) 18.540 + 18.541 +#define ia64_lfetch_excl(lfhint, y) \ 18.542 +({ \ 18.543 + switch (lfhint) { \ 18.544 + case ia64_lfhint_none: \ 18.545 + asm volatile ("lfetch.excl [%0]" :: "r"(y)); \ 18.546 + break; \ 18.547 + case ia64_lfhint_nt1: \ 18.548 + asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \ 18.549 + break; \ 18.550 + case ia64_lfhint_nt2: \ 18.551 + asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \ 18.552 + break; \ 18.553 + case ia64_lfhint_nta: \ 18.554 + asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \ 18.555 + break; \ 18.556 + } \ 18.557 +}) 18.558 + 18.559 +#define ia64_lfetch_fault(lfhint, y) \ 18.560 +({ \ 18.561 + switch (lfhint) { \ 18.562 + case ia64_lfhint_none: \ 18.563 + asm volatile ("lfetch.fault [%0]" : : "r"(y)); \ 18.564 + break; \ 18.565 + case ia64_lfhint_nt1: \ 18.566 + asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \ 18.567 + break; \ 18.568 + case ia64_lfhint_nt2: \ 18.569 + asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \ 18.570 + break; \ 18.571 + case ia64_lfhint_nta: \ 18.572 + asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \ 18.573 + break; \ 18.574 + } \ 18.575 +}) 18.576 + 18.577 +#define ia64_lfetch_fault_excl(lfhint, y) \ 18.578 +({ \ 18.579 + switch (lfhint) { \ 18.580 + case ia64_lfhint_none: \ 18.581 + asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \ 18.582 + break; \ 18.583 + case ia64_lfhint_nt1: \ 18.584 + asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \ 18.585 + break; \ 18.586 + case ia64_lfhint_nt2: \ 18.587 + asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \ 18.588 + break; \ 18.589 + case ia64_lfhint_nta: \ 18.590 + asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \ 18.591 + break; \ 18.592 + } \ 18.593 +}) 18.594 + 18.595 +#define __ia64_intrin_local_irq_restore(x) \ 18.596 +do { \ 18.597 + asm volatile (";; cmp.ne p6,p7=%0,r0;;" \ 18.598 + "(p6) ssm psr.i;" \ 18.599 + "(p7) rsm psr.i;;" \ 18.600 + "(p6) srlz.d" \ 18.601 + :: "r"((x)) : "p6", "p7", "memory"); \ 18.602 +} while (0) 18.603 + 18.604 +#define __ia64_get_psr_i() (__ia64_getreg(_IA64_REG_PSR) & 0x4000UL) 18.605 + 18.606 +#endif /* _ASM_IA64_GCC_INTRIN_H */
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/intel_intrin.h Wed Sep 21 09:06:30 2005 -0600 19.3 @@ -0,0 +1,259 @@ 19.4 +#ifndef _ASM_IA64_INTEL_INTRIN_H 19.5 +#define _ASM_IA64_INTEL_INTRIN_H 19.6 +/* 19.7 + * Intel Compiler Intrinsics 19.8 + * 19.9 + * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com> 19.10 + * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com> 19.11 + * 19.12 + */ 19.13 +#include <asm/types.h> 19.14 + 19.15 +void __lfetch(int lfhint, void *y); 19.16 +void __lfetch_excl(int lfhint, void *y); 19.17 +void __lfetch_fault(int lfhint, void *y); 19.18 +void __lfetch_fault_excl(int lfhint, void *y); 19.19 + 19.20 +/* In the following, whichFloatReg should be an integer from 0-127 */ 19.21 +void __ldfs(const int whichFloatReg, void *src); 19.22 +void __ldfd(const int whichFloatReg, void *src); 19.23 +void __ldfe(const int whichFloatReg, void *src); 19.24 +void __ldf8(const int whichFloatReg, void *src); 19.25 +void __ldf_fill(const int whichFloatReg, void *src); 19.26 +void __stfs(void *dst, const int whichFloatReg); 19.27 +void __stfd(void *dst, const int whichFloatReg); 19.28 +void __stfe(void *dst, const int whichFloatReg); 19.29 +void __stf8(void *dst, const int whichFloatReg); 19.30 +void __stf_spill(void *dst, const int whichFloatReg); 19.31 + 19.32 +void __st1_rel(void *dst, const __s8 value); 19.33 +void __st2_rel(void *dst, const __s16 value); 19.34 +void __st4_rel(void *dst, const __s32 value); 19.35 +void __st8_rel(void *dst, const __s64 value); 19.36 +__u8 __ld1_acq(void *src); 19.37 +__u16 __ld2_acq(void *src); 19.38 +__u32 __ld4_acq(void *src); 19.39 +__u64 __ld8_acq(void *src); 19.40 + 19.41 +__u64 __fetchadd4_acq(__u32 *addend, const int increment); 19.42 +__u64 __fetchadd4_rel(__u32 *addend, const int increment); 19.43 +__u64 __fetchadd8_acq(__u64 *addend, const int increment); 19.44 +__u64 __fetchadd8_rel(__u64 *addend, const int increment); 19.45 + 19.46 +__u64 __getf_exp(double d); 19.47 + 19.48 +/* OS Related Itanium(R) Intrinsics */ 19.49 + 19.50 +/* The names to use for whichReg and whichIndReg below come from 19.51 + the include file asm/ia64regs.h */ 19.52 + 19.53 +__u64 __getIndReg(const int whichIndReg, __s64 index); 19.54 +__u64 __getReg(const int whichReg); 19.55 + 19.56 +void __setIndReg(const int whichIndReg, __s64 index, __u64 value); 19.57 +void __setReg(const int whichReg, __u64 value); 19.58 + 19.59 +void __mf(void); 19.60 +void __mfa(void); 19.61 +void __synci(void); 19.62 +void __itcd(__s64 pa); 19.63 +void __itci(__s64 pa); 19.64 +void __itrd(__s64 whichTransReg, __s64 pa); 19.65 +void __itri(__s64 whichTransReg, __s64 pa); 19.66 +void __ptce(__s64 va); 19.67 +void __ptcl(__s64 va, __s64 pagesz); 19.68 +void __ptcg(__s64 va, __s64 pagesz); 19.69 +void __ptcga(__s64 va, __s64 pagesz); 19.70 +void __ptri(__s64 va, __s64 pagesz); 19.71 +void __ptrd(__s64 va, __s64 pagesz); 19.72 +void __invala (void); 19.73 +void __invala_gr(const int whichGeneralReg /* 0-127 */ ); 19.74 +void __invala_fr(const int whichFloatReg /* 0-127 */ ); 19.75 +void __nop(const int); 19.76 +void __fc(__u64 *addr); 19.77 +void __sum(int mask); 19.78 +void __rum(int mask); 19.79 +void __ssm(int mask); 19.80 +void __rsm(int mask); 19.81 +__u64 __thash(__s64); 19.82 +__u64 __ttag(__s64); 19.83 +__s64 __tpa(__s64); 19.84 + 19.85 +/* Intrinsics for implementing get/put_user macros */ 19.86 +void __st_user(const char *tableName, __u64 addr, char size, char relocType, __u64 val); 19.87 +void __ld_user(const char *tableName, __u64 addr, char size, char relocType); 19.88 + 19.89 +/* This intrinsic does not generate code, it creates a barrier across which 19.90 + * the compiler will not schedule data access instructions. 19.91 + */ 19.92 +void __memory_barrier(void); 19.93 + 19.94 +void __isrlz(void); 19.95 +void __dsrlz(void); 19.96 + 19.97 +__u64 _m64_mux1(__u64 a, const int n); 19.98 +__u64 __thash(__u64); 19.99 + 19.100 +/* Lock and Atomic Operation Related Intrinsics */ 19.101 +__u64 _InterlockedExchange8(volatile __u8 *trgt, __u8 value); 19.102 +__u64 _InterlockedExchange16(volatile __u16 *trgt, __u16 value); 19.103 +__s64 _InterlockedExchange(volatile __u32 *trgt, __u32 value); 19.104 +__s64 _InterlockedExchange64(volatile __u64 *trgt, __u64 value); 19.105 + 19.106 +__u64 _InterlockedCompareExchange8_rel(volatile __u8 *dest, __u64 xchg, __u64 comp); 19.107 +__u64 _InterlockedCompareExchange8_acq(volatile __u8 *dest, __u64 xchg, __u64 comp); 19.108 +__u64 _InterlockedCompareExchange16_rel(volatile __u16 *dest, __u64 xchg, __u64 comp); 19.109 +__u64 _InterlockedCompareExchange16_acq(volatile __u16 *dest, __u64 xchg, __u64 comp); 19.110 +__u64 _InterlockedCompareExchange_rel(volatile __u32 *dest, __u64 xchg, __u64 comp); 19.111 +__u64 _InterlockedCompareExchange_acq(volatile __u32 *dest, __u64 xchg, __u64 comp); 19.112 +__u64 _InterlockedCompareExchange64_rel(volatile __u64 *dest, __u64 xchg, __u64 comp); 19.113 +__u64 _InterlockedCompareExchange64_acq(volatile __u64 *dest, __u64 xchg, __u64 comp); 19.114 + 19.115 +__s64 _m64_dep_mi(const int v, __s64 s, const int p, const int len); 19.116 +__s64 _m64_shrp(__s64 a, __s64 b, const int count); 19.117 +__s64 _m64_popcnt(__s64 a); 19.118 + 19.119 +#define ia64_barrier() __memory_barrier() 19.120 + 19.121 +#define ia64_stop() /* Nothing: As of now stop bit is generated for each 19.122 + * intrinsic 19.123 + */ 19.124 + 19.125 +#define __ia64_getreg __getReg 19.126 +#define __ia64_setreg __setReg 19.127 + 19.128 +#define __ia64_hint(x) 19.129 + 19.130 +#define ia64_mux1_brcst 0 19.131 +#define ia64_mux1_mix 8 19.132 +#define ia64_mux1_shuf 9 19.133 +#define ia64_mux1_alt 10 19.134 +#define ia64_mux1_rev 11 19.135 + 19.136 +#define ia64_mux1 _m64_mux1 19.137 +#define ia64_popcnt _m64_popcnt 19.138 +#define ia64_getf_exp __getf_exp 19.139 +#define ia64_shrp _m64_shrp 19.140 + 19.141 +#define __ia64_tpa __tpa 19.142 +#define ia64_invala __invala 19.143 +#define ia64_invala_gr __invala_gr 19.144 +#define ia64_invala_fr __invala_fr 19.145 +#define ia64_nop __nop 19.146 +#define ia64_sum __sum 19.147 +#define __ia64_ssm __ssm 19.148 +#define ia64_rum __rum 19.149 +#define __ia64_rsm __rsm 19.150 +#define __ia64_fc __fc 19.151 + 19.152 +#define ia64_ldfs __ldfs 19.153 +#define ia64_ldfd __ldfd 19.154 +#define ia64_ldfe __ldfe 19.155 +#define ia64_ldf8 __ldf8 19.156 +#define ia64_ldf_fill __ldf_fill 19.157 + 19.158 +#define ia64_stfs __stfs 19.159 +#define ia64_stfd __stfd 19.160 +#define ia64_stfe __stfe 19.161 +#define ia64_stf8 __stf8 19.162 +#define ia64_stf_spill __stf_spill 19.163 + 19.164 +#define ia64_mf __mf 19.165 +#define ia64_mfa __mfa 19.166 + 19.167 +#define ia64_fetchadd4_acq __fetchadd4_acq 19.168 +#define ia64_fetchadd4_rel __fetchadd4_rel 19.169 +#define ia64_fetchadd8_acq __fetchadd8_acq 19.170 +#define ia64_fetchadd8_rel __fetchadd8_rel 19.171 + 19.172 +#define ia64_xchg1 _InterlockedExchange8 19.173 +#define ia64_xchg2 _InterlockedExchange16 19.174 +#define ia64_xchg4 _InterlockedExchange 19.175 +#define ia64_xchg8 _InterlockedExchange64 19.176 + 19.177 +#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel 19.178 +#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq 19.179 +#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel 19.180 +#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq 19.181 +#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel 19.182 +#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq 19.183 +#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel 19.184 +#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq 19.185 + 19.186 +#define __ia64_set_dbr(index, val) \ 19.187 + __setIndReg(_IA64_REG_INDR_DBR, index, val) 19.188 +#define __ia64_set_ibr(index, val) \ 19.189 + __setIndReg(_IA64_REG_INDR_IBR, index, val) 19.190 +#define __ia64_set_pkr(index, val) \ 19.191 + __setIndReg(_IA64_REG_INDR_PKR, index, val) 19.192 +#define __ia64_set_pmc(index, val) \ 19.193 + __setIndReg(_IA64_REG_INDR_PMC, index, val) 19.194 +#define __ia64_set_pmd(index, val) \ 19.195 + __setIndReg(_IA64_REG_INDR_PMD, index, val) 19.196 +#define __ia64_set_rr(index, val) \ 19.197 + __setIndReg(_IA64_REG_INDR_RR, index, val) 19.198 + 19.199 +#define __ia64_get_cpuid(index) __getIndReg(_IA64_REG_INDR_CPUID, index) 19.200 +#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index) 19.201 +#define __ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index) 19.202 +#define __ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index) 19.203 +#define __ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index) 19.204 +#define __ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index) 19.205 +#define __ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index) 19.206 + 19.207 +#define ia64_srlz_d __dsrlz 19.208 +#define ia64_srlz_i __isrlz 19.209 + 19.210 +#define ia64_dv_serialize_data() 19.211 +#define ia64_dv_serialize_instruction() 19.212 + 19.213 +#define ia64_st1_rel __st1_rel 19.214 +#define ia64_st2_rel __st2_rel 19.215 +#define ia64_st4_rel __st4_rel 19.216 +#define ia64_st8_rel __st8_rel 19.217 + 19.218 +#define ia64_ld1_acq __ld1_acq 19.219 +#define ia64_ld2_acq __ld2_acq 19.220 +#define ia64_ld4_acq __ld4_acq 19.221 +#define ia64_ld8_acq __ld8_acq 19.222 + 19.223 +#define ia64_sync_i __synci 19.224 +#define __ia64_thash __thash 19.225 +#define __ia64_ttag __ttag 19.226 +#define __ia64_itcd __itcd 19.227 +#define __ia64_itci __itci 19.228 +#define __ia64_itrd __itrd 19.229 +#define __ia64_itri __itri 19.230 +#define __ia64_ptce __ptce 19.231 +#define __ia64_ptcl __ptcl 19.232 +#define __ia64_ptcg __ptcg 19.233 +#define __ia64_ptcga __ptcga 19.234 +#define __ia64_ptri __ptri 19.235 +#define __ia64_ptrd __ptrd 19.236 +#define ia64_dep_mi _m64_dep_mi 19.237 + 19.238 +/* Values for lfhint in __lfetch and __lfetch_fault */ 19.239 + 19.240 +#define ia64_lfhint_none 0 19.241 +#define ia64_lfhint_nt1 1 19.242 +#define ia64_lfhint_nt2 2 19.243 +#define ia64_lfhint_nta 3 19.244 + 19.245 +#define ia64_lfetch __lfetch 19.246 +#define ia64_lfetch_excl __lfetch_excl 19.247 +#define ia64_lfetch_fault __lfetch_fault 19.248 +#define ia64_lfetch_fault_excl __lfetch_fault_excl 19.249 + 19.250 +#define __ia64_intrin_local_irq_restore(x) \ 19.251 +do { \ 19.252 + if ((x) != 0) { \ 19.253 + __ia64_ssm(IA64_PSR_I); \ 19.254 + ia64_srlz_d(); \ 19.255 + } else { \ 19.256 + __ia64_rsm(IA64_PSR_I); \ 19.257 + } \ 19.258 +} while (0) 19.259 + 19.260 +#define __ia64_get_psr_i() (__ia64_getreg(_IA64_REG_PSR) & 0x4000UL) 19.261 + 19.262 +#endif /* _ASM_IA64_INTEL_INTRIN_H */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/pal.h Wed Sep 21 09:06:30 2005 -0600 20.3 @@ -0,0 +1,1633 @@ 20.4 +#ifndef _ASM_IA64_PAL_H 20.5 +#define _ASM_IA64_PAL_H 20.6 + 20.7 +/* 20.8 + * Processor Abstraction Layer definitions. 20.9 + * 20.10 + * This is based on Intel IA-64 Architecture Software Developer's Manual rev 1.0 20.11 + * chapter 11 IA-64 Processor Abstraction Layer 20.12 + * 20.13 + * Copyright (C) 1998-2001 Hewlett-Packard Co 20.14 + * David Mosberger-Tang <davidm@hpl.hp.com> 20.15 + * Stephane Eranian <eranian@hpl.hp.com> 20.16 + * Copyright (C) 1999 VA Linux Systems 20.17 + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> 20.18 + * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com> 20.19 + * 20.20 + * 99/10/01 davidm Make sure we pass zero for reserved parameters. 20.21 + * 00/03/07 davidm Updated pal_cache_flush() to be in sync with PAL v2.6. 20.22 + * 00/03/23 cfleck Modified processor min-state save area to match updated PAL & SAL info 20.23 + * 00/05/24 eranian Updated to latest PAL spec, fix structures bugs, added 20.24 + * 00/05/25 eranian Support for stack calls, and static physical calls 20.25 + * 00/06/18 eranian Support for stacked physical calls 20.26 + */ 20.27 + 20.28 +/* 20.29 + * Note that some of these calls use a static-register only calling 20.30 + * convention which has nothing to do with the regular calling 20.31 + * convention. 20.32 + */ 20.33 +#define PAL_CACHE_FLUSH 1 /* flush i/d cache */ 20.34 +#define PAL_CACHE_INFO 2 /* get detailed i/d cache info */ 20.35 +#define PAL_CACHE_INIT 3 /* initialize i/d cache */ 20.36 +#define PAL_CACHE_SUMMARY 4 /* get summary of cache heirarchy */ 20.37 +#define PAL_MEM_ATTRIB 5 /* list supported memory attributes */ 20.38 +#define PAL_PTCE_INFO 6 /* purge TLB info */ 20.39 +#define PAL_VM_INFO 7 /* return supported virtual memory features */ 20.40 +#define PAL_VM_SUMMARY 8 /* return summary on supported vm features */ 20.41 +#define PAL_BUS_GET_FEATURES 9 /* return processor bus interface features settings */ 20.42 +#define PAL_BUS_SET_FEATURES 10 /* set processor bus features */ 20.43 +#define PAL_DEBUG_INFO 11 /* get number of debug registers */ 20.44 +#define PAL_FIXED_ADDR 12 /* get fixed component of processors's directed address */ 20.45 +#define PAL_FREQ_BASE 13 /* base frequency of the platform */ 20.46 +#define PAL_FREQ_RATIOS 14 /* ratio of processor, bus and ITC frequency */ 20.47 +#define PAL_PERF_MON_INFO 15 /* return performance monitor info */ 20.48 +#define PAL_PLATFORM_ADDR 16 /* set processor interrupt block and IO port space addr */ 20.49 +#define PAL_PROC_GET_FEATURES 17 /* get configurable processor features & settings */ 20.50 +#define PAL_PROC_SET_FEATURES 18 /* enable/disable configurable processor features */ 20.51 +#define PAL_RSE_INFO 19 /* return rse information */ 20.52 +#define PAL_VERSION 20 /* return version of PAL code */ 20.53 +#define PAL_MC_CLEAR_LOG 21 /* clear all processor log info */ 20.54 +#define PAL_MC_DRAIN 22 /* drain operations which could result in an MCA */ 20.55 +#define PAL_MC_EXPECTED 23 /* set/reset expected MCA indicator */ 20.56 +#define PAL_MC_DYNAMIC_STATE 24 /* get processor dynamic state */ 20.57 +#define PAL_MC_ERROR_INFO 25 /* get processor MCA info and static state */ 20.58 +#define PAL_MC_RESUME 26 /* Return to interrupted process */ 20.59 +#define PAL_MC_REGISTER_MEM 27 /* Register memory for PAL to use during MCAs and inits */ 20.60 +#define PAL_HALT 28 /* enter the low power HALT state */ 20.61 +#define PAL_HALT_LIGHT 29 /* enter the low power light halt state*/ 20.62 +#define PAL_COPY_INFO 30 /* returns info needed to relocate PAL */ 20.63 +#define PAL_CACHE_LINE_INIT 31 /* init tags & data of cache line */ 20.64 +#define PAL_PMI_ENTRYPOINT 32 /* register PMI memory entry points with the processor */ 20.65 +#define PAL_ENTER_IA_32_ENV 33 /* enter IA-32 system environment */ 20.66 +#define PAL_VM_PAGE_SIZE 34 /* return vm TC and page walker page sizes */ 20.67 + 20.68 +#define PAL_MEM_FOR_TEST 37 /* get amount of memory needed for late processor test */ 20.69 +#define PAL_CACHE_PROT_INFO 38 /* get i/d cache protection info */ 20.70 +#define PAL_REGISTER_INFO 39 /* return AR and CR register information*/ 20.71 +#define PAL_SHUTDOWN 40 /* enter processor shutdown state */ 20.72 +#define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */ 20.73 +#define PAL_LOGICAL_TO_PHYSICAL 42 /* returns information on logical to physical processor mapping */ 20.74 + 20.75 +#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ 20.76 +#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ 20.77 +#define PAL_TEST_PROC 258 /* perform late processor self-test */ 20.78 +#define PAL_CACHE_READ 259 /* read tag & data of cacheline for diagnostic testing */ 20.79 +#define PAL_CACHE_WRITE 260 /* write tag & data of cacheline for diagnostic testing */ 20.80 +#define PAL_VM_TR_READ 261 /* read contents of translation register */ 20.81 + 20.82 +#ifndef __ASSEMBLY__ 20.83 + 20.84 +#include <linux/types.h> 20.85 +#include <asm/processor.h> 20.86 +#include <asm/fpu.h> 20.87 + 20.88 +/* 20.89 + * Data types needed to pass information into PAL procedures and 20.90 + * interpret information returned by them. 20.91 + */ 20.92 + 20.93 +/* Return status from the PAL procedure */ 20.94 +typedef s64 pal_status_t; 20.95 + 20.96 +#define PAL_STATUS_SUCCESS 0 /* No error */ 20.97 +#define PAL_STATUS_UNIMPLEMENTED (-1) /* Unimplemented procedure */ 20.98 +#define PAL_STATUS_EINVAL (-2) /* Invalid argument */ 20.99 +#define PAL_STATUS_ERROR (-3) /* Error */ 20.100 +#define PAL_STATUS_CACHE_INIT_FAIL (-4) /* Could not initialize the 20.101 + * specified level and type of 20.102 + * cache without sideeffects 20.103 + * and "restrict" was 1 20.104 + */ 20.105 + 20.106 +/* Processor cache level in the heirarchy */ 20.107 +typedef u64 pal_cache_level_t; 20.108 +#define PAL_CACHE_LEVEL_L0 0 /* L0 */ 20.109 +#define PAL_CACHE_LEVEL_L1 1 /* L1 */ 20.110 +#define PAL_CACHE_LEVEL_L2 2 /* L2 */ 20.111 + 20.112 + 20.113 +/* Processor cache type at a particular level in the heirarchy */ 20.114 + 20.115 +typedef u64 pal_cache_type_t; 20.116 +#define PAL_CACHE_TYPE_INSTRUCTION 1 /* Instruction cache */ 20.117 +#define PAL_CACHE_TYPE_DATA 2 /* Data or unified cache */ 20.118 +#define PAL_CACHE_TYPE_INSTRUCTION_DATA 3 /* Both Data & Instruction */ 20.119 + 20.120 + 20.121 +#define PAL_CACHE_FLUSH_INVALIDATE 1 /* Invalidate clean lines */ 20.122 +#define PAL_CACHE_FLUSH_CHK_INTRS 2 /* check for interrupts/mc while flushing */ 20.123 + 20.124 +/* Processor cache line size in bytes */ 20.125 +typedef int pal_cache_line_size_t; 20.126 + 20.127 +/* Processor cache line state */ 20.128 +typedef u64 pal_cache_line_state_t; 20.129 +#define PAL_CACHE_LINE_STATE_INVALID 0 /* Invalid */ 20.130 +#define PAL_CACHE_LINE_STATE_SHARED 1 /* Shared */ 20.131 +#define PAL_CACHE_LINE_STATE_EXCLUSIVE 2 /* Exclusive */ 20.132 +#define PAL_CACHE_LINE_STATE_MODIFIED 3 /* Modified */ 20.133 + 20.134 +typedef struct pal_freq_ratio { 20.135 + u64 den : 32, num : 32; /* numerator & denominator */ 20.136 +} itc_ratio, proc_ratio; 20.137 + 20.138 +typedef union pal_cache_config_info_1_s { 20.139 + struct { 20.140 + u64 u : 1, /* 0 Unified cache ? */ 20.141 + at : 2, /* 2-1 Cache mem attr*/ 20.142 + reserved : 5, /* 7-3 Reserved */ 20.143 + associativity : 8, /* 16-8 Associativity*/ 20.144 + line_size : 8, /* 23-17 Line size */ 20.145 + stride : 8, /* 31-24 Stride */ 20.146 + store_latency : 8, /*39-32 Store latency*/ 20.147 + load_latency : 8, /* 47-40 Load latency*/ 20.148 + store_hints : 8, /* 55-48 Store hints*/ 20.149 + load_hints : 8; /* 63-56 Load hints */ 20.150 + } pcci1_bits; 20.151 + u64 pcci1_data; 20.152 +} pal_cache_config_info_1_t; 20.153 + 20.154 +typedef union pal_cache_config_info_2_s { 20.155 + struct { 20.156 + u64 cache_size : 32, /*cache size in bytes*/ 20.157 + 20.158 + 20.159 + alias_boundary : 8, /* 39-32 aliased addr 20.160 + * separation for max 20.161 + * performance. 20.162 + */ 20.163 + tag_ls_bit : 8, /* 47-40 LSb of addr*/ 20.164 + tag_ms_bit : 8, /* 55-48 MSb of addr*/ 20.165 + reserved : 8; /* 63-56 Reserved */ 20.166 + } pcci2_bits; 20.167 + u64 pcci2_data; 20.168 +} pal_cache_config_info_2_t; 20.169 + 20.170 + 20.171 +typedef struct pal_cache_config_info_s { 20.172 + pal_status_t pcci_status; 20.173 + pal_cache_config_info_1_t pcci_info_1; 20.174 + pal_cache_config_info_2_t pcci_info_2; 20.175 + u64 pcci_reserved; 20.176 +} pal_cache_config_info_t; 20.177 + 20.178 +#define pcci_ld_hints pcci_info_1.pcci1_bits.load_hints 20.179 +#define pcci_st_hints pcci_info_1.pcci1_bits.store_hints 20.180 +#define pcci_ld_latency pcci_info_1.pcci1_bits.load_latency 20.181 +#define pcci_st_latency pcci_info_1.pcci1_bits.store_latency 20.182 +#define pcci_stride pcci_info_1.pcci1_bits.stride 20.183 +#define pcci_line_size pcci_info_1.pcci1_bits.line_size 20.184 +#define pcci_assoc pcci_info_1.pcci1_bits.associativity 20.185 +#define pcci_cache_attr pcci_info_1.pcci1_bits.at 20.186 +#define pcci_unified pcci_info_1.pcci1_bits.u 20.187 +#define pcci_tag_msb pcci_info_2.pcci2_bits.tag_ms_bit 20.188 +#define pcci_tag_lsb pcci_info_2.pcci2_bits.tag_ls_bit 20.189 +#define pcci_alias_boundary pcci_info_2.pcci2_bits.alias_boundary 20.190 +#define pcci_cache_size pcci_info_2.pcci2_bits.cache_size 20.191 + 20.192 + 20.193 + 20.194 +/* Possible values for cache attributes */ 20.195 + 20.196 +#define PAL_CACHE_ATTR_WT 0 /* Write through cache */ 20.197 +#define PAL_CACHE_ATTR_WB 1 /* Write back cache */ 20.198 +#define PAL_CACHE_ATTR_WT_OR_WB 2 /* Either write thru or write 20.199 + * back depending on TLB 20.200 + * memory attributes 20.201 + */ 20.202 + 20.203 + 20.204 +/* Possible values for cache hints */ 20.205 + 20.206 +#define PAL_CACHE_HINT_TEMP_1 0 /* Temporal level 1 */ 20.207 +#define PAL_CACHE_HINT_NTEMP_1 1 /* Non-temporal level 1 */ 20.208 +#define PAL_CACHE_HINT_NTEMP_ALL 3 /* Non-temporal all levels */ 20.209 + 20.210 +/* Processor cache protection information */ 20.211 +typedef union pal_cache_protection_element_u { 20.212 + u32 pcpi_data; 20.213 + struct { 20.214 + u32 data_bits : 8, /* # data bits covered by 20.215 + * each unit of protection 20.216 + */ 20.217 + 20.218 + tagprot_lsb : 6, /* Least -do- */ 20.219 + tagprot_msb : 6, /* Most Sig. tag address 20.220 + * bit that this 20.221 + * protection covers. 20.222 + */ 20.223 + prot_bits : 6, /* # of protection bits */ 20.224 + method : 4, /* Protection method */ 20.225 + t_d : 2; /* Indicates which part 20.226 + * of the cache this 20.227 + * protection encoding 20.228 + * applies. 20.229 + */ 20.230 + } pcp_info; 20.231 +} pal_cache_protection_element_t; 20.232 + 20.233 +#define pcpi_cache_prot_part pcp_info.t_d 20.234 +#define pcpi_prot_method pcp_info.method 20.235 +#define pcpi_prot_bits pcp_info.prot_bits 20.236 +#define pcpi_tagprot_msb pcp_info.tagprot_msb 20.237 +#define pcpi_tagprot_lsb pcp_info.tagprot_lsb 20.238 +#define pcpi_data_bits pcp_info.data_bits 20.239 + 20.240 +/* Processor cache part encodings */ 20.241 +#define PAL_CACHE_PROT_PART_DATA 0 /* Data protection */ 20.242 +#define PAL_CACHE_PROT_PART_TAG 1 /* Tag protection */ 20.243 +#define PAL_CACHE_PROT_PART_TAG_DATA 2 /* Tag+data protection (tag is 20.244 + * more significant ) 20.245 + */ 20.246 +#define PAL_CACHE_PROT_PART_DATA_TAG 3 /* Data+tag protection (data is 20.247 + * more significant ) 20.248 + */ 20.249 +#define PAL_CACHE_PROT_PART_MAX 6 20.250 + 20.251 + 20.252 +typedef struct pal_cache_protection_info_s { 20.253 + pal_status_t pcpi_status; 20.254 + pal_cache_protection_element_t pcp_info[PAL_CACHE_PROT_PART_MAX]; 20.255 +} pal_cache_protection_info_t; 20.256 + 20.257 + 20.258 +/* Processor cache protection method encodings */ 20.259 +#define PAL_CACHE_PROT_METHOD_NONE 0 /* No protection */ 20.260 +#define PAL_CACHE_PROT_METHOD_ODD_PARITY 1 /* Odd parity */ 20.261 +#define PAL_CACHE_PROT_METHOD_EVEN_PARITY 2 /* Even parity */ 20.262 +#define PAL_CACHE_PROT_METHOD_ECC 3 /* ECC protection */ 20.263 + 20.264 + 20.265 +/* Processor cache line identification in the heirarchy */ 20.266 +typedef union pal_cache_line_id_u { 20.267 + u64 pclid_data; 20.268 + struct { 20.269 + u64 cache_type : 8, /* 7-0 cache type */ 20.270 + level : 8, /* 15-8 level of the 20.271 + * cache in the 20.272 + * heirarchy. 20.273 + */ 20.274 + way : 8, /* 23-16 way in the set 20.275 + */ 20.276 + part : 8, /* 31-24 part of the 20.277 + * cache 20.278 + */ 20.279 + reserved : 32; /* 63-32 is reserved*/ 20.280 + } pclid_info_read; 20.281 + struct { 20.282 + u64 cache_type : 8, /* 7-0 cache type */ 20.283 + level : 8, /* 15-8 level of the 20.284 + * cache in the 20.285 + * heirarchy. 20.286 + */ 20.287 + way : 8, /* 23-16 way in the set 20.288 + */ 20.289 + part : 8, /* 31-24 part of the 20.290 + * cache 20.291 + */ 20.292 + mesi : 8, /* 39-32 cache line 20.293 + * state 20.294 + */ 20.295 + start : 8, /* 47-40 lsb of data to 20.296 + * invert 20.297 + */ 20.298 + length : 8, /* 55-48 #bits to 20.299 + * invert 20.300 + */ 20.301 + trigger : 8; /* 63-56 Trigger error 20.302 + * by doing a load 20.303 + * after the write 20.304 + */ 20.305 + 20.306 + } pclid_info_write; 20.307 +} pal_cache_line_id_u_t; 20.308 + 20.309 +#define pclid_read_part pclid_info_read.part 20.310 +#define pclid_read_way pclid_info_read.way 20.311 +#define pclid_read_level pclid_info_read.level 20.312 +#define pclid_read_cache_type pclid_info_read.cache_type 20.313 + 20.314 +#define pclid_write_trigger pclid_info_write.trigger 20.315 +#define pclid_write_length pclid_info_write.length 20.316 +#define pclid_write_start pclid_info_write.start 20.317 +#define pclid_write_mesi pclid_info_write.mesi 20.318 +#define pclid_write_part pclid_info_write.part 20.319 +#define pclid_write_way pclid_info_write.way 20.320 +#define pclid_write_level pclid_info_write.level 20.321 +#define pclid_write_cache_type pclid_info_write.cache_type 20.322 + 20.323 +/* Processor cache line part encodings */ 20.324 +#define PAL_CACHE_LINE_ID_PART_DATA 0 /* Data */ 20.325 +#define PAL_CACHE_LINE_ID_PART_TAG 1 /* Tag */ 20.326 +#define PAL_CACHE_LINE_ID_PART_DATA_PROT 2 /* Data protection */ 20.327 +#define PAL_CACHE_LINE_ID_PART_TAG_PROT 3 /* Tag protection */ 20.328 +#define PAL_CACHE_LINE_ID_PART_DATA_TAG_PROT 4 /* Data+tag 20.329 + * protection 20.330 + */ 20.331 +typedef struct pal_cache_line_info_s { 20.332 + pal_status_t pcli_status; /* Return status of the read cache line 20.333 + * info call. 20.334 + */ 20.335 + u64 pcli_data; /* 64-bit data, tag, protection bits .. */ 20.336 + u64 pcli_data_len; /* data length in bits */ 20.337 + pal_cache_line_state_t pcli_cache_line_state; /* mesi state */ 20.338 + 20.339 +} pal_cache_line_info_t; 20.340 + 20.341 + 20.342 +/* Machine Check related crap */ 20.343 + 20.344 +/* Pending event status bits */ 20.345 +typedef u64 pal_mc_pending_events_t; 20.346 + 20.347 +#define PAL_MC_PENDING_MCA (1 << 0) 20.348 +#define PAL_MC_PENDING_INIT (1 << 1) 20.349 + 20.350 +/* Error information type */ 20.351 +typedef u64 pal_mc_info_index_t; 20.352 + 20.353 +#define PAL_MC_INFO_PROCESSOR 0 /* Processor */ 20.354 +#define PAL_MC_INFO_CACHE_CHECK 1 /* Cache check */ 20.355 +#define PAL_MC_INFO_TLB_CHECK 2 /* Tlb check */ 20.356 +#define PAL_MC_INFO_BUS_CHECK 3 /* Bus check */ 20.357 +#define PAL_MC_INFO_REQ_ADDR 4 /* Requestor address */ 20.358 +#define PAL_MC_INFO_RESP_ADDR 5 /* Responder address */ 20.359 +#define PAL_MC_INFO_TARGET_ADDR 6 /* Target address */ 20.360 +#define PAL_MC_INFO_IMPL_DEP 7 /* Implementation 20.361 + * dependent 20.362 + */ 20.363 + 20.364 + 20.365 +typedef struct pal_process_state_info_s { 20.366 + u64 reserved1 : 2, 20.367 + rz : 1, /* PAL_CHECK processor 20.368 + * rendezvous 20.369 + * successful. 20.370 + */ 20.371 + 20.372 + ra : 1, /* PAL_CHECK attempted 20.373 + * a rendezvous. 20.374 + */ 20.375 + me : 1, /* Distinct multiple 20.376 + * errors occurred 20.377 + */ 20.378 + 20.379 + mn : 1, /* Min. state save 20.380 + * area has been 20.381 + * registered with PAL 20.382 + */ 20.383 + 20.384 + sy : 1, /* Storage integrity 20.385 + * synched 20.386 + */ 20.387 + 20.388 + 20.389 + co : 1, /* Continuable */ 20.390 + ci : 1, /* MC isolated */ 20.391 + us : 1, /* Uncontained storage 20.392 + * damage. 20.393 + */ 20.394 + 20.395 + 20.396 + hd : 1, /* Non-essential hw 20.397 + * lost (no loss of 20.398 + * functionality) 20.399 + * causing the 20.400 + * processor to run in 20.401 + * degraded mode. 20.402 + */ 20.403 + 20.404 + tl : 1, /* 1 => MC occurred 20.405 + * after an instr was 20.406 + * executed but before 20.407 + * the trap that 20.408 + * resulted from instr 20.409 + * execution was 20.410 + * generated. 20.411 + * (Trap Lost ) 20.412 + */ 20.413 + mi : 1, /* More information available 20.414 + * call PAL_MC_ERROR_INFO 20.415 + */ 20.416 + pi : 1, /* Precise instruction pointer */ 20.417 + pm : 1, /* Precise min-state save area */ 20.418 + 20.419 + dy : 1, /* Processor dynamic 20.420 + * state valid 20.421 + */ 20.422 + 20.423 + 20.424 + in : 1, /* 0 = MC, 1 = INIT */ 20.425 + rs : 1, /* RSE valid */ 20.426 + cm : 1, /* MC corrected */ 20.427 + ex : 1, /* MC is expected */ 20.428 + cr : 1, /* Control regs valid*/ 20.429 + pc : 1, /* Perf cntrs valid */ 20.430 + dr : 1, /* Debug regs valid */ 20.431 + tr : 1, /* Translation regs 20.432 + * valid 20.433 + */ 20.434 + rr : 1, /* Region regs valid */ 20.435 + ar : 1, /* App regs valid */ 20.436 + br : 1, /* Branch regs valid */ 20.437 + pr : 1, /* Predicate registers 20.438 + * valid 20.439 + */ 20.440 + 20.441 + fp : 1, /* fp registers valid*/ 20.442 + b1 : 1, /* Preserved bank one 20.443 + * general registers 20.444 + * are valid 20.445 + */ 20.446 + b0 : 1, /* Preserved bank zero 20.447 + * general registers 20.448 + * are valid 20.449 + */ 20.450 + gr : 1, /* General registers 20.451 + * are valid 20.452 + * (excl. banked regs) 20.453 + */ 20.454 + dsize : 16, /* size of dynamic 20.455 + * state returned 20.456 + * by the processor 20.457 + */ 20.458 + 20.459 + reserved2 : 11, 20.460 + cc : 1, /* Cache check */ 20.461 + tc : 1, /* TLB check */ 20.462 + bc : 1, /* Bus check */ 20.463 + rc : 1, /* Register file check */ 20.464 + uc : 1; /* Uarch check */ 20.465 + 20.466 +} pal_processor_state_info_t; 20.467 + 20.468 +typedef struct pal_cache_check_info_s { 20.469 + u64 op : 4, /* Type of cache 20.470 + * operation that 20.471 + * caused the machine 20.472 + * check. 20.473 + */ 20.474 + level : 2, /* Cache level */ 20.475 + reserved1 : 2, 20.476 + dl : 1, /* Failure in data part 20.477 + * of cache line 20.478 + */ 20.479 + tl : 1, /* Failure in tag part 20.480 + * of cache line 20.481 + */ 20.482 + dc : 1, /* Failure in dcache */ 20.483 + ic : 1, /* Failure in icache */ 20.484 + mesi : 3, /* Cache line state */ 20.485 + mv : 1, /* mesi valid */ 20.486 + way : 5, /* Way in which the 20.487 + * error occurred 20.488 + */ 20.489 + wiv : 1, /* Way field valid */ 20.490 + reserved2 : 10, 20.491 + 20.492 + index : 20, /* Cache line index */ 20.493 + reserved3 : 2, 20.494 + 20.495 + is : 1, /* instruction set (1 == ia32) */ 20.496 + iv : 1, /* instruction set field valid */ 20.497 + pl : 2, /* privilege level */ 20.498 + pv : 1, /* privilege level field valid */ 20.499 + mcc : 1, /* Machine check corrected */ 20.500 + tv : 1, /* Target address 20.501 + * structure is valid 20.502 + */ 20.503 + rq : 1, /* Requester identifier 20.504 + * structure is valid 20.505 + */ 20.506 + rp : 1, /* Responder identifier 20.507 + * structure is valid 20.508 + */ 20.509 + pi : 1; /* Precise instruction pointer 20.510 + * structure is valid 20.511 + */ 20.512 +} pal_cache_check_info_t; 20.513 + 20.514 +typedef struct pal_tlb_check_info_s { 20.515 + 20.516 + u64 tr_slot : 8, /* Slot# of TR where 20.517 + * error occurred 20.518 + */ 20.519 + trv : 1, /* tr_slot field is valid */ 20.520 + reserved1 : 1, 20.521 + level : 2, /* TLB level where failure occurred */ 20.522 + reserved2 : 4, 20.523 + dtr : 1, /* Fail in data TR */ 20.524 + itr : 1, /* Fail in inst TR */ 20.525 + dtc : 1, /* Fail in data TC */ 20.526 + itc : 1, /* Fail in inst. TC */ 20.527 + op : 4, /* Cache operation */ 20.528 + reserved3 : 30, 20.529 + 20.530 + is : 1, /* instruction set (1 == ia32) */ 20.531 + iv : 1, /* instruction set field valid */ 20.532 + pl : 2, /* privilege level */ 20.533 + pv : 1, /* privilege level field valid */ 20.534 + mcc : 1, /* Machine check corrected */ 20.535 + tv : 1, /* Target address 20.536 + * structure is valid 20.537 + */ 20.538 + rq : 1, /* Requester identifier 20.539 + * structure is valid 20.540 + */ 20.541 + rp : 1, /* Responder identifier 20.542 + * structure is valid 20.543 + */ 20.544 + pi : 1; /* Precise instruction pointer 20.545 + * structure is valid 20.546 + */ 20.547 +} pal_tlb_check_info_t; 20.548 + 20.549 +typedef struct pal_bus_check_info_s { 20.550 + u64 size : 5, /* Xaction size */ 20.551 + ib : 1, /* Internal bus error */ 20.552 + eb : 1, /* External bus error */ 20.553 + cc : 1, /* Error occurred 20.554 + * during cache-cache 20.555 + * transfer. 20.556 + */ 20.557 + type : 8, /* Bus xaction type*/ 20.558 + sev : 5, /* Bus error severity*/ 20.559 + hier : 2, /* Bus hierarchy level */ 20.560 + reserved1 : 1, 20.561 + bsi : 8, /* Bus error status 20.562 + * info 20.563 + */ 20.564 + reserved2 : 22, 20.565 + 20.566 + is : 1, /* instruction set (1 == ia32) */ 20.567 + iv : 1, /* instruction set field valid */ 20.568 + pl : 2, /* privilege level */ 20.569 + pv : 1, /* privilege level field valid */ 20.570 + mcc : 1, /* Machine check corrected */ 20.571 + tv : 1, /* Target address 20.572 + * structure is valid 20.573 + */ 20.574 + rq : 1, /* Requester identifier 20.575 + * structure is valid 20.576 + */ 20.577 + rp : 1, /* Responder identifier 20.578 + * structure is valid 20.579 + */ 20.580 + pi : 1; /* Precise instruction pointer 20.581 + * structure is valid 20.582 + */ 20.583 +} pal_bus_check_info_t; 20.584 + 20.585 +typedef struct pal_reg_file_check_info_s { 20.586 + u64 id : 4, /* Register file identifier */ 20.587 + op : 4, /* Type of register 20.588 + * operation that 20.589 + * caused the machine 20.590 + * check. 20.591 + */ 20.592 + reg_num : 7, /* Register number */ 20.593 + rnv : 1, /* reg_num valid */ 20.594 + reserved2 : 38, 20.595 + 20.596 + is : 1, /* instruction set (1 == ia32) */ 20.597 + iv : 1, /* instruction set field valid */ 20.598 + pl : 2, /* privilege level */ 20.599 + pv : 1, /* privilege level field valid */ 20.600 + mcc : 1, /* Machine check corrected */ 20.601 + reserved3 : 3, 20.602 + pi : 1; /* Precise instruction pointer 20.603 + * structure is valid 20.604 + */ 20.605 +} pal_reg_file_check_info_t; 20.606 + 20.607 +typedef struct pal_uarch_check_info_s { 20.608 + u64 sid : 5, /* Structure identification */ 20.609 + level : 3, /* Level of failure */ 20.610 + array_id : 4, /* Array identification */ 20.611 + op : 4, /* Type of 20.612 + * operation that 20.613 + * caused the machine 20.614 + * check. 20.615 + */ 20.616 + way : 6, /* Way of structure */ 20.617 + wv : 1, /* way valid */ 20.618 + xv : 1, /* index valid */ 20.619 + reserved1 : 8, 20.620 + index : 8, /* Index or set of the uarch 20.621 + * structure that failed. 20.622 + */ 20.623 + reserved2 : 24, 20.624 + 20.625 + is : 1, /* instruction set (1 == ia32) */ 20.626 + iv : 1, /* instruction set field valid */ 20.627 + pl : 2, /* privilege level */ 20.628 + pv : 1, /* privilege level field valid */ 20.629 + mcc : 1, /* Machine check corrected */ 20.630 + tv : 1, /* Target address 20.631 + * structure is valid 20.632 + */ 20.633 + rq : 1, /* Requester identifier 20.634 + * structure is valid 20.635 + */ 20.636 + rp : 1, /* Responder identifier 20.637 + * structure is valid 20.638 + */ 20.639 + pi : 1; /* Precise instruction pointer 20.640 + * structure is valid 20.641 + */ 20.642 +} pal_uarch_check_info_t; 20.643 + 20.644 +typedef union pal_mc_error_info_u { 20.645 + u64 pmei_data; 20.646 + pal_processor_state_info_t pme_processor; 20.647 + pal_cache_check_info_t pme_cache; 20.648 + pal_tlb_check_info_t pme_tlb; 20.649 + pal_bus_check_info_t pme_bus; 20.650 + pal_reg_file_check_info_t pme_reg_file; 20.651 + pal_uarch_check_info_t pme_uarch; 20.652 +} pal_mc_error_info_t; 20.653 + 20.654 +#define pmci_proc_unknown_check pme_processor.uc 20.655 +#define pmci_proc_bus_check pme_processor.bc 20.656 +#define pmci_proc_tlb_check pme_processor.tc 20.657 +#define pmci_proc_cache_check pme_processor.cc 20.658 +#define pmci_proc_dynamic_state_size pme_processor.dsize 20.659 +#define pmci_proc_gpr_valid pme_processor.gr 20.660 +#define pmci_proc_preserved_bank0_gpr_valid pme_processor.b0 20.661 +#define pmci_proc_preserved_bank1_gpr_valid pme_processor.b1 20.662 +#define pmci_proc_fp_valid pme_processor.fp 20.663 +#define pmci_proc_predicate_regs_valid pme_processor.pr 20.664 +#define pmci_proc_branch_regs_valid pme_processor.br 20.665 +#define pmci_proc_app_regs_valid pme_processor.ar 20.666 +#define pmci_proc_region_regs_valid pme_processor.rr 20.667 +#define pmci_proc_translation_regs_valid pme_processor.tr 20.668 +#define pmci_proc_debug_regs_valid pme_processor.dr 20.669 +#define pmci_proc_perf_counters_valid pme_processor.pc 20.670 +#define pmci_proc_control_regs_valid pme_processor.cr 20.671 +#define pmci_proc_machine_check_expected pme_processor.ex 20.672 +#define pmci_proc_machine_check_corrected pme_processor.cm 20.673 +#define pmci_proc_rse_valid pme_processor.rs 20.674 +#define pmci_proc_machine_check_or_init pme_processor.in 20.675 +#define pmci_proc_dynamic_state_valid pme_processor.dy 20.676 +#define pmci_proc_operation pme_processor.op 20.677 +#define pmci_proc_trap_lost pme_processor.tl 20.678 +#define pmci_proc_hardware_damage pme_processor.hd 20.679 +#define pmci_proc_uncontained_storage_damage pme_processor.us 20.680 +#define pmci_proc_machine_check_isolated pme_processor.ci 20.681 +#define pmci_proc_continuable pme_processor.co 20.682 +#define pmci_proc_storage_intergrity_synced pme_processor.sy 20.683 +#define pmci_proc_min_state_save_area_regd pme_processor.mn 20.684 +#define pmci_proc_distinct_multiple_errors pme_processor.me 20.685 +#define pmci_proc_pal_attempted_rendezvous pme_processor.ra 20.686 +#define pmci_proc_pal_rendezvous_complete pme_processor.rz 20.687 + 20.688 + 20.689 +#define pmci_cache_level pme_cache.level 20.690 +#define pmci_cache_line_state pme_cache.mesi 20.691 +#define pmci_cache_line_state_valid pme_cache.mv 20.692 +#define pmci_cache_line_index pme_cache.index 20.693 +#define pmci_cache_instr_cache_fail pme_cache.ic 20.694 +#define pmci_cache_data_cache_fail pme_cache.dc 20.695 +#define pmci_cache_line_tag_fail pme_cache.tl 20.696 +#define pmci_cache_line_data_fail pme_cache.dl 20.697 +#define pmci_cache_operation pme_cache.op 20.698 +#define pmci_cache_way_valid pme_cache.wv 20.699 +#define pmci_cache_target_address_valid pme_cache.tv 20.700 +#define pmci_cache_way pme_cache.way 20.701 +#define pmci_cache_mc pme_cache.mc 20.702 + 20.703 +#define pmci_tlb_instr_translation_cache_fail pme_tlb.itc 20.704 +#define pmci_tlb_data_translation_cache_fail pme_tlb.dtc 20.705 +#define pmci_tlb_instr_translation_reg_fail pme_tlb.itr 20.706 +#define pmci_tlb_data_translation_reg_fail pme_tlb.dtr 20.707 +#define pmci_tlb_translation_reg_slot pme_tlb.tr_slot 20.708 +#define pmci_tlb_mc pme_tlb.mc 20.709 + 20.710 +#define pmci_bus_status_info pme_bus.bsi 20.711 +#define pmci_bus_req_address_valid pme_bus.rq 20.712 +#define pmci_bus_resp_address_valid pme_bus.rp 20.713 +#define pmci_bus_target_address_valid pme_bus.tv 20.714 +#define pmci_bus_error_severity pme_bus.sev 20.715 +#define pmci_bus_transaction_type pme_bus.type 20.716 +#define pmci_bus_cache_cache_transfer pme_bus.cc 20.717 +#define pmci_bus_transaction_size pme_bus.size 20.718 +#define pmci_bus_internal_error pme_bus.ib 20.719 +#define pmci_bus_external_error pme_bus.eb 20.720 +#define pmci_bus_mc pme_bus.mc 20.721 + 20.722 +/* 20.723 + * NOTE: this min_state_save area struct only includes the 1KB 20.724 + * architectural state save area. The other 3 KB is scratch space 20.725 + * for PAL. 20.726 + */ 20.727 + 20.728 +typedef struct pal_min_state_area_s { 20.729 + u64 pmsa_nat_bits; /* nat bits for saved GRs */ 20.730 + u64 pmsa_gr[15]; /* GR1 - GR15 */ 20.731 + u64 pmsa_bank0_gr[16]; /* GR16 - GR31 */ 20.732 + u64 pmsa_bank1_gr[16]; /* GR16 - GR31 */ 20.733 + u64 pmsa_pr; /* predicate registers */ 20.734 + u64 pmsa_br0; /* branch register 0 */ 20.735 + u64 pmsa_rsc; /* ar.rsc */ 20.736 + u64 pmsa_iip; /* cr.iip */ 20.737 + u64 pmsa_ipsr; /* cr.ipsr */ 20.738 + u64 pmsa_ifs; /* cr.ifs */ 20.739 + u64 pmsa_xip; /* previous iip */ 20.740 + u64 pmsa_xpsr; /* previous psr */ 20.741 + u64 pmsa_xfs; /* previous ifs */ 20.742 + u64 pmsa_br1; /* branch register 1 */ 20.743 + u64 pmsa_reserved[70]; /* pal_min_state_area should total to 1KB */ 20.744 +} pal_min_state_area_t; 20.745 + 20.746 + 20.747 +struct ia64_pal_retval { 20.748 + /* 20.749 + * A zero status value indicates call completed without error. 20.750 + * A negative status value indicates reason of call failure. 20.751 + * A positive status value indicates success but an 20.752 + * informational value should be printed (e.g., "reboot for 20.753 + * change to take effect"). 20.754 + */ 20.755 + s64 status; 20.756 + u64 v0; 20.757 + u64 v1; 20.758 + u64 v2; 20.759 +}; 20.760 + 20.761 +/* 20.762 + * Note: Currently unused PAL arguments are generally labeled 20.763 + * "reserved" so the value specified in the PAL documentation 20.764 + * (generally 0) MUST be passed. Reserved parameters are not optional 20.765 + * parameters. 20.766 + */ 20.767 +extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64, u64); 20.768 +extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64); 20.769 +extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64);