add idl4k kernel firmware version 1.13.0.105

This commit is contained in:
Jaroslav Kysela
2015-03-26 17:22:37 +01:00
parent 5194d2792e
commit e9070cdc77
31064 changed files with 12769984 additions and 0 deletions

720
kernel/arch/ia64/Kconfig Normal file
View File

@@ -0,0 +1,720 @@
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.txt.
#
mainmenu "IA-64 Linux Kernel Configuration"
source "init/Kconfig"
source "kernel/Kconfig.freezer"
menu "Processor type and features"
config IA64
bool
select PCI if (!IA64_HP_SIM)
select ACPI if (!IA64_HP_SIM)
select PM if (!IA64_HP_SIM)
select ARCH_SUPPORTS_MSI
select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
select HAVE_KRETPROBES
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
select HAVE_FUNCTION_TRACER
select HAVE_DMA_ATTRS
select HAVE_KVM
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
the 32-bit X86 line. The IA-64 Linux project has a home
page at <http://www.linuxia64.org/> and a mailing list at
<linux-ia64@vger.kernel.org>.
config 64BIT
bool
select ATA_NONSTANDARD if ATA
default y
config ZONE_DMA
def_bool y
depends on !IA64_SGI_SN2
config QUICKLIST
bool
default y
config MMU
bool
default y
config SWIOTLB
bool
config IOMMU_HELPER
bool
config GENERIC_LOCKBREAK
def_bool n
config RWSEM_XCHGADD_ALGORITHM
bool
default y
config HUGETLB_PAGE_SIZE_VARIABLE
bool
depends on HUGETLB_PAGE
default y
config GENERIC_FIND_NEXT_BIT
bool
default y
config GENERIC_CALIBRATE_DELAY
bool
default y
config GENERIC_TIME
bool
default y
config GENERIC_TIME_VSYSCALL
bool
default y
config HAVE_LEGACY_PER_CPU_AREA
def_bool y
config HAVE_SETUP_PER_CPU_AREA
def_bool y
config DMI
bool
default y
config EFI
bool
default y
config GENERIC_IOMAP
bool
default y
config SCHED_OMIT_FRAME_POINTER
bool
default y
config IA64_UNCACHED_ALLOCATOR
bool
select GENERIC_ALLOCATOR
config ARCH_USES_PG_UNCACHED
def_bool y
depends on IA64_UNCACHED_ALLOCATOR
config AUDIT_ARCH
bool
default y
menuconfig PARAVIRT_GUEST
bool "Paravirtualized guest support"
help
Say Y here to get to see options related to running Linux under
various hypervisors. This option alone does not add any kernel code.
If you say N, all options in this submenu will be skipped and disabled.
if PARAVIRT_GUEST
config PARAVIRT
bool "Enable paravirtualization code"
depends on PARAVIRT_GUEST
default y
bool
default y
help
This changes the kernel so it can modify itself when it is run
under a hypervisor, potentially improving performance significantly
over full virtualization. However, when run without a hypervisor
the kernel is theoretically slower and slightly larger.
source "arch/ia64/xen/Kconfig"
endif
choice
prompt "System type"
default IA64_GENERIC
config IA64_GENERIC
bool "generic"
select NUMA
select ACPI_NUMA
select SWIOTLB
select PCI_MSI
select DMAR
help
This selects the system type of your hardware. A "generic" kernel
will run on any supported IA-64 system. However, if you configure
a kernel for your specific system, it will be faster and smaller.
generic For any supported IA-64 system
DIG-compliant For DIG ("Developer's Interface Guide") compliant systems
DIG+Intel+IOMMU For DIG systems with Intel IOMMU
HP-zx1/sx1000 For HP systems
HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices.
SGI-SN2 For SGI Altix systems
SGI-UV For SGI UV systems
Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
Xen-domU For xen domU system
If you don't know what to do, choose "generic".
config IA64_DIG
bool "DIG-compliant"
select SWIOTLB
config IA64_DIG_VTD
bool "DIG+Intel+IOMMU"
select DMAR
select PCI_MSI
config IA64_HP_ZX1
bool "HP-zx1/sx1000"
help
Build a kernel that runs on HP zx1 and sx1000 systems. This adds
support for the HP I/O MMU.
config IA64_HP_ZX1_SWIOTLB
bool "HP-zx1/sx1000 with software I/O TLB"
select SWIOTLB
help
Build a kernel that runs on HP zx1 and sx1000 systems even when they
have broken PCI devices which cannot DMA to full 32 bits. Apart
from support for the HP I/O MMU, this includes support for the software
I/O TLB, which allows supporting the broken devices at the expense of
wasting some kernel memory (about 2MB by default).
config IA64_SGI_SN2
bool "SGI-SN2"
select NUMA
select ACPI_NUMA
help
Selecting this option will optimize the kernel for use on sn2 based
systems, but the resulting kernel binary will not run on other
types of ia64 systems. If you have an SGI Altix system, it's safe
to select this option. If in doubt, select ia64 generic support
instead.
config IA64_SGI_UV
bool "SGI-UV"
select NUMA
select ACPI_NUMA
select SWIOTLB
help
Selecting this option will optimize the kernel for use on UV based
systems, but the resulting kernel binary will not run on other
types of ia64 systems. If you have an SGI UV system, it's safe
to select this option. If in doubt, select ia64 generic support
instead.
config IA64_HP_SIM
bool "Ski-simulator"
select SWIOTLB
config IA64_XEN_GUEST
bool "Xen guest"
select SWIOTLB
depends on XEN
help
Build a kernel that runs on Xen guest domain. At this moment only
16KB page size in supported.
endchoice
choice
prompt "Processor type"
default ITANIUM
config ITANIUM
bool "Itanium"
help
Select your IA-64 processor type. The default is Itanium.
This choice is safe for all IA-64 systems, but may not perform
optimally on systems with, say, Itanium 2 or newer processors.
config MCKINLEY
bool "Itanium 2"
help
Select this to configure for an Itanium 2 (McKinley) processor.
endchoice
choice
prompt "Kernel page size"
default IA64_PAGE_SIZE_16KB
config IA64_PAGE_SIZE_4KB
bool "4KB"
help
This lets you select the page size of the kernel. For best IA-64
performance, a page size of 8KB or 16KB is recommended. For best
IA-32 compatibility, a page size of 4KB should be selected (the vast
majority of IA-32 binaries work perfectly fine with a larger page
size). For Itanium 2 or newer systems, a page size of 64KB can also
be selected.
4KB For best IA-32 compatibility
8KB For best IA-64 performance
16KB For best IA-64 performance
64KB Requires Itanium 2 or newer processor.
If you don't know what to do, choose 16KB.
config IA64_PAGE_SIZE_8KB
bool "8KB"
config IA64_PAGE_SIZE_16KB
bool "16KB"
config IA64_PAGE_SIZE_64KB
depends on !ITANIUM
bool "64KB"
endchoice
choice
prompt "Page Table Levels"
default PGTABLE_3
config PGTABLE_3
bool "3 Levels"
config PGTABLE_4
depends on !IA64_PAGE_SIZE_64KB
bool "4 Levels"
endchoice
if IA64_HP_SIM
config HZ
default 32
endif
if !IA64_HP_SIM
source kernel/Kconfig.hz
endif
config IA64_BRL_EMU
bool
depends on ITANIUM
default y
# align cache-sensitive data to 128 bytes
config IA64_L1_CACHE_SHIFT
int
default "7" if MCKINLEY
default "6" if ITANIUM
config IA64_CYCLONE
bool "Cyclone (EXA) Time Source support"
help
Say Y here to enable support for IBM EXA Cyclone time source.
If you're unsure, answer N.
config IOSAPIC
bool
depends on !IA64_HP_SIM
default y
config FORCE_MAX_ZONEORDER
int "MAX_ORDER (11 - 17)" if !HUGETLB_PAGE
range 11 17 if !HUGETLB_PAGE
default "17" if HUGETLB_PAGE
default "11"
config VIRT_CPU_ACCOUNTING
bool "Deterministic task and CPU time accounting"
default n
help
Select this option to enable more accurate task and CPU time
accounting. This is done by reading a CPU counter on each
kernel entry and exit and on transitions within the kernel
between system, softirq and hardirq state, so there is a
small performance impact.
If in doubt, say N here.
config SMP
bool "Symmetric multi-processing support"
select USE_GENERIC_SMP_HELPERS
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
systems, but will use only one CPU of a multiprocessor system. If
you say Y here, the kernel will run on many, but not all,
single processor systems. On a single processor system, the kernel
will run faster if you say N here.
See also the SMP-HOWTO available at
<http://www.tldp.org/docs.html#howto>.
If you don't know what to do here, say N.
config NR_CPUS
int "Maximum number of CPUs (2-4096)"
range 2 4096
depends on SMP
default "4096"
help
You should set this to the number of CPUs in your system, but
keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but
only use 2 CPUs on a >2 CPU system. Setting this to a value larger
than 64 will cause the use of a CPU mask array, causing a small
performance hit.
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && EXPERIMENTAL
select HOTPLUG
default n
---help---
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
config ARCH_ENABLE_MEMORY_HOTPLUG
def_bool y
config ARCH_ENABLE_MEMORY_HOTREMOVE
def_bool y
config SCHED_SMT
bool "SMT scheduler support"
depends on SMP
help
Improves the CPU scheduler's decision making when dealing with
Intel IA64 chips with MultiThreading at a cost of slightly increased
overhead in some places. If unsure say N here.
config PERMIT_BSP_REMOVE
bool "Support removal of Bootstrap Processor"
depends on HOTPLUG_CPU
default n
---help---
Say Y here if your platform SAL will support removal of BSP with HOTPLUG_CPU
support.
config FORCE_CPEI_RETARGET
bool "Force assumption that CPEI can be re-targetted"
depends on PERMIT_BSP_REMOVE
default n
---help---
Say Y if you need to force the assumption that CPEI can be re-targetted to
any cpu in the system. This hint is available via ACPI 3.0 specifications.
Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP.
This option it useful to enable this feature on older BIOS's as well.
You can also enable this by using boot command line option force_cpei=1.
source "kernel/Kconfig.preempt"
source "mm/Kconfig"
config ARCH_SELECT_MEMORY_MODEL
def_bool y
config ARCH_DISCONTIGMEM_ENABLE
def_bool y
help
Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more.
config ARCH_FLATMEM_ENABLE
def_bool y
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
select SPARSEMEM_VMEMMAP_ENABLE
config ARCH_DISCONTIGMEM_DEFAULT
def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
depends on ARCH_DISCONTIGMEM_ENABLE
config NUMA
bool "NUMA support"
depends on !IA64_HP_SIM && !FLATMEM
default y if IA64_SGI_SN2
select ACPI_NUMA if ACPI
help
Say Y to compile the kernel to support NUMA (Non-Uniform Memory
Access). This option is for configuring high-end multiprocessor
server systems. If in doubt, say N.
config NODES_SHIFT
int "Max num nodes shift(3-10)"
range 3 10
default "10"
depends on NEED_MULTIPLE_NODES
help
This option specifies the maximum number of nodes in your SSI system.
MAX_NUMNODES will be 2^(This value).
If in doubt, use the default.
config ARCH_POPULATES_NODE_MAP
def_bool y
# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent.
# VIRTUAL_MEM_MAP has been retained for historical reasons.
config VIRTUAL_MEM_MAP
bool "Virtual mem map"
depends on !SPARSEMEM
default y if !IA64_HP_SIM
help
Say Y to compile the kernel with support for a virtual mem map.
This code also only takes effect if a memory hole of greater than
1 Gb is found during boot. You must turn this option on if you
require the DISCONTIGMEM option for your machine. If you are
unsure, say Y.
config HOLES_IN_ZONE
bool
default y if VIRTUAL_MEM_MAP
config HAVE_ARCH_EARLY_PFN_TO_NID
def_bool NUMA && SPARSEMEM
config HAVE_ARCH_NODEDATA_EXTENSION
def_bool y
depends on NUMA
config ARCH_PROC_KCORE_TEXT
def_bool y
depends on PROC_KCORE
config IA32_SUPPORT
bool "Support for Linux/x86 binaries"
help
IA-64 processors can execute IA-32 (X86) instructions. By
saying Y here, the kernel will include IA-32 system call
emulation support which makes it possible to transparently
run IA-32 Linux binaries on an IA-64 Linux system.
If in doubt, say Y.
config COMPAT
bool
depends on IA32_SUPPORT
default y
config COMPAT_FOR_U64_ALIGNMENT
def_bool COMPAT
config IA64_MCA_RECOVERY
tristate "MCA recovery from errors other than TLB."
config PERFMON
bool "Performance monitor support"
help
Selects whether support for the IA-64 performance monitor hardware
is included in the kernel. This makes some kernel data-structures a
little bigger and slows down execution a bit, but it is generally
a good idea to turn this on. If you're unsure, say Y.
config IA64_PALINFO
tristate "/proc/pal support"
help
If you say Y here, you are able to get PAL (Processor Abstraction
Layer) information in /proc/pal. This contains useful information
about the processors in your systems, such as cache and TLB sizes
and the PAL firmware version in use.
To use this option, you have to ensure that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
config IA64_MC_ERR_INJECT
tristate "MC error injection support"
help
Adds support for MC error injection. If enabled, the kernel
will provide a sysfs interface for user applications to
call MC error injection PAL procedures to inject various errors.
This is a useful tool for MCA testing.
If you're unsure, do not select this option.
config SGI_SN
def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
config IA64_ESI
bool "ESI (Extensible SAL Interface) support"
help
If you say Y here, support is built into the kernel to
make ESI calls. ESI calls are used to support vendor-specific
firmware extensions, such as the ability to inject memory-errors
for test-purposes. If you're unsure, say N.
config IA64_HP_AML_NFW
bool "Support ACPI AML calls to native firmware"
help
This driver installs a global ACPI Operation Region handler for
region 0xA1. AML methods can use this OpRegion to call arbitrary
native firmware functions. The driver installs the OpRegion
handler if there is an HPQ5001 device or if the user supplies
the "force" module parameter, e.g., with the "aml_nfw.force"
kernel command line option.
source "drivers/sn/Kconfig"
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
depends on EXPERIMENTAL && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
but it is independent of the system firmware. And like a reboot
you can start any kernel with it, not just Linux.
The name comes from the similarity to the exec system call.
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
initially work for you. It may help to enable device hotplugging
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
config CRASH_DUMP
bool "kernel crash dumps"
depends on IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
help
Generate crash dump after being started by kexec.
source "drivers/firmware/Kconfig"
source "fs/Kconfig.binfmt"
endmenu
menu "Power management and ACPI options"
source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
if PM
source "arch/ia64/kernel/cpufreq/Kconfig"
endif
endmenu
if !IA64_HP_SIM
menu "Bus options (PCI, PCMCIA)"
config PCI
bool "PCI support"
help
Real IA-64 machines all have PCI/PCI-X/PCI Express busses. Say Y
here unless you are using a simulator without PCI support.
config PCI_DOMAINS
def_bool PCI
config PCI_SYSCALL
def_bool PCI
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
source "drivers/pci/hotplug/Kconfig"
source "drivers/pcmcia/Kconfig"
config DMAR
bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
depends on IA64_GENERIC && ACPI && EXPERIMENTAL
help
DMA remapping (DMAR) devices support enables independent address
translations for Direct Memory Access (DMA) from devices.
These DMA remapping devices are reported via ACPI tables
and include PCI device scope covered by these DMA
remapping devices.
config DMAR_DEFAULT_ON
def_bool y
prompt "Enable DMA Remapping Devices by default"
depends on DMAR
help
Selecting this option will enable a DMAR device at boot time if
one is found. If this option is not selected, DMAR support can
be enabled by passing intel_iommu=on to the kernel. It is
recommended you say N here while the DMAR code remains
experimental.
endmenu
endif
source "net/Kconfig"
source "drivers/Kconfig"
source "arch/ia64/hp/sim/Kconfig"
config MSPEC
tristate "Memory special operations driver"
depends on IA64
select IA64_UNCACHED_ALLOCATOR
help
If you have an ia64 and you want to enable memory special
operations support (formerly known as fetchop), say Y here,
otherwise say N.
source "fs/Kconfig"
source "arch/ia64/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
source "arch/ia64/kvm/Kconfig"
source "lib/Kconfig"
#
# Use the generic interrupt handling code in kernel/irq/:
#
config GENERIC_HARDIRQS
bool
default y
config GENERIC_IRQ_PROBE
bool
default y
config GENERIC_PENDING_IRQ
bool
depends on GENERIC_HARDIRQS && SMP
default y
config IRQ_PER_CPU
bool
default y
config IOMMU_HELPER
def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB)
config IOMMU_API
def_bool (DMAR)

View File

@@ -0,0 +1,64 @@
menu "Kernel hacking"
source "lib/Kconfig.debug"
choice
prompt "Physical memory granularity"
default IA64_GRANULE_64MB
config IA64_GRANULE_16MB
bool "16MB"
help
IA-64 identity-mapped regions use a large page size called "granules".
Select "16MB" for a small granule size.
Select "64MB" for a large granule size. This is the current default.
config IA64_GRANULE_64MB
bool "64MB"
depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_SGI_SN2)
endchoice
config IA64_PRINT_HAZARDS
bool "Print possible IA-64 dependency violations to console"
depends on DEBUG_KERNEL
help
Selecting this option prints more information for Illegal Dependency
Faults, that is, for Read-after-Write (RAW), Write-after-Write (WAW),
or Write-after-Read (WAR) violations. This option is ignored if you
are compiling for an Itanium A step processor
(CONFIG_ITANIUM_ASTEP_SPECIFIC). If you're unsure, select Y.
config DISABLE_VHPT
bool "Disable VHPT"
depends on DEBUG_KERNEL
help
The Virtual Hash Page Table (VHPT) enhances virtual address
translation performance. Normally you want the VHPT active but you
can select this option to disable the VHPT for debugging. If you're
unsure, answer N.
config IA64_DEBUG_CMPXCHG
bool "Turn on compare-and-exchange bug checking (slow!)"
depends on DEBUG_KERNEL
help
Selecting this option turns on bug checking for the IA-64
compare-and-exchange instructions. This is slow! Itaniums
from step B3 or later don't have this problem. If you're unsure,
select N.
config IA64_DEBUG_IRQ
bool "Turn on irq debug checks (slow!)"
depends on DEBUG_KERNEL
help
Selecting this option turns on bug checking for the IA-64 irq_save
and restore instructions. It's useful for tracking down spinlock
problems, but slow! If you're unsure, select N.
config SYSVIPC_COMPAT
bool
depends on COMPAT && SYSVIPC
default y
endmenu

106
kernel/arch/ia64/Makefile Normal file
View File

@@ -0,0 +1,106 @@
#
# ia64/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1998-2004 by David Mosberger-Tang <davidm@hpl.hp.com>
#
KBUILD_DEFCONFIG := generic_defconfig
NM := $(CROSS_COMPILE)nm -B
READELF := $(CROSS_COMPILE)readelf
export AWK
CHECKFLAGS += -m64 -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__
OBJCOPYFLAGS := --strip-all
LDFLAGS_vmlinux := -static
LDFLAGS_MODULE += -T $(srctree)/arch/ia64/module.lds
AFLAGS_KERNEL := -mconstant-gp
EXTRA :=
cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
-falign-functions=32 -frename-registers -fno-optimize-sibling-calls
CFLAGS_KERNEL := -mconstant-gp
GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
ifeq ($(GAS_STATUS),buggy)
$(error Sorry, you need a newer version of the assember, one that is built from \
a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \
static binary of such an assembler at: \
\
ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
endif
KBUILD_CFLAGS += $(cflags-y)
head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
libs-y += arch/ia64/lib/
core-y += arch/ia64/kernel/ arch/ia64/mm/
core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/
core-$(CONFIG_IA64_DIG) += arch/ia64/dig/
core-$(CONFIG_IA64_DIG_VTD) += arch/ia64/dig/
core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
core-$(CONFIG_IA64_XEN_GUEST) += arch/ia64/dig/
core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/
core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/
core-$(CONFIG_KVM) += arch/ia64/kvm/
core-$(CONFIG_XEN) += arch/ia64/xen/
drivers-$(CONFIG_PCI) += arch/ia64/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ arch/ia64/uv/
drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
boot := arch/ia64/hp/sim/boot
PHONY += boot compressed check
all: compressed unwcheck
compressed: vmlinux.gz
vmlinuz: vmlinux.gz
vmlinux.gz: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
unwcheck: vmlinux
-$(Q)READELF=$(READELF) python $(srctree)/arch/ia64/scripts/unwcheck.py $<
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
CLEAN_FILES += vmlinux.gz bootloader
boot: lib/lib.a vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
install: vmlinux.gz
sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
define archhelp
echo '* compressed - Build compressed kernel image'
echo ' install - Install compressed kernel image'
echo ' boot - Build vmlinux and bootloader for Ski simulator'
echo '* unwcheck - Check vmlinux for invalid unwind info'
endef
archprepare: make_nr_irqs_h FORCE
PHONY += make_nr_irqs_h FORCE
make_nr_irqs_h: FORCE
$(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,725 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16-rc5
# Mon Feb 27 16:13:41 2006
#
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLUB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
#
# Block layer
#
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
#
# Processor type and features
#
CONFIG_IA64=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_SWIOTLB=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
# CONFIG_IA64_GENERIC is not set
# CONFIG_IA64_DIG is not set
# CONFIG_IA64_HP_ZX1 is not set
# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
# CONFIG_IA64_SGI_SN2 is not set
CONFIG_IA64_HP_SIM=y
# CONFIG_ITANIUM is not set
CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_4KB is not set
# CONFIG_IA64_PAGE_SIZE_8KB is not set
# CONFIG_IA64_PAGE_SIZE_16KB is not set
CONFIG_IA64_PAGE_SIZE_64KB=y
CONFIG_PGTABLE_3=y
# CONFIG_PGTABLE_4 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_IA64_CYCLONE is not set
CONFIG_FORCE_MAX_ZONEORDER=17
CONFIG_SMP=y
CONFIG_NR_CPUS=64
# CONFIG_HOTPLUG_CPU is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
# CONFIG_VIRTUAL_MEM_MAP is not set
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
# CONFIG_IA64_MCA_RECOVERY is not set
# CONFIG_PERFMON is not set
CONFIG_IA64_PALINFO=m
#
# Firmware Drivers
#
CONFIG_EFI_VARS=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
#
# Power management and ACPI
#
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_UNIX is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
#
# TIPC Configuration (EXPERIMENTAL)
#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
#
# Plug and Play support
#
#
# Block devices
#
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
#
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
#
# I2O device support
#
#
# Network device support
#
# CONFIG_NETDEVICES is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
#
# PHY device support
#
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
#
# Ethernet (1000 Mbit)
#
#
# Ethernet (10000 Mbit)
#
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
CONFIG_EFI_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_AGP is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# Multimedia Capabilities Port drivers
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
#
# Graphics support
#
# CONFIG_FB is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
#
# EDAC - error detection and reporting (RAS)
#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
#
# Network File Systems
#
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
#
# Native Language Support
#
# CONFIG_NLS is not set
#
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
#
# HP Simulator drivers
#
CONFIG_HP_SIMETH=y
CONFIG_HP_SIMSERIAL=y
CONFIG_HP_SIMSERIAL_CONSOLE=y
CONFIG_HP_SIMSCSI=y
#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_IA64_GRANULE_16MB is not set
CONFIG_IA64_GRANULE_64MB=y
# CONFIG_IA64_PRINT_HAZARDS is not set
# CONFIG_DISABLE_VHPT is not set
# CONFIG_IA64_DEBUG_CMPXCHG is not set
# CONFIG_IA64_DEBUG_IRQ is not set
CONFIG_SYSVIPC_COMPAT=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
#
# ia64/platform/dig/Makefile
#
# Copyright (C) 1999 Silicon Graphics, Inc.
# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
#
obj-y := setup.o
ifeq ($(CONFIG_DMAR), y)
obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o
else
obj-$(CONFIG_IA64_GENERIC) += machvec.o
endif

View File

@@ -0,0 +1,3 @@
#define MACHVEC_PLATFORM_NAME dig
#define MACHVEC_PLATFORM_HEADER <asm/machvec_dig.h>
#include <asm/machvec_init.h>

View File

@@ -0,0 +1,3 @@
#define MACHVEC_PLATFORM_NAME dig_vtd
#define MACHVEC_PLATFORM_HEADER <asm/machvec_dig_vtd.h>
#include <asm/machvec_init.h>

View File

@@ -0,0 +1,70 @@
/*
* Platform dependent support for DIG64 platforms.
*
* Copyright (C) 1999 Intel Corp.
* Copyright (C) 1999, 2001 Hewlett-Packard Co
* Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/string.h>
#include <linux/screen_info.h>
#include <linux/console.h>
#include <linux/timex.h>
#include <linux/sched.h>
#include <linux/root_dev.h>
#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/system.h>
void __init
dig_setup (char **cmdline_p)
{
unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
/*
* Default to /dev/sda2. This assumes that the EFI partition
* is physical disk 1 partition 1 and the Linux root disk is
* physical disk 1 partition 2.
*/
ROOT_DEV = Root_SDA2; /* default to second partition on first drive */
#ifdef CONFIG_SMP
init_smp_config();
#endif
memset(&screen_info, 0, sizeof(screen_info));
if (!ia64_boot_param->console_info.num_rows
|| !ia64_boot_param->console_info.num_cols)
{
printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n");
orig_x = 0;
orig_y = 0;
num_cols = 80;
num_rows = 25;
font_height = 16;
} else {
orig_x = ia64_boot_param->console_info.orig_x;
orig_y = ia64_boot_param->console_info.orig_y;
num_cols = ia64_boot_param->console_info.num_cols;
num_rows = ia64_boot_param->console_info.num_rows;
font_height = 400 / num_rows;
}
screen_info.orig_x = orig_x;
screen_info.orig_y = orig_y;
screen_info.orig_video_cols = num_cols;
screen_info.orig_video_lines = num_rows;
screen_info.orig_video_points = font_height;
screen_info.orig_video_mode = 3; /* XXX fake */
screen_info.orig_video_isVGA = 1; /* XXX fake */
screen_info.orig_video_ega_bx = 3; /* XXX fake */
}

View File

@@ -0,0 +1,11 @@
#
# ia64/platform/hp/common/Makefile
#
# Copyright (C) 2002 Hewlett Packard
# Copyright (C) Alex Williamson (alex_williamson@hp.com)
#
obj-y := sba_iommu.o
obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o
obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o
obj-$(CONFIG_IA64_HP_AML_NFW) += aml_nfw.o

View File

@@ -0,0 +1,236 @@
/*
* OpRegion handler to allow AML to call native firmware
*
* (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This driver implements HP Open Source Review Board proposal 1842,
* which was approved on 9/20/2006.
*
* For technical documentation, see the HP SPPA Firmware EAS, Appendix F.
*
* ACPI does not define a mechanism for AML methods to call native firmware
* interfaces such as PAL or SAL. This OpRegion handler adds such a mechanism.
* After the handler is installed, an AML method can call native firmware by
* storing the arguments and firmware entry point to specific offsets in the
* OpRegion. When AML reads the "return value" offset from the OpRegion, this
* handler loads up the arguments, makes the firmware call, and returns the
* result.
*/
#include <linux/module.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <asm/sal.h>
MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ACPI opregion handler for native firmware calls");
static int force_register;
module_param_named(force, force_register, bool, 0);
MODULE_PARM_DESC(force, "Install opregion handler even without HPQ5001 device");
#define AML_NFW_SPACE 0xA1
struct ia64_pdesc {
void *ip;
void *gp;
};
/*
* N.B. The layout of this structure is defined in the HP SPPA FW EAS, and
* the member offsets are embedded in AML methods.
*/
struct ia64_nfw_context {
u64 arg[8];
struct ia64_sal_retval ret;
u64 ip;
u64 gp;
u64 pad[2];
};
static void *virt_map(u64 address)
{
if (address & (1UL << 63))
return (void *) (__IA64_UNCACHED_OFFSET | address);
return __va(address);
}
static void aml_nfw_execute(struct ia64_nfw_context *c)
{
struct ia64_pdesc virt_entry;
ia64_sal_handler entry;
virt_entry.ip = virt_map(c->ip);
virt_entry.gp = virt_map(c->gp);
entry = (ia64_sal_handler) &virt_entry;
IA64_FW_CALL(entry, c->ret,
c->arg[0], c->arg[1], c->arg[2], c->arg[3],
c->arg[4], c->arg[5], c->arg[6], c->arg[7]);
}
static void aml_nfw_read_arg(u8 *offset, u32 bit_width, acpi_integer *value)
{
switch (bit_width) {
case 8:
*value = *(u8 *)offset;
break;
case 16:
*value = *(u16 *)offset;
break;
case 32:
*value = *(u32 *)offset;
break;
case 64:
*value = *(u64 *)offset;
break;
}
}
static void aml_nfw_write_arg(u8 *offset, u32 bit_width, acpi_integer *value)
{
switch (bit_width) {
case 8:
*(u8 *) offset = *value;
break;
case 16:
*(u16 *) offset = *value;
break;
case 32:
*(u32 *) offset = *value;
break;
case 64:
*(u64 *) offset = *value;
break;
}
}
static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address,
u32 bit_width, acpi_integer *value, void *handler_context,
void *region_context)
{
struct ia64_nfw_context *context = handler_context;
u8 *offset = (u8 *) context + address;
if (bit_width != 8 && bit_width != 16 &&
bit_width != 32 && bit_width != 64)
return AE_BAD_PARAMETER;
if (address + (bit_width >> 3) > sizeof(struct ia64_nfw_context))
return AE_BAD_PARAMETER;
switch (function) {
case ACPI_READ:
if (address == offsetof(struct ia64_nfw_context, ret))
aml_nfw_execute(context);
aml_nfw_read_arg(offset, bit_width, value);
break;
case ACPI_WRITE:
aml_nfw_write_arg(offset, bit_width, value);
break;
}
return AE_OK;
}
static struct ia64_nfw_context global_context;
static int global_handler_registered;
static int aml_nfw_add_global_handler(void)
{
acpi_status status;
if (global_handler_registered)
return 0;
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
AML_NFW_SPACE, aml_nfw_handler, NULL, &global_context);
if (ACPI_FAILURE(status))
return -ENODEV;
global_handler_registered = 1;
printk(KERN_INFO "Global 0x%02X opregion handler registered\n",
AML_NFW_SPACE);
return 0;
}
static int aml_nfw_remove_global_handler(void)
{
acpi_status status;
if (!global_handler_registered)
return 0;
status = acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
AML_NFW_SPACE, aml_nfw_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
global_handler_registered = 0;
printk(KERN_INFO "Global 0x%02X opregion handler removed\n",
AML_NFW_SPACE);
return 0;
}
static int aml_nfw_add(struct acpi_device *device)
{
/*
* We would normally allocate a new context structure and install
* the address space handler for the specific device we found.
* But the HP-UX implementation shares a single global context
* and always puts the handler at the root, so we'll do the same.
*/
return aml_nfw_add_global_handler();
}
static int aml_nfw_remove(struct acpi_device *device, int type)
{
return aml_nfw_remove_global_handler();
}
static const struct acpi_device_id aml_nfw_ids[] = {
{"HPQ5001", 0},
{"", 0}
};
static struct acpi_driver acpi_aml_nfw_driver = {
.name = "native firmware",
.ids = aml_nfw_ids,
.ops = {
.add = aml_nfw_add,
.remove = aml_nfw_remove,
},
};
static int __init aml_nfw_init(void)
{
int result;
if (force_register)
aml_nfw_add_global_handler();
result = acpi_bus_register_driver(&acpi_aml_nfw_driver);
if (result < 0) {
aml_nfw_remove_global_handler();
return result;
}
return 0;
}
static void __exit aml_nfw_exit(void)
{
acpi_bus_unregister_driver(&acpi_aml_nfw_driver);
aml_nfw_remove_global_handler();
}
module_init(aml_nfw_init);
module_exit(aml_nfw_exit);

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
* Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
*
* This is a pseudo I/O MMU which dispatches to the hardware I/O MMU
* whenever possible. We assume that the hardware I/O MMU requires
* full 32-bit addressability, as is the case, e.g., for HP zx1-based
* systems (there, the I/O MMU window is mapped at 3-4GB). If a
* device doesn't provide full 32-bit addressability, we fall back on
* the sw I/O TLB. This is good enough to let us support broken
* hardware such as soundcards which have a DMA engine that can
* address only 28 bits.
*/
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/swiotlb.h>
#include <asm/machvec.h>
extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
/* swiotlb declarations & definitions: */
extern int swiotlb_late_init_with_default_size (size_t size);
/*
* Note: we need to make the determination of whether or not to use
* the sw I/O TLB based purely on the device structure. Anything else
* would be unreliable or would be too intrusive.
*/
static inline int use_swiotlb(struct device *dev)
{
return dev && dev->dma_mask &&
!sba_dma_ops.dma_supported(dev, *dev->dma_mask);
}
struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
{
if (use_swiotlb(dev))
return &swiotlb_dma_ops;
return &sba_dma_ops;
}
EXPORT_SYMBOL(hwsw_dma_get_ops);
void __init
hwsw_init (void)
{
/* default to a smallish 2MB sw I/O TLB */
if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) {
#ifdef CONFIG_IA64_GENERIC
/* Better to have normal DMA than panic */
printk(KERN_WARNING "%s: Failed to initialize software I/O TLB,"
" reverting to hpzx1 platform vector\n", __func__);
machvec_init("hpzx1");
#else
panic("Unable to initialize software I/O TLB services");
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
menu "HP Simulator drivers"
depends on IA64_HP_SIM || IA64_GENERIC
config HP_SIMETH
bool "Simulated Ethernet "
depends on NET
config HP_SIMSERIAL
bool "Simulated serial driver support"
config HP_SIMSERIAL_CONSOLE
bool "Console for HP simulator"
depends on HP_SIMSERIAL
config HP_SIMSCSI
bool "Simulated SCSI disk"
depends on SCSI=y
endmenu

View File

@@ -0,0 +1,16 @@
#
# ia64/platform/hp/sim/Makefile
#
# Copyright (C) 2002 Hewlett-Packard Co.
# David Mosberger-Tang <davidm@hpl.hp.com>
# Copyright (C) 1999 Silicon Graphics, Inc.
# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
#
obj-y := hpsim_irq.o hpsim_setup.o hpsim.o
obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
obj-$(CONFIG_HP_SIMETH) += simeth.o
obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o
obj-$(CONFIG_HP_SIMSCSI) += simscsi.o

View File

@@ -0,0 +1,37 @@
#
# ia64/boot/Makefile
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1998, 2003 by David Mosberger-Tang <davidm@hpl.hp.com>
#
targets-$(CONFIG_IA64_HP_SIM) += bootloader
targets := vmlinux.bin vmlinux.gz $(targets-y)
quiet_cmd_cptotop = LN $@
cmd_cptotop = ln -f $< $@
vmlinux.gz: $(obj)/vmlinux.gz $(addprefix $(obj)/,$(targets-y))
$(call cmd,cptotop)
@echo ' Kernel: $@ is ready'
boot: bootloader
bootloader: $(obj)/bootloader
$(call cmd,cptotop)
$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
LDFLAGS_bootloader = -static -T
$(obj)/bootloader: $(src)/bootloader.lds $(obj)/bootloader.o $(obj)/boot_head.o $(obj)/fw-emu.o \
lib/lib.a arch/ia64/lib/built-in.o arch/ia64/lib/lib.a FORCE
$(call if_changed,ld)

View File

@@ -0,0 +1,164 @@
/*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/asmmacro.h>
#include <asm/pal.h>
.bss
.align 16
stack_mem:
.skip 16834
.text
/* This needs to be defined because lib/string.c:strlcat() calls it in case of error... */
GLOBAL_ENTRY(printk)
break 0
END(printk)
GLOBAL_ENTRY(_start)
.prologue
.save rp, r0
.body
movl gp = __gp
movl sp = stack_mem+16384-16
bsw.1
br.call.sptk.many rp=start_bootloader
0: nop 0 /* dummy nop to make unwinding work */
END(_start)
/*
* Set a break point on this function so that symbols are available to set breakpoints in
* the kernel being debugged.
*/
GLOBAL_ENTRY(debug_break)
br.ret.sptk.many b0
END(debug_break)
GLOBAL_ENTRY(ssc)
.regstk 5,0,0,0
mov r15=in4
break 0x80001
br.ret.sptk.many b0
END(ssc)
GLOBAL_ENTRY(jmp_to_kernel)
.regstk 2,0,0,0
mov r28=in0
mov b7=in1
br.sptk.few b7
END(jmp_to_kernel)
/*
* r28 contains the index of the PAL function
* r29--31 the args
* Return values in ret0--3 (r8--11)
*/
GLOBAL_ENTRY(pal_emulator_static)
mov r8=-1
mov r9=256
;;
cmp.gtu p6,p7=r9,r28 /* r28 <= 255? */
(p6) br.cond.sptk.few static
;;
mov r9=512
;;
cmp.gtu p6,p7=r9,r28
(p6) br.cond.sptk.few stacked
;;
static: cmp.eq p6,p7=PAL_PTCE_INFO,r28
(p7) br.cond.sptk.few 1f
;;
mov r8=0 /* status = 0 */
movl r9=0x100000000 /* tc.base */
movl r10=0x0000000200000003 /* count[0], count[1] */
movl r11=0x1000000000002000 /* stride[0], stride[1] */
br.cond.sptk.few rp
1: cmp.eq p6,p7=PAL_FREQ_RATIOS,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x100000064 /* proc_ratio (1/100) */
movl r10=0x100000100 /* bus_ratio<<32 (1/256) */
movl r11=0x100000064 /* itc_ratio<<32 (1/100) */
;;
1: cmp.eq p6,p7=PAL_RSE_INFO,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
mov r9=96 /* num phys stacked */
mov r10=0 /* hints */
mov r11=0
br.cond.sptk.few rp
1: cmp.eq p6,p7=PAL_CACHE_FLUSH,r28 /* PAL_CACHE_FLUSH */
(p7) br.cond.sptk.few 1f
mov r9=ar.lc
movl r8=524288 /* flush 512k million cache lines (16MB) */
;;
mov ar.lc=r8
movl r8=0xe000000000000000
;;
.loop: fc r8
add r8=32,r8
br.cloop.sptk.few .loop
sync.i
;;
srlz.i
;;
mov ar.lc=r9
mov r8=r0
;;
1: cmp.eq p6,p7=PAL_PERF_MON_INFO,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */
mov r10=0 /* reserved */
mov r11=0 /* reserved */
mov r16=0xffff /* implemented PMC */
mov r17=0x3ffff /* implemented PMD */
add r18=8,r29 /* second index */
;;
st8 [r29]=r16,16 /* store implemented PMC */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* clear remaining bits */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r17,16 /* store implemented PMD */
st8 [r18]=r0,16 /* clear remaining bits */
mov r16=0xf0 /* cycles count capable PMC */
;;
st8 [r29]=r0,16 /* clear remaining bits */
st8 [r18]=r0,16 /* clear remaining bits */
mov r17=0xf0 /* retired bundles capable PMC */
;;
st8 [r29]=r16,16 /* store cycles capable */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* clear remaining bits */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r17,16 /* store retired bundle capable */
st8 [r18]=r0,16 /* clear remaining bits */
;;
st8 [r29]=r0,16 /* clear remaining bits */
st8 [r18]=r0,16 /* clear remaining bits */
;;
1: cmp.eq p6,p7=PAL_VM_SUMMARY,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
movl r9=0x2044040020F1865 /* num_tc_levels=2, num_unique_tcs=4 */
/* max_itr_entry=64, max_dtr_entry=64 */
/* hash_tag_id=2, max_pkr=15 */
/* key_size=24, phys_add_size=50, vw=1 */
movl r10=0x183C /* rid_size=24, impl_va_msb=60 */
;;
1: cmp.eq p6,p7=PAL_MEM_ATTRIB,r28
(p7) br.cond.sptk.few 1f
mov r8=0 /* status = 0 */
mov r9=0x80|0x01 /* NatPage|WB */
;;
1: br.cond.sptk.few rp
stacked:
br.ret.sptk.few rp
END(pal_emulator_static)

View File

@@ -0,0 +1,175 @@
/*
* arch/ia64/hp/sim/boot/bootloader.c
*
* Loads an ELF kernel.
*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
*
* 01/07/99 S.Eranian modified to pass command line arguments to kernel
*/
struct task_struct; /* forward declaration for elf.h */
#include <linux/elf.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/elf.h>
#include <asm/intrinsics.h>
#include <asm/pal.h>
#include <asm/pgtable.h>
#include <asm/sal.h>
#include <asm/system.h>
#include "ssc.h"
struct disk_req {
unsigned long addr;
unsigned len;
};
struct disk_stat {
int fd;
unsigned count;
};
extern void jmp_to_kernel (unsigned long bp, unsigned long e_entry);
extern struct ia64_boot_param *sys_fw_init (const char *args, int arglen);
extern void debug_break (void);
static void
cons_write (const char *buf)
{
unsigned long ch;
while ((ch = *buf++) != '\0') {
ssc(ch, 0, 0, 0, SSC_PUTCHAR);
if (ch == '\n')
ssc('\r', 0, 0, 0, SSC_PUTCHAR);
}
}
#define MAX_ARGS 32
void
start_bootloader (void)
{
static char mem[4096];
static char buffer[1024];
unsigned long off;
int fd, i;
struct disk_req req;
struct disk_stat stat;
struct elfhdr *elf;
struct elf_phdr *elf_phdr; /* program header */
unsigned long e_entry, e_phoff, e_phnum;
register struct ia64_boot_param *bp;
char *kpath, *args;
long arglen = 0;
ssc(0, 0, 0, 0, SSC_CONSOLE_INIT);
/*
* S.Eranian: extract the commandline argument from the simulator
*
* The expected format is as follows:
*
* kernelname args...
*
* Both are optional but you can't have the second one without the first.
*/
arglen = ssc((long) buffer, 0, 0, 0, SSC_GET_ARGS);
kpath = "vmlinux";
args = buffer;
if (arglen > 0) {
kpath = buffer;
while (*args != ' ' && *args != '\0')
++args, --arglen;
if (*args == ' ')
*args++ = '\0', --arglen;
}
if (arglen <= 0) {
args = "";
arglen = 1;
}
fd = ssc((long) kpath, 1, 0, 0, SSC_OPEN);
if (fd < 0) {
cons_write(kpath);
cons_write(": file not found, reboot now\n");
for(;;);
}
stat.fd = fd;
off = 0;
req.len = sizeof(mem);
req.addr = (long) mem;
ssc(fd, 1, (long) &req, off, SSC_READ);
ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
elf = (struct elfhdr *) mem;
if (elf->e_ident[0] == 0x7f && strncmp(elf->e_ident + 1, "ELF", 3) != 0) {
cons_write("not an ELF file\n");
return;
}
if (elf->e_type != ET_EXEC) {
cons_write("not an ELF executable\n");
return;
}
if (!elf_check_arch(elf)) {
cons_write("kernel not for this processor\n");
return;
}
e_entry = elf->e_entry;
e_phnum = elf->e_phnum;
e_phoff = elf->e_phoff;
cons_write("loading ");
cons_write(kpath);
cons_write("...\n");
for (i = 0; i < e_phnum; ++i) {
req.len = sizeof(*elf_phdr);
req.addr = (long) mem;
ssc(fd, 1, (long) &req, e_phoff, SSC_READ);
ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
if (stat.count != sizeof(*elf_phdr)) {
cons_write("failed to read phdr\n");
return;
}
e_phoff += sizeof(*elf_phdr);
elf_phdr = (struct elf_phdr *) mem;
if (elf_phdr->p_type != PT_LOAD)
continue;
req.len = elf_phdr->p_filesz;
req.addr = __pa(elf_phdr->p_paddr);
ssc(fd, 1, (long) &req, elf_phdr->p_offset, SSC_READ);
ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
memset((char *)__pa(elf_phdr->p_paddr) + elf_phdr->p_filesz, 0,
elf_phdr->p_memsz - elf_phdr->p_filesz);
}
ssc(fd, 0, 0, 0, SSC_CLOSE);
cons_write("starting kernel...\n");
/* fake an I/O base address: */
ia64_setreg(_IA64_REG_AR_KR0, 0xffffc000000UL);
bp = sys_fw_init(args, arglen);
ssc(0, (long) kpath, 0, 0, SSC_LOAD_SYMBOLS);
debug_break();
jmp_to_kernel((unsigned long) bp, e_entry);
cons_write("kernel returned!\n");
ssc(-1, 0, 0, 0, SSC_EXIT);
}

View File

@@ -0,0 +1,66 @@
OUTPUT_FORMAT("elf64-ia64-little")
OUTPUT_ARCH(ia64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x100000;
_text = .;
.text : { *(__ivt_section) *(.text) }
_etext = .;
/* Global data */
_data = .;
.rodata : { *(.rodata) *(.rodata.*) }
.data : { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
__gp = ALIGN (8) + 0x200000;
.got : { *(.got.plt) *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata : { *(.sdata) }
_edata = .;
__bss_start = .;
.sbss : { *(.sbss) *(.scommon) }
.bss : { *(.bss) *(COMMON) }
. = ALIGN(64 / 8);
__bss_stop = .;
_end = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,381 @@
/*
* PAL & SAL emulation.
*
* Copyright (C) 1998-2001 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#ifdef CONFIG_PCI
# include <linux/pci.h>
#endif
#include <linux/efi.h>
#include <asm/io.h>
#include <asm/pal.h>
#include <asm/sal.h>
#include "ssc.h"
#define MB (1024*1024UL)
#define SIMPLE_MEMMAP 1
#if SIMPLE_MEMMAP
# define NUM_MEM_DESCS 4
#else
# define NUM_MEM_DESCS 16
#endif
static char fw_mem[( sizeof(struct ia64_boot_param)
+ sizeof(efi_system_table_t)
+ sizeof(efi_runtime_services_t)
+ 1*sizeof(efi_config_table_t)
+ sizeof(struct ia64_sal_systab)
+ sizeof(struct ia64_sal_desc_entry_point)
+ NUM_MEM_DESCS*(sizeof(efi_memory_desc_t))
+ 1024)] __attribute__ ((aligned (8)));
#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
/* Compute the `struct tm' representation of *T,
offset OFFSET seconds east of UTC,
and store year, yday, mon, mday, wday, hour, min, sec into *TP.
Return nonzero if successful. */
int
offtime (unsigned long t, efi_time_t *tp)
{
const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
long int days, rem, y;
const unsigned short int *ip;
days = t / SECS_PER_DAY;
rem = t % SECS_PER_DAY;
while (rem < 0) {
rem += SECS_PER_DAY;
--days;
}
while (rem >= SECS_PER_DAY) {
rem -= SECS_PER_DAY;
++days;
}
tp->hour = rem / SECS_PER_HOUR;
rem %= SECS_PER_HOUR;
tp->minute = rem / 60;
tp->second = rem % 60;
/* January 1, 1970 was a Thursday. */
y = 1970;
# define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
# define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
# define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
while (days < 0 || days >= (__isleap (y) ? 366 : 365)) {
/* Guess a corrected year, assuming 365 days per year. */
long int yg = y + days / 365 - (days % 365 < 0);
/* Adjust DAYS and Y to match the guessed year. */
days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)
- LEAPS_THRU_END_OF (y - 1));
y = yg;
}
tp->year = y;
ip = __mon_yday[__isleap(y)];
for (y = 11; days < (long int) ip[y]; --y)
continue;
days -= ip[y];
tp->month = y + 1;
tp->day = days + 1;
return 1;
}
extern void pal_emulator_static (void);
/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
#define BUILD_CMD(addr) ((0x80000000 | (addr)) & ~3)
#define REG_OFFSET(addr) (0x00000000000000FF & (addr))
#define DEVICE_FUNCTION(addr) (0x000000000000FF00 & (addr))
#define BUS_NUMBER(addr) (0x0000000000FF0000 & (addr))
static efi_status_t
fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
{
#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
struct {
int tv_sec; /* must be 32bits to work */
int tv_usec;
} tv32bits;
ssc((unsigned long) &tv32bits, 0, 0, 0, SSC_GET_TOD);
memset(tm, 0, sizeof(*tm));
offtime(tv32bits.tv_sec, tm);
if (tc)
memset(tc, 0, sizeof(*tc));
#else
# error Not implemented yet...
#endif
return EFI_SUCCESS;
}
static void
efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
{
#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
ssc(status, 0, 0, 0, SSC_EXIT);
#else
# error Not implemented yet...
#endif
}
static efi_status_t
efi_unimplemented (void)
{
return EFI_UNSUPPORTED;
}
static struct sal_ret_values
sal_emulator (long index, unsigned long in1, unsigned long in2,
unsigned long in3, unsigned long in4, unsigned long in5,
unsigned long in6, unsigned long in7)
{
long r9 = 0;
long r10 = 0;
long r11 = 0;
long status;
/*
* Don't do a "switch" here since that gives us code that
* isn't self-relocatable.
*/
status = 0;
if (index == SAL_FREQ_BASE) {
switch (in1) {
case SAL_FREQ_BASE_PLATFORM:
r9 = 200000000;
break;
case SAL_FREQ_BASE_INTERVAL_TIMER:
/*
* Is this supposed to be the cr.itc frequency
* or something platform specific? The SAL
* doc ain't exactly clear on this...
*/
r9 = 700000000;
break;
case SAL_FREQ_BASE_REALTIME_CLOCK:
r9 = 1;
break;
default:
status = -1;
break;
}
} else if (index == SAL_SET_VECTORS) {
;
} else if (index == SAL_GET_STATE_INFO) {
;
} else if (index == SAL_GET_STATE_INFO_SIZE) {
;
} else if (index == SAL_CLEAR_STATE_INFO) {
;
} else if (index == SAL_MC_RENDEZ) {
;
} else if (index == SAL_MC_SET_PARAMS) {
;
} else if (index == SAL_CACHE_FLUSH) {
;
} else if (index == SAL_CACHE_INIT) {
;
#ifdef CONFIG_PCI
} else if (index == SAL_PCI_CONFIG_READ) {
/*
* in1 contains the PCI configuration address and in2
* the size of the read. The value that is read is
* returned via the general register r9.
*/
outl(BUILD_CMD(in1), 0xCF8);
if (in2 == 1) /* Reading byte */
r9 = inb(0xCFC + ((REG_OFFSET(in1) & 3)));
else if (in2 == 2) /* Reading word */
r9 = inw(0xCFC + ((REG_OFFSET(in1) & 2)));
else /* Reading dword */
r9 = inl(0xCFC);
status = PCIBIOS_SUCCESSFUL;
} else if (index == SAL_PCI_CONFIG_WRITE) {
/*
* in1 contains the PCI configuration address, in2 the
* size of the write, and in3 the actual value to be
* written out.
*/
outl(BUILD_CMD(in1), 0xCF8);
if (in2 == 1) /* Writing byte */
outb(in3, 0xCFC + ((REG_OFFSET(in1) & 3)));
else if (in2 == 2) /* Writing word */
outw(in3, 0xCFC + ((REG_OFFSET(in1) & 2)));
else /* Writing dword */
outl(in3, 0xCFC);
status = PCIBIOS_SUCCESSFUL;
#endif /* CONFIG_PCI */
} else if (index == SAL_UPDATE_PAL) {
;
} else {
status = -1;
}
return ((struct sal_ret_values) {status, r9, r10, r11});
}
struct ia64_boot_param *
sys_fw_init (const char *args, int arglen)
{
efi_system_table_t *efi_systab;
efi_runtime_services_t *efi_runtime;
efi_config_table_t *efi_tables;
struct ia64_sal_systab *sal_systab;
efi_memory_desc_t *efi_memmap, *md;
unsigned long *pal_desc, *sal_desc;
struct ia64_sal_desc_entry_point *sal_ed;
struct ia64_boot_param *bp;
unsigned char checksum = 0;
char *cp, *cmd_line;
int i = 0;
# define MAKE_MD(typ, attr, start, end) \
do { \
md = efi_memmap + i++; \
md->type = typ; \
md->pad = 0; \
md->phys_addr = start; \
md->virt_addr = 0; \
md->num_pages = (end - start) >> 12; \
md->attribute = attr; \
} while (0)
memset(fw_mem, 0, sizeof(fw_mem));
pal_desc = (unsigned long *) &pal_emulator_static;
sal_desc = (unsigned long *) &sal_emulator;
cp = fw_mem;
efi_systab = (void *) cp; cp += sizeof(*efi_systab);
efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
efi_tables = (void *) cp; cp += sizeof(*efi_tables);
sal_systab = (void *) cp; cp += sizeof(*sal_systab);
sal_ed = (void *) cp; cp += sizeof(*sal_ed);
efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
bp = (void *) cp; cp += sizeof(*bp);
cmd_line = (void *) cp;
if (args) {
if (arglen >= 1024)
arglen = 1023;
memcpy(cmd_line, args, arglen);
} else {
arglen = 0;
}
cmd_line[arglen] = '\0';
memset(efi_systab, 0, sizeof(*efi_systab));
efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
efi_systab->hdr.revision = ((1 << 16) | 00);
efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0");
efi_systab->fw_revision = 1;
efi_systab->runtime = (void *) __pa(efi_runtime);
efi_systab->nr_tables = 1;
efi_systab->tables = __pa(efi_tables);
efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
efi_runtime->get_time = __pa(&fw_efi_get_time);
efi_runtime->set_time = __pa(&efi_unimplemented);
efi_runtime->get_wakeup_time = __pa(&efi_unimplemented);
efi_runtime->set_wakeup_time = __pa(&efi_unimplemented);
efi_runtime->set_virtual_address_map = __pa(&efi_unimplemented);
efi_runtime->get_variable = __pa(&efi_unimplemented);
efi_runtime->get_next_variable = __pa(&efi_unimplemented);
efi_runtime->set_variable = __pa(&efi_unimplemented);
efi_runtime->get_next_high_mono_count = __pa(&efi_unimplemented);
efi_runtime->reset_system = __pa(&efi_reset_system);
efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
efi_tables->table = __pa(sal_systab);
/* fill in the SAL system table: */
memcpy(sal_systab->signature, "SST_", 4);
sal_systab->size = sizeof(*sal_systab);
sal_systab->sal_rev_minor = 1;
sal_systab->sal_rev_major = 0;
sal_systab->entry_count = 1;
#ifdef CONFIG_IA64_GENERIC
strcpy(sal_systab->oem_id, "Generic");
strcpy(sal_systab->product_id, "IA-64 system");
#endif
#ifdef CONFIG_IA64_HP_SIM
strcpy(sal_systab->oem_id, "Hewlett-Packard");
strcpy(sal_systab->product_id, "HP-simulator");
#endif
/* fill in an entry point: */
sal_ed->type = SAL_DESC_ENTRY_POINT;
sal_ed->pal_proc = __pa(pal_desc[0]);
sal_ed->sal_proc = __pa(sal_desc[0]);
sal_ed->gp = __pa(sal_desc[1]);
for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
checksum += *cp;
sal_systab->checksum = -checksum;
#if SIMPLE_MEMMAP
/* simulate free memory at physical address zero */
MAKE_MD(EFI_BOOT_SERVICES_DATA, EFI_MEMORY_WB, 0*MB, 1*MB);
MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB, 1*MB, 2*MB);
MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, 2*MB, 130*MB);
MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, 4096*MB, 4128*MB);
#else
MAKE_MD( 4, 0x9, 0x0000000000000000, 0x0000000000001000);
MAKE_MD( 7, 0x9, 0x0000000000001000, 0x000000000008a000);
MAKE_MD( 4, 0x9, 0x000000000008a000, 0x00000000000a0000);
MAKE_MD( 5, 0x8000000000000009, 0x00000000000c0000, 0x0000000000100000);
MAKE_MD( 7, 0x9, 0x0000000000100000, 0x0000000004400000);
MAKE_MD( 2, 0x9, 0x0000000004400000, 0x0000000004be5000);
MAKE_MD( 7, 0x9, 0x0000000004be5000, 0x000000007f77e000);
MAKE_MD( 6, 0x8000000000000009, 0x000000007f77e000, 0x000000007fb94000);
MAKE_MD( 6, 0x8000000000000009, 0x000000007fb94000, 0x000000007fb95000);
MAKE_MD( 6, 0x8000000000000009, 0x000000007fb95000, 0x000000007fc00000);
MAKE_MD(13, 0x8000000000000009, 0x000000007fc00000, 0x000000007fc3a000);
MAKE_MD( 7, 0x9, 0x000000007fc3a000, 0x000000007fea0000);
MAKE_MD( 5, 0x8000000000000009, 0x000000007fea0000, 0x000000007fea8000);
MAKE_MD( 7, 0x9, 0x000000007fea8000, 0x000000007feab000);
MAKE_MD( 5, 0x8000000000000009, 0x000000007feab000, 0x000000007ffff000);
MAKE_MD( 7, 0x9, 0x00000000ff400000, 0x0000000104000000);
#endif
bp->efi_systab = __pa(&fw_mem);
bp->efi_memmap = __pa(efi_memmap);
bp->efi_memmap_size = NUM_MEM_DESCS*sizeof(efi_memory_desc_t);
bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
bp->efi_memdesc_version = 1;
bp->command_line = __pa(cmd_line);
bp->console_info.num_cols = 80;
bp->console_info.num_rows = 25;
bp->console_info.orig_x = 0;
bp->console_info.orig_y = 24;
bp->fpswa = 0;
return bp;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
*/
#ifndef ssc_h
#define ssc_h
/* Simulator system calls: */
#define SSC_CONSOLE_INIT 20
#define SSC_GETCHAR 21
#define SSC_PUTCHAR 31
#define SSC_OPEN 50
#define SSC_CLOSE 51
#define SSC_READ 52
#define SSC_WRITE 53
#define SSC_GET_COMPLETION 54
#define SSC_WAIT_COMPLETION 55
#define SSC_CONNECT_INTERRUPT 58
#define SSC_GENERATE_INTERRUPT 59
#define SSC_SET_PERIODIC_INTERRUPT 60
#define SSC_GET_RTC 65
#define SSC_EXIT 66
#define SSC_LOAD_SYMBOLS 69
#define SSC_GET_TOD 74
#define SSC_GET_ARGS 75
/*
* Simulator system call.
*/
extern long ssc (long arg0, long arg1, long arg2, long arg3, int nr);
#endif /* ssc_h */

View File

@@ -0,0 +1,10 @@
#include <asm/asmmacro.h>
/*
* Simulator system call.
*/
GLOBAL_ENTRY(ia64_ssc)
mov r15=r36
break 0x80001
br.ret.sptk.many rp
END(ia64_ssc)

View File

@@ -0,0 +1,76 @@
/*
* Platform dependent support for HP simulator.
*
* Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/tty.h>
#include <linux/kdev_t.h>
#include <linux/console.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/pal.h>
#include <asm/machvec.h>
#include <asm/pgtable.h>
#include <asm/sal.h>
#include <asm/hpsim.h>
#include "hpsim_ssc.h"
static int simcons_init (struct console *, char *);
static void simcons_write (struct console *, const char *, unsigned);
static struct tty_driver *simcons_console_device (struct console *, int *);
static struct console hpsim_cons = {
.name = "simcons",
.write = simcons_write,
.device = simcons_console_device,
.setup = simcons_init,
.flags = CON_PRINTBUFFER,
.index = -1,
};
static int
simcons_init (struct console *cons, char *options)
{
return 0;
}
static void
simcons_write (struct console *cons, const char *buf, unsigned count)
{
unsigned long ch;
while (count-- > 0) {
ch = *buf++;
ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
if (ch == '\n')
ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
}
}
static struct tty_driver *simcons_console_device (struct console *c, int *index)
{
*index = c->index;
return hp_simserial_driver;
}
int simcons_register(void)
{
if (!ia64_platform_is("hpsim"))
return 1;
if (hpsim_cons.flags & CON_ENABLED)
return 1;
register_console(&hpsim_cons);
return 0;
}

View File

@@ -0,0 +1,52 @@
/*
* Platform dependent support for HP simulator.
*
* Copyright (C) 1998-2001 Hewlett-Packard Co
* Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/irq.h>
static unsigned int
hpsim_irq_startup (unsigned int irq)
{
return 0;
}
static void
hpsim_irq_noop (unsigned int irq)
{
}
static int
hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
{
return 0;
}
static struct irq_chip irq_type_hp_sim = {
.name = "hpsim",
.startup = hpsim_irq_startup,
.shutdown = hpsim_irq_noop,
.enable = hpsim_irq_noop,
.disable = hpsim_irq_noop,
.ack = hpsim_irq_noop,
.end = hpsim_irq_noop,
.set_affinity = hpsim_set_affinity_noop,
};
void __init
hpsim_irq_init (void)
{
struct irq_desc *idesc;
int i;
for (i = 0; i < NR_IRQS; ++i) {
idesc = irq_desc + i;
if (idesc->chip == &no_irq_chip)
idesc->chip = &irq_type_hp_sim;
}
}

View File

@@ -0,0 +1,3 @@
#define MACHVEC_PLATFORM_NAME hpsim
#define MACHVEC_PLATFORM_HEADER <asm/machvec_hpsim.h>
#include <asm/machvec_init.h>

View File

@@ -0,0 +1,46 @@
/*
* Platform dependent support for HP simulator.
*
* Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
*/
#include <linux/console.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/param.h>
#include <linux/root_dev.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/pal.h>
#include <asm/machvec.h>
#include <asm/pgtable.h>
#include <asm/sal.h>
#include <asm/hpsim.h>
#include "hpsim_ssc.h"
void
ia64_ssc_connect_irq (long intr, long irq)
{
ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
}
void
ia64_ctl_trace (long on)
{
ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
}
void __init
hpsim_setup (char **cmdline_p)
{
ROOT_DEV = Root_SDA1; /* default to first SCSI drive */
simcons_register();
}

View File

@@ -0,0 +1,36 @@
/*
* Platform dependent support for HP simulator.
*
* Copyright (C) 1998, 1999 Hewlett-Packard Co
* Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
*/
#ifndef _IA64_PLATFORM_HPSIM_SSC_H
#define _IA64_PLATFORM_HPSIM_SSC_H
/* Simulator system calls: */
#define SSC_CONSOLE_INIT 20
#define SSC_GETCHAR 21
#define SSC_PUTCHAR 31
#define SSC_CONNECT_INTERRUPT 58
#define SSC_GENERATE_INTERRUPT 59
#define SSC_SET_PERIODIC_INTERRUPT 60
#define SSC_GET_RTC 65
#define SSC_EXIT 66
#define SSC_LOAD_SYMBOLS 69
#define SSC_GET_TOD 74
#define SSC_CTL_TRACE 76
#define SSC_NETDEV_PROBE 100
#define SSC_NETDEV_SEND 101
#define SSC_NETDEV_RECV 102
#define SSC_NETDEV_ATTACH 103
#define SSC_NETDEV_DETACH 104
/*
* Simulator system call.
*/
extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
#endif /* _IA64_PLATFORM_HPSIM_SSC_H */

View File

@@ -0,0 +1,527 @@
/*
* Simulated Ethernet Driver
*
* Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/inetdevice.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/notifier.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/hpsim.h>
#include "hpsim_ssc.h"
#define SIMETH_RECV_MAX 10
/*
* Maximum possible received frame for Ethernet.
* We preallocate an sk_buff of that size to avoid costly
* memcpy for temporary buffer into sk_buff. We do basically
* what's done in other drivers, like eepro with a ring.
* The difference is, of course, that we don't have real DMA !!!
*/
#define SIMETH_FRAME_SIZE ETH_FRAME_LEN
#define NETWORK_INTR 8
struct simeth_local {
struct net_device_stats stats;
int simfd; /* descriptor in the simulator */
};
static int simeth_probe1(void);
static int simeth_open(struct net_device *dev);
static int simeth_close(struct net_device *dev);
static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
static int simeth_rx(struct net_device *dev);
static struct net_device_stats *simeth_get_stats(struct net_device *dev);
static irqreturn_t simeth_interrupt(int irq, void *dev_id);
static void set_multicast_list(struct net_device *dev);
static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
static char *simeth_version="0.3";
/*
* This variable is used to establish a mapping between the Linux/ia64 kernel
* and the host linux kernel.
*
* As of today, we support only one card, even though most of the code
* is ready for many more. The mapping is then:
* linux/ia64 -> linux/x86
* eth0 -> eth1
*
* In the future, we some string operations, we could easily support up
* to 10 cards (0-9).
*
* The default mapping can be changed on the kernel command line by
* specifying simeth=ethX (or whatever string you want).
*/
static char *simeth_device="eth0"; /* default host interface to use */
static volatile unsigned int card_count; /* how many cards "found" so far */
static int simeth_debug; /* set to 1 to get debug information */
/*
* Used to catch IFF_UP & IFF_DOWN events
*/
static struct notifier_block simeth_dev_notifier = {
simeth_device_event,
NULL
};
/*
* Function used when using a kernel command line option.
*
* Format: simeth=interface_name (like eth0)
*/
static int __init
simeth_setup(char *str)
{
simeth_device = str;
return 1;
}
__setup("simeth=", simeth_setup);
/*
* Function used to probe for simeth devices when not installed
* as a loadable module
*/
int __init
simeth_probe (void)
{
int r;
printk(KERN_INFO "simeth: v%s\n", simeth_version);
r = simeth_probe1();
if (r == 0) register_netdevice_notifier(&simeth_dev_notifier);
return r;
}
static inline int
netdev_probe(char *name, unsigned char *ether)
{
return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
}
static inline int
netdev_connect(int irq)
{
/* XXX Fix me
* this does not support multiple cards
* also no return value
*/
ia64_ssc_connect_irq(NETWORK_INTR, irq);
return 0;
}
static inline int
netdev_attach(int fd, int irq, unsigned int ipaddr)
{
/* this puts the host interface in the right mode (start interrupting) */
return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
}
static inline int
netdev_detach(int fd)
{
/*
* inactivate the host interface (don't interrupt anymore) */
return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
}
static inline int
netdev_send(int fd, unsigned char *buf, unsigned int len)
{
return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
}
static inline int
netdev_read(int fd, unsigned char *buf, unsigned int len)
{
return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
}
static const struct net_device_ops simeth_netdev_ops = {
.ndo_open = simeth_open,
.ndo_stop = simeth_close,
.ndo_start_xmit = simeth_tx,
.ndo_get_stats = simeth_get_stats,
.ndo_set_multicast_list = set_multicast_list, /* not yet used */
};
/*
* Function shared with module code, so cannot be in init section
*
* So far this function "detects" only one card (test_&_set) but could
* be extended easily.
*
* Return:
* - -ENODEV is no device found
* - -ENOMEM is no more memory
* - 0 otherwise
*/
static int
simeth_probe1(void)
{
unsigned char mac_addr[ETH_ALEN];
struct simeth_local *local;
struct net_device *dev;
int fd, i, err, rc;
/*
* XXX Fix me
* let's support just one card for now
*/
if (test_and_set_bit(0, &card_count))
return -ENODEV;
/*
* check with the simulator for the device
*/
fd = netdev_probe(simeth_device, mac_addr);
if (fd == -1)
return -ENODEV;
dev = alloc_etherdev(sizeof(struct simeth_local));
if (!dev)
return -ENOMEM;
memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
local = netdev_priv(dev);
local->simfd = fd; /* keep track of underlying file descriptor */
dev->netdev_ops = &simeth_netdev_ops;
err = register_netdev(dev);
if (err) {
free_netdev(dev);
return err;
}
if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
panic("%s: out of interrupt vectors!\n", __func__);
dev->irq = rc;
/*
* attach the interrupt in the simulator, this does enable interrupts
* until a netdev_attach() is called
*/
netdev_connect(dev->irq);
printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
dev->name, simeth_device, local->simfd);
for(i = 0; i < ETH_ALEN; i++) {
printk(" %2.2x", dev->dev_addr[i]);
}
printk(", IRQ %d\n", dev->irq);
return 0;
}
/*
* actually binds the device to an interrupt vector
*/
static int
simeth_open(struct net_device *dev)
{
if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq);
return -EAGAIN;
}
netif_start_queue(dev);
return 0;
}
/* copied from lapbether.c */
static __inline__ int dev_is_ethdev(struct net_device *dev)
{
return ( dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
}
/*
* Handler for IFF_UP or IFF_DOWN
*
* The reason for that is that we don't want to be interrupted when the
* interface is down. There is no way to unconnect in the simualtor. Instead
* we use this function to shutdown packet processing in the frame filter
* in the simulator. Thus no interrupts are generated
*
*
* That's also the place where we pass the IP address of this device to the
* simulator so that that we can start filtering packets for it
*
* There may be a better way of doing this, but I don't know which yet.
*/
static int
simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
struct simeth_local *local;
struct in_device *in_dev;
struct in_ifaddr **ifap = NULL;
struct in_ifaddr *ifa = NULL;
int r;
if ( ! dev ) {
printk(KERN_WARNING "simeth_device_event dev=0\n");
return NOTIFY_DONE;
}
if (dev_net(dev) != &init_net)
return NOTIFY_DONE;
if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
/*
* Check whether or not it's for an ethernet device
*
* XXX Fixme: This works only as long as we support one
* type of ethernet device.
*/
if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
if ((in_dev=dev->ip_ptr) != NULL) {
for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
if (strcmp(dev->name, ifa->ifa_label) == 0) break;
}
if ( ifa == NULL ) {
printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name);
return NOTIFY_DONE;
}
printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
dev->name, ntohl(ifa->ifa_local));
/*
* XXX Fix me
* if the device was up, and we're simply reconfiguring it, not sure
* we get DOWN then UP.
*/
local = netdev_priv(dev);
/* now do it for real */
r = event == NETDEV_UP ?
netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)):
netdev_detach(local->simfd);
printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
event == NETDEV_UP ? "attach":"detach", r);
return NOTIFY_DONE;
}
static int
simeth_close(struct net_device *dev)
{
netif_stop_queue(dev);
free_irq(dev->irq, dev);
return 0;
}
/*
* Only used for debug
*/
static void
frame_print(unsigned char *from, unsigned char *frame, int len)
{
int i;
printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
for(i=1; i < 6; i++ ) {
printk(":%02x", frame[i] &0xff);
}
printk(" %2x", frame[6] &0xff);
for(i=7; i < 12; i++ ) {
printk(":%02x", frame[i] &0xff);
}
printk(" [%02x%02x]\n", frame[12], frame[13]);
for(i=14; i < len; i++ ) {
printk("%02x ", frame[i] &0xff);
if ( (i%10)==0) printk("\n");
}
printk("\n");
}
/*
* Function used to transmit of frame, very last one on the path before
* going to the simulator.
*/
static int
simeth_tx(struct sk_buff *skb, struct net_device *dev)
{
struct simeth_local *local = netdev_priv(dev);
#if 0
/* ensure we have at least ETH_ZLEN bytes (min frame size) */
unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Where do the extra padding bytes comes from inthe skbuff ? */
#else
/* the real driver in the host system is going to take care of that
* or maybe it's the NIC itself.
*/
unsigned int length = skb->len;
#endif
local->stats.tx_bytes += skb->len;
local->stats.tx_packets++;
if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
netdev_send(local->simfd, skb->data, length);
/*
* we are synchronous on write, so we don't simulate a
* trasnmit complete interrupt, thus we don't need to arm a tx
*/
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
static inline struct sk_buff *
make_new_skb(struct net_device *dev)
{
struct sk_buff *nskb;
/*
* The +2 is used to make sure that the IP header is nicely
* aligned (on 4byte boundary I assume 14+2=16)
*/
nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
if ( nskb == NULL ) {
printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
return NULL;
}
skb_reserve(nskb, 2); /* Align IP on 16 byte boundaries */
skb_put(nskb,SIMETH_FRAME_SIZE);
return nskb;
}
/*
* called from interrupt handler to process a received frame
*/
static int
simeth_rx(struct net_device *dev)
{
struct simeth_local *local;
struct sk_buff *skb;
int len;
int rcv_count = SIMETH_RECV_MAX;
local = netdev_priv(dev);
/*
* the loop concept has been borrowed from other drivers
* looks to me like it's a throttling thing to avoid pushing to many
* packets at one time into the stack. Making sure we can process them
* upstream and make forward progress overall
*/
do {
if ( (skb=make_new_skb(dev)) == NULL ) {
printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
local->stats.rx_dropped++;
return 0;
}
/*
* Read only one frame at a time
*/
len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
if ( len == 0 ) {
if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n",
dev->name, SIMETH_RECV_MAX-rcv_count);
break;
}
#if 0
/*
* XXX Fix me
* Should really do a csum+copy here
*/
skb_copy_to_linear_data(skb, frame, len);
#endif
skb->protocol = eth_type_trans(skb, dev);
if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
/*
* push the packet up & trigger software interrupt
*/
netif_rx(skb);
local->stats.rx_packets++;
local->stats.rx_bytes += len;
} while ( --rcv_count );
return len; /* 0 = nothing left to read, otherwise, we can try again */
}
/*
* Interrupt handler (Yes, we can do it too !!!)
*/
static irqreturn_t
simeth_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
/*
* very simple loop because we get interrupts only when receiving
*/
while (simeth_rx(dev));
return IRQ_HANDLED;
}
static struct net_device_stats *
simeth_get_stats(struct net_device *dev)
{
struct simeth_local *local = netdev_priv(dev);
return &local->stats;
}
/* fake multicast ability */
static void
set_multicast_list(struct net_device *dev)
{
printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
}
__initcall(simeth_probe);

View File

@@ -0,0 +1,378 @@
/*
* Simulated SCSI driver.
*
* Copyright (C) 1999, 2001-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
*
* 02/01/15 David Mosberger Updated for v2.5.1
* 99/12/18 David Mosberger Added support for READ10/WRITE10 needed by linux v2.3.33
*/
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <asm/irq.h>
#include "hpsim_ssc.h"
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#define DEBUG_SIMSCSI 0
#define SIMSCSI_REQ_QUEUE_LEN 64
#define DEFAULT_SIMSCSI_ROOT "/var/ski-disks/sd"
/* Simulator system calls: */
#define SSC_OPEN 50
#define SSC_CLOSE 51
#define SSC_READ 52
#define SSC_WRITE 53
#define SSC_GET_COMPLETION 54
#define SSC_WAIT_COMPLETION 55
#define SSC_WRITE_ACCESS 2
#define SSC_READ_ACCESS 1
#if DEBUG_SIMSCSI
int simscsi_debug;
# define DBG simscsi_debug
#else
# define DBG 0
#endif
static struct Scsi_Host *host;
static void simscsi_interrupt (unsigned long val);
static DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
struct disk_req {
unsigned long addr;
unsigned len;
};
struct disk_stat {
int fd;
unsigned count;
};
static int desc[16] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
static struct queue_entry {
struct scsi_cmnd *sc;
} queue[SIMSCSI_REQ_QUEUE_LEN];
static int rd, wr;
static atomic_t num_reqs = ATOMIC_INIT(0);
/* base name for default disks */
static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
#define MAX_ROOT_LEN 128
/*
* used to setup a new base for disk images
* to use /foo/bar/disk[a-z] as disk images
* you have to specify simscsi=/foo/bar/disk on the command line
*/
static int __init
simscsi_setup (char *s)
{
/* XXX Fix me we may need to strcpy() ? */
if (strlen(s) > MAX_ROOT_LEN) {
printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
simscsi_root);
}
simscsi_root = s;
return 1;
}
__setup("simscsi=", simscsi_setup);
static void
simscsi_interrupt (unsigned long val)
{
struct scsi_cmnd *sc;
while ((sc = queue[rd].sc) != NULL) {
atomic_dec(&num_reqs);
queue[rd].sc = NULL;
if (DBG)
printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
(*sc->scsi_done)(sc);
rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
}
}
static int
simscsi_biosparam (struct scsi_device *sdev, struct block_device *n,
sector_t capacity, int ip[])
{
ip[0] = 64; /* heads */
ip[1] = 32; /* sectors */
ip[2] = capacity >> 11; /* cylinders */
return 0;
}
static void
simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
{
int i;
struct scatterlist *sl;
struct disk_stat stat;
struct disk_req req;
stat.fd = desc[sc->device->id];
scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
req.addr = __pa(sg_virt(sl));
req.len = sl->length;
if (DBG)
printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
mode == SSC_READ ? "read":"write", req.addr, offset,
scsi_sg_count(sc) - i, sl->length);
ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
/* should not happen in our case */
if (stat.count != req.len) {
sc->result = DID_ERROR << 16;
return;
}
offset += sl->length;
}
sc->result = GOOD;
}
/*
* function handling both READ_6/WRITE_6 (non-scatter/gather mode)
* commands.
* Added 02/26/99 S.Eranian
*/
static void
simscsi_readwrite6 (struct scsi_cmnd *sc, int mode)
{
unsigned long offset;
offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
simscsi_sg_readwrite(sc, mode, offset);
}
static size_t
simscsi_get_disk_size (int fd)
{
struct disk_stat stat;
size_t bit, sectors = 0;
struct disk_req req;
char buf[512];
/*
* This is a bit kludgey: the simulator doesn't provide a
* direct way of determining the disk size, so we do a binary
* search, assuming a maximum disk size of 128GB.
*/
for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) {
req.addr = __pa(&buf);
req.len = sizeof(buf);
ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
stat.fd = fd;
ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
if (stat.count == sizeof(buf))
sectors |= bit;
}
return sectors - 1; /* return last valid sector number */
}
static void
simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
{
unsigned long offset;
offset = (((unsigned long)sc->cmnd[2] << 24)
| ((unsigned long)sc->cmnd[3] << 16)
| ((unsigned long)sc->cmnd[4] << 8)
| ((unsigned long)sc->cmnd[5] << 0))*512UL;
simscsi_sg_readwrite(sc, mode, offset);
}
static int
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{
unsigned int target_id = sc->device->id;
char fname[MAX_ROOT_LEN+16];
size_t disk_size;
char *buf;
char localbuf[36];
#if DEBUG_SIMSCSI
register long sp asm ("sp");
if (DBG)
printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
target_id, sc->cmnd[0], sc->serial_number, sp, done);
#endif
sc->result = DID_BAD_TARGET << 16;
sc->scsi_done = done;
if (target_id <= 15 && sc->device->lun == 0) {
switch (sc->cmnd[0]) {
case INQUIRY:
if (scsi_bufflen(sc) < 35) {
break;
}
sprintf (fname, "%s%c", simscsi_root, 'a' + target_id);
desc[target_id] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
0, 0, SSC_OPEN);
if (desc[target_id] < 0) {
/* disk doesn't exist... */
break;
}
buf = localbuf;
buf[0] = 0; /* magnetic disk */
buf[1] = 0; /* not a removable medium */
buf[2] = 2; /* SCSI-2 compliant device */
buf[3] = 2; /* SCSI-2 response data format */
buf[4] = 31; /* additional length (bytes) */
buf[5] = 0; /* reserved */
buf[6] = 0; /* reserved */
buf[7] = 0; /* various flags */
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
scsi_sg_copy_from_buffer(sc, buf, 36);
sc->result = GOOD;
break;
case TEST_UNIT_READY:
sc->result = GOOD;
break;
case READ_6:
if (desc[target_id] < 0 )
break;
simscsi_readwrite6(sc, SSC_READ);
break;
case READ_10:
if (desc[target_id] < 0 )
break;
simscsi_readwrite10(sc, SSC_READ);
break;
case WRITE_6:
if (desc[target_id] < 0)
break;
simscsi_readwrite6(sc, SSC_WRITE);
break;
case WRITE_10:
if (desc[target_id] < 0)
break;
simscsi_readwrite10(sc, SSC_WRITE);
break;
case READ_CAPACITY:
if (desc[target_id] < 0 || scsi_bufflen(sc) < 8) {
break;
}
buf = localbuf;
disk_size = simscsi_get_disk_size(desc[target_id]);
buf[0] = (disk_size >> 24) & 0xff;
buf[1] = (disk_size >> 16) & 0xff;
buf[2] = (disk_size >> 8) & 0xff;
buf[3] = (disk_size >> 0) & 0xff;
/* set block size of 512 bytes: */
buf[4] = 0;
buf[5] = 0;
buf[6] = 2;
buf[7] = 0;
scsi_sg_copy_from_buffer(sc, buf, 8);
sc->result = GOOD;
break;
case MODE_SENSE:
case MODE_SENSE_10:
/* sd.c uses this to determine whether disk does write-caching. */
scsi_sg_copy_from_buffer(sc, (char *)empty_zero_page,
PAGE_SIZE);
sc->result = GOOD;
break;
case START_STOP:
printk(KERN_ERR "START_STOP\n");
break;
default:
panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
}
}
if (sc->result == DID_BAD_TARGET) {
sc->result |= DRIVER_SENSE << 24;
sc->sense_buffer[0] = 0x70;
sc->sense_buffer[2] = 0x00;
}
if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
panic("Attempt to queue command while command is pending!!");
}
atomic_inc(&num_reqs);
queue[wr].sc = sc;
wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
tasklet_schedule(&simscsi_tasklet);
return 0;
}
static int
simscsi_host_reset (struct scsi_cmnd *sc)
{
printk(KERN_ERR "simscsi_host_reset: not implemented\n");
return 0;
}
static struct scsi_host_template driver_template = {
.name = "simulated SCSI host adapter",
.proc_name = "simscsi",
.queuecommand = simscsi_queuecommand,
.eh_host_reset_handler = simscsi_host_reset,
.bios_param = simscsi_biosparam,
.can_queue = SIMSCSI_REQ_QUEUE_LEN,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_sectors = 1024,
.cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
.use_clustering = DISABLE_CLUSTERING,
};
static int __init
simscsi_init(void)
{
int error;
host = scsi_host_alloc(&driver_template, 0);
if (!host)
return -ENOMEM;
error = scsi_add_host(host, NULL);
if (error)
goto free_host;
scsi_scan_host(host);
return 0;
free_host:
scsi_host_put(host);
return error;
}
static void __exit
simscsi_exit(void)
{
scsi_remove_host(host);
scsi_host_put(host);
}
module_init(simscsi_init);
module_exit(simscsi_exit);

View File

@@ -0,0 +1,984 @@
/*
* Simulated Serial Driver (fake serial)
*
* This driver is mostly used for bringup purposes and will go away.
* It has a strong dependency on the system console. All outputs
* are rerouted to the same facility as the one used by printk which, in our
* case means sys_sim.c console (goes via the simulator). The code hereafter
* is completely leveraged from the serial.c driver.
*
* Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close().
* 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c.
* 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/major.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/capability.h>
#include <linux/console.h>
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/sysrq.h>
#include <asm/irq.h>
#include <asm/hw_irq.h>
#include <asm/uaccess.h>
#undef SIMSERIAL_DEBUG /* define this to get some debug information */
#define KEYBOARD_INTR 3 /* must match with simulator! */
#define NR_PORTS 1 /* only one port for now */
#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED)
#define SSC_GETCHAR 21
extern long ia64_ssc (long, long, long, long, int);
extern void ia64_ssc_connect_irq (long intr, long irq);
static char *serial_name = "SimSerial driver";
static char *serial_version = "0.6";
/*
* This has been extracted from asm/serial.h. We need one eventually but
* I don't know exactly what we're going to put in it so just fake one
* for now.
*/
#define BASE_BAUD ( 1843200 / 16 )
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
/*
* Most of the values here are meaningless to this particular driver.
* However some values must be preserved for the code (leveraged from serial.c
* to work correctly).
* port must not be 0
* type must not be UNKNOWN
* So I picked arbitrary (guess from where?) values instead
*/
static struct serial_state rs_table[NR_PORTS]={
/* UART CLK PORT IRQ FLAGS */
{ 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 } /* ttyS0 */
};
/*
* Just for the fun of it !
*/
static struct serial_uart_config uart_config[] = {
{ "unknown", 1, 0 },
{ "8250", 1, 0 },
{ "16450", 1, 0 },
{ "16550", 1, 0 },
{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
{ "cirrus", 1, 0 },
{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
UART_STARTECH },
{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
{ NULL, 0}
};
struct tty_driver *hp_simserial_driver;
static struct async_struct *IRQ_ports[NR_IRQS];
static struct console *console;
static unsigned char *tmp_buf;
extern struct console *console_drivers; /* from kernel/printk.c */
/*
* ------------------------------------------------------------
* rs_stop() and rs_start()
*
* This routines are called before setting or resetting tty->stopped.
* They enable or disable transmitter interrupts, as necessary.
* ------------------------------------------------------------
*/
static void rs_stop(struct tty_struct *tty)
{
#ifdef SIMSERIAL_DEBUG
printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
tty->stopped, tty->hw_stopped, tty->flow_stopped);
#endif
}
static void rs_start(struct tty_struct *tty)
{
#ifdef SIMSERIAL_DEBUG
printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
tty->stopped, tty->hw_stopped, tty->flow_stopped);
#endif
}
static void receive_chars(struct tty_struct *tty)
{
unsigned char ch;
static unsigned char seen_esc = 0;
while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
if ( ch == 27 && seen_esc == 0 ) {
seen_esc = 1;
continue;
} else {
if ( seen_esc==1 && ch == 'O' ) {
seen_esc = 2;
continue;
} else if ( seen_esc == 2 ) {
if ( ch == 'P' ) /* F1 */
show_state();
#ifdef CONFIG_MAGIC_SYSRQ
if ( ch == 'S' ) { /* F4 */
do
ch = ia64_ssc(0, 0, 0, 0,
SSC_GETCHAR);
while (!ch);
handle_sysrq(ch, NULL);
}
#endif
seen_esc = 0;
continue;
}
}
seen_esc = 0;
if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0)
break;
}
tty_flip_buffer_push(tty);
}
/*
* This is the serial driver's interrupt routine for a single port
*/
static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
{
struct async_struct * info;
/*
* I don't know exactly why they don't use the dev_id opaque data
* pointer instead of this extra lookup table
*/
info = IRQ_ports[irq];
if (!info || !info->tty) {
printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
return IRQ_NONE;
}
/*
* pretty simple in our case, because we only get interrupts
* on inbound traffic
*/
receive_chars(info->tty);
return IRQ_HANDLED;
}
/*
* -------------------------------------------------------------------
* Here ends the serial interrupt routines.
* -------------------------------------------------------------------
*/
static void do_softint(struct work_struct *private_)
{
printk(KERN_ERR "simserial: do_softint called\n");
}
static int rs_put_char(struct tty_struct *tty, unsigned char ch)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
unsigned long flags;
if (!tty || !info->xmit.buf)
return 0;
local_irq_save(flags);
if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
local_irq_restore(flags);
return 0;
}
info->xmit.buf[info->xmit.head] = ch;
info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
local_irq_restore(flags);
return 1;
}
static void transmit_chars(struct async_struct *info, int *intr_done)
{
int count;
unsigned long flags;
local_irq_save(flags);
if (info->x_char) {
char c = info->x_char;
console->write(console, &c, 1);
info->state->icount.tx++;
info->x_char = 0;
goto out;
}
if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
#ifdef SIMSERIAL_DEBUG
printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
info->xmit.head, info->xmit.tail, info->tty->stopped);
#endif
goto out;
}
/*
* We removed the loop and try to do it in to chunks. We need
* 2 operations maximum because it's a ring buffer.
*
* First from current to tail if possible.
* Then from the beginning of the buffer until necessary
*/
count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
SERIAL_XMIT_SIZE - info->xmit.tail);
console->write(console, info->xmit.buf+info->xmit.tail, count);
info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
/*
* We have more at the beginning of the buffer
*/
count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
if (count) {
console->write(console, info->xmit.buf, count);
info->xmit.tail += count;
}
out:
local_irq_restore(flags);
}
static void rs_flush_chars(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped ||
!info->xmit.buf)
return;
transmit_chars(info, NULL);
}
static int rs_write(struct tty_struct * tty,
const unsigned char *buf, int count)
{
int c, ret = 0;
struct async_struct *info = (struct async_struct *)tty->driver_data;
unsigned long flags;
if (!tty || !info->xmit.buf || !tmp_buf) return 0;
local_irq_save(flags);
while (1) {
c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
if (count < c)
c = count;
if (c <= 0) {
break;
}
memcpy(info->xmit.buf + info->xmit.head, buf, c);
info->xmit.head = ((info->xmit.head + c) &
(SERIAL_XMIT_SIZE-1));
buf += c;
count -= c;
ret += c;
}
local_irq_restore(flags);
/*
* Hey, we transmit directly from here in our case
*/
if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
&& !tty->stopped && !tty->hw_stopped) {
transmit_chars(info, NULL);
}
return ret;
}
static int rs_write_room(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}
static int rs_chars_in_buffer(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}
static void rs_flush_buffer(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
unsigned long flags;
local_irq_save(flags);
info->xmit.head = info->xmit.tail = 0;
local_irq_restore(flags);
tty_wakeup(tty);
}
/*
* This function is used to send a high-priority XON/XOFF character to
* the device
*/
static void rs_send_xchar(struct tty_struct *tty, char ch)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
info->x_char = ch;
if (ch) {
/*
* I guess we could call console->write() directly but
* let's do that for now.
*/
transmit_chars(info, NULL);
}
}
/*
* ------------------------------------------------------------
* rs_throttle()
*
* This routine is called by the upper-layer tty layer to signal that
* incoming characters should be throttled.
* ------------------------------------------------------------
*/
static void rs_throttle(struct tty_struct * tty)
{
if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
printk(KERN_INFO "simrs_throttle called\n");
}
static void rs_unthrottle(struct tty_struct * tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
if (I_IXOFF(tty)) {
if (info->x_char)
info->x_char = 0;
else
rs_send_xchar(tty, START_CHAR(tty));
}
printk(KERN_INFO "simrs_unthrottle called\n");
}
static int rs_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
}
switch (cmd) {
case TIOCGSERIAL:
printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
return 0;
case TIOCSSERIAL:
printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n");
return 0;
case TIOCSERCONFIG:
printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n");
return -EINVAL;
case TIOCSERGETLSR: /* Get line status register */
printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n");
return -EINVAL;
case TIOCSERGSTRUCT:
printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n");
#if 0
if (copy_to_user((struct async_struct *) arg,
info, sizeof(struct async_struct)))
return -EFAULT;
#endif
return 0;
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
* - mask passed in arg for lines of interest
* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
* Caller should use TIOCGICOUNT to see which one it was
*/
case TIOCMIWAIT:
printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
return 0;
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
* Return: write counters to the user passed counter struct
* NB: both 1->0 and 0->1 transitions are counted except for
* RI where only 0->1 is counted.
*/
case TIOCGICOUNT:
printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
return 0;
case TIOCSERGWILD:
case TIOCSERSWILD:
/* "setserial -W" is called in Debian boot */
printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n");
return 0;
default:
return -ENOIOCTLCMD;
}
return 0;
}
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
/* Handle turning off CRTSCTS */
if ((old_termios->c_cflag & CRTSCTS) &&
!(tty->termios->c_cflag & CRTSCTS)) {
tty->hw_stopped = 0;
rs_start(tty);
}
}
/*
* This routine will shutdown a serial port; interrupts are disabled, and
* DTR is dropped if the hangup on close termio flag is on.
*/
static void shutdown(struct async_struct * info)
{
unsigned long flags;
struct serial_state *state;
int retval;
if (!(info->flags & ASYNC_INITIALIZED)) return;
state = info->state;
#ifdef SIMSERIAL_DEBUG
printk("Shutting down serial port %d (irq %d)....", info->line,
state->irq);
#endif
local_irq_save(flags);
{
/*
* First unlink the serial port from the IRQ chain...
*/
if (info->next_port)
info->next_port->prev_port = info->prev_port;
if (info->prev_port)
info->prev_port->next_port = info->next_port;
else
IRQ_ports[state->irq] = info->next_port;
/*
* Free the IRQ, if necessary
*/
if (state->irq && (!IRQ_ports[state->irq] ||
!IRQ_ports[state->irq]->next_port)) {
if (IRQ_ports[state->irq]) {
free_irq(state->irq, NULL);
retval = request_irq(state->irq, rs_interrupt_single,
IRQ_T(info), "serial", NULL);
if (retval)
printk(KERN_ERR "serial shutdown: request_irq: error %d"
" Couldn't reacquire IRQ.\n", retval);
} else
free_irq(state->irq, NULL);
}
if (info->xmit.buf) {
free_page((unsigned long) info->xmit.buf);
info->xmit.buf = NULL;
}
if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
}
local_irq_restore(flags);
}
/*
* ------------------------------------------------------------
* rs_close()
*
* This routine is called when the serial port gets closed. First, we
* wait for the last remaining data to be sent. Then, we unlink its
* async structure from the interrupt chain if necessary, and we free
* that IRQ if nothing is left in the chain.
* ------------------------------------------------------------
*/
static void rs_close(struct tty_struct *tty, struct file * filp)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct serial_state *state;
unsigned long flags;
if (!info ) return;
state = info->state;
local_irq_save(flags);
if (tty_hung_up_p(filp)) {
#ifdef SIMSERIAL_DEBUG
printk("rs_close: hung_up\n");
#endif
local_irq_restore(flags);
return;
}
#ifdef SIMSERIAL_DEBUG
printk("rs_close ttys%d, count = %d\n", info->line, state->count);
#endif
if ((tty->count == 1) && (state->count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. state->count should always
* be one in these conditions. If it's greater than
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
"state->count is %d\n", state->count);
state->count = 1;
}
if (--state->count < 0) {
printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
info->line, state->count);
state->count = 0;
}
if (state->count) {
local_irq_restore(flags);
return;
}
info->flags |= ASYNC_CLOSING;
local_irq_restore(flags);
/*
* Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
shutdown(info);
rs_flush_buffer(tty);
tty_ldisc_flush(tty);
info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
if (info->close_delay)
schedule_timeout_interruptible(info->close_delay);
wake_up_interruptible(&info->open_wait);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
}
/*
* rs_wait_until_sent() --- wait until the transmitter is empty
*/
static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
{
}
/*
* rs_hangup() --- called by tty_hangup() when a hangup is signaled.
*/
static void rs_hangup(struct tty_struct *tty)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct serial_state *state = info->state;
#ifdef SIMSERIAL_DEBUG
printk("rs_hangup: called\n");
#endif
state = info->state;
rs_flush_buffer(tty);
if (info->flags & ASYNC_CLOSING)
return;
shutdown(info);
info->event = 0;
state->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
info->tty = NULL;
wake_up_interruptible(&info->open_wait);
}
static int get_async_struct(int line, struct async_struct **ret_info)
{
struct async_struct *info;
struct serial_state *sstate;
sstate = rs_table + line;
sstate->count++;
if (sstate->info) {
*ret_info = sstate->info;
return 0;
}
info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
if (!info) {
sstate->count--;
return -ENOMEM;
}
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->delta_msr_wait);
info->magic = SERIAL_MAGIC;
info->port = sstate->port;
info->flags = sstate->flags;
info->xmit_fifo_size = sstate->xmit_fifo_size;
info->line = line;
INIT_WORK(&info->work, do_softint);
info->state = sstate;
if (sstate->info) {
kfree(info);
*ret_info = sstate->info;
return 0;
}
*ret_info = sstate->info = info;
return 0;
}
static int
startup(struct async_struct *info)
{
unsigned long flags;
int retval=0;
irq_handler_t handler;
struct serial_state *state= info->state;
unsigned long page;
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
local_irq_save(flags);
if (info->flags & ASYNC_INITIALIZED) {
free_page(page);
goto errout;
}
if (!state->port || !state->type) {
if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
free_page(page);
goto errout;
}
if (info->xmit.buf)
free_page(page);
else
info->xmit.buf = (unsigned char *) page;
#ifdef SIMSERIAL_DEBUG
printk("startup: ttys%d (irq %d)...", info->line, state->irq);
#endif
/*
* Allocate the IRQ if necessary
*/
if (state->irq && (!IRQ_ports[state->irq] ||
!IRQ_ports[state->irq]->next_port)) {
if (IRQ_ports[state->irq]) {
retval = -EBUSY;
goto errout;
} else
handler = rs_interrupt_single;
retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL);
if (retval) {
if (capable(CAP_SYS_ADMIN)) {
if (info->tty)
set_bit(TTY_IO_ERROR,
&info->tty->flags);
retval = 0;
}
goto errout;
}
}
/*
* Insert serial port into IRQ chain.
*/
info->prev_port = NULL;
info->next_port = IRQ_ports[state->irq];
if (info->next_port)
info->next_port->prev_port = info;
IRQ_ports[state->irq] = info;
if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
info->xmit.head = info->xmit.tail = 0;
#if 0
/*
* Set up serial timers...
*/
timer_table[RS_TIMER].expires = jiffies + 2*HZ/100;
timer_active |= 1 << RS_TIMER;
#endif
/*
* Set up the tty->alt_speed kludge
*/
if (info->tty) {
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
info->tty->alt_speed = 57600;
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
info->tty->alt_speed = 115200;
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
info->tty->alt_speed = 230400;
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
info->tty->alt_speed = 460800;
}
info->flags |= ASYNC_INITIALIZED;
local_irq_restore(flags);
return 0;
errout:
local_irq_restore(flags);
return retval;
}
/*
* This routine is called whenever a serial port is opened. It
* enables interrupts for a serial port, linking in its async structure into
* the IRQ chain. It also performs the serial-specific
* initialization for the tty structure.
*/
static int rs_open(struct tty_struct *tty, struct file * filp)
{
struct async_struct *info;
int retval, line;
unsigned long page;
line = tty->index;
if ((line < 0) || (line >= NR_PORTS))
return -ENODEV;
retval = get_async_struct(line, &info);
if (retval)
return retval;
tty->driver_data = info;
info->tty = tty;
#ifdef SIMSERIAL_DEBUG
printk("rs_open %s, count = %d\n", tty->name, info->state->count);
#endif
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
if (tmp_buf)
free_page(page);
else
tmp_buf = (unsigned char *) page;
}
/*
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
if (info->flags & ASYNC_CLOSING)
interruptible_sleep_on(&info->close_wait);
#ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
#else
return -EAGAIN;
#endif
}
/*
* Start up serial port
*/
retval = startup(info);
if (retval) {
return retval;
}
/*
* figure out which console to use (should be one already)
*/
console = console_drivers;
while (console) {
if ((console->flags & CON_ENABLED) && console->write) break;
console = console->next;
}
#ifdef SIMSERIAL_DEBUG
printk("rs_open ttys%d successful\n", info->line);
#endif
return 0;
}
/*
* /proc fs routines....
*/
static inline void line_info(struct seq_file *m, struct serial_state *state)
{
seq_printf(m, "%d: uart:%s port:%lX irq:%d\n",
state->line, uart_config[state->type].name,
state->port, state->irq);
}
static int rs_proc_show(struct seq_file *m, void *v)
{
int i;
seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version);
for (i = 0; i < NR_PORTS; i++)
line_info(m, &rs_table[i]);
return 0;
}
static int rs_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, rs_proc_show, NULL);
}
static const struct file_operations rs_proc_fops = {
.owner = THIS_MODULE,
.open = rs_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/*
* ---------------------------------------------------------------------
* rs_init() and friends
*
* rs_init() is called at boot-time to initialize the serial driver.
* ---------------------------------------------------------------------
*/
/*
* This routine prints out the appropriate serial driver version
* number, and identifies which options were configured into this
* driver.
*/
static inline void show_serial_version(void)
{
printk(KERN_INFO "%s version %s with", serial_name, serial_version);
printk(KERN_INFO " no serial options enabled\n");
}
static const struct tty_operations hp_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
.put_char = rs_put_char,
.flush_chars = rs_flush_chars,
.write_room = rs_write_room,
.chars_in_buffer = rs_chars_in_buffer,
.flush_buffer = rs_flush_buffer,
.ioctl = rs_ioctl,
.throttle = rs_throttle,
.unthrottle = rs_unthrottle,
.send_xchar = rs_send_xchar,
.set_termios = rs_set_termios,
.stop = rs_stop,
.start = rs_start,
.hangup = rs_hangup,
.wait_until_sent = rs_wait_until_sent,
.proc_fops = &rs_proc_fops,
};
/*
* The serial driver boot-time initialization code!
*/
static int __init
simrs_init (void)
{
int i, rc;
struct serial_state *state;
if (!ia64_platform_is("hpsim"))
return -ENODEV;
hp_simserial_driver = alloc_tty_driver(1);
if (!hp_simserial_driver)
return -ENOMEM;
show_serial_version();
/* Initialize the tty_driver structure */
hp_simserial_driver->owner = THIS_MODULE;
hp_simserial_driver->driver_name = "simserial";
hp_simserial_driver->name = "ttyS";
hp_simserial_driver->major = TTY_MAJOR;
hp_simserial_driver->minor_start = 64;
hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL;
hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL;
hp_simserial_driver->init_termios = tty_std_termios;
hp_simserial_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(hp_simserial_driver, &hp_ops);
/*
* Let's have a little bit of fun !
*/
for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
if (state->type == PORT_UNKNOWN) continue;
if (!state->irq) {
if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
panic("%s: out of interrupt vectors!\n",
__func__);
state->irq = rc;
ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
}
printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n",
state->line,
state->port, state->irq,
uart_config[state->type].name);
}
if (tty_register_driver(hp_simserial_driver))
panic("Couldn't register simserial driver\n");
return 0;
}
#ifndef MODULE
__initcall(simrs_init);
#endif

View File

@@ -0,0 +1,8 @@
#
# ia64/hp/zx1/Makefile
#
# Copyright (C) 2002 Hewlett Packard
# Copyright (C) Alex Williamson (alex_williamson@hp.com)
#
obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o hpzx1_swiotlb_machvec.o

View File

@@ -0,0 +1,3 @@
#define MACHVEC_PLATFORM_NAME hpzx1
#define MACHVEC_PLATFORM_HEADER <asm/machvec_hpzx1.h>
#include <asm/machvec_init.h>

View File

@@ -0,0 +1,3 @@
#define MACHVEC_PLATFORM_NAME hpzx1_swiotlb
#define MACHVEC_PLATFORM_HEADER <asm/machvec_hpzx1_swiotlb.h>
#include <asm/machvec_init.h>

View File

@@ -0,0 +1,11 @@
#
# Makefile for the ia32 kernel emulation subsystem.
#
obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \
ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o
obj-$(CONFIG_AUDIT) += audit.o
# Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and
# restore_ia32_fpstate_live() can be sure the live register contain user-level state.
CFLAGS_ia32_signal.o += -mfixed-range=f16-f31

View File

@@ -0,0 +1,42 @@
#include "../../x86/include/asm/unistd_32.h"
unsigned ia32_dir_class[] = {
#include <asm-generic/audit_dir_write.h>
~0U
};
unsigned ia32_chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
unsigned ia32_write_class[] = {
#include <asm-generic/audit_write.h>
~0U
};
unsigned ia32_read_class[] = {
#include <asm-generic/audit_read.h>
~0U
};
unsigned ia32_signal_class[] = {
#include <asm-generic/audit_signal.h>
~0U
};
int ia32_classify_syscall(unsigned syscall)
{
switch(syscall) {
case __NR_open:
return 2;
case __NR_openat:
return 3;
case __NR_socketcall:
return 4;
case __NR_execve:
return 5;
default:
return 1;
}
}

View File

@@ -0,0 +1,245 @@
/*
* IA-32 ELF support.
*
* Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
* Copyright (C) 2001 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 06/16/00 A. Mallick initialize csd/ssd/tssd/cflg for ia32_load_state
* 04/13/01 D. Mosberger dropped saving tssd in ar.k1---it's not needed
* 09/14/01 D. Mosberger fixed memory management for gdt/tss page
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/security.h>
#include <asm/param.h>
#include <asm/signal.h>
#include "ia32priv.h"
#include "elfcore32.h"
/* Override some function names */
#undef start_thread
#define start_thread ia32_start_thread
#define elf_format elf32_format
#define init_elf_binfmt init_elf32_binfmt
#define exit_elf_binfmt exit_elf32_binfmt
#undef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC IA32_CLOCKS_PER_SEC
extern void ia64_elf32_init (struct pt_regs *regs);
static void elf32_set_personality (void);
static unsigned long __attribute ((unused))
randomize_stack_top(unsigned long stack_top);
#define setup_arg_pages(bprm,tos,exec) ia32_setup_arg_pages(bprm,exec)
#define elf_map elf32_map
#undef SET_PERSONALITY
#define SET_PERSONALITY(ex) elf32_set_personality()
#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
/* Ugly but avoids duplication */
#include "../../../fs/binfmt_elf.c"
extern struct page *ia32_shared_page[];
extern unsigned long *ia32_gdt;
extern struct page *ia32_gate_page;
int
ia32_install_shared_page (struct vm_area_struct *vma, struct vm_fault *vmf)
{
vmf->page = ia32_shared_page[smp_processor_id()];
get_page(vmf->page);
return 0;
}
int
ia32_install_gate_page (struct vm_area_struct *vma, struct vm_fault *vmf)
{
vmf->page = ia32_gate_page;
get_page(vmf->page);
return 0;
}
static const struct vm_operations_struct ia32_shared_page_vm_ops = {
.fault = ia32_install_shared_page
};
static const struct vm_operations_struct ia32_gate_page_vm_ops = {
.fault = ia32_install_gate_page
};
void
ia64_elf32_init (struct pt_regs *regs)
{
struct vm_area_struct *vma;
/*
* Map GDT below 4GB, where the processor can find it. We need to map
* it with privilege level 3 because the IVE uses non-privileged accesses to these
* tables. IA-32 segmentation is used to protect against IA-32 accesses to them.
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (vma) {
vma->vm_mm = current->mm;
vma->vm_start = IA32_GDT_OFFSET;
vma->vm_end = vma->vm_start + PAGE_SIZE;
vma->vm_page_prot = PAGE_SHARED;
vma->vm_flags = VM_READ|VM_MAYREAD|VM_RESERVED;
vma->vm_ops = &ia32_shared_page_vm_ops;
down_write(&current->mm->mmap_sem);
{
if (insert_vm_struct(current->mm, vma)) {
kmem_cache_free(vm_area_cachep, vma);
up_write(&current->mm->mmap_sem);
BUG();
}
}
up_write(&current->mm->mmap_sem);
}
/*
* When user stack is not executable, push sigreturn code to stack makes
* segmentation fault raised when returning to kernel. So now sigreturn
* code is locked in specific gate page, which is pointed by pretcode
* when setup_frame_ia32
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (vma) {
vma->vm_mm = current->mm;
vma->vm_start = IA32_GATE_OFFSET;
vma->vm_end = vma->vm_start + PAGE_SIZE;
vma->vm_page_prot = PAGE_COPY_EXEC;
vma->vm_flags = VM_READ | VM_MAYREAD | VM_EXEC
| VM_MAYEXEC | VM_RESERVED;
vma->vm_ops = &ia32_gate_page_vm_ops;
down_write(&current->mm->mmap_sem);
{
if (insert_vm_struct(current->mm, vma)) {
kmem_cache_free(vm_area_cachep, vma);
up_write(&current->mm->mmap_sem);
BUG();
}
}
up_write(&current->mm->mmap_sem);
}
/*
* Install LDT as anonymous memory. This gives us all-zero segment descriptors
* until a task modifies them via modify_ldt().
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (vma) {
vma->vm_mm = current->mm;
vma->vm_start = IA32_LDT_OFFSET;
vma->vm_end = vma->vm_start + PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE);
vma->vm_page_prot = PAGE_SHARED;
vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE;
down_write(&current->mm->mmap_sem);
{
if (insert_vm_struct(current->mm, vma)) {
kmem_cache_free(vm_area_cachep, vma);
up_write(&current->mm->mmap_sem);
BUG();
}
}
up_write(&current->mm->mmap_sem);
}
ia64_psr(regs)->ac = 0; /* turn off alignment checking */
regs->loadrs = 0;
/*
* According to the ABI %edx points to an `atexit' handler. Since we don't have
* one we'll set it to 0 and initialize all the other registers just to make
* things more deterministic, ala the i386 implementation.
*/
regs->r8 = 0; /* %eax */
regs->r11 = 0; /* %ebx */
regs->r9 = 0; /* %ecx */
regs->r10 = 0; /* %edx */
regs->r13 = 0; /* %ebp */
regs->r14 = 0; /* %esi */
regs->r15 = 0; /* %edi */
current->thread.eflag = IA32_EFLAG;
current->thread.fsr = IA32_FSR_DEFAULT;
current->thread.fcr = IA32_FCR_DEFAULT;
current->thread.fir = 0;
current->thread.fdr = 0;
/*
* Setup GDTD. Note: GDTD is the descrambled version of the pseudo-descriptor
* format defined by Figure 3-11 "Pseudo-Descriptor Format" in the IA-32
* architecture manual. Also note that the only fields that are not ignored are
* `base', `limit', 'G', `P' (must be 1) and `S' (must be 0).
*/
regs->r31 = IA32_SEG_UNSCRAMBLE(IA32_SEG_DESCRIPTOR(IA32_GDT_OFFSET, IA32_PAGE_SIZE - 1,
0, 0, 0, 1, 0, 0, 0));
/* Setup the segment selectors */
regs->r16 = (__USER_DS << 16) | __USER_DS; /* ES == DS, GS, FS are zero */
regs->r17 = (__USER_DS << 16) | __USER_CS; /* SS, CS; ia32_load_state() sets TSS and LDT */
ia32_load_segment_descriptors(current);
ia32_load_state(current);
}
/*
* Undo the override of setup_arg_pages() without this ia32_setup_arg_pages()
* will suffer infinite self recursion.
*/
#undef setup_arg_pages
int
ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
{
int ret;
ret = setup_arg_pages(bprm, IA32_STACK_TOP, executable_stack);
if (!ret) {
/*
* Can't do it in ia64_elf32_init(). Needs to be done before
* calls to elf32_map()
*/
current->thread.ppl = ia32_init_pp_list();
}
return ret;
}
static void
elf32_set_personality (void)
{
set_personality(PER_LINUX32);
current->thread.map_base = IA32_PAGE_OFFSET/3;
}
static unsigned long
elf32_map(struct file *filep, unsigned long addr, struct elf_phdr *eppnt,
int prot, int type, unsigned long unused)
{
unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
return ia32_do_mmap(filep, (addr & IA32_PAGE_MASK), eppnt->p_filesz + pgoff, prot, type,
eppnt->p_offset - pgoff);
}
#define cpu_uses_ia32el() (local_cpu_data->family > 0x1f)
static int __init check_elf32_binfmt(void)
{
if (cpu_uses_ia32el()) {
printk("Please use IA-32 EL for executing IA-32 binaries\n");
unregister_binfmt(&elf_format);
}
return 0;
}
module_init(check_elf32_binfmt)

View File

@@ -0,0 +1,150 @@
/*
* IA-32 ELF core dump support.
*
* Copyright (C) 2003 Arun Sharma <arun.sharma@intel.com>
*
* Derived from the x86_64 version
*/
#ifndef _ELFCORE32_H_
#define _ELFCORE32_H_
#include <asm/intrinsics.h>
#include <asm/uaccess.h>
#define USE_ELF_CORE_DUMP 1
/* Override elfcore.h */
#define _LINUX_ELFCORE_H 1
typedef unsigned int elf_greg_t;
#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct ia32_user_i387_struct elf_fpregset_t;
typedef struct ia32_user_fxsr_struct elf_fpxregset_t;
struct elf_siginfo
{
int si_signo; /* signal number */
int si_code; /* extra code */
int si_errno; /* errno */
};
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/*
* Hacks are here since types between compat_timeval (= pair of s32) and
* ia64-native timeval (= pair of s64) are not compatible, at least a file
* arch/ia64/ia32/../../../fs/binfmt_elf.c will get warnings from compiler on
* use of cputime_to_timeval(), which usually an alias of jiffies_to_timeval().
*/
#define cputime_to_timeval(a,b) \
do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
#else
#define jiffies_to_timeval(a,b) \
do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; } while(0)
#endif
struct elf_prstatus
{
struct elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
unsigned int pr_sigpend; /* Set of pending signals */
unsigned int pr_sighold; /* Set of held signals */
pid_t pr_pid;
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct compat_timeval pr_utime; /* User time */
struct compat_timeval pr_stime; /* System time */
struct compat_timeval pr_cutime; /* Cumulative user time */
struct compat_timeval pr_cstime; /* Cumulative system time */
elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* True if math co-processor being used. */
};
#define ELF_PRARGSZ (80) /* Number of chars for args */
struct elf_prpsinfo
{
char pr_state; /* numeric process state */
char pr_sname; /* char for pr_state */
char pr_zomb; /* zombie */
char pr_nice; /* nice val */
unsigned int pr_flag; /* flags */
__u16 pr_uid;
__u16 pr_gid;
pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
/* Lots missing */
char pr_fname[16]; /* filename of executable */
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
pr_reg[0] = regs->r11; \
pr_reg[1] = regs->r9; \
pr_reg[2] = regs->r10; \
pr_reg[3] = regs->r14; \
pr_reg[4] = regs->r15; \
pr_reg[5] = regs->r13; \
pr_reg[6] = regs->r8; \
pr_reg[7] = regs->r16 & 0xffff; \
pr_reg[8] = (regs->r16 >> 16) & 0xffff; \
pr_reg[9] = (regs->r16 >> 32) & 0xffff; \
pr_reg[10] = (regs->r16 >> 48) & 0xffff; \
pr_reg[11] = regs->r1; \
pr_reg[12] = regs->cr_iip; \
pr_reg[13] = regs->r17 & 0xffff; \
pr_reg[14] = ia64_getreg(_IA64_REG_AR_EFLAG); \
pr_reg[15] = regs->r12; \
pr_reg[16] = (regs->r17 >> 16) & 0xffff;
static inline void elf_core_copy_regs(elf_gregset_t *elfregs,
struct pt_regs *regs)
{
ELF_CORE_COPY_REGS((*elfregs), regs)
}
static inline int elf_core_copy_task_regs(struct task_struct *t,
elf_gregset_t* elfregs)
{
ELF_CORE_COPY_REGS((*elfregs), task_pt_regs(t));
return 1;
}
static inline int
elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
{
struct ia32_user_i387_struct *fpstate = (void*)fpu;
mm_segment_t old_fs;
if (!tsk_used_math(tsk))
return 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
save_ia32_fpstate(tsk, (struct ia32_user_i387_struct __user *) fpstate);
set_fs(old_fs);
return 1;
}
#define ELF_CORE_COPY_XFPREGS 1
#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
static inline int
elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
{
struct ia32_user_fxsr_struct *fpxstate = (void*) xfpu;
mm_segment_t old_fs;
if (!tsk_used_math(tsk))
return 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
save_ia32_fpxstate(tsk, (struct ia32_user_fxsr_struct __user *) fpxstate);
set_fs(old_fs);
return 1;
}
#endif /* _ELFCORE32_H_ */

View File

@@ -0,0 +1,468 @@
#include <asm/asmmacro.h>
#include <asm/ia32.h>
#include <asm/asm-offsets.h>
#include <asm/signal.h>
#include <asm/thread_info.h>
#include "../kernel/minstate.h"
/*
* execve() is special because in case of success, we need to
* setup a null register window frame (in case an IA-32 process
* is exec'ing an IA-64 program).
*/
ENTRY(ia32_execve)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
alloc loc1=ar.pfs,3,2,4,0
mov loc0=rp
.body
zxt4 out0=in0 // filename
;; // stop bit between alloc and call
zxt4 out1=in1 // argv
zxt4 out2=in2 // envp
add out3=16,sp // regs
br.call.sptk.few rp=sys32_execve
1: cmp.ge p6,p0=r8,r0
mov ar.pfs=loc1 // restore ar.pfs
;;
(p6) mov ar.pfs=r0 // clear ar.pfs in case of success
sxt4 r8=r8 // return 64-bit result
mov rp=loc0
br.ret.sptk.few rp
END(ia32_execve)
ENTRY(ia32_clone)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
alloc r16=ar.pfs,5,2,6,0
DO_SAVE_SWITCH_STACK
mov loc0=rp
mov loc1=r16 // save ar.pfs across do_fork
.body
zxt4 out1=in1 // newsp
mov out3=16 // stacksize (compensates for 16-byte scratch area)
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
mov out0=in0 // out0 = clone_flags
zxt4 out4=in2 // out4 = parent_tidptr
zxt4 out5=in4 // out5 = child_tidptr
br.call.sptk.many rp=do_fork
.ret0: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
END(ia32_clone)
GLOBAL_ENTRY(ia32_ret_from_clone)
PT_REGS_UNWIND_INFO(0)
{ /*
* Some versions of gas generate bad unwind info if the first instruction of a
* procedure doesn't go into the first slot of a bundle. This is a workaround.
*/
nop.m 0
nop.i 0
/*
* We need to call schedule_tail() to complete the scheduling process.
* Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the
* address of the previously executing task.
*/
br.call.sptk.many rp=ia64_invoke_schedule_tail
}
.ret1:
adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
;;
ld4 r2=[r2]
;;
mov r8=0
and r2=_TIF_SYSCALL_TRACEAUDIT,r2
;;
cmp.ne p6,p0=r2,r0
(p6) br.cond.spnt .ia32_strace_check_retval
;; // prevent RAW on r8
END(ia32_ret_from_clone)
// fall thrugh
GLOBAL_ENTRY(ia32_ret_from_syscall)
PT_REGS_UNWIND_INFO(0)
cmp.ge p6,p7=r8,r0 // syscall executed successfully?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
alloc r3=ar.pfs,0,0,0,0 // drop the syscall argument frame
st8 [r2]=r8 // store return value in slot for r8
br.cond.sptk.many ia64_leave_kernel
END(ia32_ret_from_syscall)
//
// Invoke a system call, but do some tracing before and after the call.
// We MUST preserve the current register frame throughout this routine
// because some system calls (such as ia64_execve) directly
// manipulate ar.pfs.
//
// Input:
// r8 = syscall number
// b6 = syscall entry point
//
GLOBAL_ENTRY(ia32_trace_syscall)
PT_REGS_UNWIND_INFO(0)
mov r3=-38
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp
;;
st8 [r2]=r3 // initialize return code to -ENOSYS
br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args
cmp.lt p6,p0=r8,r0 // check tracehook
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
(p6) st8.spill [r2]=r8 // store return value in slot for r8
(p6) br.spnt.few .ret4
.ret2: // Need to reload arguments (they may be changed by the tracing process)
adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1
adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13
mov r15=IA32_NR_syscalls
;;
ld4 r8=[r2],IA64_PT_REGS_R9_OFFSET-IA64_PT_REGS_R1_OFFSET
movl r16=ia32_syscall_table
;;
ld4 r33=[r2],8 // r9 == ecx
ld4 r37=[r3],16 // r13 == ebp
cmp.ltu.unc p6,p7=r8,r15
;;
ld4 r34=[r2],8 // r10 == edx
ld4 r36=[r3],8 // r15 == edi
(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number
;;
ld8 r16=[r16]
;;
ld4 r32=[r2],8 // r11 == ebx
mov b6=r16
ld4 r35=[r3],8 // r14 == esi
br.call.sptk.few rp=b6 // do the syscall
.ia32_strace_check_retval:
cmp.lt p6,p0=r8,r0 // syscall failed?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
st8.spill [r2]=r8 // store return value in slot for r8
br.call.sptk.few rp=syscall_trace_leave // give parent a chance to catch return value
.ret4: alloc r2=ar.pfs,0,0,0,0 // drop the syscall argument frame
br.cond.sptk.many ia64_leave_kernel
END(ia32_trace_syscall)
GLOBAL_ENTRY(sys32_vfork)
alloc r16=ar.pfs,2,2,4,0;;
mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags
br.cond.sptk.few .fork1 // do the work
END(sys32_vfork)
GLOBAL_ENTRY(sys32_fork)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
alloc r16=ar.pfs,2,2,4,0
mov out0=SIGCHLD // out0 = clone_flags
;;
.fork1:
mov loc0=rp
mov loc1=r16 // save ar.pfs across do_fork
DO_SAVE_SWITCH_STACK
.body
mov out1=0
mov out3=0
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
br.call.sptk.few rp=do_fork
.ret5: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
END(sys32_fork)
.rodata
.align 8
.globl ia32_syscall_table
ia32_syscall_table:
data8 sys_ni_syscall /* 0 - old "setup(" system call*/
data8 sys_exit
data8 sys32_fork
data8 sys_read
data8 sys_write
data8 compat_sys_open /* 5 */
data8 sys_close
data8 sys32_waitpid
data8 sys_creat
data8 sys_link
data8 sys_unlink /* 10 */
data8 ia32_execve
data8 sys_chdir
data8 compat_sys_time
data8 sys_mknod
data8 sys_chmod /* 15 */
data8 sys_lchown /* 16-bit version */
data8 sys_ni_syscall /* old break syscall holder */
data8 sys_ni_syscall
data8 sys32_lseek
data8 sys_getpid /* 20 */
data8 compat_sys_mount
data8 sys_oldumount
data8 sys_setuid /* 16-bit version */
data8 sys_getuid /* 16-bit version */
data8 compat_sys_stime /* 25 */
data8 compat_sys_ptrace
data8 sys32_alarm
data8 sys_ni_syscall
data8 sys_pause
data8 compat_sys_utime /* 30 */
data8 sys_ni_syscall /* old stty syscall holder */
data8 sys_ni_syscall /* old gtty syscall holder */
data8 sys_access
data8 sys_nice
data8 sys_ni_syscall /* 35 */ /* old ftime syscall holder */
data8 sys_sync
data8 sys_kill
data8 sys_rename
data8 sys_mkdir
data8 sys_rmdir /* 40 */
data8 sys_dup
data8 sys_ia64_pipe
data8 compat_sys_times
data8 sys_ni_syscall /* old prof syscall holder */
data8 sys32_brk /* 45 */
data8 sys_setgid /* 16-bit version */
data8 sys_getgid /* 16-bit version */
data8 sys32_signal
data8 sys_geteuid /* 16-bit version */
data8 sys_getegid /* 16-bit version */ /* 50 */
data8 sys_acct
data8 sys_umount /* recycled never used phys( */
data8 sys_ni_syscall /* old lock syscall holder */
data8 compat_sys_ioctl
data8 compat_sys_fcntl /* 55 */
data8 sys_ni_syscall /* old mpx syscall holder */
data8 sys_setpgid
data8 sys_ni_syscall /* old ulimit syscall holder */
data8 sys_ni_syscall
data8 sys_umask /* 60 */
data8 sys_chroot
data8 compat_sys_ustat
data8 sys_dup2
data8 sys_getppid
data8 sys_getpgrp /* 65 */
data8 sys_setsid
data8 sys32_sigaction
data8 sys_ni_syscall
data8 sys_ni_syscall
data8 sys_setreuid /* 16-bit version */ /* 70 */
data8 sys_setregid /* 16-bit version */
data8 sys32_sigsuspend
data8 compat_sys_sigpending
data8 sys_sethostname
data8 compat_sys_setrlimit /* 75 */
data8 compat_sys_old_getrlimit
data8 compat_sys_getrusage
data8 compat_sys_gettimeofday
data8 compat_sys_settimeofday
data8 sys32_getgroups16 /* 80 */
data8 sys32_setgroups16
data8 sys32_old_select
data8 sys_symlink
data8 sys_ni_syscall
data8 sys_readlink /* 85 */
data8 sys_uselib
data8 sys_swapon
data8 sys_reboot
data8 compat_sys_old_readdir
data8 sys32_mmap /* 90 */
data8 sys32_munmap
data8 sys_truncate
data8 sys_ftruncate
data8 sys_fchmod
data8 sys_fchown /* 16-bit version */ /* 95 */
data8 sys_getpriority
data8 sys_setpriority
data8 sys_ni_syscall /* old profil syscall holder */
data8 compat_sys_statfs
data8 compat_sys_fstatfs /* 100 */
data8 sys_ni_syscall /* ioperm */
data8 compat_sys_socketcall
data8 sys_syslog
data8 compat_sys_setitimer
data8 compat_sys_getitimer /* 105 */
data8 compat_sys_newstat
data8 compat_sys_newlstat
data8 compat_sys_newfstat
data8 sys_ni_syscall
data8 sys_ni_syscall /* iopl */ /* 110 */
data8 sys_vhangup
data8 sys_ni_syscall /* used to be sys_idle */
data8 sys_ni_syscall
data8 compat_sys_wait4
data8 sys_swapoff /* 115 */
data8 compat_sys_sysinfo
data8 sys32_ipc
data8 sys_fsync
data8 sys32_sigreturn
data8 ia32_clone /* 120 */
data8 sys_setdomainname
data8 sys32_newuname
data8 sys32_modify_ldt
data8 compat_sys_adjtimex
data8 sys32_mprotect /* 125 */
data8 compat_sys_sigprocmask
data8 sys_ni_syscall /* create_module */
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
data8 sys_sysfs /* 135 */
data8 sys32_personality
data8 sys_ni_syscall /* for afs_syscall */
data8 sys_setfsuid /* 16-bit version */
data8 sys_setfsgid /* 16-bit version */
data8 sys_llseek /* 140 */
data8 compat_sys_getdents
data8 compat_sys_select
data8 sys_flock
data8 sys32_msync
data8 compat_sys_readv /* 145 */
data8 compat_sys_writev
data8 sys_getsid
data8 sys_fdatasync
data8 sys32_sysctl
data8 sys_mlock /* 150 */
data8 sys_munlock
data8 sys_mlockall
data8 sys_munlockall
data8 sys_sched_setparam
data8 sys_sched_getparam /* 155 */
data8 sys_sched_setscheduler
data8 sys_sched_getscheduler
data8 sys_sched_yield
data8 sys_sched_get_priority_max
data8 sys_sched_get_priority_min /* 160 */
data8 sys32_sched_rr_get_interval
data8 compat_sys_nanosleep
data8 sys32_mremap
data8 sys_setresuid /* 16-bit version */
data8 sys32_getresuid16 /* 16-bit version */ /* 165 */
data8 sys_ni_syscall /* vm86 */
data8 sys_ni_syscall /* sys_query_module */
data8 sys_poll
data8 sys_ni_syscall /* nfsservctl */
data8 sys_setresgid /* 170 */
data8 sys32_getresgid16
data8 sys_prctl
data8 sys32_rt_sigreturn
data8 sys32_rt_sigaction
data8 sys32_rt_sigprocmask /* 175 */
data8 sys_rt_sigpending
data8 compat_sys_rt_sigtimedwait
data8 sys32_rt_sigqueueinfo
data8 compat_sys_rt_sigsuspend
data8 sys32_pread /* 180 */
data8 sys32_pwrite
data8 sys_chown /* 16-bit version */
data8 sys_getcwd
data8 sys_capget
data8 sys_capset /* 185 */
data8 sys32_sigaltstack
data8 sys32_sendfile
data8 sys_ni_syscall /* streams1 */
data8 sys_ni_syscall /* streams2 */
data8 sys32_vfork /* 190 */
data8 compat_sys_getrlimit
data8 sys32_mmap2
data8 sys32_truncate64
data8 sys32_ftruncate64
data8 sys32_stat64 /* 195 */
data8 sys32_lstat64
data8 sys32_fstat64
data8 sys_lchown
data8 sys_getuid
data8 sys_getgid /* 200 */
data8 sys_geteuid
data8 sys_getegid
data8 sys_setreuid
data8 sys_setregid
data8 sys_getgroups /* 205 */
data8 sys_setgroups
data8 sys_fchown
data8 sys_setresuid
data8 sys_getresuid
data8 sys_setresgid /* 210 */
data8 sys_getresgid
data8 sys_chown
data8 sys_setuid
data8 sys_setgid
data8 sys_setfsuid /* 215 */
data8 sys_setfsgid
data8 sys_pivot_root
data8 sys_mincore
data8 sys_madvise
data8 compat_sys_getdents64 /* 220 */
data8 compat_sys_fcntl64
data8 sys_ni_syscall /* reserved for TUX */
data8 sys_ni_syscall /* reserved for Security */
data8 sys_gettid
data8 sys_readahead /* 225 */
data8 sys_setxattr
data8 sys_lsetxattr
data8 sys_fsetxattr
data8 sys_getxattr
data8 sys_lgetxattr /* 230 */
data8 sys_fgetxattr
data8 sys_listxattr
data8 sys_llistxattr
data8 sys_flistxattr
data8 sys_removexattr /* 235 */
data8 sys_lremovexattr
data8 sys_fremovexattr
data8 sys_tkill
data8 sys_sendfile64
data8 compat_sys_futex /* 240 */
data8 compat_sys_sched_setaffinity
data8 compat_sys_sched_getaffinity
data8 sys32_set_thread_area
data8 sys32_get_thread_area
data8 compat_sys_io_setup /* 245 */
data8 sys_io_destroy
data8 compat_sys_io_getevents
data8 compat_sys_io_submit
data8 sys_io_cancel
data8 sys_fadvise64 /* 250 */
data8 sys_ni_syscall
data8 sys_exit_group
data8 sys_lookup_dcookie
data8 sys_epoll_create
data8 sys32_epoll_ctl /* 255 */
data8 sys32_epoll_wait
data8 sys_remap_file_pages
data8 sys_set_tid_address
data8 compat_sys_timer_create
data8 compat_sys_timer_settime /* 260 */
data8 compat_sys_timer_gettime
data8 sys_timer_getoverrun
data8 sys_timer_delete
data8 compat_sys_clock_settime
data8 compat_sys_clock_gettime /* 265 */
data8 compat_sys_clock_getres
data8 compat_sys_clock_nanosleep
data8 compat_sys_statfs64
data8 compat_sys_fstatfs64
data8 sys_tgkill /* 270 */
data8 compat_sys_utimes
data8 sys32_fadvise64_64
data8 sys_ni_syscall
data8 sys_ni_syscall
data8 sys_ni_syscall /* 275 */
data8 sys_ni_syscall
data8 compat_sys_mq_open
data8 sys_mq_unlink
data8 compat_sys_mq_timedsend
data8 compat_sys_mq_timedreceive /* 280 */
data8 compat_sys_mq_notify
data8 compat_sys_mq_getsetattr
data8 sys_ni_syscall /* reserved for kexec */
data8 compat_sys_waitid
// guard against failures to increase IA32_NR_syscalls
.org ia32_syscall_table + 8*IA32_NR_syscalls

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2001, 2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* Adapted from arch/i386/kernel/ldt.c
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
#include "ia32priv.h"
/*
* read_ldt() is not really atomic - this is not a problem since synchronization of reads
* and writes done to the LDT has to be assured by user-space anyway. Writes are atomic,
* to protect the security checks done on new descriptors.
*/
static int
read_ldt (void __user *ptr, unsigned long bytecount)
{
unsigned long bytes_left, n;
char __user *src, *dst;
char buf[256]; /* temporary buffer (don't overflow kernel stack!) */
if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE)
bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE;
bytes_left = bytecount;
src = (void __user *) IA32_LDT_OFFSET;
dst = ptr;
while (bytes_left) {
n = sizeof(buf);
if (n > bytes_left)
n = bytes_left;
/*
* We know we're reading valid memory, but we still must guard against
* running out of memory.
*/
if (__copy_from_user(buf, src, n))
return -EFAULT;
if (copy_to_user(dst, buf, n))
return -EFAULT;
src += n;
dst += n;
bytes_left -= n;
}
return bytecount;
}
static int
read_default_ldt (void __user * ptr, unsigned long bytecount)
{
unsigned long size;
int err;
/* XXX fix me: should return equivalent of default_ldt[0] */
err = 0;
size = 8;
if (size > bytecount)
size = bytecount;
err = size;
if (clear_user(ptr, size))
err = -EFAULT;
return err;
}
static int
write_ldt (void __user * ptr, unsigned long bytecount, int oldmode)
{
struct ia32_user_desc ldt_info;
__u64 entry;
int ret;
if (bytecount != sizeof(ldt_info))
return -EINVAL;
if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
return -EFAULT;
if (ldt_info.entry_number >= IA32_LDT_ENTRIES)
return -EINVAL;
if (ldt_info.contents == 3) {
if (oldmode)
return -EINVAL;
if (ldt_info.seg_not_present == 0)
return -EINVAL;
}
if (ldt_info.base_addr == 0 && ldt_info.limit == 0
&& (oldmode || (ldt_info.contents == 0 && ldt_info.read_exec_only == 1
&& ldt_info.seg_32bit == 0 && ldt_info.limit_in_pages == 0
&& ldt_info.seg_not_present == 1 && ldt_info.useable == 0)))
/* allow LDTs to be cleared by the user */
entry = 0;
else
/* we must set the "Accessed" bit as IVE doesn't emulate it */
entry = IA32_SEG_DESCRIPTOR(ldt_info.base_addr, ldt_info.limit,
(((ldt_info.read_exec_only ^ 1) << 1)
| (ldt_info.contents << 2)) | 1,
1, 3, ldt_info.seg_not_present ^ 1,
(oldmode ? 0 : ldt_info.useable),
ldt_info.seg_32bit,
ldt_info.limit_in_pages);
/*
* Install the new entry. We know we're accessing valid (mapped) user-level
* memory, but we still need to guard against out-of-memory, hence we must use
* put_user().
*/
ret = __put_user(entry, (__u64 __user *) IA32_LDT_OFFSET + ldt_info.entry_number);
ia32_load_segment_descriptors(current);
return ret;
}
asmlinkage int
sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount)
{
int ret = -ENOSYS;
switch (func) {
case 0:
ret = read_ldt(compat_ptr(ptr), bytecount);
break;
case 1:
ret = write_ldt(compat_ptr(ptr), bytecount, 1);
break;
case 2:
ret = read_default_ldt(compat_ptr(ptr), bytecount);
break;
case 0x11:
ret = write_ldt(compat_ptr(ptr), bytecount, 0);
break;
}
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
/*
* IA32 helper functions
*
* Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
* Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
* Copyright (C) 2001-2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 06/16/00 A. Mallick added csd/ssd/tssd for ia32 thread context
* 02/19/01 D. Mosberger dropped tssd; it's not needed
* 09/14/01 D. Mosberger fixed memory management for gdt/tss page
* 09/29/01 D. Mosberger added ia32_load_segment_descriptors()
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <asm/intrinsics.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include "ia32priv.h"
extern int die_if_kernel (char *str, struct pt_regs *regs, long err);
struct page *ia32_shared_page[NR_CPUS];
unsigned long *ia32_boot_gdt;
unsigned long *cpu_gdt_table[NR_CPUS];
struct page *ia32_gate_page;
static unsigned long
load_desc (u16 selector)
{
unsigned long *table, limit, index;
if (!selector)
return 0;
if (selector & IA32_SEGSEL_TI) {
table = (unsigned long *) IA32_LDT_OFFSET;
limit = IA32_LDT_ENTRIES;
} else {
table = cpu_gdt_table[smp_processor_id()];
limit = IA32_PAGE_SIZE / sizeof(ia32_boot_gdt[0]);
}
index = selector >> IA32_SEGSEL_INDEX_SHIFT;
if (index >= limit)
return 0;
return IA32_SEG_UNSCRAMBLE(table[index]);
}
void
ia32_load_segment_descriptors (struct task_struct *task)
{
struct pt_regs *regs = task_pt_regs(task);
/* Setup the segment descriptors */
regs->r24 = load_desc(regs->r16 >> 16); /* ESD */
regs->r27 = load_desc(regs->r16 >> 0); /* DSD */
regs->r28 = load_desc(regs->r16 >> 32); /* FSD */
regs->r29 = load_desc(regs->r16 >> 48); /* GSD */
regs->ar_csd = load_desc(regs->r17 >> 0); /* CSD */
regs->ar_ssd = load_desc(regs->r17 >> 16); /* SSD */
}
int
ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs)
{
struct desc_struct *desc;
struct ia32_user_desc info;
int idx;
if (copy_from_user(&info, (void __user *)(childregs->r14 & 0xffffffff), sizeof(info)))
return -EFAULT;
if (LDT_empty(&info))
return -EINVAL;
idx = info.entry_number;
if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
return -EINVAL;
desc = child->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
desc->a = LDT_entry_a(&info);
desc->b = LDT_entry_b(&info);
/* XXX: can this be done in a cleaner way ? */
load_TLS(&child->thread, smp_processor_id());
ia32_load_segment_descriptors(child);
load_TLS(&current->thread, smp_processor_id());
return 0;
}
void
ia32_save_state (struct task_struct *t)
{
t->thread.eflag = ia64_getreg(_IA64_REG_AR_EFLAG);
t->thread.fsr = ia64_getreg(_IA64_REG_AR_FSR);
t->thread.fcr = ia64_getreg(_IA64_REG_AR_FCR);
t->thread.fir = ia64_getreg(_IA64_REG_AR_FIR);
t->thread.fdr = ia64_getreg(_IA64_REG_AR_FDR);
ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob);
ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1);
}
void
ia32_load_state (struct task_struct *t)
{
unsigned long eflag, fsr, fcr, fir, fdr, tssd;
struct pt_regs *regs = task_pt_regs(t);
eflag = t->thread.eflag;
fsr = t->thread.fsr;
fcr = t->thread.fcr;
fir = t->thread.fir;
fdr = t->thread.fdr;
tssd = load_desc(_TSS); /* TSSD */
ia64_setreg(_IA64_REG_AR_EFLAG, eflag);
ia64_setreg(_IA64_REG_AR_FSR, fsr);
ia64_setreg(_IA64_REG_AR_FCR, fcr);
ia64_setreg(_IA64_REG_AR_FIR, fir);
ia64_setreg(_IA64_REG_AR_FDR, fdr);
current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD);
ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
ia64_set_kr(IA64_KR_TSSD, tssd);
regs->r17 = (_TSS << 48) | (_LDT << 32) | (__u32) regs->r17;
regs->r30 = load_desc(_LDT); /* LDTD */
load_TLS(&t->thread, smp_processor_id());
}
/*
* Setup IA32 GDT and TSS
*/
void
ia32_gdt_init (void)
{
int cpu = smp_processor_id();
ia32_shared_page[cpu] = alloc_page(GFP_KERNEL);
if (!ia32_shared_page[cpu])
panic("failed to allocate ia32_shared_page[%d]\n", cpu);
cpu_gdt_table[cpu] = page_address(ia32_shared_page[cpu]);
/* Copy from the boot cpu's GDT */
memcpy(cpu_gdt_table[cpu], ia32_boot_gdt, PAGE_SIZE);
}
/*
* Setup IA32 GDT and TSS
*/
static void
ia32_boot_gdt_init (void)
{
unsigned long ldt_size;
ia32_shared_page[0] = alloc_page(GFP_KERNEL);
if (!ia32_shared_page[0])
panic("failed to allocate ia32_shared_page[0]\n");
ia32_boot_gdt = page_address(ia32_shared_page[0]);
cpu_gdt_table[0] = ia32_boot_gdt;
/* CS descriptor in IA-32 (scrambled) format */
ia32_boot_gdt[__USER_CS >> 3]
= IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT,
0xb, 1, 3, 1, 1, 1, 1);
/* DS descriptor in IA-32 (scrambled) format */
ia32_boot_gdt[__USER_DS >> 3]
= IA32_SEG_DESCRIPTOR(0, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT,
0x3, 1, 3, 1, 1, 1, 1);
ldt_size = PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE);
ia32_boot_gdt[TSS_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_TSS_OFFSET, 235,
0xb, 0, 3, 1, 1, 1, 0);
ia32_boot_gdt[LDT_ENTRY] = IA32_SEG_DESCRIPTOR(IA32_LDT_OFFSET, ldt_size - 1,
0x2, 0, 3, 1, 1, 1, 0);
}
static void
ia32_gate_page_init(void)
{
unsigned long *sr;
ia32_gate_page = alloc_page(GFP_KERNEL);
sr = page_address(ia32_gate_page);
/* This is popl %eax ; movl $,%eax ; int $0x80 */
*sr++ = 0xb858 | (__IA32_NR_sigreturn << 16) | (0x80cdUL << 48);
/* This is movl $,%eax ; int $0x80 */
*sr = 0xb8 | (__IA32_NR_rt_sigreturn << 8) | (0x80cdUL << 40);
}
void
ia32_mem_init(void)
{
ia32_boot_gdt_init();
ia32_gate_page_init();
}
/*
* Handle bad IA32 interrupt via syscall
*/
void
ia32_bad_interrupt (unsigned long int_num, struct pt_regs *regs)
{
siginfo_t siginfo;
if (die_if_kernel("Bad IA-32 interrupt", regs, int_num))
return;
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = int_num; /* XXX is it OK to abuse si_errno like this? */
siginfo.si_flags = 0;
siginfo.si_isr = 0;
siginfo.si_addr = NULL;
siginfo.si_imm = 0;
siginfo.si_code = TRAP_BRKPT;
force_sig_info(SIGTRAP, &siginfo, current);
}
void
ia32_cpu_init (void)
{
/* initialize global ia32 state - CR0 and CR4 */
ia64_setreg(_IA64_REG_AR_CFLAG, (((ulong) IA32_CR4 << 32) | IA32_CR0));
}
static int __init
ia32_init (void)
{
#if PAGE_SHIFT > IA32_PAGE_SHIFT
{
extern struct kmem_cache *ia64_partial_page_cachep;
ia64_partial_page_cachep = kmem_cache_create("ia64_partial_page_cache",
sizeof(struct ia64_partial_page),
0, SLAB_PANIC, NULL);
}
#endif
return 0;
}
__initcall(ia32_init);

View File

@@ -0,0 +1,156 @@
/*
* IA-32 exception handlers
*
* Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
* Copyright (C) 2001-2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 06/16/00 A. Mallick added siginfo for most cases (close to IA32)
* 09/29/00 D. Mosberger added ia32_intercept()
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include "ia32priv.h"
#include <asm/intrinsics.h>
#include <asm/ptrace.h>
int
ia32_intercept (struct pt_regs *regs, unsigned long isr)
{
switch ((isr >> 16) & 0xff) {
case 0: /* Instruction intercept fault */
case 4: /* Locked Data reference fault */
case 1: /* Gate intercept trap */
return -1;
case 2: /* System flag trap */
if (((isr >> 14) & 0x3) >= 2) {
/* MOV SS, POP SS instructions */
ia64_psr(regs)->id = 1;
return 0;
} else
return -1;
}
return -1;
}
int
ia32_exception (struct pt_regs *regs, unsigned long isr)
{
struct siginfo siginfo;
/* initialize these fields to avoid leaking kernel bits to user space: */
siginfo.si_errno = 0;
siginfo.si_flags = 0;
siginfo.si_isr = 0;
siginfo.si_imm = 0;
switch ((isr >> 16) & 0xff) {
case 1:
case 2:
siginfo.si_signo = SIGTRAP;
if (isr == 0)
siginfo.si_code = TRAP_TRACE;
else if (isr & 0x4)
siginfo.si_code = TRAP_BRANCH;
else
siginfo.si_code = TRAP_BRKPT;
break;
case 3:
siginfo.si_signo = SIGTRAP;
siginfo.si_code = TRAP_BRKPT;
break;
case 0: /* Divide fault */
siginfo.si_signo = SIGFPE;
siginfo.si_code = FPE_INTDIV;
break;
case 4: /* Overflow */
case 5: /* Bounds fault */
siginfo.si_signo = SIGFPE;
siginfo.si_code = 0;
break;
case 6: /* Invalid Op-code */
siginfo.si_signo = SIGILL;
siginfo.si_code = ILL_ILLOPN;
break;
case 7: /* FP DNA */
case 8: /* Double Fault */
case 9: /* Invalid TSS */
case 11: /* Segment not present */
case 12: /* Stack fault */
case 13: /* General Protection Fault */
siginfo.si_signo = SIGSEGV;
siginfo.si_code = 0;
break;
case 16: /* Pending FP error */
{
unsigned long fsr, fcr;
fsr = ia64_getreg(_IA64_REG_AR_FSR);
fcr = ia64_getreg(_IA64_REG_AR_FCR);
siginfo.si_signo = SIGFPE;
/*
* (~cwd & swd) will mask out exceptions that are not set to unmasked
* status. 0x3f is the exception bits in these regs, 0x200 is the
* C1 reg you need in case of a stack fault, 0x040 is the stack
* fault bit. We should only be taking one exception at a time,
* so if this combination doesn't produce any single exception,
* then we have a bad program that isn't synchronizing its FPU usage
* and it will suffer the consequences since we won't be able to
* fully reproduce the context of the exception
*/
siginfo.si_isr = isr;
siginfo.si_flags = __ISR_VALID;
switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) {
case 0x000:
default:
siginfo.si_code = 0;
break;
case 0x001: /* Invalid Op */
case 0x040: /* Stack Fault */
case 0x240: /* Stack Fault | Direction */
siginfo.si_code = FPE_FLTINV;
break;
case 0x002: /* Denormalize */
case 0x010: /* Underflow */
siginfo.si_code = FPE_FLTUND;
break;
case 0x004: /* Zero Divide */
siginfo.si_code = FPE_FLTDIV;
break;
case 0x008: /* Overflow */
siginfo.si_code = FPE_FLTOVF;
break;
case 0x020: /* Precision */
siginfo.si_code = FPE_FLTRES;
break;
}
break;
}
case 17: /* Alignment check */
siginfo.si_signo = SIGSEGV;
siginfo.si_code = BUS_ADRALN;
break;
case 19: /* SSE Numeric error */
siginfo.si_signo = SIGFPE;
siginfo.si_code = 0;
break;
default:
return -1;
}
force_sig_info(siginfo.si_signo, &siginfo, current);
return 0;
}

View File

@@ -0,0 +1,532 @@
#ifndef _ASM_IA64_IA32_PRIV_H
#define _ASM_IA64_IA32_PRIV_H
#include <asm/ia32.h>
#ifdef CONFIG_IA32_SUPPORT
#include <linux/binfmts.h>
#include <linux/compat.h>
#include <linux/rbtree.h>
#include <asm/processor.h>
/*
* 32 bit structures for IA32 support.
*/
#define IA32_PAGE_SIZE (1UL << IA32_PAGE_SHIFT)
#define IA32_PAGE_MASK (~(IA32_PAGE_SIZE - 1))
#define IA32_PAGE_ALIGN(addr) (((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK)
#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */
/*
* partially mapped pages provide precise accounting of which 4k sub pages
* are mapped and which ones are not, thereby improving IA-32 compatibility.
*/
struct ia64_partial_page {
struct ia64_partial_page *next; /* linked list, sorted by address */
struct rb_node pp_rb;
/* 64K is the largest "normal" page supported by ia64 ABI. So 4K*64
* should suffice.*/
unsigned long bitmap;
unsigned int base;
};
struct ia64_partial_page_list {
struct ia64_partial_page *pp_head; /* list head, points to the lowest
* addressed partial page */
struct rb_root ppl_rb;
struct ia64_partial_page *pp_hint; /* pp_hint->next is the last
* accessed partial page */
atomic_t pp_count; /* reference count */
};
#if PAGE_SHIFT > IA32_PAGE_SHIFT
struct ia64_partial_page_list* ia32_init_pp_list (void);
#else
# define ia32_init_pp_list() 0
#endif
/* sigcontext.h */
/*
* As documented in the iBCS2 standard..
*
* The first part of "struct _fpstate" is just the
* normal i387 hardware setup, the extra "status"
* word is used to save the coprocessor status word
* before entering the handler.
*/
struct _fpreg_ia32 {
unsigned short significand[4];
unsigned short exponent;
};
struct _fpxreg_ia32 {
unsigned short significand[4];
unsigned short exponent;
unsigned short padding[3];
};
struct _xmmreg_ia32 {
unsigned int element[4];
};
struct _fpstate_ia32 {
unsigned int cw,
sw,
tag,
ipoff,
cssel,
dataoff,
datasel;
struct _fpreg_ia32 _st[8];
unsigned short status;
unsigned short magic; /* 0xffff = regular FPU data only */
/* FXSR FPU environment */
unsigned int _fxsr_env[6]; /* FXSR FPU env is ignored */
unsigned int mxcsr;
unsigned int reserved;
struct _fpxreg_ia32 _fxsr_st[8]; /* FXSR FPU reg data is ignored */
struct _xmmreg_ia32 _xmm[8];
unsigned int padding[56];
};
struct sigcontext_ia32 {
unsigned short gs, __gsh;
unsigned short fs, __fsh;
unsigned short es, __esh;
unsigned short ds, __dsh;
unsigned int edi;
unsigned int esi;
unsigned int ebp;
unsigned int esp;
unsigned int ebx;
unsigned int edx;
unsigned int ecx;
unsigned int eax;
unsigned int trapno;
unsigned int err;
unsigned int eip;
unsigned short cs, __csh;
unsigned int eflags;
unsigned int esp_at_signal;
unsigned short ss, __ssh;
unsigned int fpstate; /* really (struct _fpstate_ia32 *) */
unsigned int oldmask;
unsigned int cr2;
};
/* user.h */
/*
* IA32 (Pentium III/4) FXSR, SSE support
*
* Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for
* interacting with the FXSR-format floating point environment. Floating
* point data can be accessed in the regular format in the usual manner,
* and both the standard and SIMD floating point data can be accessed via
* the new ptrace requests. In either case, changes to the FPU environment
* will be reflected in the task's state as expected.
*/
struct ia32_user_i387_struct {
int cwd;
int swd;
int twd;
int fip;
int fcs;
int foo;
int fos;
/* 8*10 bytes for each FP-reg = 80 bytes */
struct _fpreg_ia32 st_space[8];
};
struct ia32_user_fxsr_struct {
unsigned short cwd;
unsigned short swd;
unsigned short twd;
unsigned short fop;
int fip;
int fcs;
int foo;
int fos;
int mxcsr;
int reserved;
int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
int padding[56];
};
/* signal.h */
#define IA32_SET_SA_HANDLER(ka,handler,restorer) \
((ka)->sa.sa_handler = (__sighandler_t) \
(((unsigned long)(restorer) << 32) \
| ((handler) & 0xffffffff)))
#define IA32_SA_HANDLER(ka) ((unsigned long) (ka)->sa.sa_handler & 0xffffffff)
#define IA32_SA_RESTORER(ka) ((unsigned long) (ka)->sa.sa_handler >> 32)
#define __IA32_NR_sigreturn 119
#define __IA32_NR_rt_sigreturn 173
struct sigaction32 {
unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */
unsigned int sa_flags;
unsigned int sa_restorer; /* Another 32 bit pointer */
compat_sigset_t sa_mask; /* A 32 bit mask */
};
struct old_sigaction32 {
unsigned int sa_handler; /* Really a pointer, but need to deal
with 32 bits */
compat_old_sigset_t sa_mask; /* A 32 bit mask */
unsigned int sa_flags;
unsigned int sa_restorer; /* Another 32 bit pointer */
};
typedef struct sigaltstack_ia32 {
unsigned int ss_sp;
int ss_flags;
unsigned int ss_size;
} stack_ia32_t;
struct ucontext_ia32 {
unsigned int uc_flags;
unsigned int uc_link;
stack_ia32_t uc_stack;
struct sigcontext_ia32 uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
};
struct stat64 {
unsigned long long st_dev;
unsigned char __pad0[4];
unsigned int __st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned long long st_rdev;
unsigned char __pad3[4];
unsigned int st_size_lo;
unsigned int st_size_hi;
unsigned int st_blksize;
unsigned int st_blocks; /* Number 512-byte blocks allocated. */
unsigned int __pad4; /* future possible st_blocks high bits */
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int st_ino_lo;
unsigned int st_ino_hi;
};
typedef struct compat_siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[((128/sizeof(int)) - 3)];
/* kill() */
struct {
unsigned int _pid; /* sender's pid */
unsigned int _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
compat_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
char _pad[sizeof(unsigned int) - sizeof(int)];
compat_sigval_t _sigval; /* same as below */
int _sys_private; /* not to be passed to user */
} _timer;
/* POSIX.1b signals */
struct {
unsigned int _pid; /* sender's pid */
unsigned int _uid; /* sender's uid */
compat_sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
unsigned int _pid; /* which child */
unsigned int _uid; /* sender's uid */
int _status; /* exit code */
compat_clock_t _utime;
compat_clock_t _stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
struct {
unsigned int _addr; /* faulting insn/memory ref. */
} _sigfault;
/* SIGPOLL */
struct {
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;
} _sifields;
} compat_siginfo_t;
/*
* IA-32 ELF specific definitions for IA-64.
*/
#define _ASM_IA64_ELF_H /* Don't include elf.h */
#include <linux/sched.h>
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x)->e_machine == EM_386)
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_386
#define IA32_STACK_TOP IA32_PAGE_OFFSET
#define IA32_GATE_OFFSET IA32_PAGE_OFFSET
#define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
/*
* The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
* access them.
*/
#define IA32_GDT_OFFSET (IA32_PAGE_OFFSET + PAGE_SIZE)
#define IA32_TSS_OFFSET (IA32_PAGE_OFFSET + 2*PAGE_SIZE)
#define IA32_LDT_OFFSET (IA32_PAGE_OFFSET + 3*PAGE_SIZE)
#define ELF_EXEC_PAGESIZE IA32_PAGE_SIZE
/*
* This is the location that an ET_DYN program is loaded if exec'ed.
* Typical use of this is to invoke "./ld.so someprog" to test out a
* new version of the loader. We need to make sure that it is out of
* the way of the program that it will "exec", and that there is
* sufficient room for the brk.
*/
#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000)
void ia64_elf32_init(struct pt_regs *regs);
#define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r)
/* This macro yields a bitmask that programs can use to figure out
what instruction set this CPU supports. */
#define ELF_HWCAP 0
/* This macro yields a string that ld.so will use to load
implementation specific libraries for optimization. Not terribly
relevant until we have real hardware to play with... */
#define ELF_PLATFORM NULL
#ifdef __KERNEL__
# define SET_PERSONALITY(EX) \
(current->personality = PER_LINUX)
#endif
#define IA32_EFLAG 0x200
/*
* IA-32 ELF specific definitions for IA-64.
*/
#define __USER_CS 0x23
#define __USER_DS 0x2B
/*
* The per-cpu GDT has 32 entries: see <asm-i386/segment.h>
*/
#define GDT_ENTRIES 32
#define GDT_SIZE (GDT_ENTRIES * 8)
#define TSS_ENTRY 14
#define LDT_ENTRY (TSS_ENTRY + 1)
#define IA32_SEGSEL_RPL (0x3 << 0)
#define IA32_SEGSEL_TI (0x1 << 2)
#define IA32_SEGSEL_INDEX_SHIFT 3
#define _TSS ((unsigned long) TSS_ENTRY << IA32_SEGSEL_INDEX_SHIFT)
#define _LDT ((unsigned long) LDT_ENTRY << IA32_SEGSEL_INDEX_SHIFT)
#define IA32_SEG_BASE 16
#define IA32_SEG_TYPE 40
#define IA32_SEG_SYS 44
#define IA32_SEG_DPL 45
#define IA32_SEG_P 47
#define IA32_SEG_HIGH_LIMIT 48
#define IA32_SEG_AVL 52
#define IA32_SEG_DB 54
#define IA32_SEG_G 55
#define IA32_SEG_HIGH_BASE 56
#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran) \
(((limit) & 0xffff) \
| (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE) \
| ((unsigned long) (segtype) << IA32_SEG_TYPE) \
| ((unsigned long) (nonsysseg) << IA32_SEG_SYS) \
| ((unsigned long) (dpl) << IA32_SEG_DPL) \
| ((unsigned long) (segpresent) << IA32_SEG_P) \
| ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT) \
| ((unsigned long) (avl) << IA32_SEG_AVL) \
| ((unsigned long) (segdb) << IA32_SEG_DB) \
| ((unsigned long) (gran) << IA32_SEG_G) \
| ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE))
#define SEG_LIM 32
#define SEG_TYPE 52
#define SEG_SYS 56
#define SEG_DPL 57
#define SEG_P 59
#define SEG_AVL 60
#define SEG_DB 62
#define SEG_G 63
/* Unscramble an IA-32 segment descriptor into the IA-64 format. */
#define IA32_SEG_UNSCRAMBLE(sd) \
( (((sd) >> IA32_SEG_BASE) & 0xffffff) | ((((sd) >> IA32_SEG_HIGH_BASE) & 0xff) << 24) \
| ((((sd) & 0xffff) | ((((sd) >> IA32_SEG_HIGH_LIMIT) & 0xf) << 16)) << SEG_LIM) \
| ((((sd) >> IA32_SEG_TYPE) & 0xf) << SEG_TYPE) \
| ((((sd) >> IA32_SEG_SYS) & 0x1) << SEG_SYS) \
| ((((sd) >> IA32_SEG_DPL) & 0x3) << SEG_DPL) \
| ((((sd) >> IA32_SEG_P) & 0x1) << SEG_P) \
| ((((sd) >> IA32_SEG_AVL) & 0x1) << SEG_AVL) \
| ((((sd) >> IA32_SEG_DB) & 0x1) << SEG_DB) \
| ((((sd) >> IA32_SEG_G) & 0x1) << SEG_G))
#define IA32_IOBASE 0x2000000000000000UL /* Virtual address for I/O space */
#define IA32_CR0 0x80000001 /* Enable PG and PE bits */
#define IA32_CR4 0x600 /* MMXEX and FXSR on */
/*
* IA32 floating point control registers starting values
*/
#define IA32_FSR_DEFAULT 0x55550000 /* set all tag bits */
#define IA32_FCR_DEFAULT 0x17800000037fUL /* extended precision, all masks */
#define IA32_PTRACE_GETREGS 12
#define IA32_PTRACE_SETREGS 13
#define IA32_PTRACE_GETFPREGS 14
#define IA32_PTRACE_SETFPREGS 15
#define IA32_PTRACE_GETFPXREGS 18
#define IA32_PTRACE_SETFPXREGS 19
#define ia32_start_thread(regs,new_ip,new_sp) do { \
set_fs(USER_DS); \
ia64_psr(regs)->cpl = 3; /* set user mode */ \
ia64_psr(regs)->ri = 0; /* clear return slot number */ \
ia64_psr(regs)->is = 1; /* IA-32 instruction set */ \
regs->cr_iip = new_ip; \
regs->ar_rsc = 0xc; /* enforced lazy mode, priv. level 3 */ \
regs->ar_rnat = 0; \
regs->loadrs = 0; \
regs->r12 = new_sp; \
} while (0)
/*
* Local Descriptor Table (LDT) related declarations.
*/
#define IA32_LDT_ENTRIES 8192 /* Maximum number of LDT entries supported. */
#define IA32_LDT_ENTRY_SIZE 8 /* The size of each LDT entry. */
#define LDT_entry_a(info) \
((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
#define LDT_entry_b(info) \
(((info)->base_addr & 0xff000000) | \
(((info)->base_addr & 0x00ff0000) >> 16) | \
((info)->limit & 0xf0000) | \
(((info)->read_exec_only ^ 1) << 9) | \
((info)->contents << 10) | \
(((info)->seg_not_present ^ 1) << 15) | \
((info)->seg_32bit << 22) | \
((info)->limit_in_pages << 23) | \
((info)->useable << 20) | \
0x7100)
#define LDT_empty(info) ( \
(info)->base_addr == 0 && \
(info)->limit == 0 && \
(info)->contents == 0 && \
(info)->read_exec_only == 1 && \
(info)->seg_32bit == 0 && \
(info)->limit_in_pages == 0 && \
(info)->seg_not_present == 1 && \
(info)->useable == 0 )
static inline void
load_TLS (struct thread_struct *t, unsigned int cpu)
{
extern unsigned long *cpu_gdt_table[NR_CPUS];
memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 0, &t->tls_array[0], sizeof(long));
memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 1, &t->tls_array[1], sizeof(long));
memcpy(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN + 2, &t->tls_array[2], sizeof(long));
}
struct ia32_user_desc {
unsigned int entry_number;
unsigned int base_addr;
unsigned int limit;
unsigned int seg_32bit:1;
unsigned int contents:2;
unsigned int read_exec_only:1;
unsigned int limit_in_pages:1;
unsigned int seg_not_present:1;
unsigned int useable:1;
};
struct linux_binprm;
extern void ia32_init_addr_space (struct pt_regs *regs);
extern int ia32_setup_arg_pages (struct linux_binprm *bprm, int exec_stack);
extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t);
extern void ia32_load_segment_descriptors (struct task_struct *task);
#define ia32f2ia64f(dst,src) \
do { \
ia64_ldfe(6,src); \
ia64_stop(); \
ia64_stf_spill(dst, 6); \
} while(0)
#define ia64f2ia32f(dst,src) \
do { \
ia64_ldf_fill(6, src); \
ia64_stop(); \
ia64_stfe(dst, 6); \
} while(0)
struct user_regs_struct32 {
__u32 ebx, ecx, edx, esi, edi, ebp, eax;
unsigned short ds, __ds, es, __es;
unsigned short fs, __fs, gs, __gs;
__u32 orig_eax, eip;
unsigned short cs, __cs;
__u32 eflags, esp;
unsigned short ss, __ss;
};
/* Prototypes for use in elfcore32.h */
extern int save_ia32_fpstate (struct task_struct *, struct ia32_user_i387_struct __user *);
extern int save_ia32_fpxstate (struct task_struct *, struct ia32_user_fxsr_struct __user *);
#endif /* !CONFIG_IA32_SUPPORT */
#endif /* _ASM_IA64_IA32_PRIV_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
include include/asm-generic/Kbuild.asm
header-y += break.h
header-y += fpu.h
header-y += ia64regs.h
header-y += intel_intrin.h
header-y += perfmon_default_smpl.h
header-y += ptrace_offsets.h
header-y += rse.h
header-y += ucontext.h
unifdef-y += gcc_intrin.h
unifdef-y += intrinsics.h
unifdef-y += perfmon.h
unifdef-y += ustack.h

View File

@@ -0,0 +1,20 @@
/*
* (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
* Alex Williamson <alex.williamson@hp.com>
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Vendor specific extensions to ACPI.
*/
#ifndef _ASM_IA64_ACPI_EXT_H
#define _ASM_IA64_ACPI_EXT_H
#include <linux/types.h>
extern acpi_status hp_acpi_csr_space (acpi_handle, u64 *base, u64 *length);
#endif /* _ASM_IA64_ACPI_EXT_H */

View File

@@ -0,0 +1,168 @@
/*
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
* Copyright (C) 2001,2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef _ASM_ACPI_H
#define _ASM_ACPI_H
#ifdef __KERNEL__
#include <acpi/pdc_intel.h>
#include <linux/init.h>
#include <linux/numa.h>
#include <asm/system.h>
#include <asm/numa.h>
#define COMPILER_DEPENDENT_INT64 long
#define COMPILER_DEPENDENT_UINT64 unsigned long
/*
* Calling conventions:
*
* ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads)
* ACPI_EXTERNAL_XFACE - External ACPI interfaces
* ACPI_INTERNAL_XFACE - Internal ACPI interfaces
* ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces
*/
#define ACPI_SYSTEM_XFACE
#define ACPI_EXTERNAL_XFACE
#define ACPI_INTERNAL_XFACE
#define ACPI_INTERNAL_VAR_XFACE
/* Asm macros */
#define ACPI_ASM_MACROS
#define BREAKPOINT3
#define ACPI_DISABLE_IRQS() local_irq_disable()
#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE()
static inline int
ia64_acpi_acquire_global_lock (unsigned int *lock)
{
unsigned int old, new, val;
do {
old = *lock;
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
val = ia64_cmpxchg4_acq(lock, new, old);
} while (unlikely (val != old));
return (new < 3) ? -1 : 0;
}
static inline int
ia64_acpi_release_global_lock (unsigned int *lock)
{
unsigned int old, new, val;
do {
old = *lock;
new = old & ~0x3;
val = ia64_cmpxchg4_acq(lock, new, old);
} while (unlikely (val != old));
return old & 0x1;
}
#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock))
#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \
((Acq) = ia64_acpi_release_global_lock(&facs->global_lock))
#ifdef CONFIG_ACPI
#define acpi_disabled 0 /* ACPI always enabled on IA64 */
#define acpi_noirq 0 /* ACPI always enabled on IA64 */
#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */
#define acpi_ht 0 /* no HT-only mode on IA64 */
#endif
#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
static inline void disable_acpi(void) { }
const char *acpi_get_sysname (void);
int acpi_request_vector (u32 int_type);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
extern void acpi_restore_state_mem(void);
extern unsigned long acpi_wakeup_address;
/*
* Record the cpei override flag and current logical cpu. This is
* useful for CPU removal.
*/
extern unsigned int can_cpei_retarget(void);
extern unsigned int is_cpu_cpei_target(unsigned int cpu);
extern void set_cpei_target_cpu(unsigned int cpu);
extern unsigned int get_cpei_target_cpu(void);
extern void prefill_possible_map(void);
#ifdef CONFIG_ACPI_HOTPLUG_CPU
extern int additional_cpus;
#else
#define additional_cpus 0
#endif
#ifdef CONFIG_ACPI_NUMA
#if MAX_NUMNODES > 256
#define MAX_PXM_DOMAINS MAX_NUMNODES
#else
#define MAX_PXM_DOMAINS (256)
#endif
extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
#endif
#define acpi_unlazy_tlb(x)
#ifdef CONFIG_ACPI_NUMA
extern cpumask_t early_cpu_possible_map;
#define for_each_possible_early_cpu(cpu) \
for_each_cpu_mask((cpu), early_cpu_possible_map)
static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus)
{
int low_cpu, high_cpu;
int cpu;
int next_nid = 0;
low_cpu = cpus_weight(early_cpu_possible_map);
high_cpu = max(low_cpu, min_cpus);
high_cpu = min(high_cpu + reserve_cpus, NR_CPUS);
for (cpu = low_cpu; cpu < high_cpu; cpu++) {
cpu_set(cpu, early_cpu_possible_map);
if (node_cpuid[cpu].nid == NUMA_NO_NODE) {
node_cpuid[cpu].nid = next_nid;
next_nid++;
if (next_nid >= num_online_nodes())
next_nid = 0;
}
}
}
#endif /* CONFIG_ACPI_NUMA */
#endif /*__KERNEL__*/
#endif /*_ASM_ACPI_H*/

View File

@@ -0,0 +1,26 @@
#ifndef _ASM_IA64_AGP_H
#define _ASM_IA64_AGP_H
/*
* IA-64 specific AGP definitions.
*
* Copyright (C) 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
/*
* To avoid memory-attribute aliasing issues, we require that the AGPGART engine operate
* in coherent mode, which lets us map the AGP memory as normal (write-back) memory
* (unlike x86, where it gets mapped "write-coalescing").
*/
#define map_page_into_agp(page) /* nothing */
#define unmap_page_from_agp(page) /* nothing */
#define flush_agp_cache() mb()
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
#define alloc_gatt_pages(order) \
((char *)__get_free_pages(GFP_KERNEL, (order)))
#define free_gatt_pages(table, order) \
free_pages((unsigned long)(table), (order))
#endif /* _ASM_IA64_AGP_H */

View File

@@ -0,0 +1,135 @@
#ifndef _ASM_IA64_ASMMACRO_H
#define _ASM_IA64_ASMMACRO_H
/*
* Copyright (C) 2000-2001, 2003-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#define ENTRY(name) \
.align 32; \
.proc name; \
name:
#define ENTRY_MIN_ALIGN(name) \
.align 16; \
.proc name; \
name:
#define GLOBAL_ENTRY(name) \
.global name; \
ENTRY(name)
#define END(name) \
.endp name
/*
* Helper macros to make unwind directives more readable:
*/
/* prologue_gr: */
#define ASM_UNW_PRLG_RP 0x8
#define ASM_UNW_PRLG_PFS 0x4
#define ASM_UNW_PRLG_PSP 0x2
#define ASM_UNW_PRLG_PR 0x1
#define ASM_UNW_PRLG_GRSAVE(ninputs) (32+(ninputs))
/*
* Helper macros for accessing user memory.
*
* When adding any new .section/.previous entries here, make sure to
* also add it to the DISCARD section in arch/ia64/kernel/gate.lds.S or
* unpleasant things will happen.
*/
.section "__ex_table", "a" // declare section & section attributes
.previous
# define EX(y,x...) \
.xdata4 "__ex_table", 99f-., y-.; \
[99:] x
# define EXCLR(y,x...) \
.xdata4 "__ex_table", 99f-., y-.+4; \
[99:] x
/*
* Tag MCA recoverable instruction ranges.
*/
.section "__mca_table", "a" // declare section & section attributes
.previous
# define MCA_RECOVER_RANGE(y) \
.xdata4 "__mca_table", y-., 99f-.; \
[99:]
/*
* Mark instructions that need a load of a virtual address patched to be
* a load of a physical address. We use this either in critical performance
* path (ivt.S - TLB miss processing) or in places where it might not be
* safe to use a "tpa" instruction (mca_asm.S - error recovery).
*/
.section ".data.patch.vtop", "a" // declare section & section attributes
.previous
#define LOAD_PHYSICAL(pr, reg, obj) \
[1:](pr)movl reg = obj; \
.xdata4 ".data.patch.vtop", 1b-.
/*
* For now, we always put in the McKinley E9 workaround. On CPUs that don't need it,
* we'll patch out the work-around bundles with NOPs, so their impact is minimal.
*/
#define DO_MCKINLEY_E9_WORKAROUND
#ifdef DO_MCKINLEY_E9_WORKAROUND
.section ".data.patch.mckinley_e9", "a"
.previous
/* workaround for Itanium 2 Errata 9: */
# define FSYS_RETURN \
.xdata4 ".data.patch.mckinley_e9", 1f-.; \
1:{ .mib; \
nop.m 0; \
mov r16=ar.pfs; \
br.call.sptk.many b7=2f;; \
}; \
2:{ .mib; \
nop.m 0; \
mov ar.pfs=r16; \
br.ret.sptk.many b6;; \
}
#else
# define FSYS_RETURN br.ret.sptk.many b6
#endif
/*
* If physical stack register size is different from DEF_NUM_STACK_REG,
* dynamically patch the kernel for correct size.
*/
.section ".data.patch.phys_stack_reg", "a"
.previous
#define LOAD_PHYS_STACK_REG_SIZE(reg) \
[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \
.xdata4 ".data.patch.phys_stack_reg", 1b-.
/*
* Up until early 2004, use of .align within a function caused bad unwind info.
* TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing
* otherwise.
*/
#ifdef HAVE_WORKING_TEXT_ALIGN
# define TEXT_ALIGN(n) .align n
#else
# define TEXT_ALIGN(n)
#endif
#ifdef HAVE_SERIALIZE_DIRECTIVE
# define dv_serialize_data .serialize.data
# define dv_serialize_instruction .serialize.instruction
#else
# define dv_serialize_data
# define dv_serialize_instruction
#endif
#endif /* _ASM_IA64_ASMMACRO_H */

View File

@@ -0,0 +1,220 @@
#ifndef _ASM_IA64_ATOMIC_H
#define _ASM_IA64_ATOMIC_H
/*
* Atomic operations that C can't guarantee us. Useful for
* resource counting etc..
*
* NOTE: don't mess with the types below! The "unsigned long" and
* "int" types were carefully placed so as to ensure proper operation
* of the macros.
*
* Copyright (C) 1998, 1999, 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/types.h>
#include <asm/intrinsics.h>
#include <asm/system.h>
#define ATOMIC_INIT(i) ((atomic_t) { (i) })
#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
#define atomic_read(v) ((v)->counter)
#define atomic64_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic64_set(v,i) (((v)->counter) = (i))
static __inline__ int
ia64_atomic_add (int i, atomic_t *v)
{
__s32 old, new;
CMPXCHG_BUGCHECK_DECL
do {
CMPXCHG_BUGCHECK(v);
old = atomic_read(v);
new = old + i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old);
return new;
}
static __inline__ int
ia64_atomic64_add (__s64 i, atomic64_t *v)
{
__s64 old, new;
CMPXCHG_BUGCHECK_DECL
do {
CMPXCHG_BUGCHECK(v);
old = atomic64_read(v);
new = old + i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old);
return new;
}
static __inline__ int
ia64_atomic_sub (int i, atomic_t *v)
{
__s32 old, new;
CMPXCHG_BUGCHECK_DECL
do {
CMPXCHG_BUGCHECK(v);
old = atomic_read(v);
new = old - i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old);
return new;
}
static __inline__ int
ia64_atomic64_sub (__s64 i, atomic64_t *v)
{
__s64 old, new;
CMPXCHG_BUGCHECK_DECL
do {
CMPXCHG_BUGCHECK(v);
old = atomic64_read(v);
new = old - i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old);
return new;
}
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic64_cmpxchg(v, old, new) \
(cmpxchg(&((v)->counter), old, new))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
for (;;) {
if (unlikely(c == (u)))
break;
old = atomic_cmpxchg((v), c, c + (a));
if (likely(old == c))
break;
c = old;
}
return c != (u);
}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
{
long c, old;
c = atomic64_read(v);
for (;;) {
if (unlikely(c == (u)))
break;
old = atomic64_cmpxchg((v), c, c + (a));
if (likely(old == c))
break;
c = old;
}
return c != (u);
}
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
#define atomic_add_return(i,v) \
({ \
int __ia64_aar_i = (i); \
(__builtin_constant_p(i) \
&& ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \
|| (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \
|| (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \
|| (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \
? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \
: ia64_atomic_add(__ia64_aar_i, v); \
})
#define atomic64_add_return(i,v) \
({ \
long __ia64_aar_i = (i); \
(__builtin_constant_p(i) \
&& ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \
|| (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \
|| (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \
|| (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \
? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \
: ia64_atomic64_add(__ia64_aar_i, v); \
})
/*
* Atomically add I to V and return TRUE if the resulting value is
* negative.
*/
static __inline__ int
atomic_add_negative (int i, atomic_t *v)
{
return atomic_add_return(i, v) < 0;
}
static __inline__ int
atomic64_add_negative (__s64 i, atomic64_t *v)
{
return atomic64_add_return(i, v) < 0;
}
#define atomic_sub_return(i,v) \
({ \
int __ia64_asr_i = (i); \
(__builtin_constant_p(i) \
&& ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \
|| (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \
|| (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \
|| (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \
? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \
: ia64_atomic_sub(__ia64_asr_i, v); \
})
#define atomic64_sub_return(i,v) \
({ \
long __ia64_asr_i = (i); \
(__builtin_constant_p(i) \
&& ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \
|| (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \
|| (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \
|| (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \
? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \
: ia64_atomic64_sub(__ia64_asr_i, v); \
})
#define atomic_dec_return(v) atomic_sub_return(1, (v))
#define atomic_inc_return(v) atomic_add_return(1, (v))
#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
#define atomic64_inc_return(v) atomic64_add_return(1, (v))
#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0)
#define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0)
#define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0)
#define atomic_add(i,v) atomic_add_return((i), (v))
#define atomic_sub(i,v) atomic_sub_return((i), (v))
#define atomic_inc(v) atomic_add(1, (v))
#define atomic_dec(v) atomic_sub(1, (v))
#define atomic64_add(i,v) atomic64_add_return((i), (v))
#define atomic64_sub(i,v) atomic64_sub_return((i), (v))
#define atomic64_inc(v) atomic64_add(1, (v))
#define atomic64_dec(v) atomic64_sub(1, (v))
/* Atomic operations are already serializing */
#define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier()
#define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier()
#include <asm-generic/atomic-long.h>
#endif /* _ASM_IA64_ATOMIC_H */

View File

@@ -0,0 +1,11 @@
#ifndef _ASM_IA64_AUXVEC_H
#define _ASM_IA64_AUXVEC_H
/*
* Architecture-neutral AT_ values are in the range 0-17. Leave some room for more of
* them, start the architecture-specific ones at 32.
*/
#define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33
#endif /* _ASM_IA64_AUXVEC_H */

View File

@@ -0,0 +1,468 @@
#ifndef _ASM_IA64_BITOPS_H
#define _ASM_IA64_BITOPS_H
/*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* 02/06/02 find_next_bit() and find_first_bit() added from Erich Focht's ia64
* O(1) scheduler patch
*/
#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/intrinsics.h>
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*
* The address must be (at least) "long" aligned.
* Note that there are driver (e.g., eepro100) which use these operations to
* operate on hw-defined data-structures, so we can't easily change these
* operations to force a bigger alignment.
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
static __inline__ void
set_bit (int nr, volatile void *addr)
{
__u32 bit, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
bit = 1 << (nr & 31);
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old | bit;
} while (cmpxchg_acq(m, old, new) != old);
}
/**
* __set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike set_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void
__set_bit (int nr, volatile void *addr)
{
*((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
}
/*
* clear_bit() has "acquire" semantics.
*/
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() do { /* skip */; } while (0)
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static __inline__ void
clear_bit (int nr, volatile void *addr)
{
__u32 mask, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
mask = ~(1 << (nr & 31));
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old & mask;
} while (cmpxchg_acq(m, old, new) != old);
}
/**
* clear_bit_unlock - Clears a bit in memory with release
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit_unlock() is atomic and may not be reordered. It does
* contain a memory barrier suitable for unlock type operations.
*/
static __inline__ void
clear_bit_unlock (int nr, volatile void *addr)
{
__u32 mask, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
mask = ~(1 << (nr & 31));
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old & mask;
} while (cmpxchg_rel(m, old, new) != old);
}
/**
* __clear_bit_unlock - Non-atomically clears a bit in memory with release
* @nr: Bit to clear
* @addr: Address to start counting from
*
* Similarly to clear_bit_unlock, the implementation uses a store
* with release semantics. See also __raw_spin_unlock().
*/
static __inline__ void
__clear_bit_unlock(int nr, void *addr)
{
__u32 * const m = (__u32 *) addr + (nr >> 5);
__u32 const new = *m & ~(1 << (nr & 31));
ia64_st4_rel_nta(m, new);
}
/**
* __clear_bit - Clears a bit in memory (non-atomic version)
* @nr: the bit to clear
* @addr: the address to start counting from
*
* Unlike clear_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void
__clear_bit (int nr, volatile void *addr)
{
*((__u32 *) addr + (nr >> 5)) &= ~(1 << (nr & 31));
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to toggle
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void
change_bit (int nr, volatile void *addr)
{
__u32 bit, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
bit = (1 << (nr & 31));
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old ^ bit;
} while (cmpxchg_acq(m, old, new) != old);
}
/**
* __change_bit - Toggle a bit in memory
* @nr: the bit to toggle
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static __inline__ void
__change_bit (int nr, volatile void *addr)
{
*((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies the acquisition side of the memory barrier.
*/
static __inline__ int
test_and_set_bit (int nr, volatile void *addr)
{
__u32 bit, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
bit = 1 << (nr & 31);
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old | bit;
} while (cmpxchg_acq(m, old, new) != old);
return (old & bit) != 0;
}
/**
* test_and_set_bit_lock - Set a bit and return its old value for lock
* @nr: Bit to set
* @addr: Address to count from
*
* This is the same as test_and_set_bit on ia64
*/
#define test_and_set_bit_lock test_and_set_bit
/**
* __test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int
__test_and_set_bit (int nr, volatile void *addr)
{
__u32 *p = (__u32 *) addr + (nr >> 5);
__u32 m = 1 << (nr & 31);
int oldbitset = (*p & m) != 0;
*p |= m;
return oldbitset;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies the acquisition side of the memory barrier.
*/
static __inline__ int
test_and_clear_bit (int nr, volatile void *addr)
{
__u32 mask, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
mask = ~(1 << (nr & 31));
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old & mask;
} while (cmpxchg_acq(m, old, new) != old);
return (old & ~mask) != 0;
}
/**
* __test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static __inline__ int
__test_and_clear_bit(int nr, volatile void * addr)
{
__u32 *p = (__u32 *) addr + (nr >> 5);
__u32 m = 1 << (nr & 31);
int oldbitset = (*p & m) != 0;
*p &= ~m;
return oldbitset;
}
/**
* test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies the acquisition side of the memory barrier.
*/
static __inline__ int
test_and_change_bit (int nr, volatile void *addr)
{
__u32 bit, old, new;
volatile __u32 *m;
CMPXCHG_BUGCHECK_DECL
m = (volatile __u32 *) addr + (nr >> 5);
bit = (1 << (nr & 31));
do {
CMPXCHG_BUGCHECK(m);
old = *m;
new = old ^ bit;
} while (cmpxchg_acq(m, old, new) != old);
return (old & bit) != 0;
}
/**
* __test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
*/
static __inline__ int
__test_and_change_bit (int nr, void *addr)
{
__u32 old, bit = (1 << (nr & 31));
__u32 *m = (__u32 *) addr + (nr >> 5);
old = *m;
*m = old ^ bit;
return (old & bit) != 0;
}
static __inline__ int
test_bit (int nr, const volatile void *addr)
{
return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
}
/**
* ffz - find the first zero bit in a long word
* @x: The long word to find the bit in
*
* Returns the bit-number (0..63) of the first (least significant) zero bit.
* Undefined if no zero exists, so code should check against ~0UL first...
*/
static inline unsigned long
ffz (unsigned long x)
{
unsigned long result;
result = ia64_popcnt(x & (~x - 1));
return result;
}
/**
* __ffs - find first bit in word.
* @x: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static __inline__ unsigned long
__ffs (unsigned long x)
{
unsigned long result;
result = ia64_popcnt((x-1) & ~x);
return result;
}
#ifdef __KERNEL__
/*
* Return bit number of last (most-significant) bit set. Undefined
* for x==0. Bits are numbered from 0..63 (e.g., ia64_fls(9) == 3).
*/
static inline unsigned long
ia64_fls (unsigned long x)
{
long double d = x;
long exp;
exp = ia64_getf_exp(d);
return exp - 0xffff;
}
/*
* Find the last (most significant) bit set. Returns 0 for x==0 and
* bits are numbered from 1..32 (e.g., fls(9) == 4).
*/
static inline int
fls (int t)
{
unsigned long x = t & 0xffffffffu;
if (!x)
return 0;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return ia64_popcnt(x);
}
/*
* Find the last (most significant) bit set. Undefined for x==0.
* Bits are numbered from 0..63 (e.g., __fls(9) == 3).
*/
static inline unsigned long
__fls (unsigned long x)
{
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
return ia64_popcnt(x) - 1;
}
#include <asm-generic/bitops/fls64.h>
/*
* ffs: find first bit set. This is defined the same way as the libc and
* compiler builtin ffs routines, therefore differs in spirit from the above
* ffz (man ffs): it operates on "int" values only and the result value is the
* bit number + 1. ffs(0) is defined to return zero.
*/
#define ffs(x) __builtin_ffs(x)
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
static __inline__ unsigned long
hweight64 (unsigned long x)
{
unsigned long result;
result = ia64_popcnt(x);
return result;
}
#define hweight32(x) (unsigned int) hweight64((x) & 0xfffffffful)
#define hweight16(x) (unsigned int) hweight64((x) & 0xfffful)
#define hweight8(x) (unsigned int) hweight64((x) & 0xfful)
#endif /* __KERNEL__ */
#include <asm-generic/bitops/find.h>
#ifdef __KERNEL__
#include <asm-generic/bitops/ext2-non-atomic.h>
#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a)
#define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a)
#include <asm-generic/bitops/minix.h>
#include <asm-generic/bitops/sched.h>
#endif /* __KERNEL__ */
#endif /* _ASM_IA64_BITOPS_H */

View File

@@ -0,0 +1,8 @@
#ifndef __ASM_IA64_BITSPERLONG_H
#define __ASM_IA64_BITSPERLONG_H
#define __BITS_PER_LONG 64
#include <asm-generic/bitsperlong.h>
#endif /* __ASM_IA64_BITSPERLONG_H */

View File

@@ -0,0 +1,32 @@
#ifndef _ASM_IA64_BREAK_H
#define _ASM_IA64_BREAK_H
/*
* IA-64 Linux break numbers.
*
* Copyright (C) 1999 Hewlett-Packard Co
* Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
*/
/*
* OS-specific debug break numbers:
*/
#define __IA64_BREAK_KDB 0x80100
#define __IA64_BREAK_KPROBE 0x81000 /* .. 0x81fff */
#define __IA64_BREAK_JPROBE 0x82000
/*
* OS-specific break numbers:
*/
#define __IA64_BREAK_SYSCALL 0x100000
/*
* Xen specific break numbers:
*/
#define __IA64_XEN_HYPERCALL 0x1000
/* [__IA64_XEN_HYPERPRIVOP_START, __IA64_XEN_HYPERPRIVOP_MAX] is used
for xen hyperprivops */
#define __IA64_XEN_HYPERPRIVOP_START 0x1
#define __IA64_XEN_HYPERPRIVOP_MAX 0x1a
#endif /* _ASM_IA64_BREAK_H */

View File

@@ -0,0 +1,14 @@
#ifndef _ASM_IA64_BUG_H
#define _ASM_IA64_BUG_H
#ifdef CONFIG_BUG
#define ia64_abort() __builtin_trap()
#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
/* should this BUG be made generic? */
#define HAVE_ARCH_BUG
#endif
#include <asm-generic/bug.h>
#endif

View File

@@ -0,0 +1,19 @@
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*
* Based on <asm-alpha/bugs.h>.
*
* Modified 1998, 1999, 2003
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
*/
#ifndef _ASM_IA64_BUGS_H
#define _ASM_IA64_BUGS_H
#include <asm/processor.h>
extern void check_bugs (void);
#endif /* _ASM_IA64_BUGS_H */

View File

@@ -0,0 +1,6 @@
#ifndef _ASM_IA64_BYTEORDER_H
#define _ASM_IA64_BYTEORDER_H
#include <linux/byteorder/little_endian.h>
#endif /* _ASM_IA64_BYTEORDER_H */

View File

@@ -0,0 +1,29 @@
#ifndef _ASM_IA64_CACHE_H
#define _ASM_IA64_CACHE_H
/*
* Copyright (C) 1998-2000 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
/* Bytes per L1 (data) cache line. */
#define L1_CACHE_SHIFT CONFIG_IA64_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#ifdef CONFIG_SMP
# define SMP_CACHE_SHIFT L1_CACHE_SHIFT
# define SMP_CACHE_BYTES L1_CACHE_BYTES
#else
/*
* The "aligned" directive can only _increase_ alignment, so this is
* safe and provides an easy way to avoid wasting space on a
* uni-processor:
*/
# define SMP_CACHE_SHIFT 3
# define SMP_CACHE_BYTES (1 << 3)
#endif
#define __read_mostly __attribute__((__section__(".data.read_mostly")))
#endif /* _ASM_IA64_CACHE_H */

View File

@@ -0,0 +1,53 @@
#ifndef _ASM_IA64_CACHEFLUSH_H
#define _ASM_IA64_CACHEFLUSH_H
/*
* Copyright (C) 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/page-flags.h>
#include <linux/bitops.h>
#include <asm/page.h>
/*
* Cache flushing routines. This is the kind of stuff that can be very expensive, so try
* to avoid them whenever possible.
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
#define flush_cache_range(vma, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
#define flush_icache_page(vma,page) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#define flush_dcache_page(page) \
do { \
clear_bit(PG_arch_1, &(page)->flags); \
} while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
extern void flush_icache_range (unsigned long start, unsigned long end);
extern void clflush_cache_range(void *addr, int size);
#define flush_icache_user_range(vma, page, user_addr, len) \
do { \
unsigned long _addr = (unsigned long) page_address(page) + ((user_addr) & ~PAGE_MASK); \
flush_icache_range(_addr, _addr + (len)); \
} while (0)
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { memcpy(dst, src, len); \
flush_icache_user_range(vma, page, vaddr, len); \
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
#endif /* _ASM_IA64_CACHEFLUSH_H */

View File

@@ -0,0 +1,79 @@
#ifndef _ASM_IA64_CHECKSUM_H
#define _ASM_IA64_CHECKSUM_H
/*
* Modified 1998, 1999
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
/*
* Computes the checksum of the TCP/UDP pseudo-header returns a 16-bit
* checksum, already complemented
*/
extern __sum16 csum_tcpudp_magic (__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum);
extern __wsum csum_tcpudp_nofold (__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum);
/*
* Computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* Same as csum_partial, but copies from src while it checksums.
*
* Here it is even more important to align src and dst on a 32-bit (or
* even better 64-bit) boundary.
*/
extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum,
int *errp);
extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
int len, __wsum sum);
/*
* This routine is used for miscellaneous IP-like checksums, mainly in
* icmp.c
*/
extern __sum16 ip_compute_csum(const void *buff, int len);
/*
* Fold a partial checksum without adding pseudo headers.
*/
static inline __sum16 csum_fold(__wsum csum)
{
u32 sum = (__force u32)csum;
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
return (__force __sum16)~sum;
}
#define _HAVE_ARCH_IPV6_CSUM 1
struct in6_addr;
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr, __u32 len, unsigned short proto,
__wsum csum);
#endif /* _ASM_IA64_CHECKSUM_H */

View File

@@ -0,0 +1,207 @@
#ifndef _ASM_IA64_COMPAT_H
#define _ASM_IA64_COMPAT_H
/*
* Architecture specific compatibility types
*/
#include <linux/types.h>
#define COMPAT_USER_HZ 100
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_key_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u32 compat_ino_t;
typedef u16 compat_dev_t;
typedef s32 compat_off_t;
typedef s64 compat_loff_t;
typedef u16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef s32 compat_daddr_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;
typedef s32 compat_timer_t;
typedef s32 compat_int_t;
typedef s32 compat_long_t;
typedef s64 __attribute__((aligned(4))) compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 __attribute__((aligned(4))) compat_u64;
struct compat_timespec {
compat_time_t tv_sec;
s32 tv_nsec;
};
struct compat_timeval {
compat_time_t tv_sec;
s32 tv_usec;
};
struct compat_stat {
compat_dev_t st_dev;
u16 __pad1;
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
__compat_uid_t st_uid;
__compat_gid_t st_gid;
compat_dev_t st_rdev;
u16 __pad2;
u32 st_size;
u32 st_blksize;
u32 st_blocks;
u32 st_atime;
u32 st_atime_nsec;
u32 st_mtime;
u32 st_mtime_nsec;
u32 st_ctime;
u32 st_ctime_nsec;
u32 __unused4;
u32 __unused5;
};
struct compat_flock {
short l_type;
short l_whence;
compat_off_t l_start;
compat_off_t l_len;
compat_pid_t l_pid;
};
#define F_GETLK64 12
#define F_SETLK64 13
#define F_SETLKW64 14
/*
* IA32 uses 4 byte alignment for 64 bit quantities,
* so we need to pack this structure.
*/
struct compat_flock64 {
short l_type;
short l_whence;
compat_loff_t l_start;
compat_loff_t l_len;
compat_pid_t l_pid;
} __attribute__((packed));
struct compat_statfs {
int f_type;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */
int f_frsize;
int f_spare[5];
};
#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
#define COMPAT_RLIM_INFINITY 0xffffffff
typedef u32 compat_old_sigset_t; /* at least 32 bits */
#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32
typedef u32 compat_sigset_word;
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
struct compat_ipc64_perm {
compat_key_t key;
__compat_uid32_t uid;
__compat_gid32_t gid;
__compat_uid32_t cuid;
__compat_gid32_t cgid;
unsigned short mode;
unsigned short __pad1;
unsigned short seq;
unsigned short __pad2;
compat_ulong_t unused1;
compat_ulong_t unused2;
};
struct compat_semid64_ds {
struct compat_ipc64_perm sem_perm;
compat_time_t sem_otime;
compat_ulong_t __unused1;
compat_time_t sem_ctime;
compat_ulong_t __unused2;
compat_ulong_t sem_nsems;
compat_ulong_t __unused3;
compat_ulong_t __unused4;
};
struct compat_msqid64_ds {
struct compat_ipc64_perm msg_perm;
compat_time_t msg_stime;
compat_ulong_t __unused1;
compat_time_t msg_rtime;
compat_ulong_t __unused2;
compat_time_t msg_ctime;
compat_ulong_t __unused3;
compat_ulong_t msg_cbytes;
compat_ulong_t msg_qnum;
compat_ulong_t msg_qbytes;
compat_pid_t msg_lspid;
compat_pid_t msg_lrpid;
compat_ulong_t __unused4;
compat_ulong_t __unused5;
};
struct compat_shmid64_ds {
struct compat_ipc64_perm shm_perm;
compat_size_t shm_segsz;
compat_time_t shm_atime;
compat_ulong_t __unused1;
compat_time_t shm_dtime;
compat_ulong_t __unused2;
compat_time_t shm_ctime;
compat_ulong_t __unused3;
compat_pid_t shm_cpid;
compat_pid_t shm_lpid;
compat_ulong_t shm_nattch;
compat_ulong_t __unused4;
compat_ulong_t __unused5;
};
/*
* A pointer passed in from user mode. This should not be used for syscall parameters,
* just declare them as pointers because the syscall entry code will have appropriately
* converted them already.
*/
typedef u32 compat_uptr_t;
static inline void __user *
compat_ptr (compat_uptr_t uptr)
{
return (void __user *) (unsigned long) uptr;
}
static inline compat_uptr_t
ptr_to_compat(void __user *uptr)
{
return (u32)(unsigned long)uptr;
}
static __inline__ void __user *
arch_compat_alloc_user_space (long len)
{
struct pt_regs *regs = task_pt_regs(current);
return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
}
#endif /* _ASM_IA64_COMPAT_H */

View File

@@ -0,0 +1,22 @@
#ifndef _ASM_IA64_CPU_H_
#define _ASM_IA64_CPU_H_
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/topology.h>
#include <linux/percpu.h>
struct ia64_cpu {
struct cpu cpu;
};
DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
DECLARE_PER_CPU(int, cpu_state);
#ifdef CONFIG_HOTPLUG_CPU
extern int arch_register_cpu(int num);
extern void arch_unregister_cpu(int);
#endif
#endif /* _ASM_IA64_CPU_H_ */

View File

@@ -0,0 +1,110 @@
/*
* Definitions for measuring cputime on ia64 machines.
*
* Based on <asm-powerpc/cputime.h>.
*
* Copyright (C) 2007 FUJITSU LIMITED
* Copyright (C) 2007 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec.
* Otherwise we measure cpu time in jiffies using the generic definitions.
*/
#ifndef __IA64_CPUTIME_H
#define __IA64_CPUTIME_H
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#include <asm-generic/cputime.h>
#else
#include <linux/time.h>
#include <linux/jiffies.h>
#include <asm/processor.h>
typedef u64 cputime_t;
typedef u64 cputime64_t;
#define cputime_zero ((cputime_t)0)
#define cputime_one_jiffy jiffies_to_cputime(1)
#define cputime_max ((~((cputime_t)0) >> 1) - 1)
#define cputime_add(__a, __b) ((__a) + (__b))
#define cputime_sub(__a, __b) ((__a) - (__b))
#define cputime_div(__a, __n) ((__a) / (__n))
#define cputime_halve(__a) ((__a) >> 1)
#define cputime_eq(__a, __b) ((__a) == (__b))
#define cputime_gt(__a, __b) ((__a) > (__b))
#define cputime_ge(__a, __b) ((__a) >= (__b))
#define cputime_lt(__a, __b) ((__a) < (__b))
#define cputime_le(__a, __b) ((__a) <= (__b))
#define cputime64_zero ((cputime64_t)0)
#define cputime64_add(__a, __b) ((__a) + (__b))
#define cputime64_sub(__a, __b) ((__a) - (__b))
#define cputime_to_cputime64(__ct) (__ct)
/*
* Convert cputime <-> jiffies (HZ)
*/
#define cputime_to_jiffies(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies_to_cputime(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
#define cputime64_to_jiffies64(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
/*
* Convert cputime <-> milliseconds
*/
#define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC)
#define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC)
/*
* Convert cputime <-> seconds
*/
#define cputime_to_secs(__ct) ((__ct) / NSEC_PER_SEC)
#define secs_to_cputime(__secs) ((__secs) * NSEC_PER_SEC)
/*
* Convert cputime <-> timespec (nsec)
*/
static inline cputime_t timespec_to_cputime(const struct timespec *val)
{
cputime_t ret = val->tv_sec * NSEC_PER_SEC;
return (ret + val->tv_nsec);
}
static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
{
val->tv_sec = ct / NSEC_PER_SEC;
val->tv_nsec = ct % NSEC_PER_SEC;
}
/*
* Convert cputime <-> timeval (msec)
*/
static inline cputime_t timeval_to_cputime(struct timeval *val)
{
cputime_t ret = val->tv_sec * NSEC_PER_SEC;
return (ret + val->tv_usec * NSEC_PER_USEC);
}
static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
{
val->tv_sec = ct / NSEC_PER_SEC;
val->tv_usec = (ct % NSEC_PER_SEC) / NSEC_PER_USEC;
}
/*
* Convert cputime <-> clock (USER_HZ)
*/
#define cputime_to_clock_t(__ct) ((__ct) / (NSEC_PER_SEC / USER_HZ))
#define clock_t_to_cputime(__x) ((__x) * (NSEC_PER_SEC / USER_HZ))
/*
* Convert cputime64 to clock.
*/
#define cputime64_to_clock_t(__ct) cputime_to_clock_t((cputime_t)__ct)
#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
#endif /* __IA64_CPUTIME_H */

View File

@@ -0,0 +1,17 @@
#ifndef _ASM_IA64_CURRENT_H
#define _ASM_IA64_CURRENT_H
/*
* Modified 1998-2000
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
#include <asm/intrinsics.h>
/*
* In kernel mode, thread pointer (r13) is used to point to the current task
* structure.
*/
#define current ((struct task_struct *) ia64_getreg(_IA64_REG_TP))
#endif /* _ASM_IA64_CURRENT_H */

View File

@@ -0,0 +1,15 @@
#ifndef ASM_IA64_CYCLONE_H
#define ASM_IA64_CYCLONE_H
#ifdef CONFIG_IA64_CYCLONE
extern int use_cyclone;
extern void __init cyclone_setup(void);
#else /* CONFIG_IA64_CYCLONE */
#define use_cyclone 0
static inline void cyclone_setup(void)
{
printk(KERN_ERR "Cyclone Counter: System not configured"
" w/ CONFIG_IA64_CYCLONE.\n");
}
#endif /* CONFIG_IA64_CYCLONE */
#endif /* !ASM_IA64_CYCLONE_H */

View File

@@ -0,0 +1,88 @@
#ifndef _ASM_IA64_DELAY_H
#define _ASM_IA64_DELAY_H
/*
* Delay routines using a pre-computed "cycles/usec" value.
*
* Copyright (C) 1998, 1999 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
* Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
* Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/compiler.h>
#include <asm/intrinsics.h>
#include <asm/processor.h>
static __inline__ void
ia64_set_itm (unsigned long val)
{
ia64_setreg(_IA64_REG_CR_ITM, val);
ia64_srlz_d();
}
static __inline__ unsigned long
ia64_get_itm (void)
{
unsigned long result;
result = ia64_getreg(_IA64_REG_CR_ITM);
ia64_srlz_d();
return result;
}
static __inline__ void
ia64_set_itv (unsigned long val)
{
ia64_setreg(_IA64_REG_CR_ITV, val);
ia64_srlz_d();
}
static __inline__ unsigned long
ia64_get_itv (void)
{
return ia64_getreg(_IA64_REG_CR_ITV);
}
static __inline__ void
ia64_set_itc (unsigned long val)
{
ia64_setreg(_IA64_REG_AR_ITC, val);
ia64_srlz_d();
}
static __inline__ unsigned long
ia64_get_itc (void)
{
unsigned long result;
result = ia64_getreg(_IA64_REG_AR_ITC);
ia64_barrier();
#ifdef CONFIG_ITANIUM
while (unlikely((__s32) result == -1)) {
result = ia64_getreg(_IA64_REG_AR_ITC);
ia64_barrier();
}
#endif
return result;
}
extern void ia64_delay_loop (unsigned long loops);
static __inline__ void
__delay (unsigned long loops)
{
if (unlikely(loops < 1))
return;
ia64_delay_loop (loops - 1);
}
extern void udelay (unsigned long usecs);
#endif /* _ASM_IA64_DELAY_H */

View File

@@ -0,0 +1,21 @@
/*
* Arch specific extensions to struct device
*
* This file is released under the GPLv2
*/
#ifndef _ASM_IA64_DEVICE_H
#define _ASM_IA64_DEVICE_H
struct dev_archdata {
#ifdef CONFIG_ACPI
void *acpi_handle;
#endif
#ifdef CONFIG_DMAR
void *iommu; /* hook for IOMMU specific extension */
#endif
};
struct pdev_archdata {
};
#endif /* _ASM_IA64_DEVICE_H */

View File

@@ -0,0 +1 @@
#include <asm-generic/div64.h>

View File

@@ -0,0 +1,104 @@
#ifndef _ASM_IA64_DMA_MAPPING_H
#define _ASM_IA64_DMA_MAPPING_H
/*
* Copyright (C) 2003-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/machvec.h>
#include <linux/scatterlist.h>
#include <asm/swiotlb.h>
#include <linux/dma-debug.h>
#define ARCH_HAS_DMA_GET_REQUIRED_MASK
extern struct dma_map_ops *dma_ops;
extern struct ia64_machine_vector ia64_mv;
extern void set_iommu_machvec(void);
extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
enum dma_data_direction);
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *daddr, gfp_t gfp)
{
struct dma_map_ops *ops = platform_dma_get_ops(dev);
void *caddr;
caddr = ops->alloc_coherent(dev, size, daddr, gfp);
debug_dma_alloc_coherent(dev, size, *daddr, caddr);
return caddr;
}
static inline void dma_free_coherent(struct device *dev, size_t size,
void *caddr, dma_addr_t daddr)
{
struct dma_map_ops *ops = platform_dma_get_ops(dev);
debug_dma_free_coherent(dev, size, caddr, daddr);
ops->free_coherent(dev, size, caddr, daddr);
}
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
#define get_dma_ops(dev) platform_dma_get_ops(dev)
#include <asm-generic/dma-mapping-common.h>
static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
{
struct dma_map_ops *ops = platform_dma_get_ops(dev);
return ops->mapping_error(dev, daddr);
}
static inline int dma_supported(struct device *dev, u64 mask)
{
struct dma_map_ops *ops = platform_dma_get_ops(dev);
return ops->dma_supported(dev, mask);
}
static inline int
dma_set_mask (struct device *dev, u64 mask)
{
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;
*dev->dma_mask = mask;
return 0;
}
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
return 0;
return addr + size <= *dev->dma_mask;
}
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return paddr;
}
static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
{
return daddr;
}
extern int dma_get_cache_alignment(void);
static inline void
dma_cache_sync (struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
{
/*
* IA-64 is cache-coherent, so this is mostly a no-op. However, we do need to
* ensure that dma_cache_sync() enforces order, hence the mb().
*/
mb();
}
#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */
#endif /* _ASM_IA64_DMA_MAPPING_H */

View File

@@ -0,0 +1,24 @@
#ifndef _ASM_IA64_DMA_H
#define _ASM_IA64_DMA_H
/*
* Copyright (C) 1998-2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/io.h> /* need byte IO */
extern unsigned long MAX_DMA_ADDRESS;
#ifdef CONFIG_PCI
extern int isa_dma_bridge_buggy;
#else
# define isa_dma_bridge_buggy (0)
#endif
#define free_dma(x)
void dma_mark_clean(void *addr, size_t size);
#endif /* _ASM_IA64_DMA_H */

View File

@@ -0,0 +1,11 @@
#ifndef _ASM_DMI_H
#define _ASM_DMI_H 1
#include <asm/io.h>
/* Use normal IO mappings for DMI */
#define dmi_ioremap ioremap
#define dmi_iounmap(x,l) iounmap(x)
#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
#endif

View File

@@ -0,0 +1,284 @@
#ifndef _ASM_IA64_ELF_H
#define _ASM_IA64_ELF_H
/*
* ELF-specific definitions.
*
* Copyright (C) 1998-1999, 2002-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/fpu.h>
#include <asm/page.h>
#include <asm/auxvec.h>
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x)->e_machine == EM_IA_64)
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS64
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_IA_64
#define USE_ELF_CORE_DUMP
#define CORE_DUMP_USE_REGSET
/* Least-significant four bits of ELF header's e_flags are OS-specific. The bits are
interpreted as follows by Linux: */
#define EF_IA_64_LINUX_EXECUTABLE_STACK 0x1 /* is stack (& heap) executable by default? */
#define ELF_EXEC_PAGESIZE PAGE_SIZE
/*
* This is the location that an ET_DYN program is loaded if exec'ed.
* Typical use of this is to invoke "./ld.so someprog" to test out a
* new version of the loader. We need to make sure that it is out of
* the way of the program that it will "exec", and that there is
* sufficient room for the brk.
*/
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
#define PT_IA_64_UNWIND 0x70000001
/* IA-64 relocations: */
#define R_IA64_NONE 0x00 /* none */
#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
#define R_IA64_GPREL22 0x2a /* @gprel(sym+add), add imm22 */
#define R_IA64_GPREL64I 0x2b /* @gprel(sym+add), mov imm64 */
#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym+add), data4 MSB */
#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym+add), data4 LSB */
#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym+add), data8 MSB */
#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym+add), data8 LSB */
#define R_IA64_LTOFF22 0x32 /* @ltoff(sym+add), add imm22 */
#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym+add), mov imm64 */
#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym+add), add imm22 */
#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym+add), mov imm64 */
#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym+add), data8 MSB */
#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym+add), data8 LSB */
#define R_IA64_FPTR64I 0x43 /* @fptr(sym+add), mov imm64 */
#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym+add), data4 MSB */
#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym+add), data4 LSB */
#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym+add), data8 MSB */
#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym+add), data8 LSB */
#define R_IA64_PCREL60B 0x48 /* @pcrel(sym+add), brl */
#define R_IA64_PCREL21B 0x49 /* @pcrel(sym+add), ptb, call */
#define R_IA64_PCREL21M 0x4a /* @pcrel(sym+add), chk.s */
#define R_IA64_PCREL21F 0x4b /* @pcrel(sym+add), fchkf */
#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym+add), data4 MSB */
#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym+add), data4 LSB */
#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym+add), data8 MSB */
#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym+add), data8 LSB */
#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), 4 MSB */
#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), 4 LSB */
#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), 8 MSB */
#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), 8 LSB */
#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym+add), data4 MSB */
#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym+add), data4 LSB */
#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym+add), data8 MSB */
#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym+add), data8 LSB */
#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym+add), data4 MSB */
#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym+add), data4 LSB */
#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym+add), data8 MSB */
#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym+add), data8 LSB */
#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym+add), ptb, call */
#define R_IA64_PCREL22 0x7a /* @pcrel(sym+add), imm22 */
#define R_IA64_PCREL64I 0x7b /* @pcrel(sym+add), imm64 */
#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
#define R_IA64_COPY 0x84 /* dynamic reloc, data copy */
#define R_IA64_SUB 0x85 /* -symbol + addend, add imm22 */
#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
#define R_IA64_TPREL14 0x91 /* @tprel(sym+add), add imm14 */
#define R_IA64_TPREL22 0x92 /* @tprel(sym+add), add imm22 */
#define R_IA64_TPREL64I 0x93 /* @tprel(sym+add), add imm64 */
#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym+add), data8 MSB */
#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym+add), data8 LSB */
#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), add imm22 */
#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym+add), data8 MSB */
#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym+add), data8 LSB */
#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(s+a)), imm22 */
#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym+add), imm14 */
#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym+add), imm22 */
#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym+add), imm64 */
#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym+add), data4 MSB */
#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym+add), data4 LSB */
#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym+add), data8 MSB */
#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym+add), data8 LSB */
#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
/* IA-64 specific section flags: */
#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
/*
* We use (abuse?) this macro to insert the (empty) vm_area that is
* used to map the register backing store. I don't see any better
* place to do this, but we should discuss this with Linus once we can
* talk to him...
*/
extern void ia64_init_addr_space (void);
#define ELF_PLAT_INIT(_r, load_addr) ia64_init_addr_space()
/* ELF register definitions. This is needed for core dump support. */
/*
* elf_gregset_t contains the application-level state in the following order:
* r0-r31
* NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
* predicate registers (p0-p63)
* b0-b7
* ip cfm psr
* ar.rsc ar.bsp ar.bspstore ar.rnat
* ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
*/
#define ELF_NGREG 128 /* we really need just 72 but let's leave some headroom... */
#define ELF_NFPREG 128 /* f0 and f1 could be omitted, but so what... */
/* elf_gregset_t register offsets */
#define ELF_GR_0_OFFSET 0
#define ELF_NAT_OFFSET (32 * sizeof(elf_greg_t))
#define ELF_PR_OFFSET (33 * sizeof(elf_greg_t))
#define ELF_BR_0_OFFSET (34 * sizeof(elf_greg_t))
#define ELF_CR_IIP_OFFSET (42 * sizeof(elf_greg_t))
#define ELF_CFM_OFFSET (43 * sizeof(elf_greg_t))
#define ELF_CR_IPSR_OFFSET (44 * sizeof(elf_greg_t))
#define ELF_GR_OFFSET(i) (ELF_GR_0_OFFSET + i * sizeof(elf_greg_t))
#define ELF_BR_OFFSET(i) (ELF_BR_0_OFFSET + i * sizeof(elf_greg_t))
#define ELF_AR_RSC_OFFSET (45 * sizeof(elf_greg_t))
#define ELF_AR_BSP_OFFSET (46 * sizeof(elf_greg_t))
#define ELF_AR_BSPSTORE_OFFSET (47 * sizeof(elf_greg_t))
#define ELF_AR_RNAT_OFFSET (48 * sizeof(elf_greg_t))
#define ELF_AR_CCV_OFFSET (49 * sizeof(elf_greg_t))
#define ELF_AR_UNAT_OFFSET (50 * sizeof(elf_greg_t))
#define ELF_AR_FPSR_OFFSET (51 * sizeof(elf_greg_t))
#define ELF_AR_PFS_OFFSET (52 * sizeof(elf_greg_t))
#define ELF_AR_LC_OFFSET (53 * sizeof(elf_greg_t))
#define ELF_AR_EC_OFFSET (54 * sizeof(elf_greg_t))
#define ELF_AR_CSD_OFFSET (55 * sizeof(elf_greg_t))
#define ELF_AR_SSD_OFFSET (56 * sizeof(elf_greg_t))
#define ELF_AR_END_OFFSET (57 * sizeof(elf_greg_t))
typedef unsigned long elf_fpxregset_t;
typedef unsigned long elf_greg_t;
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct ia64_fpreg elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
struct pt_regs; /* forward declaration... */
extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
#define ELF_CORE_COPY_REGS(_dest,_regs) ia64_elf_core_copy_regs(_regs, _dest);
/* This macro yields a bitmask that programs can use to figure out
what instruction set this CPU supports. */
#define ELF_HWCAP 0
/* This macro yields a string that ld.so will use to load
implementation specific libraries for optimization. Not terribly
relevant until we have real hardware to play with... */
#define ELF_PLATFORM NULL
#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#define elf_read_implies_exec(ex, executable_stack) \
((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
struct task_struct;
#define GATE_EHDR ((const struct elfhdr *) GATE_ADDR)
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do { \
extern char __kernel_syscall_via_epc[]; \
NEW_AUX_ENT(AT_SYSINFO, (unsigned long) __kernel_syscall_via_epc); \
NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
} while (0)
/*
* These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
* extra segments containing the gate DSO contents. Dumping its
* contents makes post-mortem fully interpretable later without matching up
* the same kernel and hardware config to see what PC values meant.
* Dumping its extra ELF program headers includes all the other information
* a debugger needs to easily find how the gate DSO was being used.
*/
#define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum)
#define ELF_CORE_WRITE_EXTRA_PHDRS \
do { \
const struct elf_phdr *const gate_phdrs = \
(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
int i; \
Elf64_Off ofs = 0; \
for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
struct elf_phdr phdr = gate_phdrs[i]; \
if (phdr.p_type == PT_LOAD) { \
phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
phdr.p_filesz = phdr.p_memsz; \
if (ofs == 0) { \
ofs = phdr.p_offset = offset; \
offset += phdr.p_filesz; \
} \
else \
phdr.p_offset = ofs; \
} \
else \
phdr.p_offset += ofs; \
phdr.p_paddr = 0; /* match other core phdrs */ \
DUMP_WRITE(&phdr, sizeof(phdr)); \
} \
} while (0)
#define ELF_CORE_WRITE_EXTRA_DATA \
do { \
const struct elf_phdr *const gate_phdrs = \
(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
int i; \
for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
if (gate_phdrs[i].p_type == PT_LOAD) { \
DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \
PAGE_ALIGN(gate_phdrs[i].p_memsz)); \
break; \
} \
} \
} while (0)
/*
* format for entries in the Global Offset Table
*/
struct got_entry {
uint64_t val;
};
/*
* Layout of the Function Descriptor
*/
struct fdesc {
uint64_t ip;
uint64_t gp;
};
#endif /* _ASM_IA64_ELF_H */

View File

@@ -0,0 +1,6 @@
#ifndef _ASM_EMERGENCY_RESTART_H
#define _ASM_EMERGENCY_RESTART_H
#include <asm-generic/emergency-restart.h>
#endif /* _ASM_EMERGENCY_RESTART_H */

View File

@@ -0,0 +1 @@
#include <asm-generic/errno.h>

View File

@@ -0,0 +1,29 @@
/*
* ESI service calls.
*
* Copyright (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P.
* Alex Williamson <alex.williamson@hp.com>
*/
#ifndef esi_h
#define esi_h
#include <linux/efi.h>
#define ESI_QUERY 0x00000001
#define ESI_OPEN_HANDLE 0x02000000
#define ESI_CLOSE_HANDLE 0x02000001
enum esi_proc_type {
ESI_PROC_SERIALIZED, /* calls need to be serialized */
ESI_PROC_MP_SAFE, /* MP-safe, but not reentrant */
ESI_PROC_REENTRANT /* MP-safe and reentrant */
};
extern struct ia64_sal_retval esi_call_phys (void *, u64 *);
extern int ia64_esi_call(efi_guid_t, struct ia64_sal_retval *,
enum esi_proc_type,
u64, u64, u64, u64, u64, u64, u64, u64);
extern int ia64_esi_call_phys(efi_guid_t, struct ia64_sal_retval *, u64, u64,
u64, u64, u64, u64, u64, u64);
#endif /* esi_h */

View File

@@ -0,0 +1,23 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_
#include <linux/fb.h>
#include <linux/fs.h>
#include <linux/efi.h>
#include <asm/page.h>
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
unsigned long off)
{
if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
}
static inline int fb_is_primary_device(struct fb_info *info)
{
return 0;
}
#endif /* _ASM_FB_H_ */

View File

@@ -0,0 +1,13 @@
#ifndef _ASM_IA64_FCNTL_H
#define _ASM_IA64_FCNTL_H
/*
* Modified 1998-2000
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
*/
#define force_o_largefile() \
(personality(current->personality) != PER_LINUX32)
#include <asm-generic/fcntl.h>
#endif /* _ASM_IA64_FCNTL_H */

View File

@@ -0,0 +1,73 @@
#ifndef _ASM_IA64_FPSWA_H
#define _ASM_IA64_FPSWA_H
/*
* Floating-point Software Assist
*
* Copyright (C) 1999 Intel Corporation.
* Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
* Copyright (C) 1999 Goutham Rao <goutham.rao@intel.com>
*/
typedef struct {
/* 4 * 128 bits */
unsigned long fp_lp[4*2];
} fp_state_low_preserved_t;
typedef struct {
/* 10 * 128 bits */
unsigned long fp_lv[10 * 2];
} fp_state_low_volatile_t;
typedef struct {
/* 16 * 128 bits */
unsigned long fp_hp[16 * 2];
} fp_state_high_preserved_t;
typedef struct {
/* 96 * 128 bits */
unsigned long fp_hv[96 * 2];
} fp_state_high_volatile_t;
/**
* floating point state to be passed to the FP emulation library by
* the trap/fault handler
*/
typedef struct {
unsigned long bitmask_low64;
unsigned long bitmask_high64;
fp_state_low_preserved_t *fp_state_low_preserved;
fp_state_low_volatile_t *fp_state_low_volatile;
fp_state_high_preserved_t *fp_state_high_preserved;
fp_state_high_volatile_t *fp_state_high_volatile;
} fp_state_t;
typedef struct {
unsigned long status;
unsigned long err0;
unsigned long err1;
unsigned long err2;
} fpswa_ret_t;
/**
* function header for the Floating Point software assist
* library. This function is invoked by the Floating point software
* assist trap/fault handler.
*/
typedef fpswa_ret_t (*efi_fpswa_t) (unsigned long trap_type, void *bundle, unsigned long *ipsr,
unsigned long *fsr, unsigned long *isr, unsigned long *preds,
unsigned long *ifs, fp_state_t *fp_state);
/**
* This is the FPSWA library interface as defined by EFI. We need to pass a
* pointer to the interface itself on a call to the assist library
*/
typedef struct {
unsigned int revision;
unsigned int reserved;
efi_fpswa_t fpswa;
} fpswa_interface_t;
extern fpswa_interface_t *fpswa_interface;
#endif /* _ASM_IA64_FPSWA_H */

View File

@@ -0,0 +1,66 @@
#ifndef _ASM_IA64_FPU_H
#define _ASM_IA64_FPU_H
/*
* Copyright (C) 1998, 1999, 2002, 2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/types.h>
/* floating point status register: */
#define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */
#define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */
#define FPSR_TRAP_ZD (1 << 2) /* zero-divide trap disabled */
#define FPSR_TRAP_OD (1 << 3) /* overflow trap disabled */
#define FPSR_TRAP_UD (1 << 4) /* underflow trap disabled */
#define FPSR_TRAP_ID (1 << 5) /* inexact trap disabled */
#define FPSR_S0(x) ((x) << 6)
#define FPSR_S1(x) ((x) << 19)
#define FPSR_S2(x) (__IA64_UL(x) << 32)
#define FPSR_S3(x) (__IA64_UL(x) << 45)
/* floating-point status field controls: */
#define FPSF_FTZ (1 << 0) /* flush-to-zero */
#define FPSF_WRE (1 << 1) /* widest-range exponent */
#define FPSF_PC(x) (((x) & 0x3) << 2) /* precision control */
#define FPSF_RC(x) (((x) & 0x3) << 4) /* rounding control */
#define FPSF_TD (1 << 6) /* trap disabled */
/* floating-point status field flags: */
#define FPSF_V (1 << 7) /* invalid operation flag */
#define FPSF_D (1 << 8) /* denormal/unnormal operand flag */
#define FPSF_Z (1 << 9) /* zero divide (IEEE) flag */
#define FPSF_O (1 << 10) /* overflow (IEEE) flag */
#define FPSF_U (1 << 11) /* underflow (IEEE) flag */
#define FPSF_I (1 << 12) /* inexact (IEEE) flag) */
/* floating-point rounding control: */
#define FPRC_NEAREST 0x0
#define FPRC_NEGINF 0x1
#define FPRC_POSINF 0x2
#define FPRC_TRUNC 0x3
#define FPSF_DEFAULT (FPSF_PC (0x3) | FPSF_RC (FPRC_NEAREST))
/* This default value is the same as HP-UX uses. Don't change it
without a very good reason. */
#define FPSR_DEFAULT (FPSR_TRAP_VD | FPSR_TRAP_DD | FPSR_TRAP_ZD \
| FPSR_TRAP_OD | FPSR_TRAP_UD | FPSR_TRAP_ID \
| FPSR_S0 (FPSF_DEFAULT) \
| FPSR_S1 (FPSF_DEFAULT | FPSF_TD | FPSF_WRE) \
| FPSR_S2 (FPSF_DEFAULT | FPSF_TD) \
| FPSR_S3 (FPSF_DEFAULT | FPSF_TD))
# ifndef __ASSEMBLY__
struct ia64_fpreg {
union {
unsigned long bits[2];
long double __dummy; /* force 16-byte alignment */
} u;
};
# endif /* __ASSEMBLY__ */
#endif /* _ASM_IA64_FPU_H */

View File

@@ -0,0 +1,28 @@
#ifndef _ASM_IA64_FTRACE_H
#define _ASM_IA64_FTRACE_H
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_INSN_SIZE 32 /* sizeof mcount call */
#ifndef __ASSEMBLY__
extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0);
#define mcount _mcount
#include <asm/kprobes.h>
/* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */
#define MCOUNT_ADDR (((struct fnptr *)mcount)->ip)
#define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip)
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
/* second bundle, insn 2 */
return addr - 0x12;
}
struct dyn_arch_ftrace {
};
#endif
#endif /* CONFIG_FUNCTION_TRACER */
#endif /* _ASM_IA64_FTRACE_H */

View File

@@ -0,0 +1,124 @@
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#include <asm/system.h>
#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
do { \
register unsigned long r8 __asm ("r8") = 0; \
__asm__ __volatile__( \
" mf;; \n" \
"[1:] " insn ";; \n" \
" .xdata4 \"__ex_table\", 1b-., 2f-. \n" \
"[2:]" \
: "+r" (r8), "=r" (oldval) \
: "r" (uaddr), "r" (oparg) \
: "memory"); \
ret = r8; \
} while (0)
#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
do { \
register unsigned long r8 __asm ("r8") = 0; \
int val, newval; \
do { \
__asm__ __volatile__( \
" mf;; \n" \
"[1:] ld4 %3=[%4];; \n" \
" mov %2=%3 \n" \
insn ";; \n" \
" mov ar.ccv=%2;; \n" \
"[2:] cmpxchg4.acq %1=[%4],%3,ar.ccv;; \n" \
" .xdata4 \"__ex_table\", 1b-., 3f-.\n" \
" .xdata4 \"__ex_table\", 2b-., 3f-.\n" \
"[3:]" \
: "+r" (r8), "=r" (val), "=&r" (oldval), \
"=&r" (newval) \
: "r" (uaddr), "r" (oparg) \
: "memory"); \
if (unlikely (r8)) \
break; \
} while (unlikely (val != oldval)); \
ret = r8; \
} while (0)
static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op1("xchg4 %1=[%2],%3", ret, oldval, uaddr,
oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op2("add %3=%3,%5", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op2("or %3=%3,%5", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op2("and %3=%3,%5", ret, oldval, uaddr,
~oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op2("xor %3=%3,%5", ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable();
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
default: ret = -ENOSYS;
}
}
return ret;
}
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
{
register unsigned long r8 __asm ("r8");
__asm__ __volatile__(
" mf;; \n"
" mov ar.ccv=%3;; \n"
"[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n"
" .xdata4 \"__ex_table\", 1b-., 2f-. \n"
"[2:]"
: "=r" (r8)
: "r" (uaddr), "r" (newval),
"rO" ((long) (unsigned) oldval)
: "memory");
return r8;
}
}
#endif /* _ASM_FUTEX_H */

View File

@@ -0,0 +1,621 @@
#ifndef _ASM_IA64_GCC_INTRIN_H
#define _ASM_IA64_GCC_INTRIN_H
/*
*
* Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
*/
#include <linux/types.h>
#include <linux/compiler.h>
/* define this macro to get some asm stmts included in 'c' files */
#define ASM_SUPPORTED
/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
#define ia64_barrier() asm volatile ("":::"memory")
#define ia64_stop() asm volatile (";;"::)
#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum))
#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum))
#define ia64_flushrs() asm volatile ("flushrs;;":::"memory")
#define ia64_loadrs() asm volatile ("loadrs;;":::"memory")
extern void ia64_bad_param_for_setreg (void);
extern void ia64_bad_param_for_getreg (void);
#ifdef __KERNEL__
register unsigned long ia64_r13 asm ("r13") __used;
#endif
#define ia64_native_setreg(regnum, val) \
({ \
switch (regnum) { \
case _IA64_REG_PSR_L: \
asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \
break; \
case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
asm volatile ("mov ar%0=%1" :: \
"i" (regnum - _IA64_REG_AR_KR0), \
"r"(val): "memory"); \
break; \
case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
asm volatile ("mov cr%0=%1" :: \
"i" (regnum - _IA64_REG_CR_DCR), \
"r"(val): "memory" ); \
break; \
case _IA64_REG_SP: \
asm volatile ("mov r12=%0" :: \
"r"(val): "memory"); \
break; \
case _IA64_REG_GP: \
asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \
break; \
default: \
ia64_bad_param_for_setreg(); \
break; \
} \
})
#define ia64_native_getreg(regnum) \
({ \
__u64 ia64_intri_res; \
\
switch (regnum) { \
case _IA64_REG_GP: \
asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \
break; \
case _IA64_REG_IP: \
asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \
break; \
case _IA64_REG_PSR: \
asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \
break; \
case _IA64_REG_TP: /* for current() */ \
ia64_intri_res = ia64_r13; \
break; \
case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \
: "i"(regnum - _IA64_REG_AR_KR0)); \
break; \
case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \
: "i" (regnum - _IA64_REG_CR_DCR)); \
break; \
case _IA64_REG_SP: \
asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \
break; \
default: \
ia64_bad_param_for_getreg(); \
break; \
} \
ia64_intri_res; \
})
#define ia64_hint_pause 0
#define ia64_hint(mode) \
({ \
switch (mode) { \
case ia64_hint_pause: \
asm volatile ("hint @pause" ::: "memory"); \
break; \
} \
})
/* Integer values for mux1 instruction */
#define ia64_mux1_brcst 0
#define ia64_mux1_mix 8
#define ia64_mux1_shuf 9
#define ia64_mux1_alt 10
#define ia64_mux1_rev 11
#define ia64_mux1(x, mode) \
({ \
__u64 ia64_intri_res; \
\
switch (mode) { \
case ia64_mux1_brcst: \
asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \
break; \
case ia64_mux1_mix: \
asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \
break; \
case ia64_mux1_shuf: \
asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \
break; \
case ia64_mux1_alt: \
asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \
break; \
case ia64_mux1_rev: \
asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \
break; \
} \
ia64_intri_res; \
})
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# define ia64_popcnt(x) __builtin_popcountl(x)
#else
# define ia64_popcnt(x) \
({ \
__u64 ia64_intri_res; \
asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
\
ia64_intri_res; \
})
#endif
#define ia64_getf_exp(x) \
({ \
long ia64_intri_res; \
\
asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \
\
ia64_intri_res; \
})
#define ia64_shrp(a, b, count) \
({ \
__u64 ia64_intri_res; \
asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \
ia64_intri_res; \
})
#define ia64_ldfs(regnum, x) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \
})
#define ia64_ldfd(regnum, x) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \
})
#define ia64_ldfe(regnum, x) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \
})
#define ia64_ldf8(regnum, x) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \
})
#define ia64_ldf_fill(regnum, x) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \
})
#define ia64_st4_rel_nta(m, val) \
({ \
asm volatile ("st4.rel.nta [%0] = %1\n\t" :: "r"(m), "r"(val)); \
})
#define ia64_stfs(x, regnum) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
})
#define ia64_stfd(x, regnum) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
})
#define ia64_stfe(x, regnum) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
})
#define ia64_stf8(x, regnum) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
})
#define ia64_stf_spill(x, regnum) \
({ \
register double __f__ asm ("f"#regnum); \
asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
})
#define ia64_fetchadd4_acq(p, inc) \
({ \
\
__u64 ia64_intri_res; \
asm volatile ("fetchadd4.acq %0=[%1],%2" \
: "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
: "memory"); \
\
ia64_intri_res; \
})
#define ia64_fetchadd4_rel(p, inc) \
({ \
__u64 ia64_intri_res; \
asm volatile ("fetchadd4.rel %0=[%1],%2" \
: "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
: "memory"); \
\
ia64_intri_res; \
})
#define ia64_fetchadd8_acq(p, inc) \
({ \
\
__u64 ia64_intri_res; \
asm volatile ("fetchadd8.acq %0=[%1],%2" \
: "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
: "memory"); \
\
ia64_intri_res; \
})
#define ia64_fetchadd8_rel(p, inc) \
({ \
__u64 ia64_intri_res; \
asm volatile ("fetchadd8.rel %0=[%1],%2" \
: "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
: "memory"); \
\
ia64_intri_res; \
})
#define ia64_xchg1(ptr,x) \
({ \
__u64 ia64_intri_res; \
asm volatile ("xchg1 %0=[%1],%2" \
: "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \
ia64_intri_res; \
})
#define ia64_xchg2(ptr,x) \
({ \
__u64 ia64_intri_res; \
asm volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \
: "r" (ptr), "r" (x) : "memory"); \
ia64_intri_res; \
})
#define ia64_xchg4(ptr,x) \
({ \
__u64 ia64_intri_res; \
asm volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \
: "r" (ptr), "r" (x) : "memory"); \
ia64_intri_res; \
})
#define ia64_xchg8(ptr,x) \
({ \
__u64 ia64_intri_res; \
asm volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \
: "r" (ptr), "r" (x) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg1_acq(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg1_rel(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg2_acq(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg2_rel(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
\
asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg4_acq(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg4_rel(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg8_acq(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_cmpxchg8_rel(ptr, new, old) \
({ \
__u64 ia64_intri_res; \
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
\
asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
ia64_intri_res; \
})
#define ia64_mf() asm volatile ("mf" ::: "memory")
#define ia64_mfa() asm volatile ("mf.a" ::: "memory")
#define ia64_invala() asm volatile ("invala" ::: "memory")
#define ia64_native_thash(addr) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
ia64_intri_res; \
})
#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
#ifdef HAVE_SERIALIZE_DIRECTIVE
# define ia64_dv_serialize_data() asm volatile (".serialize.data");
# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction");
#else
# define ia64_dv_serialize_data()
# define ia64_dv_serialize_instruction()
#endif
#define ia64_nop(x) asm volatile ("nop %0"::"i"(x));
#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
#define ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \
:: "r"(trnum), "r"(addr) : "memory")
#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \
:: "r"(trnum), "r"(addr) : "memory")
#define ia64_tpa(addr) \
({ \
unsigned long ia64_pa; \
asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \
ia64_pa; \
})
#define __ia64_set_dbr(index, val) \
asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
#define ia64_set_ibr(index, val) \
asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
#define ia64_set_pkr(index, val) \
asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
#define ia64_set_pmc(index, val) \
asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
#define ia64_set_pmd(index, val) \
asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
#define ia64_native_set_rr(index, val) \
asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
#define ia64_native_get_cpuid(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
ia64_intri_res; \
})
#define __ia64_get_dbr(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
#define ia64_get_ibr(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
#define ia64_get_pkr(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
#define ia64_get_pmc(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
#define ia64_native_get_pmd(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
ia64_intri_res; \
})
#define ia64_native_get_rr(index) \
({ \
unsigned long ia64_intri_res; \
asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
ia64_intri_res; \
})
#define ia64_native_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
#define ia64_native_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
#define ia64_native_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
#define ia64_native_ptcga(addr, size) \
do { \
asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
ia64_dv_serialize_data(); \
} while (0)
#define ia64_ptcl(addr, size) \
do { \
asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory"); \
ia64_dv_serialize_data(); \
} while (0)
#define ia64_ptri(addr, size) \
asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
#define ia64_ptrd(addr, size) \
asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
#define ia64_ttag(addr) \
({ \
__u64 ia64_intri_res; \
asm volatile ("ttag %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
ia64_intri_res; \
})
/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
#define ia64_lfhint_none 0
#define ia64_lfhint_nt1 1
#define ia64_lfhint_nt2 2
#define ia64_lfhint_nta 3
#define ia64_lfetch(lfhint, y) \
({ \
switch (lfhint) { \
case ia64_lfhint_none: \
asm volatile ("lfetch [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nt1: \
asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nt2: \
asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nta: \
asm volatile ("lfetch.nta [%0]" : : "r"(y)); \
break; \
} \
})
#define ia64_lfetch_excl(lfhint, y) \
({ \
switch (lfhint) { \
case ia64_lfhint_none: \
asm volatile ("lfetch.excl [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nt1: \
asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nt2: \
asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nta: \
asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \
break; \
} \
})
#define ia64_lfetch_fault(lfhint, y) \
({ \
switch (lfhint) { \
case ia64_lfhint_none: \
asm volatile ("lfetch.fault [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nt1: \
asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nt2: \
asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \
break; \
case ia64_lfhint_nta: \
asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \
break; \
} \
})
#define ia64_lfetch_fault_excl(lfhint, y) \
({ \
switch (lfhint) { \
case ia64_lfhint_none: \
asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nt1: \
asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nt2: \
asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \
break; \
case ia64_lfhint_nta: \
asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \
break; \
} \
})
#define ia64_native_intrin_local_irq_restore(x) \
do { \
asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
"(p6) ssm psr.i;" \
"(p7) rsm psr.i;;" \
"(p6) srlz.d" \
:: "r"((x)) : "p6", "p7", "memory"); \
} while (0)
#endif /* _ASM_IA64_GCC_INTRIN_H */

View File

@@ -0,0 +1,27 @@
#ifndef _ASM_IA64_HARDIRQ_H
#define _ASM_IA64_HARDIRQ_H
/*
* Modified 1998-2002, 2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/threads.h>
#include <linux/irq.h>
#include <asm/processor.h>
/*
* No irq_cpustat_t for IA-64. The data is held in the per-CPU data structure.
*/
#define __ARCH_IRQ_STAT 1
#define local_softirq_pending() (local_cpu_data->softirq_pending)
extern void __iomem *ipi_base_addr;
void ack_bad_irq(unsigned int irq);
#endif /* _ASM_IA64_HARDIRQ_H */

View File

@@ -0,0 +1,16 @@
#ifndef _ASMIA64_HPSIM_H
#define _ASMIA64_HPSIM_H
#ifndef CONFIG_HP_SIMSERIAL_CONSOLE
static inline int simcons_register(void) { return 1; }
#else
int simcons_register(void);
#endif
struct tty_driver;
extern struct tty_driver *hp_simserial_driver;
void ia64_ssc_connect_irq(long intr, long irq);
void ia64_ctl_trace(long on);
#endif

View File

@@ -0,0 +1,80 @@
#ifndef _ASM_IA64_HUGETLB_H
#define _ASM_IA64_HUGETLB_H
#include <asm/page.h>
void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
unsigned long end, unsigned long floor,
unsigned long ceiling);
int prepare_hugepage_range(struct file *file,
unsigned long addr, unsigned long len);
static inline int is_hugepage_only_range(struct mm_struct *mm,
unsigned long addr,
unsigned long len)
{
return (REGION_NUMBER(addr) == RGN_HPAGE ||
REGION_NUMBER((addr)+(len)-1) == RGN_HPAGE);
}
static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
{
}
static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
set_pte_at(mm, addr, ptep, pte);
}
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
return ptep_get_and_clear(mm, addr, ptep);
}
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
}
static inline int huge_pte_none(pte_t pte)
{
return pte_none(pte);
}
static inline pte_t huge_pte_wrprotect(pte_t pte)
{
return pte_wrprotect(pte);
}
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
ptep_set_wrprotect(mm, addr, ptep);
}
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
{
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
}
static inline pte_t huge_ptep_get(pte_t *ptep)
{
return *ptep;
}
static inline int arch_prepare_hugepage(struct page *page)
{
return 0;
}
static inline void arch_release_hugepage(struct page *page)
{
}
#endif /* _ASM_IA64_HUGETLB_H */

View File

@@ -0,0 +1,192 @@
#ifndef _ASM_IA64_HW_IRQ_H
#define _ASM_IA64_HW_IRQ_H
/*
* Copyright (C) 2001-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/profile.h>
#include <asm/machvec.h>
#include <asm/ptrace.h>
#include <asm/smp.h>
#ifndef CONFIG_PARAVIRT
typedef u8 ia64_vector;
#else
typedef u16 ia64_vector;
#endif
/*
* 0 special
*
* 1,3-14 are reserved from firmware
*
* 16-255 (vectored external interrupts) are available
*
* 15 spurious interrupt (see IVR)
*
* 16 lowest priority, 255 highest priority
*
* 15 classes of 16 interrupts each.
*/
#define IA64_MIN_VECTORED_IRQ 16
#define IA64_MAX_VECTORED_IRQ 255
#define IA64_NUM_VECTORS 256
#define AUTO_ASSIGN -1
#define IA64_SPURIOUS_INT_VECTOR 0x0f
/*
* Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI.
*/
#define IA64_CPEP_VECTOR 0x1c /* corrected platform error polling vector */
#define IA64_CMCP_VECTOR 0x1d /* corrected machine-check polling vector */
#define IA64_CPE_VECTOR 0x1e /* corrected platform error interrupt vector */
#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */
/*
* Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
* Use vectors 0x30-0xe7 as the default device vector range for ia64.
* Platforms may choose to reduce this range in platform_irq_setup, but the
* platform range must fall within
* [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR]
*/
extern int ia64_first_device_vector;
extern int ia64_last_device_vector;
#define IA64_DEF_FIRST_DEVICE_VECTOR 0x30
#define IA64_DEF_LAST_DEVICE_VECTOR 0xe7
#define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector
#define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector
#define IA64_MAX_DEVICE_VECTORS (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1)
#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
#define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */
#define IA64_PERFMON_VECTOR 0xee /* performance monitor interrupt vector */
#define IA64_TIMER_VECTOR 0xef /* use highest-prio group 15 interrupt for timer */
#define IA64_MCA_WAKEUP_VECTOR 0xf0 /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */
#define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */
#define IA64_IPI_RESCHEDULE 0xfd /* SMP reschedule */
#define IA64_IPI_VECTOR 0xfe /* inter-processor interrupt vector */
/* Used for encoding redirected irqs */
#define IA64_IRQ_REDIRECTED (1 << 31)
/* IA64 inter-cpu interrupt related definitions */
#define IA64_IPI_DEFAULT_BASE_ADDR 0xfee00000
/* Delivery modes for inter-cpu interrupts */
enum {
IA64_IPI_DM_INT = 0x0, /* pend an external interrupt */
IA64_IPI_DM_PMI = 0x2, /* pend a PMI */
IA64_IPI_DM_NMI = 0x4, /* pend an NMI (vector 2) */
IA64_IPI_DM_INIT = 0x5, /* pend an INIT interrupt */
IA64_IPI_DM_EXTINT = 0x7, /* pend an 8259-compatible interrupt. */
};
extern __u8 isa_irq_to_vector_map[16];
#define isa_irq_to_vector(x) isa_irq_to_vector_map[(x)]
struct irq_cfg {
ia64_vector vector;
cpumask_t domain;
cpumask_t old_domain;
unsigned move_cleanup_count;
u8 move_in_progress : 1;
};
extern spinlock_t vector_lock;
extern struct irq_cfg irq_cfg[NR_IRQS];
#define irq_to_domain(x) irq_cfg[(x)].domain
DECLARE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq);
extern struct irq_chip irq_type_ia64_lsapic; /* CPU-internal interrupt controller */
#ifdef CONFIG_PARAVIRT_GUEST
#include <asm/paravirt.h>
#else
#define ia64_register_ipi ia64_native_register_ipi
#define assign_irq_vector ia64_native_assign_irq_vector
#define free_irq_vector ia64_native_free_irq_vector
#define register_percpu_irq ia64_native_register_percpu_irq
#define ia64_resend_irq ia64_native_resend_irq
#endif
extern void ia64_native_register_ipi(void);
extern int bind_irq_vector(int irq, int vector, cpumask_t domain);
extern int ia64_native_assign_irq_vector (int irq); /* allocate a free vector */
extern void ia64_native_free_irq_vector (int vector);
extern int reserve_irq_vector (int vector);
extern void __setup_vector_irq(int cpu);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action);
extern int check_irq_used (int irq);
extern void destroy_and_reserve_irq (unsigned int irq);
#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
extern int irq_prepare_move(int irq, int cpu);
extern void irq_complete_move(unsigned int irq);
#else
static inline int irq_prepare_move(int irq, int cpu) { return 0; }
static inline void irq_complete_move(unsigned int irq) {}
#endif
static inline void ia64_native_resend_irq(unsigned int vector)
{
platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
}
/*
* Default implementations for the irq-descriptor API:
*/
extern struct irq_desc irq_desc[NR_IRQS];
#ifndef CONFIG_IA64_GENERIC
static inline ia64_vector __ia64_irq_to_vector(int irq)
{
return irq_cfg[irq].vector;
}
static inline unsigned int
__ia64_local_vector_to_irq (ia64_vector vec)
{
return __get_cpu_var(vector_irq)[vec];
}
#endif
/*
* Next follows the irq descriptor interface. On IA-64, each CPU supports 256 interrupt
* vectors. On smaller systems, there is a one-to-one correspondence between interrupt
* vectors and the Linux irq numbers. However, larger systems may have multiple interrupt
* domains meaning that the translation from vector number to irq number depends on the
* interrupt domain that a CPU belongs to. This API abstracts such platform-dependent
* differences and provides a uniform means to translate between vector and irq numbers
* and to obtain the irq descriptor for a given irq number.
*/
/* Extract the IA-64 vector that corresponds to IRQ. */
static inline ia64_vector
irq_to_vector (int irq)
{
return platform_irq_to_vector(irq);
}
/*
* Convert the local IA-64 vector to the corresponding irq number. This translation is
* done in the context of the interrupt domain that the currently executing CPU belongs
* to.
*/
static inline unsigned int
local_vector_to_irq (ia64_vector vec)
{
return platform_local_vector_to_irq(vec);
}
#endif /* _ASM_IA64_HW_IRQ_H */

View File

@@ -0,0 +1,40 @@
#ifndef _ASM_IA64_IA32_H
#define _ASM_IA64_IA32_H
#include <asm/ptrace.h>
#include <asm/signal.h>
#define IA32_NR_syscalls 285 /* length of syscall table */
#define IA32_PAGE_SHIFT 12 /* 4KB pages */
#ifndef __ASSEMBLY__
# ifdef CONFIG_IA32_SUPPORT
#define IA32_PAGE_OFFSET 0xc0000000
extern void ia32_cpu_init (void);
extern void ia32_mem_init (void);
extern void ia32_gdt_init (void);
extern int ia32_exception (struct pt_regs *regs, unsigned long isr);
extern int ia32_intercept (struct pt_regs *regs, unsigned long isr);
extern int ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs);
# endif /* !CONFIG_IA32_SUPPORT */
/* Declare this unconditionally, so we don't get warnings for unreachable code. */
extern int ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs);
#if PAGE_SHIFT > IA32_PAGE_SHIFT
extern int ia32_copy_ia64_partial_page_list(struct task_struct *,
unsigned long);
extern void ia32_drop_ia64_partial_page_list(struct task_struct *);
#else
# define ia32_copy_ia64_partial_page_list(a1, a2) 0
# define ia32_drop_ia64_partial_page_list(a1) do { ; } while (0)
#endif
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_IA32_H */

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2002,2003 Intel Corp.
* Jun Nakajima <jun.nakajima@intel.com>
* Suresh Siddha <suresh.b.siddha@intel.com>
*/
#ifndef _ASM_IA64_IA64REGS_H
#define _ASM_IA64_IA64REGS_H
/*
* Register Names for getreg() and setreg().
*
* The "magic" numbers happen to match the values used by the Intel compiler's
* getreg()/setreg() intrinsics.
*/
/* Special Registers */
#define _IA64_REG_IP 1016 /* getreg only */
#define _IA64_REG_PSR 1019
#define _IA64_REG_PSR_L 1019
/* General Integer Registers */
#define _IA64_REG_GP 1025 /* R1 */
#define _IA64_REG_R8 1032 /* R8 */
#define _IA64_REG_R9 1033 /* R9 */
#define _IA64_REG_SP 1036 /* R12 */
#define _IA64_REG_TP 1037 /* R13 */
/* Application Registers */
#define _IA64_REG_AR_KR0 3072
#define _IA64_REG_AR_KR1 3073
#define _IA64_REG_AR_KR2 3074
#define _IA64_REG_AR_KR3 3075
#define _IA64_REG_AR_KR4 3076
#define _IA64_REG_AR_KR5 3077
#define _IA64_REG_AR_KR6 3078
#define _IA64_REG_AR_KR7 3079
#define _IA64_REG_AR_RSC 3088
#define _IA64_REG_AR_BSP 3089
#define _IA64_REG_AR_BSPSTORE 3090
#define _IA64_REG_AR_RNAT 3091
#define _IA64_REG_AR_FCR 3093
#define _IA64_REG_AR_EFLAG 3096
#define _IA64_REG_AR_CSD 3097
#define _IA64_REG_AR_SSD 3098
#define _IA64_REG_AR_CFLAG 3099
#define _IA64_REG_AR_FSR 3100
#define _IA64_REG_AR_FIR 3101
#define _IA64_REG_AR_FDR 3102
#define _IA64_REG_AR_CCV 3104
#define _IA64_REG_AR_UNAT 3108
#define _IA64_REG_AR_FPSR 3112
#define _IA64_REG_AR_ITC 3116
#define _IA64_REG_AR_PFS 3136
#define _IA64_REG_AR_LC 3137
#define _IA64_REG_AR_EC 3138
/* Control Registers */
#define _IA64_REG_CR_DCR 4096
#define _IA64_REG_CR_ITM 4097
#define _IA64_REG_CR_IVA 4098
#define _IA64_REG_CR_PTA 4104
#define _IA64_REG_CR_IPSR 4112
#define _IA64_REG_CR_ISR 4113
#define _IA64_REG_CR_IIP 4115
#define _IA64_REG_CR_IFA 4116
#define _IA64_REG_CR_ITIR 4117
#define _IA64_REG_CR_IIPA 4118
#define _IA64_REG_CR_IFS 4119
#define _IA64_REG_CR_IIM 4120
#define _IA64_REG_CR_IHA 4121
#define _IA64_REG_CR_LID 4160
#define _IA64_REG_CR_IVR 4161 /* getreg only */
#define _IA64_REG_CR_TPR 4162
#define _IA64_REG_CR_EOI 4163
#define _IA64_REG_CR_IRR0 4164 /* getreg only */
#define _IA64_REG_CR_IRR1 4165 /* getreg only */
#define _IA64_REG_CR_IRR2 4166 /* getreg only */
#define _IA64_REG_CR_IRR3 4167 /* getreg only */
#define _IA64_REG_CR_ITV 4168
#define _IA64_REG_CR_PMV 4169
#define _IA64_REG_CR_CMCV 4170
#define _IA64_REG_CR_LRR0 4176
#define _IA64_REG_CR_LRR1 4177
/* Indirect Registers for getindreg() and setindreg() */
#define _IA64_REG_INDR_CPUID 9000 /* getindreg only */
#define _IA64_REG_INDR_DBR 9001
#define _IA64_REG_INDR_IBR 9002
#define _IA64_REG_INDR_PKR 9003
#define _IA64_REG_INDR_PMC 9004
#define _IA64_REG_INDR_PMD 9005
#define _IA64_REG_INDR_RR 9006
#endif /* _ASM_IA64_IA64REGS_H */

View File

@@ -0,0 +1,7 @@
#ifndef _ASM_IA64_IDLE_H
#define _ASM_IA64_IDLE_H
static inline void enter_idle(void) { }
static inline void exit_idle(void) { }
#endif /* _ASM_IA64_IDLE_H */

View File

@@ -0,0 +1,161 @@
#ifndef _ASM_IA64_INTEL_INTRIN_H
#define _ASM_IA64_INTEL_INTRIN_H
/*
* Intel Compiler Intrinsics
*
* Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
* Copyright (C) 2005,2006 Hongjiu Lu <hongjiu.lu@intel.com>
*
*/
#include <ia64intrin.h>
#define ia64_barrier() __memory_barrier()
#define ia64_stop() /* Nothing: As of now stop bit is generated for each
* intrinsic
*/
#define ia64_native_getreg __getReg
#define ia64_native_setreg __setReg
#define ia64_hint __hint
#define ia64_hint_pause __hint_pause
#define ia64_mux1_brcst _m64_mux1_brcst
#define ia64_mux1_mix _m64_mux1_mix
#define ia64_mux1_shuf _m64_mux1_shuf
#define ia64_mux1_alt _m64_mux1_alt
#define ia64_mux1_rev _m64_mux1_rev
#define ia64_mux1(x,v) _m_to_int64(_m64_mux1(_m_from_int64(x), (v)))
#define ia64_popcnt _m64_popcnt
#define ia64_getf_exp __getf_exp
#define ia64_shrp _m64_shrp
#define ia64_tpa __tpa
#define ia64_invala __invala
#define ia64_invala_gr __invala_gr
#define ia64_invala_fr __invala_fr
#define ia64_nop __nop
#define ia64_sum __sum
#define ia64_native_ssm __ssm
#define ia64_rum __rum
#define ia64_native_rsm __rsm
#define ia64_native_fc __fc
#define ia64_ldfs __ldfs
#define ia64_ldfd __ldfd
#define ia64_ldfe __ldfe
#define ia64_ldf8 __ldf8
#define ia64_ldf_fill __ldf_fill
#define ia64_stfs __stfs
#define ia64_stfd __stfd
#define ia64_stfe __stfe
#define ia64_stf8 __stf8
#define ia64_stf_spill __stf_spill
#define ia64_mf __mf
#define ia64_mfa __mfa
#define ia64_fetchadd4_acq __fetchadd4_acq
#define ia64_fetchadd4_rel __fetchadd4_rel
#define ia64_fetchadd8_acq __fetchadd8_acq
#define ia64_fetchadd8_rel __fetchadd8_rel
#define ia64_xchg1 _InterlockedExchange8
#define ia64_xchg2 _InterlockedExchange16
#define ia64_xchg4 _InterlockedExchange
#define ia64_xchg8 _InterlockedExchange64
#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel
#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq
#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel
#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq
#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel
#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq
#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel
#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq
#define __ia64_set_dbr(index, val) \
__setIndReg(_IA64_REG_INDR_DBR, index, val)
#define ia64_set_ibr(index, val) \
__setIndReg(_IA64_REG_INDR_IBR, index, val)
#define ia64_set_pkr(index, val) \
__setIndReg(_IA64_REG_INDR_PKR, index, val)
#define ia64_set_pmc(index, val) \
__setIndReg(_IA64_REG_INDR_PMC, index, val)
#define ia64_set_pmd(index, val) \
__setIndReg(_IA64_REG_INDR_PMD, index, val)
#define ia64_native_set_rr(index, val) \
__setIndReg(_IA64_REG_INDR_RR, index, val)
#define ia64_native_get_cpuid(index) \
__getIndReg(_IA64_REG_INDR_CPUID, index)
#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index)
#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index)
#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index)
#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index)
#define ia64_native_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index)
#define ia64_native_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index)
#define ia64_srlz_d __dsrlz
#define ia64_srlz_i __isrlz
#define ia64_dv_serialize_data()
#define ia64_dv_serialize_instruction()
#define ia64_st1_rel __st1_rel
#define ia64_st2_rel __st2_rel
#define ia64_st4_rel __st4_rel
#define ia64_st8_rel __st8_rel
/* FIXME: need st4.rel.nta intrinsic */
#define ia64_st4_rel_nta __st4_rel
#define ia64_ld1_acq __ld1_acq
#define ia64_ld2_acq __ld2_acq
#define ia64_ld4_acq __ld4_acq
#define ia64_ld8_acq __ld8_acq
#define ia64_sync_i __synci
#define ia64_native_thash __thash
#define ia64_native_ttag __ttag
#define ia64_itcd __itcd
#define ia64_itci __itci
#define ia64_itrd __itrd
#define ia64_itri __itri
#define ia64_ptce __ptce
#define ia64_ptcl __ptcl
#define ia64_native_ptcg __ptcg
#define ia64_native_ptcga __ptcga
#define ia64_ptri __ptri
#define ia64_ptrd __ptrd
#define ia64_dep_mi _m64_dep_mi
/* Values for lfhint in __lfetch and __lfetch_fault */
#define ia64_lfhint_none __lfhint_none
#define ia64_lfhint_nt1 __lfhint_nt1
#define ia64_lfhint_nt2 __lfhint_nt2
#define ia64_lfhint_nta __lfhint_nta
#define ia64_lfetch __lfetch
#define ia64_lfetch_excl __lfetch_excl
#define ia64_lfetch_fault __lfetch_fault
#define ia64_lfetch_fault_excl __lfetch_fault_excl
#define ia64_native_intrin_local_irq_restore(x) \
do { \
if ((x) != 0) { \
ia64_native_ssm(IA64_PSR_I); \
ia64_srlz_d(); \
} else { \
ia64_native_rsm(IA64_PSR_I); \
} \
} while (0)
#define __builtin_trap() __break(0);
#endif /* _ASM_IA64_INTEL_INTRIN_H */

View File

@@ -0,0 +1,246 @@
#ifndef _ASM_IA64_INTRINSICS_H
#define _ASM_IA64_INTRINSICS_H
/*
* Compiler-dependent intrinsics.
*
* Copyright (C) 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#ifndef __ASSEMBLY__
#include <linux/types.h>
/* include compiler specific intrinsics */
#include <asm/ia64regs.h>
#ifdef __INTEL_COMPILER
# include <asm/intel_intrin.h>
#else
# include <asm/gcc_intrin.h>
#endif
#define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
do { \
ia64_native_set_rr(0x0000000000000000UL, (val0)); \
ia64_native_set_rr(0x2000000000000000UL, (val1)); \
ia64_native_set_rr(0x4000000000000000UL, (val2)); \
ia64_native_set_rr(0x6000000000000000UL, (val3)); \
ia64_native_set_rr(0x8000000000000000UL, (val4)); \
} while (0)
/*
* Force an unresolved reference if someone tries to use
* ia64_fetch_and_add() with a bad value.
*/
extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
#define IA64_FETCHADD(tmp,v,n,sz,sem) \
({ \
switch (sz) { \
case 4: \
tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \
break; \
\
case 8: \
tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \
break; \
\
default: \
__bad_size_for_ia64_fetch_and_add(); \
} \
})
#define ia64_fetchadd(i,v,sem) \
({ \
__u64 _tmp; \
volatile __typeof__(*(v)) *_v = (v); \
/* Can't use a switch () here: gcc isn't always smart enough for that... */ \
if ((i) == -16) \
IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \
else if ((i) == -8) \
IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \
else if ((i) == -4) \
IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \
else if ((i) == -1) \
IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \
else if ((i) == 1) \
IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \
else if ((i) == 4) \
IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \
else if ((i) == 8) \
IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \
else if ((i) == 16) \
IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \
else \
_tmp = __bad_increment_for_ia64_fetch_and_add(); \
(__typeof__(*(v))) (_tmp); /* return old value */ \
})
#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */
/*
* This function doesn't exist, so you'll get a linker error if
* something tries to do an invalid xchg().
*/
extern void ia64_xchg_called_with_bad_pointer (void);
#define __xchg(x,ptr,size) \
({ \
unsigned long __xchg_result; \
\
switch (size) { \
case 1: \
__xchg_result = ia64_xchg1((__u8 *)ptr, x); \
break; \
\
case 2: \
__xchg_result = ia64_xchg2((__u16 *)ptr, x); \
break; \
\
case 4: \
__xchg_result = ia64_xchg4((__u32 *)ptr, x); \
break; \
\
case 8: \
__xchg_result = ia64_xchg8((__u64 *)ptr, x); \
break; \
default: \
ia64_xchg_called_with_bad_pointer(); \
} \
__xchg_result; \
})
#define xchg(ptr,x) \
((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
#define __HAVE_ARCH_CMPXCHG 1
/*
* This function doesn't exist, so you'll get a linker error
* if something tries to do an invalid cmpxchg().
*/
extern long ia64_cmpxchg_called_with_bad_pointer (void);
#define ia64_cmpxchg(sem,ptr,old,new,size) \
({ \
__u64 _o_, _r_; \
\
switch (size) { \
case 1: _o_ = (__u8 ) (long) (old); break; \
case 2: _o_ = (__u16) (long) (old); break; \
case 4: _o_ = (__u32) (long) (old); break; \
case 8: _o_ = (__u64) (long) (old); break; \
default: break; \
} \
switch (size) { \
case 1: \
_r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \
break; \
\
case 2: \
_r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \
break; \
\
case 4: \
_r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \
break; \
\
case 8: \
_r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \
break; \
\
default: \
_r_ = ia64_cmpxchg_called_with_bad_pointer(); \
break; \
} \
(__typeof__(old)) _r_; \
})
#define cmpxchg_acq(ptr, o, n) \
ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
#define cmpxchg_rel(ptr, o, n) \
ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
/* for compatibility with other platforms: */
#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n))
#define cmpxchg_local cmpxchg
#define cmpxchg64_local cmpxchg64
#ifdef CONFIG_IA64_DEBUG_CMPXCHG
# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128;
# define CMPXCHG_BUGCHECK(v) \
do { \
if (_cmpxchg_bugcheck_count-- <= 0) { \
void *ip; \
extern int printk(const char *fmt, ...); \
ip = (void *) ia64_getreg(_IA64_REG_IP); \
printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \
break; \
} \
} while (0)
#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
# define CMPXCHG_BUGCHECK_DECL
# define CMPXCHG_BUGCHECK(v)
#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
#endif
#ifdef __KERNEL__
#include <asm/paravirt_privop.h>
#endif
#ifndef __ASSEMBLY__
#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
#ifdef ASM_SUPPORTED
# define IA64_INTRINSIC_API(name) paravirt_ ## name
#else
# define IA64_INTRINSIC_API(name) pv_cpu_ops.name
#endif
#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
#else
#define IA64_INTRINSIC_API(name) ia64_native_ ## name
#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
#endif
/************************************************/
/* Instructions paravirtualized for correctness */
/************************************************/
/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
* is not currently used (though it may be in a long-format VHPT system!)
*/
#define ia64_fc IA64_INTRINSIC_API(fc)
#define ia64_thash IA64_INTRINSIC_API(thash)
#define ia64_get_cpuid IA64_INTRINSIC_API(get_cpuid)
#define ia64_get_pmd IA64_INTRINSIC_API(get_pmd)
/************************************************/
/* Instructions paravirtualized for performance */
/************************************************/
#define ia64_ssm IA64_INTRINSIC_MACRO(ssm)
#define ia64_rsm IA64_INTRINSIC_MACRO(rsm)
#define ia64_getreg IA64_INTRINSIC_MACRO(getreg)
#define ia64_setreg IA64_INTRINSIC_API(setreg)
#define ia64_set_rr IA64_INTRINSIC_API(set_rr)
#define ia64_get_rr IA64_INTRINSIC_API(get_rr)
#define ia64_ptcga IA64_INTRINSIC_API(ptcga)
#define ia64_get_psr_i IA64_INTRINSIC_API(get_psr_i)
#define ia64_intrin_local_irq_restore \
IA64_INTRINSIC_API(intrin_local_irq_restore)
#define ia64_set_rr0_to_rr4 IA64_INTRINSIC_API(set_rr0_to_rr4)
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_INTRINSICS_H */

View File

@@ -0,0 +1,439 @@
#ifndef _ASM_IA64_IO_H
#define _ASM_IA64_IO_H
/*
* This file contains the definitions for the emulated IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated to
* (a) handle it all in a way that makes gcc able to optimize it as
* well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
* Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
*/
#include <asm/unaligned.h>
/* We don't use IO slowdowns on the ia64, but.. */
#define __SLOW_DOWN_IO do { } while (0)
#define SLOW_DOWN_IO do { } while (0)
#define __IA64_UNCACHED_OFFSET RGN_BASE(RGN_UNCACHED)
/*
* The legacy I/O space defined by the ia64 architecture supports only 65536 ports, but
* large machines may have multiple other I/O spaces so we can't place any a priori limit
* on IO_SPACE_LIMIT. These additional spaces are described in ACPI.
*/
#define IO_SPACE_LIMIT 0xffffffffffffffffUL
#define MAX_IO_SPACES_BITS 8
#define MAX_IO_SPACES (1UL << MAX_IO_SPACES_BITS)
#define IO_SPACE_BITS 24
#define IO_SPACE_SIZE (1UL << IO_SPACE_BITS)
#define IO_SPACE_NR(port) ((port) >> IO_SPACE_BITS)
#define IO_SPACE_BASE(space) ((space) << IO_SPACE_BITS)
#define IO_SPACE_PORT(port) ((port) & (IO_SPACE_SIZE - 1))
#define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | ((p) & 0xfff))
struct io_space {
unsigned long mmio_base; /* base in MMIO space */
int sparse;
};
extern struct io_space io_space[];
extern unsigned int num_io_spaces;
# ifdef __KERNEL__
/*
* All MMIO iomem cookies are in region 6; anything less is a PIO cookie:
* 0xCxxxxxxxxxxxxxxx MMIO cookie (return from ioremap)
* 0x000000001SPPPPPP PIO cookie (S=space number, P..P=port)
*
* ioread/writeX() uses the leading 1 in PIO cookies (PIO_OFFSET) to catch
* code that uses bare port numbers without the prerequisite pci_iomap().
*/
#define PIO_OFFSET (1UL << (MAX_IO_SPACES_BITS + IO_SPACE_BITS))
#define PIO_MASK (PIO_OFFSET - 1)
#define PIO_RESERVED __IA64_UNCACHED_OFFSET
#define HAVE_ARCH_PIO_SIZE
#include <asm/intrinsics.h>
#include <asm/machvec.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm-generic/iomap.h>
/*
* Change virtual addresses to physical addresses and vv.
*/
static inline unsigned long
virt_to_phys (volatile void *address)
{
return (unsigned long) address - PAGE_OFFSET;
}
static inline void*
phys_to_virt (unsigned long address)
{
return (void *) (address + PAGE_OFFSET);
}
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
extern int valid_phys_addr_range (unsigned long addr, size_t count); /* efi.c */
extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
/*
* The following two macros are deprecated and scheduled for removal.
* Please use the PCI-DMA interface defined in <asm/pci.h> instead.
*/
#define bus_to_virt phys_to_virt
#define virt_to_bus virt_to_phys
#define page_to_bus page_to_phys
# endif /* KERNEL */
/*
* Memory fence w/accept. This should never be used in code that is
* not IA-64 specific.
*/
#define __ia64_mf_a() ia64_mfa()
/**
* ___ia64_mmiowb - I/O write barrier
*
* Ensure ordering of I/O space writes. This will make sure that writes
* following the barrier will arrive after all previous writes. For most
* ia64 platforms, this is a simple 'mf.a' instruction.
*
* See Documentation/DocBook/deviceiobook.tmpl for more information.
*/
static inline void ___ia64_mmiowb(void)
{
ia64_mfa();
}
static inline void*
__ia64_mk_io_addr (unsigned long port)
{
struct io_space *space;
unsigned long offset;
space = &io_space[IO_SPACE_NR(port)];
port = IO_SPACE_PORT(port);
if (space->sparse)
offset = IO_SPACE_SPARSE_ENCODING(port);
else
offset = port;
return (void *) (space->mmio_base | offset);
}
#define __ia64_inb ___ia64_inb
#define __ia64_inw ___ia64_inw
#define __ia64_inl ___ia64_inl
#define __ia64_outb ___ia64_outb
#define __ia64_outw ___ia64_outw
#define __ia64_outl ___ia64_outl
#define __ia64_readb ___ia64_readb
#define __ia64_readw ___ia64_readw
#define __ia64_readl ___ia64_readl
#define __ia64_readq ___ia64_readq
#define __ia64_readb_relaxed ___ia64_readb
#define __ia64_readw_relaxed ___ia64_readw
#define __ia64_readl_relaxed ___ia64_readl
#define __ia64_readq_relaxed ___ia64_readq
#define __ia64_writeb ___ia64_writeb
#define __ia64_writew ___ia64_writew
#define __ia64_writel ___ia64_writel
#define __ia64_writeq ___ia64_writeq
#define __ia64_mmiowb ___ia64_mmiowb
/*
* For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
* that the access has completed before executing other I/O accesses. Since we're doing
* the accesses through an uncachable (UC) translation, the CPU will execute them in
* program order. However, we still need to tell the compiler not to shuffle them around
* during optimization, which is why we use "volatile" pointers.
*/
static inline unsigned int
___ia64_inb (unsigned long port)
{
volatile unsigned char *addr = __ia64_mk_io_addr(port);
unsigned char ret;
ret = *addr;
__ia64_mf_a();
return ret;
}
static inline unsigned int
___ia64_inw (unsigned long port)
{
volatile unsigned short *addr = __ia64_mk_io_addr(port);
unsigned short ret;
ret = *addr;
__ia64_mf_a();
return ret;
}
static inline unsigned int
___ia64_inl (unsigned long port)
{
volatile unsigned int *addr = __ia64_mk_io_addr(port);
unsigned int ret;
ret = *addr;
__ia64_mf_a();
return ret;
}
static inline void
___ia64_outb (unsigned char val, unsigned long port)
{
volatile unsigned char *addr = __ia64_mk_io_addr(port);
*addr = val;
__ia64_mf_a();
}
static inline void
___ia64_outw (unsigned short val, unsigned long port)
{
volatile unsigned short *addr = __ia64_mk_io_addr(port);
*addr = val;
__ia64_mf_a();
}
static inline void
___ia64_outl (unsigned int val, unsigned long port)
{
volatile unsigned int *addr = __ia64_mk_io_addr(port);
*addr = val;
__ia64_mf_a();
}
static inline void
__insb (unsigned long port, void *dst, unsigned long count)
{
unsigned char *dp = dst;
while (count--)
*dp++ = platform_inb(port);
}
static inline void
__insw (unsigned long port, void *dst, unsigned long count)
{
unsigned short *dp = dst;
while (count--)
put_unaligned(platform_inw(port), dp++);
}
static inline void
__insl (unsigned long port, void *dst, unsigned long count)
{
unsigned int *dp = dst;
while (count--)
put_unaligned(platform_inl(port), dp++);
}
static inline void
__outsb (unsigned long port, const void *src, unsigned long count)
{
const unsigned char *sp = src;
while (count--)
platform_outb(*sp++, port);
}
static inline void
__outsw (unsigned long port, const void *src, unsigned long count)
{
const unsigned short *sp = src;
while (count--)
platform_outw(get_unaligned(sp++), port);
}
static inline void
__outsl (unsigned long port, const void *src, unsigned long count)
{
const unsigned int *sp = src;
while (count--)
platform_outl(get_unaligned(sp++), port);
}
/*
* Unfortunately, some platforms are broken and do not follow the IA-64 architecture
* specification regarding legacy I/O support. Thus, we have to make these operations
* platform dependent...
*/
#define __inb platform_inb
#define __inw platform_inw
#define __inl platform_inl
#define __outb platform_outb
#define __outw platform_outw
#define __outl platform_outl
#define __mmiowb platform_mmiowb
#define inb(p) __inb(p)
#define inw(p) __inw(p)
#define inl(p) __inl(p)
#define insb(p,d,c) __insb(p,d,c)
#define insw(p,d,c) __insw(p,d,c)
#define insl(p,d,c) __insl(p,d,c)
#define outb(v,p) __outb(v,p)
#define outw(v,p) __outw(v,p)
#define outl(v,p) __outl(v,p)
#define outsb(p,s,c) __outsb(p,s,c)
#define outsw(p,s,c) __outsw(p,s,c)
#define outsl(p,s,c) __outsl(p,s,c)
#define mmiowb() __mmiowb()
/*
* The address passed to these functions are ioremap()ped already.
*
* We need these to be machine vectors since some platforms don't provide
* DMA coherence via PIO reads (PCI drivers and the spec imply that this is
* a good idea). Writes are ok though for all existing ia64 platforms (and
* hopefully it'll stay that way).
*/
static inline unsigned char
___ia64_readb (const volatile void __iomem *addr)
{
return *(volatile unsigned char __force *)addr;
}
static inline unsigned short
___ia64_readw (const volatile void __iomem *addr)
{
return *(volatile unsigned short __force *)addr;
}
static inline unsigned int
___ia64_readl (const volatile void __iomem *addr)
{
return *(volatile unsigned int __force *) addr;
}
static inline unsigned long
___ia64_readq (const volatile void __iomem *addr)
{
return *(volatile unsigned long __force *) addr;
}
static inline void
__writeb (unsigned char val, volatile void __iomem *addr)
{
*(volatile unsigned char __force *) addr = val;
}
static inline void
__writew (unsigned short val, volatile void __iomem *addr)
{
*(volatile unsigned short __force *) addr = val;
}
static inline void
__writel (unsigned int val, volatile void __iomem *addr)
{
*(volatile unsigned int __force *) addr = val;
}
static inline void
__writeq (unsigned long val, volatile void __iomem *addr)
{
*(volatile unsigned long __force *) addr = val;
}
#define __readb platform_readb
#define __readw platform_readw
#define __readl platform_readl
#define __readq platform_readq
#define __readb_relaxed platform_readb_relaxed
#define __readw_relaxed platform_readw_relaxed
#define __readl_relaxed platform_readl_relaxed
#define __readq_relaxed platform_readq_relaxed
#define readb(a) __readb((a))
#define readw(a) __readw((a))
#define readl(a) __readl((a))
#define readq(a) __readq((a))
#define readb_relaxed(a) __readb_relaxed((a))
#define readw_relaxed(a) __readw_relaxed((a))
#define readl_relaxed(a) __readl_relaxed((a))
#define readq_relaxed(a) __readq_relaxed((a))
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_readq readq
#define __raw_readb_relaxed readb_relaxed
#define __raw_readw_relaxed readw_relaxed
#define __raw_readl_relaxed readl_relaxed
#define __raw_readq_relaxed readq_relaxed
#define writeb(v,a) __writeb((v), (a))
#define writew(v,a) __writew((v), (a))
#define writel(v,a) __writel((v), (a))
#define writeq(v,a) __writeq((v), (a))
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define __raw_writeq writeq
#ifndef inb_p
# define inb_p inb
#endif
#ifndef inw_p
# define inw_p inw
#endif
#ifndef inl_p
# define inl_p inl
#endif
#ifndef outb_p
# define outb_p outb
#endif
#ifndef outw_p
# define outw_p outw
#endif
#ifndef outl_p
# define outl_p outl
#endif
# ifdef __KERNEL__
extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap (volatile void __iomem *addr);
extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
/*
* String version of IO memory access ops:
*/
extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
extern void memset_io(volatile void __iomem *s, int c, long n);
# endif /* __KERNEL__ */
#endif /* _ASM_IA64_IO_H */

View File

@@ -0,0 +1 @@
#include <asm-generic/ioctl.h>

View File

@@ -0,0 +1,93 @@
#ifndef _ASM_IA64_IOCTLS_H
#define _ASM_IA64_IOCTLS_H
/*
* Based on <asm-i386/ioctls.h>
*
* Modified 1998, 1999, 2002
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
#include <asm/ioctl.h>
/* 0x54 is just a magic number to make these relatively unique ('T') */
#define TCGETS 0x5401
#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TCGETA 0x5405
#define TCSETA 0x5406
#define TCSETAW 0x5407
#define TCSETAF 0x5408
#define TCSBRK 0x5409
#define TCXONC 0x540A
#define TCFLSH 0x540B
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define FIONREAD 0x541B
#define TIOCINQ FIONREAD
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define FIONBIO 0x5421
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
#define TCGETS2 _IOR('T',0x2A, struct termios2)
#define TCSETS2 _IOW('T',0x2B, struct termios2)
#define TCSETSW2 _IOW('T',0x2C, struct termios2)
#define TCSETSF2 _IOW('T',0x2D, struct termios2)
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
#define FIOQSIZE 0x5460
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#endif /* _ASM_IA64_IOCTLS_H */

View File

@@ -0,0 +1,20 @@
#ifndef _ASM_IA64_IOMMU_H
#define _ASM_IA64_IOMMU_H 1
#define cpu_has_x2apic 0
/* 10 seconds */
#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
extern void pci_iommu_shutdown(void);
extern void no_iommu_init(void);
extern int force_iommu, no_iommu;
extern int iommu_detected;
#ifdef CONFIG_DMAR
extern int iommu_pass_through;
#else
#define iommu_pass_through (0)
#endif
extern void iommu_dma_init(void);
extern void machvec_init(const char *name);
#endif

Some files were not shown because too many files have changed in this diff Show More