mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
tools: drop ia64 support
Removed support from libxc and mini-os. This also took me under xen/include/public via various symlinks. Dropped tools/debugger/xenitp entirely, it was described upon commit as: "Xenitp is a low-level debugger for ia64" and doesn't appear to be linked into the build anywhere. 99 files changed, 14 insertions(+), 32361 deletions(-) Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Keir Fraser <keir@xen.org> Committed-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
1 parent
2fcb3c6fc7
commit
e567964a54
103 files changed
+31
-32399
No files matched your search
@@ -9,7 +9,7 @@ export XEN_INTERFACE_VERSION
|
||||
|
||||
# Try to find out the architecture family TARGET_ARCH_FAM.
|
||||
# First check whether x86_... is contained (for x86_32, x86_32y, x86_64).
|
||||
# If not x86 then use $(XEN_TARGET_ARCH) -> for ia64, ...
|
||||
# If not x86 then use $(XEN_TARGET_ARCH)
|
||||
ifeq ($(findstring x86_,$(XEN_TARGET_ARCH)),x86_)
|
||||
TARGET_ARCH_FAM = x86
|
||||
else
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#
|
||||
# Special makefile for ia64.
|
||||
#
|
||||
|
||||
XEN_ROOT = $(CURDIR)/../../../..
|
||||
include $(XEN_ROOT)/Config.mk
|
||||
|
||||
include ../../Config.mk
|
||||
|
||||
include arch.mk
|
||||
include ../../minios.mk
|
||||
|
||||
ARCH_SRCS := sal.c
|
||||
ARCH_SRCS += efi.c
|
||||
ARCH_SRCS += time.c
|
||||
ARCH_SRCS += ivt.S
|
||||
ARCH_SRCS += fw.S
|
||||
ARCH_SRCS += common.c
|
||||
ARCH_SRCS += time.c
|
||||
ARCH_SRCS += mm.c
|
||||
ARCH_SRCS += debug.c
|
||||
ARCH_SRCS += sched.c
|
||||
ARCH_SRCS += xencomm.c
|
||||
ARCH_SRCS += __umoddi3.S
|
||||
ARCH_SRCS += __udivdi3.S
|
||||
ARCH_SRCS += __divdi3.S
|
||||
|
||||
ARCH_OBJS := sal.o
|
||||
ARCH_OBJS += efi.o
|
||||
ARCH_OBJS += time.o
|
||||
ARCH_OBJS += ivt.o
|
||||
ARCH_OBJS += fw.o
|
||||
ARCH_OBJS += common.o
|
||||
ARCH_OBJS += time.o
|
||||
ARCH_OBJS += mm.o
|
||||
ARCH_OBJS += debug.o
|
||||
ARCH_OBJS += sched.o
|
||||
ARCH_OBJS += xencomm.o
|
||||
ARCH_OBJS += __umoddi3.o
|
||||
ARCH_OBJS += __udivdi3.o
|
||||
ARCH_OBJS += __udivsi3.o
|
||||
ARCH_OBJS += __divdi3.o
|
||||
ARCH_OBJS := $(addprefix $(OBJ_DIR)/,$(ARCH_OBJS))
|
||||
|
||||
GEN_OFF_SRC := gen_off.c
|
||||
GEN_OFF_ASM := gen_off.s
|
||||
GEN_OFF_H := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h
|
||||
|
||||
all: $(OBJ_DIR)/$(ARCH_LIB)
|
||||
|
||||
$(GEN_OFF_ASM): $(GEN_OFF_SRC)
|
||||
$(CC) -S -o $@ $(CPPFLAGS) $<
|
||||
|
||||
$(GEN_OFF_H): $(GEN_OFF_ASM)
|
||||
sed -ne "/^->/ {s/->/#define /; p}" < $< > $@
|
||||
|
||||
$(OBJ_DIR)/$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
|
||||
$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
|
||||
rm -f $(GEN_OFF_ASM)
|
||||
rm -f $(GEN_OFF_H)
|
||||
@@ -1,141 +0,0 @@
|
||||
.file "__divdi3.s"
|
||||
|
||||
// $FreeBSD: src/sys/libkern/ia64/__divdi3.S,v 1.1 2000/10/04 17:53:03 dfr Exp $
|
||||
//
|
||||
// Copyright (c) 2000, Intel Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// Contributed 2/15/2000 by Marius Cornea, John Harrison, Cristina Iordache,
|
||||
// Ted Kubaska, Bob Norin, and Shane Story of the Computational Software Lab,
|
||||
// Intel Corporation.
|
||||
//
|
||||
// WARRANTY DISCLAIMER
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Intel Corporation is the author of this code, and requests that all
|
||||
// problem reports or change requests be submitted to it directly at
|
||||
// http://developer.intel.com/opensource.
|
||||
//
|
||||
|
||||
.section .text
|
||||
.proc __divdi3#
|
||||
.align 32
|
||||
.global __divdi3#
|
||||
.align 32
|
||||
|
||||
// 64-bit signed integer divide
|
||||
|
||||
__divdi3:
|
||||
|
||||
{ .mii
|
||||
alloc r31=ar.pfs,2,0,0,0
|
||||
nop.i 0
|
||||
nop.i 0;;
|
||||
} { .mmi
|
||||
|
||||
// 64-BIT SIGNED INTEGER DIVIDE BEGINS HERE
|
||||
|
||||
setf.sig f8=r32
|
||||
setf.sig f9=r33
|
||||
nop.i 0;;
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
fcvt.xf f6=f8
|
||||
nop.b 0
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
fcvt.xf f7=f9
|
||||
nop.b 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (1)
|
||||
// y0 = 1 / b in f8
|
||||
frcpa.s1 f8,p6=f6,f7
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (2)
|
||||
// e0 = 1 - b * y0 in f9
|
||||
(p6) fnma.s1 f9=f7,f8,f1
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (3)
|
||||
// q0 = a * y0 in f10
|
||||
(p6) fma.s1 f10=f6,f8,f0
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (4)
|
||||
// e1 = e0 * e0 in f11
|
||||
(p6) fma.s1 f11=f9,f9,f0
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (5)
|
||||
// q1 = q0 + e0 * q0 in f10
|
||||
(p6) fma.s1 f10=f9,f10,f10
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (6)
|
||||
// y1 = y0 + e0 * y0 in f8
|
||||
(p6) fma.s1 f8=f9,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (7)
|
||||
// q2 = q1 + e1 * q1 in f9
|
||||
(p6) fma.s1 f9=f11,f10,f10
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (8)
|
||||
// y2 = y1 + e1 * y1 in f8
|
||||
(p6) fma.s1 f8=f11,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (9)
|
||||
// r2 = a - b * q2 in f10
|
||||
(p6) fnma.s1 f10=f7,f9,f6
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (10)
|
||||
// q3 = q2 + r2 * y2 in f8
|
||||
(p6) fma.s1 f8=f10,f8,f9
|
||||
nop.i 0;;
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
// Step (11)
|
||||
// q = trunc (q3)
|
||||
fcvt.fx.trunc.s1 f8=f8
|
||||
nop.b 0;;
|
||||
} { .mmi
|
||||
// quotient will be in r8 (if b != 0)
|
||||
getf.sig r8=f8
|
||||
nop.m 0
|
||||
nop.i 0;;
|
||||
}
|
||||
|
||||
// 64-BIT SIGNED INTEGER DIVIDE ENDS HERE
|
||||
|
||||
{ .mmb
|
||||
nop.m 0
|
||||
nop.m 0
|
||||
br.ret.sptk b0;;
|
||||
}
|
||||
|
||||
.endp __divdi3
|
||||
@@ -1,142 +0,0 @@
|
||||
.file "__udivdi3.s"
|
||||
|
||||
// $FreeBSD: src/sys/libkern/ia64/__udivdi3.S,v 1.1 2000/10/04 17:53:03 dfr Exp $
|
||||
//
|
||||
// Copyright (c) 2000, Intel Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// Contributed 2/15/2000 by Marius Cornea, John Harrison, Cristina Iordache,
|
||||
// Ted Kubaska, Bob Norin, and Shane Story of the Computational Software Lab,
|
||||
// Intel Corporation.
|
||||
//
|
||||
// WARRANTY DISCLAIMER
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Intel Corporation is the author of this code, and requests that all
|
||||
// problem reports or change requests be submitted to it directly at
|
||||
// http://developer.intel.com/opensource.
|
||||
//
|
||||
|
||||
.section .text
|
||||
.proc __udivdi3#
|
||||
.align 32
|
||||
.global __udivdi3#
|
||||
.align 32
|
||||
|
||||
// 64-bit unsigned integer divide
|
||||
|
||||
__udivdi3:
|
||||
|
||||
{ .mii
|
||||
alloc r31=ar.pfs,2,0,0,0
|
||||
nop.i 0
|
||||
nop.i 0;;
|
||||
}
|
||||
|
||||
{ .mmi
|
||||
|
||||
// 64-BIT UNSIGNED INTEGER DIVIDE BEGINS HERE
|
||||
|
||||
setf.sig f8=r32
|
||||
setf.sig f9=r33
|
||||
nop.i 0;;
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
fma.s1 f6=f8,f1,f0
|
||||
nop.b 0
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
fma.s1 f7=f9,f1,f0
|
||||
nop.b 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (1)
|
||||
// y0 = 1 / b in f8
|
||||
frcpa.s1 f8,p6=f6,f7
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (2)
|
||||
// e0 = 1 - b * y0 in f9
|
||||
(p6) fnma.s1 f9=f7,f8,f1
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (3)
|
||||
// q0 = a * y0 in f10
|
||||
(p6) fma.s1 f10=f6,f8,f0
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (4)
|
||||
// e1 = e0 * e0 in f11
|
||||
(p6) fma.s1 f11=f9,f9,f0
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (5)
|
||||
// q1 = q0 + e0 * q0 in f10
|
||||
(p6) fma.s1 f10=f9,f10,f10
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (6)
|
||||
// y1 = y0 + e0 * y0 in f8
|
||||
(p6) fma.s1 f8=f9,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (7)
|
||||
// q2 = q1 + e1 * q1 in f9
|
||||
(p6) fma.s1 f9=f11,f10,f10
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (8)
|
||||
// y2 = y1 + e1 * y1 in f8
|
||||
(p6) fma.s1 f8=f11,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (9)
|
||||
// r2 = a - b * q2 in f10
|
||||
(p6) fnma.s1 f10=f7,f9,f6
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (10)
|
||||
// q3 = q2 + r2 * y2 in f8
|
||||
(p6) fma.s1 f8=f10,f8,f9
|
||||
nop.i 0;;
|
||||
} { .mfb
|
||||
nop.m 0
|
||||
// (11) q = trunc(q3)
|
||||
fcvt.fxu.trunc.s1 f8=f8
|
||||
nop.b 0;;
|
||||
} { .mmi
|
||||
// quotient will be in r8 (if b != 0)
|
||||
getf.sig r8=f8
|
||||
nop.m 0
|
||||
nop.i 0;;
|
||||
}
|
||||
|
||||
// 64-BIT UNSIGNED INTEGER DIVIDE ENDS HERE
|
||||
|
||||
{ .mmb
|
||||
nop.m 0
|
||||
nop.m 0
|
||||
br.ret.sptk b0;;
|
||||
}
|
||||
|
||||
.endp __udivdi3
|
||||
@@ -1,124 +0,0 @@
|
||||
.file "__udivsi3.s"
|
||||
|
||||
// $FreeBSD: src/sys/libkern/ia64/__udivsi3.S,v 1.1.8.1 2005/01/31 23:26:21 imp Exp $
|
||||
|
||||
//-
|
||||
// Copyright (c) 2000, Intel Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// Contributed 2/15/2000 by Marius Cornea, John Harrison, Cristina Iordache,
|
||||
// Ted Kubaska, Bob Norin, and Shane Story of the Computational Software Lab,
|
||||
// Intel Corporation.
|
||||
//
|
||||
// WARRANTY DISCLAIMER
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Intel Corporation is the author of this code, and requests that all
|
||||
// problem reports or change requests be submitted to it directly at
|
||||
// http://developer.intel.com/opensource.
|
||||
//
|
||||
|
||||
.section .text
|
||||
|
||||
// 32-bit unsigned integer divide
|
||||
|
||||
.proc __udivsi3#
|
||||
.align 32
|
||||
.global __udivsi3#
|
||||
.align 32
|
||||
|
||||
__udivsi3:
|
||||
|
||||
{ .mii
|
||||
alloc r31=ar.pfs,2,0,0,0
|
||||
nop.i 0
|
||||
nop.i 0;;
|
||||
} { .mii
|
||||
nop.m 0
|
||||
|
||||
// 32-BIT UNSIGNED INTEGER DIVIDE BEGINS HERE
|
||||
|
||||
// general register used:
|
||||
// r32 - 32-bit unsigned integer dividend
|
||||
// r33 - 32-bit unsigned integer divisor
|
||||
// r8 - 32-bit unsigned integer result
|
||||
// r2 - scratch register
|
||||
// floating-point registers used: f6, f7, f8, f9
|
||||
// predicate registers used: p6
|
||||
|
||||
zxt4 r32=r32
|
||||
zxt4 r33=r33;;
|
||||
} { .mmb
|
||||
setf.sig f6=r32
|
||||
setf.sig f7=r33
|
||||
nop.b 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
fcvt.xf f6=f6
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
fcvt.xf f7=f7
|
||||
mov r2 = 0x0ffdd;;
|
||||
} { .mfi
|
||||
setf.exp f9 = r2
|
||||
// (1) y0
|
||||
frcpa.s1 f8,p6=f6,f7
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (2) q0 = a * y0
|
||||
(p6) fma.s1 f6=f6,f8,f0
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (3) e0 = 1 - b * y0
|
||||
(p6) fnma.s1 f7=f7,f8,f1
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (4) q1 = q0 + e0 * q0
|
||||
(p6) fma.s1 f6=f7,f6,f6
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (5) e1 = e0 * e0 + 2^-34
|
||||
(p6) fma.s1 f7=f7,f7,f9
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (6) q2 = q1 + e1 * q1
|
||||
(p6) fma.s1 f8=f7,f6,f6
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (7) q = trunc(q2)
|
||||
fcvt.fxu.trunc.s1 f8=f8
|
||||
nop.i 0;;
|
||||
} { .mmi
|
||||
// quotient will be in the least significant 32 bits of r8 (if b != 0)
|
||||
getf.sig r8=f8
|
||||
nop.m 0
|
||||
nop.i 0;;
|
||||
}
|
||||
|
||||
// 32-BIT UNSIGNED INTEGER DIVIDE ENDS HERE
|
||||
|
||||
{ .mmb
|
||||
nop.m 0
|
||||
nop.m 0
|
||||
br.ret.sptk b0;;
|
||||
}
|
||||
|
||||
.endp __udivsi3
|
||||
@@ -1,154 +0,0 @@
|
||||
.file "__umoddi3.s"
|
||||
|
||||
// $FreeBSD: src/sys/libkern/ia64/__umoddi3.S,v 1.3 2003/02/11 20:15:11 schweikh Exp $
|
||||
//
|
||||
// Copyright (c) 2000, Intel Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// Contributed 2/15/2000 by Marius Cornea, John Harrison, Cristina Iordache,
|
||||
// Ted Kubaska, Bob Norin, and Shane Story of the Computational Software Lab,
|
||||
// Intel Corporation.
|
||||
//
|
||||
// WARRANTY DISCLAIMER
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Intel Corporation is the author of this code, and requests that all
|
||||
// problem reports or change requests be submitted to it directly at
|
||||
// http://developer.intel.com/opensource.
|
||||
//
|
||||
|
||||
.section .text
|
||||
|
||||
// 64-bit unsigned integer remainder
|
||||
|
||||
.proc __umoddi3#
|
||||
.align 32
|
||||
.global __umoddi3#
|
||||
.align 32
|
||||
|
||||
__umoddi3:
|
||||
|
||||
{ .mii
|
||||
alloc r31=ar.pfs,3,0,0,0
|
||||
nop.i 0
|
||||
nop.i 0
|
||||
} { .mmb
|
||||
|
||||
// 64-BIT UNSIGNED INTEGER REMAINDER BEGINS HERE
|
||||
|
||||
// general register used:
|
||||
// r32 - 64-bit unsigned integer dividend, called a below
|
||||
// r33 - 64-bit unsigned integer divisor, called b below
|
||||
// r8 - 64-bit unsigned integer result
|
||||
// floating-point registers used: f6, f7, f8, f9, f10, f11, f12
|
||||
// predicate registers used: p6
|
||||
|
||||
setf.sig f12=r32 // holds a in integer form
|
||||
setf.sig f7=r33
|
||||
nop.b 0;;
|
||||
} { .mfi
|
||||
// get 2s complement of b
|
||||
sub r33=r0,r33
|
||||
fcvt.xuf.s1 f6=f12
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
fcvt.xuf.s1 f7=f7
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (1)
|
||||
// y0 = 1 / b in f8
|
||||
frcpa.s1 f8,p6=f6,f7
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (2)
|
||||
// q0 = a * y0 in f10
|
||||
(p6) fma.s1 f10=f6,f8,f0
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (3)
|
||||
// e0 = 1 - b * y0 in f9
|
||||
(p6) fnma.s1 f9=f7,f8,f1
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (4)
|
||||
// q1 = q0 + e0 * q0 in f10
|
||||
(p6) fma.s1 f10=f9,f10,f10
|
||||
nop.i 0
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (5)
|
||||
// e1 = e0 * e0 in f11
|
||||
(p6) fma.s1 f11=f9,f9,f0
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (6)
|
||||
// y1 = y0 + e0 * y0 in f8
|
||||
(p6) fma.s1 f8=f9,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (7)
|
||||
// q2 = q1 + e1 * q1 in f9
|
||||
(p6) fma.s1 f9=f11,f10,f10
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (8)
|
||||
// y2 = y1 + e1 * y1 in f8
|
||||
(p6) fma.s1 f8=f11,f8,f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// Step (9)
|
||||
// r2 = a - b * q2 in f10
|
||||
(p6) fnma.s1 f10=f7,f9,f6
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
// f7=-b
|
||||
setf.sig f7=r33
|
||||
// Step (10)
|
||||
// q3 = q2 + r2 * y2 in f8
|
||||
(p6) fma.s1 f8=f10,f8,f9
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (11) q = trunc(q3)
|
||||
fcvt.fxu.trunc.s1 f8=f8
|
||||
nop.i 0;;
|
||||
} { .mfi
|
||||
nop.m 0
|
||||
// (12) r = a + (-b) * q
|
||||
xma.l f8=f8,f7,f12
|
||||
nop.i 0;;
|
||||
} { .mib
|
||||
getf.sig r8=f8
|
||||
nop.i 0
|
||||
nop.b 0
|
||||
}
|
||||
|
||||
// 64-BIT UNSIGNED INTEGER REMAINDER ENDS HERE
|
||||
|
||||
{ .mib
|
||||
nop.m 0
|
||||
nop.i 0
|
||||
br.ret.sptk b0;;
|
||||
}
|
||||
|
||||
.endp __umoddi3
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
ARCH_CFLAGS := -mfixed-range=f2-f5,f12-f15,f32-f127 -mconstant-gp
|
||||
ARCH_CFLAGS += -O2
|
||||
ARCH_ASFLAGS := -x assembler-with-cpp
|
||||
ARCH_ASFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -fomit-frame-pointer
|
||||
ARCH_ASFLAGS += -fno-builtin -fno-common -fno-strict-aliasing -mconstant-gp
|
||||
|
||||
ARCH_LDFLAGS = -warn-common
|
||||
|
||||
@@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/types.h>
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/page.h>
|
||||
#include <xen/xen.h>
|
||||
#include <mini-os/privop.h>
|
||||
#include <xen/callback.h>
|
||||
#include <mini-os/ia64_cpu.h>
|
||||
#include <mini-os/hypervisor.h>
|
||||
#include <mini-os/events.h>
|
||||
#include <mini-os/console.h>
|
||||
#include <mini-os/time.h>
|
||||
#include <mini-os/xmalloc.h>
|
||||
|
||||
|
||||
/* For more console boot messages. */
|
||||
int bootverbose;
|
||||
|
||||
/*
|
||||
* This structure contains start-of-day info, such as pagetable base pointer,
|
||||
* address of the shared_info structure, and things like that.
|
||||
*/
|
||||
union start_info_union start_info_union;
|
||||
|
||||
shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)XSI_BASE;
|
||||
|
||||
struct machine_fw machineFwG;
|
||||
|
||||
/* This pointer is initialized in ia64.S with the address of the boot param
|
||||
* area passed by the bootloader. */
|
||||
struct xen_ia64_boot_param* ia64_boot_paramP;
|
||||
|
||||
struct xen_ia64_boot_param ia64BootParamG;
|
||||
char boot_cmd_line[COMMAND_LINE_SIZE+1];
|
||||
|
||||
|
||||
void
|
||||
ia64_write_itr_i(ia64_pte_t* pteP, uint32_t reg, uint64_t vAddr,
|
||||
uint64_t ps, uint64_t pk)
|
||||
{
|
||||
/* The virtual address. */
|
||||
__asm __volatile("mov cr.ifa=%0" :: "r"(vAddr));
|
||||
/* The page size */
|
||||
__asm __volatile("mov cr.itir=%0;;" :: "r"((ps << IA64_ITIR_PS)|(pk << IA64_ITIR_KEY)));
|
||||
/* Put pte into instruction translation register. */
|
||||
__asm __volatile("itr.i itr[%0]=%1" :: "r"(reg), "r"(*(uint64_t*)pteP));
|
||||
/* Serialization */
|
||||
__asm __volatile("srlz.i");
|
||||
}
|
||||
|
||||
void
|
||||
map_pal_code(void)
|
||||
{
|
||||
ia64_pte_t pte;
|
||||
|
||||
xen_set_virtual_psr_ic(0);
|
||||
memset(&pte, 0, sizeof(pte)); /* Prepare the pte */
|
||||
pte.pte_p = 1; /* present bit */
|
||||
pte.pte_ma = PTE_MA_WB; /* memory attribute */
|
||||
pte.pte_a = 1; /* accessed bit */
|
||||
pte.pte_d = 1; /* dirty bit */
|
||||
pte.pte_pl = PTE_PL_KERN; /* privilege level */
|
||||
pte.pte_ar = PTE_AR_RWX; /* access rights */
|
||||
pte.pte_ppn = ((uint64_t) __pa(machineFwG.ia64_pal_base)) >> 14;
|
||||
pte.pte_ed = 0; /* exception deferral */
|
||||
|
||||
/*
|
||||
* Must purge here because a itc/dtc with the same address
|
||||
* may be in the tlb!
|
||||
*/
|
||||
ia64_ptc_l(machineFwG.ia64_pal_base, PTE_PS_16K);
|
||||
ia64_write_itr_i(&pte, IA64_TR_PAL,
|
||||
(uint64_t)machineFwG.ia64_pal_base,
|
||||
PTE_PS_16K, IA64_KEY_REG7);
|
||||
xen_set_virtual_psr_ic(1);
|
||||
}
|
||||
|
||||
/* In ivt.S */
|
||||
extern char hypervisor_callback;
|
||||
|
||||
static void
|
||||
registerCallback(void)
|
||||
{
|
||||
struct callback_register event =
|
||||
{
|
||||
.type = CALLBACKTYPE_event,
|
||||
.address = (unsigned long)&hypervisor_callback,
|
||||
};
|
||||
HYPERVISOR_callback_op(CALLBACKOP_register, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
init_start_info(start_info_t* xen_start_info)
|
||||
{
|
||||
/* Make a copy of the start_info structure */
|
||||
start_info.nr_pages = xen_start_info->nr_pages;
|
||||
start_info.shared_info = xen_start_info->shared_info;
|
||||
start_info.flags = xen_start_info->flags;
|
||||
start_info.store_mfn = xen_start_info->store_mfn;
|
||||
start_info.store_evtchn = xen_start_info->store_evtchn;
|
||||
start_info.console.domU.mfn = xen_start_info->console.domU.mfn;
|
||||
start_info.console.domU.evtchn =
|
||||
xen_start_info->console.domU.evtchn;
|
||||
start_info.pt_base = xen_start_info->pt_base;
|
||||
start_info.nr_pt_frames = xen_start_info->nr_pt_frames;
|
||||
start_info.mfn_list = xen_start_info->mfn_list;
|
||||
start_info.mod_start = xen_start_info->mod_start;
|
||||
start_info.mod_len = xen_start_info->mod_len;
|
||||
}
|
||||
|
||||
static void
|
||||
init_boot_params(void)
|
||||
{
|
||||
ia64BootParamG.command_line = ia64_boot_paramP->command_line;
|
||||
ia64BootParamG.efi_systab = ia64_boot_paramP->efi_systab;
|
||||
ia64BootParamG.efi_memmap = ia64_boot_paramP->efi_memmap;
|
||||
ia64BootParamG.efi_memmap_size = ia64_boot_paramP->efi_memmap_size;
|
||||
ia64BootParamG.efi_memdesc_size = ia64_boot_paramP->efi_memdesc_size;
|
||||
ia64BootParamG.efi_memdesc_version =
|
||||
ia64_boot_paramP->efi_memdesc_version;
|
||||
ia64BootParamG.console_info.num_cols =
|
||||
ia64_boot_paramP->console_info.num_cols;
|
||||
ia64BootParamG.console_info.num_rows =
|
||||
ia64_boot_paramP->console_info.num_rows;
|
||||
ia64BootParamG.console_info.orig_x =
|
||||
ia64_boot_paramP->console_info.orig_x;
|
||||
ia64BootParamG.console_info.orig_y =
|
||||
ia64_boot_paramP->console_info.orig_y;
|
||||
ia64BootParamG.fpswa = ia64_boot_paramP->fpswa;
|
||||
ia64BootParamG.initrd_start = ia64_boot_paramP->initrd_start;
|
||||
ia64BootParamG.initrd_size = ia64_boot_paramP->initrd_size;
|
||||
ia64BootParamG.domain_start = ia64_boot_paramP->domain_start;
|
||||
ia64BootParamG.domain_size = ia64_boot_paramP->domain_size;
|
||||
|
||||
/*
|
||||
* Copy and parse the boot command line.
|
||||
* Currently only a check of bootverbose is done.
|
||||
*/
|
||||
memset(boot_cmd_line, 0, sizeof(boot_cmd_line));
|
||||
strncpy(boot_cmd_line,
|
||||
(char*)__va(ia64BootParamG.command_line), COMMAND_LINE_SIZE);
|
||||
boot_cmd_line[COMMAND_LINE_SIZE - 1] = '\0';
|
||||
|
||||
/* Look for bootverbose. */
|
||||
if (strstr(boot_cmd_line, "bootverbose"))
|
||||
bootverbose = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
set_opt_feature(void)
|
||||
{
|
||||
struct xen_ia64_opt_feature optf;
|
||||
|
||||
optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7;
|
||||
optf.on = XEN_IA64_OPTF_ON;
|
||||
optf.pgprot = ((1 << PTE_OFF_P) | (1 << PTE_OFF_A) | (1 << PTE_OFF_D) |
|
||||
(PTE_MA_WB << PTE_OFF_MA) |
|
||||
(PTE_PL_KERN << PTE_OFF_PL) |
|
||||
(PTE_AR_RW << PTE_OFF_AR));
|
||||
optf.key = IA64_KEY_REG7;
|
||||
HYPERVISOR_opt_feature(&optf);
|
||||
}
|
||||
|
||||
void
|
||||
arch_init(start_info_t *si)
|
||||
{
|
||||
efi_time_t tm;
|
||||
static int initialized;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
init_start_info(si);
|
||||
|
||||
init_boot_params();
|
||||
|
||||
init_efi();
|
||||
|
||||
map_pal_code();
|
||||
|
||||
ia64_sal_init(machineFwG.ia64_sal_tableP);
|
||||
|
||||
if (efi_get_time(&tm)) {
|
||||
printk("EFI-SystemTime: %d.%d.%d %d:%d:%d",
|
||||
tm.Day, tm.Month, tm.Year,
|
||||
tm.Hour, tm.Minute, tm.Second);
|
||||
|
||||
if (tm.TimeZone == EFI_UNSPECIFIED_TIMEZONE)
|
||||
printk(" Timezone not specified!\n");
|
||||
else
|
||||
printk(" TimeZone: %d Daylight: 0x%x\n",
|
||||
tm.TimeZone, tm.Daylight);
|
||||
} else
|
||||
printk("efi_get_time() failed\n");
|
||||
|
||||
registerCallback();
|
||||
|
||||
set_opt_feature();
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
void
|
||||
arch_fini(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void
|
||||
arch_print_info(void)
|
||||
{
|
||||
int major, minor;
|
||||
|
||||
minor = HYPERVISOR_xen_version(XENVER_version, 0);
|
||||
major = minor >> 16;
|
||||
minor &= ~0xffffffff;
|
||||
printk("Running on Xen version: %d.%d\n", major, minor);
|
||||
#if 0
|
||||
printk("machine addr of shared_info_t : 0x%lx\n",
|
||||
start_info.shared_info);
|
||||
printk("machine page number of shared page: 0x%lx\n",
|
||||
start_info.store_mfn);
|
||||
printk("evtchn for store communication : %d\n",
|
||||
start_info.store_evtchn);
|
||||
printk("MACHINE address of console page: 0x%lx\n",
|
||||
start_info.console.domU.mfn);
|
||||
printk("evtchn for console messages : %d\n",
|
||||
start_info.console.domU.evtchn);
|
||||
#endif
|
||||
if(strlen(boot_cmd_line) > 0)
|
||||
printk("xen_guest_cmdline : %s\n", boot_cmd_line);
|
||||
}
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
****************************************************************************
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
*
|
||||
* Description: ia64 specific part of the mini-os
|
||||
* Prints debug information on a crash of mini-os
|
||||
*
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <mini-os/os.h>
|
||||
|
||||
static const char *ia64_vector_names[] = {
|
||||
"VHPT Translation", /* 0 */
|
||||
"Instruction TLB", /* 1 */
|
||||
"Data TLB", /* 2 */
|
||||
"Alternate Instruction TLB", /* 3 */
|
||||
"Alternate Data TLB", /* 4 */
|
||||
"Data Nested TLB", /* 5 */
|
||||
"Instruction Key Miss", /* 6 */
|
||||
"Data Key Miss", /* 7 */
|
||||
"Dirty-Bit", /* 8 */
|
||||
"Instruction Access-Bit", /* 9 */
|
||||
"Data Access-Bit", /* 10 */
|
||||
"Break Instruction", /* 11 */
|
||||
"External Interrupt", /* 12 */
|
||||
"Reserved 13", /* 13 */
|
||||
"Reserved 14", /* 14 */
|
||||
"Reserved 15", /* 15 */
|
||||
"Reserved 16", /* 16 */
|
||||
"Reserved 17", /* 17 */
|
||||
"Reserved 18", /* 18 */
|
||||
"Reserved 19", /* 19 */
|
||||
"Page Not Present", /* 20 */
|
||||
"Key Permission", /* 21 */
|
||||
"Instruction Access Rights", /* 22 */
|
||||
"Data Access Rights", /* 23 */
|
||||
"General Exception", /* 24 */
|
||||
"Disabled FP-Register", /* 25 */
|
||||
"NaT Consumption", /* 26 */
|
||||
"Speculation", /* 27 */
|
||||
"Reserved 28", /* 28 */
|
||||
"Debug", /* 29 */
|
||||
"Unaligned Reference", /* 30 */
|
||||
"Unsupported Data Reference", /* 31 */
|
||||
"Floating-point Fault", /* 32 */
|
||||
"Floating-point Trap", /* 33 */
|
||||
"Lower-Privilege Transfer Trap", /* 34 */
|
||||
"Taken Branch Trap", /* 35 */
|
||||
"Single Step Trap", /* 36 */
|
||||
"Reserved 37", /* 37 */
|
||||
"Reserved 38", /* 38 */
|
||||
"Reserved 39", /* 39 */
|
||||
"Reserved 40", /* 40 */
|
||||
"Reserved 41", /* 41 */
|
||||
"Reserved 42", /* 42 */
|
||||
"Reserved 43", /* 43 */
|
||||
"Reserved 44", /* 44 */
|
||||
"IA-32 Exception", /* 45 */
|
||||
"IA-32 Intercept", /* 46 */
|
||||
"IA-32 Interrupt", /* 47 */
|
||||
"Reserved 48", /* 48 */
|
||||
"Reserved 49", /* 49 */
|
||||
"Reserved 50", /* 50 */
|
||||
"Reserved 51", /* 51 */
|
||||
"Reserved 52", /* 52 */
|
||||
"Reserved 53", /* 53 */
|
||||
"Reserved 54", /* 54 */
|
||||
"Reserved 55", /* 55 */
|
||||
"Reserved 56", /* 56 */
|
||||
"Reserved 57", /* 57 */
|
||||
"Reserved 58", /* 58 */
|
||||
"Reserved 59", /* 59 */
|
||||
"Reserved 60", /* 60 */
|
||||
"Reserved 61", /* 61 */
|
||||
"Reserved 62", /* 62 */
|
||||
"Reserved 63", /* 63 */
|
||||
"Reserved 64", /* 64 */
|
||||
"Reserved 65", /* 65 */
|
||||
"Reserved 66", /* 66 */
|
||||
"Reserved 67", /* 67 */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t sof :7; /* 0-6 size of frame */
|
||||
uint64_t sol :7; /* 7-13 size of locals (in + loc) */
|
||||
uint64_t sor :4;
|
||||
uint64_t rrb_gr :7;
|
||||
uint64_t rrb_fr :7;
|
||||
uint64_t rrb_pr :6;
|
||||
uint64_t res :25; /* reserved */
|
||||
uint64_t v :1; /* The v bit */
|
||||
} ifs_t;
|
||||
|
||||
void
|
||||
do_trap_error(trap_frame_t* tf)
|
||||
{
|
||||
ifs_t curIfs;
|
||||
|
||||
printk("TRAP in mini-os:\n");
|
||||
printk(" trap: %d (%s)\n", tf->trap_num,
|
||||
ia64_vector_names[tf->trap_num]);
|
||||
printk(" iip : 0x%.16lx ifa: 0x%.16lx\n", tf->iip, tf->ifa);
|
||||
printk(" ipsr: 0x%.16lx ifs: 0x%.16lx\n", tf->ipsr, tf->ifs);
|
||||
printk(" isr : 0x%.16lx\n", tf->isr);
|
||||
printk(" gp : 0x%.16lx sp : 0x%.16lx\n", tf->gp, tf->sp);
|
||||
printk(" rp : 0x%.16lx tp : 0x%.16lx\n", tf->b0, tf->tp);
|
||||
printk(" b6 : 0x%.16lx b7 : 0x%.16lx\n", tf->b6, tf->b7);
|
||||
printk(" r8 : 0x%.16lx\n", tf->r8);
|
||||
printk(" bsp : 0x%.16lx rsc: 0x%.16lx\n", tf->bsp, tf->rsc);
|
||||
printk(" r14 : 0x%.16lx r15: 0x%.16lx\n", tf->r14, tf->r15);
|
||||
printk(" r16 : 0x%.16lx r17: 0x%.16lx\n", tf->r16, tf->r17);
|
||||
printk(" r18 : 0x%.16lx r19: 0x%.16lx\n", tf->r18, tf->r19);
|
||||
printk(" r20 : 0x%.16lx r21: 0x%.16lx\n", tf->r20, tf->r21);
|
||||
printk(" r22 : 0x%.16lx r23: 0x%.16lx\n", tf->r22, tf->r23);
|
||||
printk(" r24 : 0x%.16lx r25: 0x%.16lx\n", tf->r24, tf->r25);
|
||||
printk(" r26 : 0x%.16lx r27: 0x%.16lx\n", tf->r26, tf->r27);
|
||||
printk(" r28 : 0x%.16lx r29: 0x%.16lx\n", tf->r28, tf->r29);
|
||||
printk(" r30 : 0x%.16lx r31: 0x%.16lx\n", tf->r30, tf->r31);
|
||||
|
||||
__asm __volatile("flushrs;;");
|
||||
curIfs = *((ifs_t*)((void*)(&tf->ifs)));
|
||||
if (!curIfs.v)
|
||||
printk(" ifs.v = 0");
|
||||
else {
|
||||
uint64_t* regP;
|
||||
uint32_t i;
|
||||
|
||||
printk(" cfm.sof: %d cfm.sol: %d\n", curIfs.sof, curIfs.sol);
|
||||
regP = (uint64_t *)(tf->bsp + tf->ndirty);
|
||||
for (i = curIfs.sof; i != 0; ) {
|
||||
if (i <= (((uint64_t)regP & 0x000001f8) >> 3)) {
|
||||
regP -= i;
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
i -= ((uint64_t)regP & 0x000001f8) >> 3;
|
||||
regP = (uint64_t *)((uint64_t)regP & ~0x000001ff) - 1;
|
||||
}
|
||||
for (i = 0; i < curIfs.sof; i++) {
|
||||
if (((uint64_t)regP & 0x000001f8) == 0x000001f8)
|
||||
regP++;
|
||||
printk(" r%d: 0x%lx\n", i+32, *regP);
|
||||
regP++;
|
||||
}
|
||||
}
|
||||
HYPERVISOR_shutdown(SHUTDOWN_poweroff);
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* The code is partly taken from FreeBSD.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/efi.h>
|
||||
#include <mini-os/page.h>
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/console.h>
|
||||
|
||||
|
||||
/* The implementation is in fw.S. */
|
||||
extern uint64_t
|
||||
ia64_call_efi_func(uint64_t funcP,uint64_t a,uint64_t b,uint64_t c,uint64_t d);
|
||||
|
||||
int
|
||||
efi_get_time(efi_time_t* tmP)
|
||||
{
|
||||
memset(tmP, 0, sizeof(efi_time_t));
|
||||
if (ia64_call_efi_func((uint64_t)machineFwG.efi.getTimeF,
|
||||
(uint64_t)tmP,
|
||||
(uint64_t)NULL, 0, 0) != EFI_SUCCESS) {
|
||||
printk("efi.getTime() failed\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The function compares two efi_guid_t and returns 0 on equality, otherwise 1.
|
||||
*/
|
||||
static int
|
||||
efi_guid_cmp(efi_guid_t* a_le, efi_guid_t* b)
|
||||
{
|
||||
return memcmp(a_le, b, sizeof(efi_guid_t));
|
||||
}
|
||||
|
||||
void
|
||||
init_efi(void)
|
||||
{
|
||||
efi_system_table_t* efiSysTableP;
|
||||
int mdcnt, i, numConvMem;
|
||||
efi_memory_descriptor_t *memdP, *mdP;
|
||||
efi_status_t status;
|
||||
char fwVendor[100] = "unknown";
|
||||
efi_char16_t* fwP;
|
||||
efi_runtime_services_t* rsP;
|
||||
|
||||
efi_configuration_table_t* confP = (efi_configuration_table_t*)0;
|
||||
efi_guid_t sal = SAL_SYSTEM_TABLE_GUID;
|
||||
efi_guid_t acpi = ACPI_TABLE_GUID;
|
||||
efi_guid_t acpi20 = ACPI_20_TABLE_GUID;
|
||||
|
||||
memset(&machineFwG, 0, sizeof(machineFwG));
|
||||
/* Read the efi_system_table. */
|
||||
efiSysTableP = (efi_system_table_t*)__va(ia64BootParamG.efi_systab);
|
||||
machineFwG.efi.efiSysTableP = efiSysTableP;
|
||||
PRINT_BV("EfiSystemTable at: %p\n", efiSysTableP);
|
||||
fwP = (uint16_t*) __va(efiSysTableP->FirmwareVendor);
|
||||
if (fwP) {
|
||||
for (i = 0; i < (int)sizeof(fwVendor) - 1 && *fwP; ++i)
|
||||
fwVendor[i] = *fwP++;
|
||||
fwVendor[i] = '\0';
|
||||
}
|
||||
PRINT_BV(" EFI-FirmwareVendor : %s\n", fwVendor);
|
||||
PRINT_BV(" EFI-FirmwareRevision : %d\n",
|
||||
efiSysTableP->FirmwareRevision);
|
||||
PRINT_BV(" EFI-SystemTable-Revision : %d.%d\n",
|
||||
efiSysTableP->Hdr.Revision >> 16,
|
||||
efiSysTableP->Hdr.Revision & 0xffff);
|
||||
rsP = (efi_runtime_services_t*)
|
||||
__va(efiSysTableP->RuntimeServices);
|
||||
mdcnt = ia64BootParamG.efi_memmap_size /
|
||||
ia64BootParamG.efi_memdesc_size;
|
||||
memdP = (efi_memory_descriptor_t*) __va(ia64BootParamG.efi_memmap);
|
||||
|
||||
PRINT_BV("EFI-Memorydescriptors: %d\n", mdcnt);
|
||||
|
||||
for (i = numConvMem = 0, mdP = memdP; i < mdcnt; i++,
|
||||
mdP = NextMemoryDescriptor(mdP, ia64BootParamG.efi_memdesc_size)) {
|
||||
/* Relocate runtime memory segments for firmware. */
|
||||
PRINT_BV(" %d. Type: %x Attributes: 0x%lx\n",
|
||||
i, mdP->Type, mdP->Attribute);
|
||||
PRINT_BV(" PhysStart: 0x%lx NumPages: 0x%lx\n",
|
||||
mdP->PhysicalStart, mdP->NumberOfPages);
|
||||
switch (mdP->Type) {
|
||||
case EfiRuntimeServicesData:
|
||||
PRINT_BV(" -> EfiRuntimeServicesData\n");
|
||||
break;
|
||||
case EfiACPIReclaimMemory:
|
||||
PRINT_BV(" -> EfiACPIReclaimMemory\n");
|
||||
break;
|
||||
case EfiACPIMemoryNVS:
|
||||
PRINT_BV(" -> EfiACPIMemoryNVS\n");
|
||||
break;
|
||||
case EfiConventionalMemory:
|
||||
PRINT_BV(" -> EfiConventionalMemory\n");
|
||||
PRINT_BV(" start: 0x%lx end: 0x%lx\n",
|
||||
mdP->PhysicalStart,
|
||||
mdP->PhysicalStart +
|
||||
mdP->NumberOfPages * EFI_PAGE_SIZE);
|
||||
if (numConvMem) {
|
||||
printk(" Currently only one efi "
|
||||
"memory chunk supported !!!\n");
|
||||
break;
|
||||
}
|
||||
machineFwG.mach_mem_start = mdP->PhysicalStart;
|
||||
machineFwG.mach_mem_size =
|
||||
mdP->NumberOfPages * EFI_PAGE_SIZE;
|
||||
numConvMem++;
|
||||
break;
|
||||
case EfiMemoryMappedIOPortSpace:
|
||||
PRINT_BV(" -> EfiMemMappedIOPortSpace\n");
|
||||
break;
|
||||
case EfiPalCode:
|
||||
machineFwG.ia64_pal_base =
|
||||
__va(mdP->PhysicalStart);
|
||||
PRINT_BV(" -> EfiPalCode\n"
|
||||
" start : %p\n",
|
||||
machineFwG.ia64_pal_base);
|
||||
break;
|
||||
}
|
||||
/* I have to setup the VirtualStart address of every
|
||||
* RUNTIME-area in preparing the later call of
|
||||
* SetVirtualAddressMap() therewidth the efi stuff uses
|
||||
* virtual addressing and the efi runtime functions
|
||||
* may be called directly.
|
||||
*/
|
||||
if (mdP->Attribute & EFI_MEMORY_RUNTIME) {
|
||||
if (mdP->Attribute & EFI_MEMORY_WB)
|
||||
mdP->VirtualStart = __va(mdP->PhysicalStart);
|
||||
else {
|
||||
if (mdP->Attribute & EFI_MEMORY_UC)
|
||||
printk("efi_init: RuntimeMemory with "
|
||||
"UC attribute !!!!!!\n");
|
||||
/*
|
||||
mdP->VirtualStart =
|
||||
IA64_PHYS_TO_RR6(mdP->PhysicalStart);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Now switch efi runtime stuff to virtual addressing. */
|
||||
status = ia64_call_efi_physical(
|
||||
(void*)__va((uint64_t)rsP->SetVirtualAddressMap),
|
||||
ia64BootParamG.efi_memmap_size,
|
||||
ia64BootParamG.efi_memdesc_size,
|
||||
ia64BootParamG.efi_memdesc_version,
|
||||
ia64BootParamG.efi_memmap);
|
||||
status = EFI_SUCCESS;
|
||||
if (status != EFI_SUCCESS) {
|
||||
printk("warning: unable to switch EFI into virtual "
|
||||
"(status=%lu)\n", status);
|
||||
return;
|
||||
}
|
||||
/* Getting efi function pointer for getEfiTime. */
|
||||
machineFwG.efi.getTimeF =
|
||||
(efi_get_time_t)__va((uint64_t)rsP->GetTime);
|
||||
/* Getting efi function pointer for resetSystem. */
|
||||
machineFwG.efi.resetSystemF =
|
||||
(efi_reset_system_t)__va((uint64_t)rsP->ResetSystem);
|
||||
|
||||
/* Scanning the Configuration table of the EfiSystemTable. */
|
||||
PRINT_BV("NumberOfConfigTableEntries: %ld\n",
|
||||
efiSysTableP->NumberOfTableEntries);
|
||||
|
||||
confP = (efi_configuration_table_t*)
|
||||
__va(efiSysTableP->ConfigurationTable);
|
||||
for (i = 0; i < efiSysTableP->NumberOfTableEntries; i++) {
|
||||
if (!efi_guid_cmp(&confP[i].VendorGuid, &sal)) {
|
||||
machineFwG.ia64_sal_tableP = (sal_system_table_t*)
|
||||
__va((uint64_t) confP[i].VendorTable);
|
||||
PRINT_BV(" Found SalSystemTable at: 0x%lx\n",
|
||||
(uint64_t) machineFwG.ia64_sal_tableP);
|
||||
continue;
|
||||
}
|
||||
if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi)) {
|
||||
machineFwG.ia64_efi_acpi_table =
|
||||
__va((uint64_t) confP[i].VendorTable);
|
||||
PRINT_BV(" Found AcpiTable at: 0x%lx\n",
|
||||
(uint64_t) machineFwG.ia64_efi_acpi_table);
|
||||
continue;
|
||||
}
|
||||
if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi20)) {
|
||||
machineFwG.ia64_efi_acpi20_table =
|
||||
__va((uint64_t) confP[i].VendorTable);
|
||||
PRINT_BV(" Found Acpi20Table at: 0x%lx\n",
|
||||
(uint64_t) machineFwG.ia64_efi_acpi20_table);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Parts taken from FreeBSD.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/asm.h>
|
||||
#include <mini-os/page.h>
|
||||
#include <mini-os/ia64_cpu.h>
|
||||
#include <mini-os/ia64_fpu.h>
|
||||
#include <mini-os/offsets.h>
|
||||
#include <mini-os/xen/xen.h>
|
||||
|
||||
|
||||
/*
|
||||
* ia64_change_mode: change mode to/from physical mode
|
||||
*
|
||||
* Arguments:
|
||||
* r14 psr for desired mode
|
||||
*
|
||||
* Modifies:
|
||||
* r15-r20 scratch
|
||||
* ar.bsp translated to new mode
|
||||
* sp translated to new mode
|
||||
* iip translated to new mode
|
||||
*/
|
||||
ENTRY(ia64_change_mode)
|
||||
rsm psr.i | psr.ic
|
||||
mov r19=ar.rsc // save rsc while we change mode
|
||||
tbit.nz p8,p9=r14,17 // Uses psr.dt-physical or virtual ?
|
||||
// p8 == true: switch to virtual
|
||||
// p9 == true: switch to physical
|
||||
;;
|
||||
mov ar.rsc=IA64_RSE_LAZY // turn off RSE
|
||||
mov r16=rp
|
||||
;;
|
||||
flushrs // clean the rse
|
||||
srlz.i
|
||||
;;
|
||||
1: mov r15=ip
|
||||
mov r17=ar.bsp
|
||||
mov r18=ar.rnat
|
||||
;;
|
||||
add r15=2f-1b,r15 // address to rfi to
|
||||
/* !!! must be the same like in minios-ia64.lds */
|
||||
(p8) movl r20=(KERNEL_START - (1<<KERNEL_PHYS_START_SHIFT))
|
||||
;;
|
||||
// (p8): switch to virtual
|
||||
// (p9): switch to physical
|
||||
|
||||
// from virtual to physical
|
||||
(p9) tpa r15=r15 // ip
|
||||
(p9) tpa r16=r16 // rp
|
||||
(p9) tpa r17=r17 // ar.bsp
|
||||
(p9) tpa sp=sp // sp
|
||||
;; /* Needed only for assembler violate ... warnings. */
|
||||
// from physical to virtual
|
||||
(p8) add r15=r20,r15 // ip
|
||||
(p8) add r16=r20,r16 // rp
|
||||
(p8) add r17=r20,r17 // ar.bsp
|
||||
(p8) add sp=r20,sp // sp
|
||||
;;
|
||||
mov ar.bspstore=r17
|
||||
mov rp=r16
|
||||
;;
|
||||
mov ar.rnat=r18
|
||||
mov cr.iip=r15
|
||||
mov cr.ipsr=r14 // psr for new mode
|
||||
mov cr.ifs=r0
|
||||
;;
|
||||
rfi
|
||||
;;
|
||||
2: mov ar.rsc=r19 // restore ar.rsc
|
||||
;;
|
||||
br.ret.sptk.few rp // now in new mode
|
||||
END(ia64_change_mode)
|
||||
|
||||
/*
|
||||
* ia64_physical_mode: change mode to physical mode
|
||||
*
|
||||
* Return:
|
||||
* ret0 psr to restore
|
||||
*
|
||||
* Modifies:
|
||||
* r15-r18 scratch
|
||||
* ar.bsp tranlated to physical mode
|
||||
* psr.i cleared
|
||||
*/
|
||||
ENTRY(ia64_physical_mode)
|
||||
mov r14=psr
|
||||
movl r15=(IA64_PSR_I|IA64_PSR_IT|IA64_PSR_DT| \
|
||||
IA64_PSR_RT|IA64_PSR_DFL|IA64_PSR_DFH)
|
||||
;;
|
||||
mov ret0=r14
|
||||
movl r16=IA64_PSR_BN
|
||||
;;
|
||||
andcm r14=r14,r15 // clear various xT bits
|
||||
;;
|
||||
or r14=r14,r16 // make sure BN=1
|
||||
or ret0=ret0,r16 // make sure BN=1
|
||||
;;
|
||||
br.cond.sptk.many ia64_change_mode
|
||||
END(ia64_physical_mode)
|
||||
|
||||
/*
|
||||
* ia64_call_efi_physical: call an EFI procedure in physical mode
|
||||
*
|
||||
* Arguments:
|
||||
* in0 Address of EFI procedure descriptor
|
||||
* in1-in5 Arguments to EFI procedure
|
||||
*
|
||||
* Return:
|
||||
* ret0-ret3 return values from EFI
|
||||
*
|
||||
*/
|
||||
ENTRY(ia64_call_efi_physical)
|
||||
.prologue
|
||||
.regstk 6,4,5,0
|
||||
.save ar.pfs,loc0
|
||||
alloc loc0=ar.pfs,6,4,5,0
|
||||
;;
|
||||
.save rp,loc1
|
||||
mov loc1=rp
|
||||
;;
|
||||
.body
|
||||
br.call.sptk.many rp=ia64_physical_mode
|
||||
;;
|
||||
|
||||
mov loc2=r8 // psr to restore mode
|
||||
mov loc3=gp // save kernel gp
|
||||
ld8 r14=[in0],8 // function address
|
||||
;;
|
||||
ld8 gp=[in0] // function gp value
|
||||
mov out0=in1
|
||||
mov out1=in2
|
||||
mov out2=in3
|
||||
mov out3=in4
|
||||
mov out4=in5
|
||||
mov b6=r14
|
||||
;;
|
||||
br.call.sptk.many rp=b6 // call EFI procedure
|
||||
mov gp=loc3 // restore kernel gp
|
||||
mov r14=loc2 // psr to restore mode
|
||||
;;
|
||||
br.call.sptk.many rp=ia64_change_mode
|
||||
;;
|
||||
mov rp=loc1
|
||||
mov ar.pfs=loc0
|
||||
;;
|
||||
br.ret.sptk.many rp
|
||||
END(ia64_call_efi_physical)
|
||||
|
||||
|
||||
/*
|
||||
* struct ia64_pal_result ia64_call_pal_static(uint64_t proc,
|
||||
* uint64_t arg1, uint64_t arg2, uint64_t arg3)
|
||||
*/
|
||||
ENTRY(ia64_call_pal_static)
|
||||
|
||||
.regstk 4,5,0,0
|
||||
palret = loc0
|
||||
entry = loc1
|
||||
rpsave = loc2
|
||||
pfssave = loc3
|
||||
psrsave = loc4
|
||||
|
||||
alloc pfssave=ar.pfs,4,5,0,0
|
||||
;;
|
||||
mov rpsave=rp
|
||||
|
||||
movl entry=@gprel(ia64_pal_entry)
|
||||
1: mov palret=ip // for return address
|
||||
;;
|
||||
add entry=entry,gp
|
||||
mov psrsave=psr
|
||||
mov r28=in0 // procedure number
|
||||
;;
|
||||
ld8 entry=[entry] // read entry point
|
||||
mov r29=in1 // copy arguments
|
||||
mov r30=in2
|
||||
mov r31=in3
|
||||
;;
|
||||
mov b6=entry
|
||||
add palret=2f-1b,palret // calculate return address
|
||||
;;
|
||||
mov b0=palret
|
||||
rsm psr.i // disable interrupts
|
||||
;;
|
||||
br.cond.sptk b6 // call into firmware
|
||||
;;
|
||||
ssm psr.i // enable interrupts
|
||||
;;
|
||||
2: mov psr.l=psrsave
|
||||
mov rp=rpsave
|
||||
mov ar.pfs=pfssave
|
||||
;;
|
||||
srlz.d
|
||||
br.ret.sptk rp
|
||||
|
||||
END(ia64_call_pal_static)
|
||||
|
||||
/*
|
||||
* Call a efi function.
|
||||
* in0: func descriptor
|
||||
* in1: param1
|
||||
* ...
|
||||
* in5: param5
|
||||
*/
|
||||
ENTRY(ia64_call_efi_func)
|
||||
alloc loc0=ar.pfs,6,3,5,0
|
||||
|
||||
mov loc1=gp
|
||||
mov loc2=rp
|
||||
|
||||
mov out0=in1
|
||||
mov out1=in2
|
||||
mov out2=in3
|
||||
mov out3=in4
|
||||
mov out4=in5
|
||||
|
||||
ld8 r14=[in0],8 // get function address
|
||||
;;
|
||||
ld8 gp=[in0] // function gp value
|
||||
;;
|
||||
mov b6=r14
|
||||
br.call.sptk.many rp=b6 // call EFI procedure
|
||||
|
||||
mov ar.pfs=loc0
|
||||
mov gp=loc1
|
||||
mov rp=loc2
|
||||
br.ret.sptk rp
|
||||
|
||||
END(ia64_call_efi_func)
|
||||
|
||||
|
||||
/* Restore the context from the thread context.
|
||||
*/
|
||||
ENTRY(restore_context)
|
||||
{ .mmi
|
||||
invala
|
||||
mov ar.rsc=IA64_RSE_LAZY
|
||||
add r29=SW_SP,in0
|
||||
}
|
||||
add r30=SW_RP,in0
|
||||
add r31=SW_PR,in0
|
||||
;;
|
||||
ld8 r12=[r29],SW_LC-SW_SP // load sp
|
||||
ld8 r16=[r30],SW_BSP-SW_RP // load rp
|
||||
;;
|
||||
ld8 r17=[r31],SW_RNAT-SW_PR // load pr
|
||||
ld8 r18=[r30],SW_PFS-SW_BSP // load bsp
|
||||
mov rp=r16
|
||||
;;
|
||||
ld8 r16=[r31],SW_R4-SW_RNAT // load rnat
|
||||
mov pr=r17,-1 // set pr
|
||||
mov ar.bspstore=r18
|
||||
;;
|
||||
ld8 r18=[r30],SW_UNATA-SW_PFS // load pfs
|
||||
ld8 r17=[r29],SW_UNATB-SW_LC // load lc
|
||||
mov ar.rnat=r16
|
||||
;;
|
||||
ld8 r16=[r30],SW_R5-SW_UNATA // load unat_a
|
||||
mov ar.pfs=r18
|
||||
mov ar.lc=r17
|
||||
;;
|
||||
ld8.fill r4=[r31],SW_R6-SW_R4 // load r4
|
||||
mov ar.unat=r16
|
||||
;;
|
||||
ld8.fill r5=[r30],SW_R7-SW_R5 // load r5
|
||||
ld8 r16=[r29],SW_B3-SW_UNATB // load unat_b
|
||||
mov ar.rsc=IA64_RSE_EAGER
|
||||
;;
|
||||
ld8.fill r6=[r31],SW_B1-SW_R6 // load r6
|
||||
ld8.fill r7=[r30],SW_B2-SW_R7 // load r7
|
||||
;;
|
||||
ld8 r17=[r31],SW_B4-SW_B1 // load b1
|
||||
ld8 r18=[r30],SW_B5-SW_B2 // load b2
|
||||
mov ar.unat=r16 // unat_b
|
||||
;;
|
||||
ld8 r16=[r29],SW_F2-SW_B3 // load b3
|
||||
mov b1=r17
|
||||
mov b2=r18
|
||||
;;
|
||||
ld8 r17=[r31],SW_F3-SW_B4 // load b4
|
||||
ld8 r18=[r30],SW_F4-SW_B5 // load b5
|
||||
mov b3=r16
|
||||
;;
|
||||
ldf.fill f2=[r29] // load f2
|
||||
mov b4=r17
|
||||
mov b5=r18
|
||||
;;
|
||||
ldf.fill f3=[r31],SW_F5-SW_F3 // load f3
|
||||
ldf.fill f4=[r30],SW_F4-SW_F2 // load f4
|
||||
;;
|
||||
ldf.fill f5=[r31],SW_F5-SW_F3 // load f5
|
||||
ldf.fill f16=[r30],SW_F4-SW_F2 // load f16
|
||||
;;
|
||||
ldf.fill f17=[r31],SW_F5-SW_F3 // load f17
|
||||
ldf.fill f18=[r30],SW_F4-SW_F2 // load f18
|
||||
;;
|
||||
ldf.fill f19=[r31],SW_F5-SW_F3 // load f19
|
||||
ldf.fill f20=[r30],SW_F4-SW_F2 // load f20
|
||||
;;
|
||||
ldf.fill f21=[r31],SW_F5-SW_F3 // load f21
|
||||
ldf.fill f22=[r30],SW_F4-SW_F2 // load f22
|
||||
;;
|
||||
ldf.fill f23=[r31],SW_F5-SW_F3 // load f23
|
||||
ldf.fill f24=[r30],SW_F4-SW_F2 // load f24
|
||||
;;
|
||||
ldf.fill f25=[r31],SW_F5-SW_F3 // load f25
|
||||
ldf.fill f26=[r30],SW_F4-SW_F2 // load f26
|
||||
;;
|
||||
ldf.fill f27=[r31],SW_F5-SW_F3 // load f27
|
||||
ldf.fill f28=[r30],SW_F4-SW_F2 // load f28
|
||||
;;
|
||||
ldf.fill f29=[r31],SW_F5-SW_F3 // load f29
|
||||
ldf.fill f30=[r30],SW_F4-SW_F2 // load f30
|
||||
;;
|
||||
ldf.fill f31=[r30],SW_F4-SW_F2 // load f31
|
||||
add r8=1,r0
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
END(restore_context)
|
||||
|
||||
/*
|
||||
* void switch_context(struct thread* old, struct thread* new)
|
||||
*/
|
||||
ENTRY(switch_context)
|
||||
|
||||
mov ar.rsc=IA64_RSE_LAZY
|
||||
mov r16=ar.unat
|
||||
add r31=SW_UNATB,in0
|
||||
add r30=SW_SP,in0
|
||||
;;
|
||||
{ .mmi
|
||||
flushrs
|
||||
st8 [r30]=sp,SW_RP-SW_SP // sp
|
||||
mov r17=rp
|
||||
;;
|
||||
}
|
||||
st8 [r31]=r16,SW_PR-SW_UNATB // unat (before)
|
||||
st8 [r30]=r17,SW_BSP-SW_RP // rp
|
||||
mov r16=pr
|
||||
;;
|
||||
st8 [r31]=r16,SW_PFS-SW_PR // pr
|
||||
mov r17=ar.bsp
|
||||
mov r16=ar.pfs
|
||||
;;
|
||||
st8 [r31]=r16,SW_RNAT-SW_PFS // save pfs
|
||||
st8 [r30]=r17,SW_R4-SW_BSP // save bsp
|
||||
mov r16=ar.rnat
|
||||
;;
|
||||
st8 [r31]=r16,SW_R5-SW_RNAT // save rnat
|
||||
mov ar.rsc=IA64_RSE_EAGER
|
||||
;;
|
||||
{ .mmi
|
||||
.mem.offset 8,0
|
||||
st8.spill [r30]=r4,SW_R6-SW_R4 // r4
|
||||
.mem.offset 16,0
|
||||
st8.spill [r31]=r5,SW_R7-SW_R5 // r5
|
||||
mov r16=b1
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
.mem.offset 8,0
|
||||
st8.spill [r30]=r4,SW_B1-SW_R6 // r6
|
||||
.mem.offset 16,0
|
||||
st8.spill [r31]=r5,SW_B2-SW_R7 // r7
|
||||
mov r17=b2
|
||||
;;
|
||||
}
|
||||
st8 [r30]=r16,SW_UNATA-SW_B1 // b1
|
||||
st8 [r31]=r17,SW_B3-SW_B2 // b2
|
||||
mov r18=ar.unat
|
||||
mov r19=b3
|
||||
mov r20=b4
|
||||
mov r21=b5
|
||||
;;
|
||||
st8 [r30]=r18,SW_B4-SW_UNATA // unat (after)
|
||||
st8 [r31]=r19,SW_B5-SW_B3 // b3
|
||||
;;
|
||||
st8 [r30]=r20,SW_LC-SW_B4 // b4
|
||||
st8 [r31]=r21,SW_F2-SW_B5 // b5
|
||||
mov r17=ar.lc
|
||||
;;
|
||||
st8 [r30]=r17,SW_F3-SW_LC // ar.lc
|
||||
stf.spill [r31]=f2,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f3,SW_F5-SW_F3
|
||||
stf.spill [r31]=f4,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f5,SW_F5-SW_F3
|
||||
stf.spill [r31]=f16,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f17,SW_F5-SW_F3
|
||||
stf.spill [r31]=f18,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f19,SW_F5-SW_F3
|
||||
stf.spill [r31]=f20,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f21,SW_F5-SW_F3
|
||||
stf.spill [r31]=f22,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f23,SW_F5-SW_F3
|
||||
stf.spill [r31]=f24,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f25,SW_F5-SW_F3
|
||||
stf.spill [r31]=f26,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f27,SW_F5-SW_F3
|
||||
stf.spill [r31]=f28,SW_F4-SW_F2
|
||||
;;
|
||||
stf.spill [r30]=f29,SW_F4-SW_F2
|
||||
stf.spill [r31]=f30
|
||||
;;
|
||||
stf.spill [r30]=f31
|
||||
add r8=0,r0
|
||||
mf
|
||||
// br.ret.sptk rp
|
||||
|
||||
{ .mfb
|
||||
mov r32=r33
|
||||
nop 0
|
||||
br.sptk restore_context
|
||||
;;
|
||||
}
|
||||
|
||||
END(switch_context)
|
||||
|
||||
/*
|
||||
* The function is used to start a new thread.
|
||||
*/
|
||||
ENTRY(thread_starter)
|
||||
|
||||
.prologue
|
||||
.save ar.pfs,loc0
|
||||
alloc loc0=ar.pfs,0,1,1,0
|
||||
;;
|
||||
.body
|
||||
;;
|
||||
mov b7=r4 // the function pointer
|
||||
mov out0=r6 // the argument
|
||||
;;
|
||||
br.call.sptk.many rp=b7 // Call the thread function
|
||||
;;
|
||||
br.call.sptk.many rp=exit_thread // call exit_thread
|
||||
;;
|
||||
END(thread_starter)
|
||||
|
||||
ENTRY(__hypercall)
|
||||
mov r2=r37
|
||||
break 0x1000
|
||||
br.ret.sptk.many b0
|
||||
;;
|
||||
END(__hypercall)
|
||||
|
||||
/*
|
||||
* Stub for suspend.
|
||||
* Just force the stacked registers to be written in memory.
|
||||
*/
|
||||
ENTRY(xencomm_arch_hypercall_suspend)
|
||||
;;
|
||||
alloc r20=ar.pfs,0,0,6,0
|
||||
mov r2=__HYPERVISOR_sched_op
|
||||
;;
|
||||
/* We don't want to deal with RSE. */
|
||||
flushrs
|
||||
mov r33=r32
|
||||
mov r32=2 // SCHEDOP_shutdown
|
||||
;;
|
||||
break 0x1000
|
||||
;;
|
||||
br.ret.sptk.many b0
|
||||
END(xencomm_arch_hypercall_suspend)
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <mini-os/types.h>
|
||||
#include <mini-os/sched.h>
|
||||
#include <xen/xen.h>
|
||||
#include <xen/arch-ia64.h>
|
||||
|
||||
#define DEFINE(sym, val) \
|
||||
asm volatile("\n->" sym " %0 /* " #val " */": : "i" (val))
|
||||
#define DEFINE_STR2(sym, pfx, val) \
|
||||
asm volatile("\n->" sym " " pfx "%0" : : "i"(val));
|
||||
|
||||
#define SZ(st,e) sizeof(((st *)0)->e)
|
||||
#define OFF(st,e,d,o) \
|
||||
DEFINE(#d, offsetof(st, e) + o); \
|
||||
DEFINE(#d "_sz", SZ(st,e )); \
|
||||
DEFINE_STR2(#d "_ld", "ld", SZ(st, e)); \
|
||||
DEFINE_STR2(#d "_st", "st", SZ(st, e));
|
||||
|
||||
#define TFOFF(e,d) OFF(trap_frame_t, e, d, 0)
|
||||
#define SIZE(st,d) DEFINE(#d, sizeof(st))
|
||||
|
||||
#define SWOFF(e,d) OFF(struct thread, e, d, 0)
|
||||
|
||||
/* shared_info_t from xen/xen.h */
|
||||
#define SI_OFF(e, d) OFF(shared_info_t, e, d,0)
|
||||
/* mapped_regs_t from xen/arch-ia64.h */
|
||||
#define MR_OFF(e, d) OFF(mapped_regs_t, e, d, XMAPPEDREGS_OFS)
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
TFOFF(cfm, TF_CFM);
|
||||
TFOFF(pfs, TF_PFS);
|
||||
TFOFF(bsp, TF_BSP);
|
||||
TFOFF(rnat, TF_RNAT);
|
||||
TFOFF(csd, TF_CSD);
|
||||
TFOFF(ccv, TF_CCV);
|
||||
TFOFF(unat, TF_UNAT);
|
||||
TFOFF(fpsr, TF_FPSR);
|
||||
TFOFF(pr, TF_PR);
|
||||
|
||||
TFOFF(sp, TF_SP);
|
||||
TFOFF(gp, TF_GP);
|
||||
TFOFF(tp, TF_TP);
|
||||
|
||||
TFOFF(r2, TF_GREG2);
|
||||
TFOFF(r3, TF_GREG3);
|
||||
TFOFF(r16, TF_GREG16);
|
||||
TFOFF(r17, TF_GREG17);
|
||||
|
||||
TFOFF(b0, TF_BREG0);
|
||||
TFOFF(b6, TF_BREG6);
|
||||
TFOFF(b7, TF_BREG7);
|
||||
|
||||
TFOFF(f6, TF_FREG6);
|
||||
TFOFF(f7, TF_FREG7);
|
||||
|
||||
TFOFF(rsc, TF_RSC);
|
||||
TFOFF(ndirty, TF_NDIRTY);
|
||||
TFOFF(ssd, TF_SSD);
|
||||
TFOFF(iip, TF_IIP);
|
||||
TFOFF(ipsr, TF_IPSR);
|
||||
TFOFF(ifs, TF_IFS);
|
||||
TFOFF(trap_num, TF_TRAP_NUM);
|
||||
|
||||
TFOFF(ifa, TF_IFA);
|
||||
TFOFF(isr, TF_ISR);
|
||||
TFOFF(iim, TF_IIM);
|
||||
|
||||
SIZE(trap_frame_t, TF_SIZE);
|
||||
|
||||
SIZE(struct thread, SW_SIZE);
|
||||
SWOFF(regs.unat_b, SW_UNATB);
|
||||
SWOFF(regs.sp, SW_SP);
|
||||
SWOFF(regs.rp, SW_RP);
|
||||
SWOFF(regs.pr, SW_PR);
|
||||
SWOFF(regs.pfs, SW_PFS);
|
||||
SWOFF(regs.bsp, SW_BSP);
|
||||
SWOFF(regs.rnat, SW_RNAT);
|
||||
SWOFF(regs.lc, SW_LC);
|
||||
//SWOFF(regs.fpsr, SW_FPSR);
|
||||
//SWOFF(regs.psr, SW_PSR);
|
||||
//SWOFF(regs.gp, SW_GP);
|
||||
SWOFF(regs.unat_a, SW_UNATA);
|
||||
SWOFF(regs.r4, SW_R4);
|
||||
SWOFF(regs.r5, SW_R5);
|
||||
SWOFF(regs.r6, SW_R6);
|
||||
SWOFF(regs.r7, SW_R7);
|
||||
SWOFF(regs.b1, SW_B1);
|
||||
SWOFF(regs.b2, SW_B2);
|
||||
SWOFF(regs.b3, SW_B3);
|
||||
SWOFF(regs.b4, SW_B4);
|
||||
SWOFF(regs.b5, SW_B5);
|
||||
SWOFF(regs.f2, SW_F2);
|
||||
SWOFF(regs.f3, SW_F3);
|
||||
SWOFF(regs.f4, SW_F4);
|
||||
SWOFF(regs.f5, SW_F5);
|
||||
|
||||
SI_OFF(arch.start_info_pfn, START_INFO_PFN);
|
||||
MR_OFF(interrupt_mask_addr, XSI_PSR_I_ADDR_OFS);
|
||||
MR_OFF(interrupt_collection_enabled, XSI_PSR_IC_OFS);
|
||||
MR_OFF(ipsr, XSI_IPSR_OFS);
|
||||
MR_OFF(iip, XSI_IIP_OFS);
|
||||
MR_OFF(ifs, XSI_IFS_OFS);
|
||||
MR_OFF(ifa, XSI_IFA_OFS);
|
||||
MR_OFF(iim, XSI_IIM_OFS);
|
||||
MR_OFF(iim, XSI_IIM_OFS);
|
||||
MR_OFF(iipa, XSI_IIPA_OFS);
|
||||
MR_OFF(isr, XSI_ISR_OFS);
|
||||
MR_OFF(banknum, XSI_BANKNUM_OFS);
|
||||
MR_OFF(bank1_regs[0], XSI_BANK1_R16_OFS);
|
||||
MR_OFF(precover_ifs, XSI_PRECOVER_IFS_OFS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
*****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <mini-os/asm.h>
|
||||
#include <mini-os/page.h>
|
||||
#include <mini-os/ia64_cpu.h>
|
||||
#include <mini-os/ia64_fpu.h>
|
||||
#include <mini-os/privop.h>
|
||||
#include <mini-os/offsets.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Allocate kernel stack area.
|
||||
* This is used for stack pointer (goes down from kstack+PAGE_SIZE) and
|
||||
* RSE (goes up from kstack).
|
||||
*/
|
||||
.section .data.start,"aw"
|
||||
.global kstack
|
||||
.align PAGE_SIZE
|
||||
kstack: .space KSTACK_PAGES * PAGE_SIZE
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* Start the kernel.
|
||||
* r28 points to the address of the boot parameter area, given
|
||||
* from the bootloader.
|
||||
* Execution reaches here in physical mode.
|
||||
*/
|
||||
ENTRY(_start)
|
||||
.prologue
|
||||
.save rp, r0 // terminate unwind chain with a NULL rp
|
||||
.body
|
||||
|
||||
alloc loc0=ar.pfs,0,1,1,0
|
||||
|
||||
rsm psr.i | psr.ic
|
||||
;;
|
||||
srlz.i
|
||||
;;
|
||||
|
||||
/*
|
||||
* Initialize mini-os region registers:
|
||||
* Currently only region registers 5 and 7 are used for addressing.
|
||||
* rr[5] : virtual kernel address space
|
||||
* rr[7] : directly mapped physically addresses.
|
||||
*/
|
||||
movl r2=0<<IA64_RR_IDX_POS
|
||||
movl r3=1<<IA64_RR_IDX_POS
|
||||
;;
|
||||
mov rr[r2]=r0
|
||||
mov rr[r3]=r0
|
||||
;;
|
||||
movl r2=2<<IA64_RR_IDX_POS
|
||||
movl r3=3<<IA64_RR_IDX_POS
|
||||
;;
|
||||
mov rr[r2]=r0
|
||||
mov rr[r3]=r0
|
||||
;;
|
||||
movl r2=4<<IA64_RR_IDX_POS
|
||||
movl r3=6<<IA64_RR_IDX_POS
|
||||
;;
|
||||
mov rr[r2]=r0
|
||||
mov rr[r3]=r0
|
||||
;;
|
||||
// Wired memory for kernel data and text.
|
||||
movl r2=IA64_RR_VAL(KERNEL_TR_PAGE_SIZE,0)
|
||||
movl r3=5<<IA64_RR_IDX_POS // region 5
|
||||
;;
|
||||
mov rr[r3]=r2
|
||||
;;
|
||||
/*
|
||||
* Region 7 addresses are only for directly mapped physically
|
||||
* addresses.
|
||||
*/
|
||||
movl r2=IA64_RR_VAL(PTE_PS_16K,0)
|
||||
movl r3=7<<IA64_RR_IDX_POS // region 7
|
||||
;;
|
||||
mov rr[r3]=r2
|
||||
;;
|
||||
/*
|
||||
* Setup protection keys for region 5 and 7.
|
||||
*/
|
||||
mov r2=(IA64_KEY_REG5 << IA64_PKR_KEY) | IA64_PKR_VALID
|
||||
mov r3=(IA64_KEY_REG7 << IA64_PKR_KEY) | IA64_PKR_VALID
|
||||
mov r14=0x1
|
||||
;;
|
||||
mov pkr[r0]=r2 /* Region 5 */
|
||||
mov pkr[r14]=r3 /* Region 7 */
|
||||
;;
|
||||
/*
|
||||
* Now pin mappings into the TLB for kernel text and data
|
||||
*/
|
||||
mov r18=(KERNEL_TR_PAGE_SIZE<<IA64_ITIR_PS)| \
|
||||
(IA64_KEY_REG5<<IA64_ITIR_KEY)
|
||||
movl r17=KERNEL_START
|
||||
;;
|
||||
mov cr.itir=r18
|
||||
mov cr.ifa=r17
|
||||
mov r16=IA64_TR_KERNEL
|
||||
mov r3=ip
|
||||
movl r18=PTE_KERNEL_ATTR
|
||||
;;
|
||||
dep r2=0,r3,0,KERNEL_TR_PAGE_SIZE
|
||||
;;
|
||||
or r18=r2,r18
|
||||
;;
|
||||
srlz.i
|
||||
;;
|
||||
itr.i itr[r16]=r18
|
||||
;;
|
||||
itr.d dtr[r16]=r18
|
||||
;;
|
||||
srlz.i
|
||||
|
||||
/* Switch into virtual mode */
|
||||
movl r16=STARTUP_PSR
|
||||
;;
|
||||
mov cr.ipsr=r16
|
||||
movl r17=1f
|
||||
;;
|
||||
mov cr.iip=r17
|
||||
mov cr.ifs=r0
|
||||
;;
|
||||
rfi
|
||||
;;
|
||||
1: /* now we are in virtual mode */
|
||||
|
||||
movl r3=ia64_trap_table
|
||||
;;
|
||||
mov cr.iva=r3
|
||||
;;
|
||||
|
||||
movl r2=IA64_FPSR_DEFAULT
|
||||
movl r3=IA64_DCR_DEFAULT
|
||||
;;
|
||||
srlz.i
|
||||
movl gp=__gp
|
||||
|
||||
mov ar.fpsr=r2
|
||||
mov cr.dcr=r3
|
||||
;;
|
||||
movl r2=kstack
|
||||
movl r5=KSTACK_PAGES * PAGE_SIZE - 16
|
||||
mov ar.rsc=0 // place RSE in enforced lazy mode
|
||||
;;
|
||||
loadrs // clear the dirty partition
|
||||
;;
|
||||
mov ar.bspstore=r2 // establish the new RSE stack
|
||||
add sp=r2,r5
|
||||
;;
|
||||
mov ar.rsc=IA64_RSE_EAGER // place RSE in eager mode
|
||||
|
||||
;;
|
||||
movl r2=ia64_boot_paramP
|
||||
mov r3=7 // make address virtual region 7.
|
||||
;;
|
||||
dep r28=r3,r28,61,3
|
||||
;;
|
||||
// save the address of the boot param area
|
||||
// passed by the bootloader
|
||||
st8 [r2]=r28
|
||||
;;
|
||||
|
||||
/* Set xsi base. I use here XSI_BASE. */
|
||||
#define FW_HYPERCALL_SET_SHARED_INFO_VA 0x600
|
||||
mov r2=FW_HYPERCALL_SET_SHARED_INFO_VA
|
||||
movl r28=XSI_BASE
|
||||
;;
|
||||
break 0x1000
|
||||
;;
|
||||
/*
|
||||
* I set up here the pointer to the global start_info structure.
|
||||
* This structure will be initialized in arch_init().
|
||||
*/
|
||||
movl out0=start_info_union
|
||||
// Prepare out0 - the pointer to start_info_t.
|
||||
movl r14=XSI_BASE
|
||||
;;
|
||||
add r15=START_INFO_PFN,r14 // add offset to XSI_BASE
|
||||
;;
|
||||
START_INFO_PFN_ld r14=[r15] // load the start_info_pfn
|
||||
add r16=7, r0
|
||||
;;
|
||||
shl r15=r14,PAGE_SHIFT_XEN_16K // pfn << PAGE_SHIFT_XEN_16K
|
||||
shl r16=r16,IA64_RR_IDX_POS // (7<<IA64_RR_IDX_POS)
|
||||
;;
|
||||
or out0=r16, r15 // make a region 7 address
|
||||
;;
|
||||
ssm psr.i | psr.ic
|
||||
;;
|
||||
srlz.i
|
||||
;;
|
||||
br.call.sptk.many rp=start_kernel
|
||||
;;
|
||||
add r2=3,r0
|
||||
;;
|
||||
ld8 r3=[r2]
|
||||
;;
|
||||
|
||||
self: hint @pause
|
||||
br.sptk.many self // endless loop
|
||||
END(_start)
|
||||
|
||||
|
||||
ENTRY(do_nop)
|
||||
nop 0x01
|
||||
add r15=1,r15
|
||||
br.ret.sptk.many rp
|
||||
END(do_nop)
|
||||
@@ -1,774 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Description: ia64 specific trap handling.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/asm.h>
|
||||
#include <mini-os/page.h>
|
||||
#include <mini-os/ia64_cpu.h>
|
||||
#include <mini-os/privop.h>
|
||||
#include <mini-os/offsets.h>
|
||||
|
||||
|
||||
/* General register usage in interrupt handling:
|
||||
* r16, r17, ... are used for input parameters of sub-routines
|
||||
* r29: used to access memory which may raise nested TLB fault
|
||||
* r30: b0 save register
|
||||
* r31: predicates save register
|
||||
* p30,p31: used for TLB stuff: (0,1)=data, (1,0)=instruction
|
||||
*/
|
||||
|
||||
|
||||
#define FILL_FP_PAIR(f1, f2, b1, b2) \
|
||||
ldf.fill f1=[b1],32 ;\
|
||||
ldf.fill f2=[b2],32 ;\
|
||||
;;
|
||||
|
||||
#define SPILL_FP_PAIR(f1, f2, b1, b2) \
|
||||
stf.spill [b1]=f1,32 ;\
|
||||
stf.spill [b2]=f2,32 ;\
|
||||
;;
|
||||
|
||||
#define FILL_REG_PAIR(r1, r2, b1, b2) \
|
||||
ld8.fill r1=[b1],16 ;\
|
||||
ld8.fill r2=[b2],16 ;\
|
||||
;;
|
||||
|
||||
#define SPILL_REG_PAIR(r1, r2, b1, b2) \
|
||||
.mem.offset 0,0 ;\
|
||||
st8.spill [b1]=r1,16 ;\
|
||||
.mem.offset 8,0 ;\
|
||||
st8.spill [b2]=r2,16 ;\
|
||||
;;
|
||||
|
||||
|
||||
/**
|
||||
* The function does a store of the current processor context
|
||||
* to the given exception frame address.
|
||||
* These are some special and the scratch registers for calling
|
||||
* C-functions later.
|
||||
* The bspstore will be the same. A clean RSE is made with the
|
||||
* cover instruction.
|
||||
*
|
||||
* The return is done through a jump to the next bundle after ip (r16).
|
||||
*
|
||||
* Used register: r16, r18, r19, r20, r21, r22 of bank 0
|
||||
*
|
||||
* @param: r16 ip of the bundle with the jump.
|
||||
* @param: r18 pointer to the trap frame.
|
||||
* @param: r23 trap number/err val
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(save_tf_rse_switch)
|
||||
movl r21=XSI_IPSR // XEN !!
|
||||
movl r22=XSI_IIP // XEN !!
|
||||
;;
|
||||
ld8 r21=[r21] // XEN.ipsr
|
||||
ld8 r22=[r22];; // XEN.iip
|
||||
add r19=TF_IPSR,r18
|
||||
add r20=TF_IIP,r18
|
||||
;;
|
||||
st8 [r19]=r21 // store cr.ipsr
|
||||
st8 [r20]=r22 // store cr.iip
|
||||
;;
|
||||
//// r16 return jump pointer, r18 - trap frame base,
|
||||
add r19=TF_UNAT,r18
|
||||
mov r20=ar.unat
|
||||
;;
|
||||
st8 [r19]=r20 // store scratch unat
|
||||
;;
|
||||
|
||||
add r19=TF_GP,r18
|
||||
add r20=TF_SP,r18
|
||||
;;
|
||||
st8 [r19]=gp,TF_TP-TF_GP // store gp
|
||||
st8 [r20]=sp,TF_PR-TF_SP // store sp
|
||||
mov r21=pr
|
||||
;;
|
||||
st8 [r19]=r13 // store tp
|
||||
st8 [r20]=r21 // store pr
|
||||
;;
|
||||
add r19=TF_GREG2,r18 // Now first general regs.
|
||||
add r20=TF_GREG3,r18
|
||||
;;
|
||||
SPILL_REG_PAIR( r2, r3,r19,r20)
|
||||
SPILL_REG_PAIR( r8, r9,r19,r20)
|
||||
SPILL_REG_PAIR(r10,r11,r19,r20)
|
||||
SPILL_REG_PAIR(r14,r15,r19,r20)
|
||||
;;
|
||||
mov r14=r18 // move trap frame base for bsw
|
||||
mov r15=r16 // save return address
|
||||
;;
|
||||
//bsw.1 // switch to bank 1 for saving these registers.
|
||||
movl r30=XSI_BANKNUM // Switch to bank 1.
|
||||
mov r31=1;;
|
||||
st4 [r30]=r31
|
||||
;;
|
||||
/*
|
||||
* On XEN the hypervisor has stored the bank 1 registers
|
||||
* r16-r31. I must reload these registers here to get
|
||||
* access.
|
||||
*/
|
||||
movl r30=XSI_BANK1_R16;
|
||||
movl r31=XSI_BANK1_R16+8;;
|
||||
ld8 r16=[r30],16; ld8 r17=[r31],16;;
|
||||
ld8 r18=[r30],16; ld8 r19=[r31],16;;
|
||||
ld8 r20=[r30],16; ld8 r21=[r31],16;;
|
||||
ld8 r22=[r30],16; ld8 r23=[r31],16;;
|
||||
ld8 r24=[r30],16; ld8 r25=[r31],16;;
|
||||
ld8 r26=[r30],16; ld8 r27=[r31],16;;
|
||||
ld8 r28=[r30],16; ld8 r29=[r31],16;;
|
||||
ld8 r30=[r30]; ld8 r31=[r31];;
|
||||
add r2=TF_GREG16,r14
|
||||
add r3=TF_GREG17,r14
|
||||
;;
|
||||
SPILL_REG_PAIR(r16,r17,r2,r3)
|
||||
SPILL_REG_PAIR(r18,r19,r2,r3)
|
||||
SPILL_REG_PAIR(r20,r21,r2,r3)
|
||||
SPILL_REG_PAIR(r22,r23,r2,r3)
|
||||
SPILL_REG_PAIR(r24,r25,r2,r3)
|
||||
SPILL_REG_PAIR(r26,r27,r2,r3)
|
||||
SPILL_REG_PAIR(r28,r29,r2,r3)
|
||||
SPILL_REG_PAIR(r30,r31,r2,r3)
|
||||
;;
|
||||
//bsw.0 // back to interrupt bank 0
|
||||
movl r2=XSI_BANKNUM;;
|
||||
st4 [r2]=r0
|
||||
;;
|
||||
mov r18=r14 // restore context pointer
|
||||
mov r16=r15 // restore return address
|
||||
;;
|
||||
//// r16 return jump pointer, r18 - trap frame base,
|
||||
add r19=TF_CCV,r18
|
||||
add r20=TF_CSD,r18
|
||||
mov r21=ar.ccv
|
||||
mov r22=ar.csd
|
||||
;;
|
||||
st8 [r19]=r21 // ar.ccv
|
||||
st8 [r20]=r22 // ar.csd
|
||||
;;
|
||||
add r19=TF_SSD,r18
|
||||
mov r21=ar.ssd
|
||||
;;
|
||||
st8 [r19]=r21 // ar.ssd
|
||||
;;
|
||||
add r19=TF_FREG6,r18
|
||||
add r20=TF_FREG7,r18
|
||||
;;
|
||||
SPILL_FP_PAIR(f6, f7, r19, r20)
|
||||
SPILL_FP_PAIR(f8, f9, r19, r20)
|
||||
SPILL_FP_PAIR(f10, f11, r19, r20)
|
||||
|
||||
add r19=TF_BREG0,r18 // b0, b6, b7
|
||||
add r20=TF_BREG6,r18
|
||||
mov r21=b0
|
||||
mov r22=b6
|
||||
;;
|
||||
st8 [r19]=r21,TF_BREG7-TF_BREG0 // store b0
|
||||
st8 [r20]=r22,16 // store b6
|
||||
;;
|
||||
mov r21=b7
|
||||
;;
|
||||
st8 [r19]=r21 // store b7
|
||||
|
||||
//// r16 return jump pointer, r18 - trap frame base,
|
||||
|
||||
// Read and save RSC, PFS
|
||||
add r19=TF_PFS,r18
|
||||
add r20=TF_RSC,r18
|
||||
mov r21=ar.pfs
|
||||
mov r22=ar.rsc
|
||||
;;
|
||||
{ .mmb
|
||||
st8 [r19]=r21 // store ar.pfs
|
||||
st8 [r20]=r22 // store ar.rsc
|
||||
// Issue cover instruction
|
||||
cover // must be the last instruction in bundle
|
||||
//XEN_HYPER_COVER
|
||||
;;
|
||||
}
|
||||
// Read and save IFS
|
||||
add r19=TF_IFS,r18
|
||||
add r20=TF_CFM,r18
|
||||
/* xen special handling for possibly lazy cover */
|
||||
movl r8=XSI_PRECOVER_IFS;
|
||||
;;
|
||||
ld8 r21=[r8]
|
||||
;;
|
||||
st8 [r19]=r21 // store cr.ifs
|
||||
dep.z r22=r21,0,38 // copy ifm part from ifs.ifm
|
||||
;;
|
||||
st8 [r20]=r22 // store cfm
|
||||
// RSE in enforced lazy mode
|
||||
mov ar.rsc=IA64_RSE_LAZY
|
||||
;;
|
||||
// Read and save BSPSTORE and RNAT
|
||||
add r19=TF_BSP,r18
|
||||
add r20=TF_RNAT,r18
|
||||
mov r21=ar.bspstore
|
||||
mov r22=ar.rnat
|
||||
;;
|
||||
st8 [r19]=r21 // store ar.bspstore
|
||||
st8 [r20]=r22 // store ar.rnat
|
||||
;;
|
||||
// Write new BSPSTORE
|
||||
//mov r21=ar.bsp
|
||||
//;;
|
||||
mov r22=r21 // new bspstore equal to old
|
||||
;;
|
||||
mov ar.bspstore=r22 // the new bspstore
|
||||
;;
|
||||
// Read and save the new BSP for calculating number of dirty regs.
|
||||
mov r21=ar.bsp
|
||||
;;
|
||||
sub r21=r21,r22 // r21 -> ndirty
|
||||
add r19=TF_NDIRTY-TF_BSP,r19 // TF_NDIRTY pos in r19
|
||||
;;
|
||||
st8 [r19]=r21 // store ndirty
|
||||
;;
|
||||
mov ar.rsc=IA64_RSE_EAGER // RSE on again
|
||||
;;
|
||||
add r19=TF_FPSR,r18
|
||||
;;
|
||||
mov r21=ar.fpsr
|
||||
;;
|
||||
st8 [r19]=r21 // ar.fpsr
|
||||
;;
|
||||
//// r16 return jump pointer, r18 - trap frame base,
|
||||
// Load the gp with our module __gp
|
||||
movl gp=__gp
|
||||
;;
|
||||
add r16=16,r16 // for jump to next bundle
|
||||
;;
|
||||
mov b7=r16
|
||||
;;
|
||||
|
||||
{ .mfb
|
||||
srlz.d
|
||||
nop 0
|
||||
br.sptk b7
|
||||
;;
|
||||
}
|
||||
|
||||
END(save_tf_rse_switch)
|
||||
|
||||
|
||||
/**
|
||||
* The function reloads the processor context stored in
|
||||
* save_tf_rse_switch().
|
||||
*
|
||||
* On calling the function the bank 0 must be activ.
|
||||
* The return is done through a rfi.
|
||||
* Used register: b7, r16, r18, r19, r20, r21, r22 of bank 0
|
||||
*
|
||||
* @param: r18 pointer to the exception frame
|
||||
*
|
||||
*/
|
||||
ENTRY(restore_tf_rse_switch)
|
||||
add r19=TF_IPSR,r18
|
||||
add r20=TF_IIP,r18
|
||||
;;
|
||||
ld8 r21=[r19] // load cr.ipsr
|
||||
ld8 r22=[r20] // load cr.iip
|
||||
movl r16=XSI_IPSR // XEN !!
|
||||
;;
|
||||
st8 [r16]=r21,XSI_IIP_OFS-XSI_IPSR_OFS // XEN.ipsr
|
||||
mov r2=r21 // save for fp stuff below
|
||||
;;
|
||||
st8 [r16]=r22 // XEN.iip
|
||||
;;
|
||||
//// r18 - trap frame base
|
||||
// Allocate a zero sized frame
|
||||
alloc r30=ar.pfs,0,0,0,0 // discard current frame
|
||||
;;
|
||||
// calc number of dirty regs and put this into rsc.loardrs
|
||||
add r19=TF_NDIRTY,r18
|
||||
;;
|
||||
ld8 r22=[r19] // ndirty
|
||||
;;
|
||||
shl r21=r22,16 // value for ar.rsc
|
||||
;;
|
||||
mov ar.rsc=r21 // setup for loadrs
|
||||
;;
|
||||
// Issue a loadrs instruction
|
||||
{ .mmi
|
||||
loadrs // must be the first instruction
|
||||
;;
|
||||
nop 0x0
|
||||
nop 0x0
|
||||
}
|
||||
// Restore BSPSTORE from interrupted context
|
||||
add r19=TF_BSP,r18
|
||||
add r20=TF_RNAT,r18
|
||||
;;
|
||||
ld8 r21=[r19] // load ar.bspstore
|
||||
ld8 r22=[r20] // load ar.rnat
|
||||
;;
|
||||
mov ar.bspstore=r21 // set ar.bspstore
|
||||
;;
|
||||
// Restore RNAT
|
||||
mov ar.rnat=r22 // set ar.rnat
|
||||
;;
|
||||
// Restore PFS and IFS
|
||||
add r19=TF_PFS,r18
|
||||
add r20=TF_IFS,r18
|
||||
movl r16=XSI_IFS // XEN !!
|
||||
;;
|
||||
ld8 r21=[r19] // load ar.pfs
|
||||
ld8 r22=[r20] // load cr.ifs
|
||||
;;
|
||||
add r19=TF_RSC,r18
|
||||
mov ar.pfs=r21
|
||||
st8 [r16]=r22 // XEN.ifs
|
||||
;;
|
||||
// Restore RSC
|
||||
ld8 r21=[r19] // load ar.rsc
|
||||
;;
|
||||
mov ar.rsc=r21 // set ar.rsc
|
||||
//// r18 - trap frame base
|
||||
add r19=TF_GP,r18
|
||||
add r20=TF_SP,r18
|
||||
;;
|
||||
ld8 gp=[r19],TF_TP-TF_GP // load gp
|
||||
ld8 sp=[r20],TF_PR-TF_SP // load sp
|
||||
;;
|
||||
ld8 r13=[r19] // load tp
|
||||
ld8 r21=[r20] // load pr
|
||||
;;
|
||||
mov pr=r21,-1 // set pr
|
||||
;;
|
||||
add r19=TF_BREG0,r18
|
||||
add r20=TF_BREG6,r18
|
||||
;;
|
||||
ld8 r21=[r19],TF_BREG7-TF_BREG0 // load b0
|
||||
ld8 r22=[r20],16 // load b6
|
||||
;;
|
||||
mov b0=r21
|
||||
mov b6=r22
|
||||
;;
|
||||
ld8 r21=[r19] // load b7
|
||||
ld8 r22=[r20],16 // load b3
|
||||
;;
|
||||
mov b7=r21
|
||||
//// r18 - trap frame base
|
||||
mov r14=r18 // Save the context pointer
|
||||
;;
|
||||
// bsw.1
|
||||
movl r30=XSI_BANKNUM // Switch to bank 1.
|
||||
mov r31=1;;
|
||||
st4 [r30]=r31
|
||||
;;
|
||||
add r2=TF_GREG16,r14
|
||||
add r3=TF_GREG17,r14
|
||||
;;
|
||||
FILL_REG_PAIR(r16,r17,r2,r3)
|
||||
FILL_REG_PAIR(r18,r19,r2,r3)
|
||||
FILL_REG_PAIR(r20,r21,r2,r3)
|
||||
FILL_REG_PAIR(r22,r23,r2,r3)
|
||||
FILL_REG_PAIR(r24,r25,r2,r3)
|
||||
FILL_REG_PAIR(r26,r27,r2,r3)
|
||||
FILL_REG_PAIR(r28,r29,r2,r3)
|
||||
FILL_REG_PAIR(r30,r31,r2,r3)
|
||||
|
||||
/*
|
||||
* On XEN I have to store the bank 1 register into the
|
||||
* global XSI_... area.
|
||||
*/
|
||||
// r16-r31 all now hold bank1 values
|
||||
movl r2=XSI_BANK1_R16
|
||||
movl r3=XSI_BANK1_R16+8
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r16,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r17,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r18,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r19,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r20,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r21,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r22,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r23,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r24,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r25,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r26,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r27,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r28,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r29,16
|
||||
;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r30,16
|
||||
.mem.offset 8,0; st8.spill [r3]=r31,16
|
||||
;;
|
||||
// bsw.0
|
||||
movl r2=XSI_BANKNUM;;
|
||||
st4 [r2]=r0;
|
||||
|
||||
mov r18=r14 // Move back the context pointer
|
||||
;;
|
||||
add r19=TF_GREG2,r18
|
||||
add r20=TF_GREG3,r18
|
||||
;;
|
||||
FILL_REG_PAIR( r2, r3,r19,r20)
|
||||
FILL_REG_PAIR( r8, r9,r19,r20)
|
||||
FILL_REG_PAIR(r10,r11,r19,r20)
|
||||
FILL_REG_PAIR(r14,r15,r19,r20)
|
||||
|
||||
//// r18 - trap frame base,
|
||||
|
||||
add r19=TF_CCV,r18
|
||||
add r20=TF_CSD,r18
|
||||
;;
|
||||
ld8 r21=[r19] // ar.ccv
|
||||
ld8 r22=[r20] // ar.csd
|
||||
;;
|
||||
mov ar.ccv=r21
|
||||
mov ar.csd=r22
|
||||
add r19=TF_SSD,r18
|
||||
;;
|
||||
ld8 r21=[r19] // ar.ssd
|
||||
;;
|
||||
mov ar.ssd=r21
|
||||
add r19=TF_FREG6,r18
|
||||
add r20=TF_FREG7,r18
|
||||
;;
|
||||
FILL_FP_PAIR(f6, f7, r19, r20)
|
||||
FILL_FP_PAIR(f8, f9, r19, r20)
|
||||
FILL_FP_PAIR(f10, f11, r19, r20)
|
||||
add r19=TF_FPSR,r18
|
||||
;;
|
||||
ld8 r21=[r19] // ar.fpsr
|
||||
;;
|
||||
mov ar.fpsr=r21
|
||||
add r19=TF_UNAT,r18
|
||||
;;
|
||||
ld8 r21=[r19]
|
||||
;;
|
||||
mov ar.unat=r21
|
||||
;;
|
||||
srlz.i
|
||||
;;
|
||||
//rfi
|
||||
XEN_HYPER_RFI;
|
||||
;;
|
||||
END(restore_tf_rse_switch)
|
||||
|
||||
|
||||
ENTRY(save_special_regs)
|
||||
alloc loc0=ar.pfs,1,7,0,0
|
||||
movl loc1=XSI_IFA // XEN !!
|
||||
movl loc2=XSI_ISR // XEN !!
|
||||
;;
|
||||
ld8 loc3=[loc1],XSI_IIM_OFS-XSI_IFA_OFS // load XEN.ifa
|
||||
ld8 loc4=[loc2],XSI_IIPA_OFS-XSI_ISR_OFS // load XEN.isr
|
||||
add loc5=TF_IFA,in0
|
||||
add loc6=TF_ISR,in0
|
||||
;;
|
||||
st8 [loc5]=loc3,TF_IIM-TF_IFA // store cr.ifa
|
||||
st8 [loc6]=loc4 // store cr.isr
|
||||
;;
|
||||
ld8 loc3=[loc1] // load XEN.iim
|
||||
;;
|
||||
st8 [loc5]=loc3 // store cr.iim
|
||||
;;
|
||||
mov ar.pfs=loc0
|
||||
;;
|
||||
br.ret.sptk.few rp
|
||||
END(save_special_regs)
|
||||
|
||||
|
||||
ENTRY(hypervisor_callback)
|
||||
/*
|
||||
* Use the thread stack here for storing the trap frame.
|
||||
* It's not wired mapped, so nested data tlb faults may occur!
|
||||
*/
|
||||
add r18=-TF_SIZE,sp
|
||||
;;
|
||||
{ .mib
|
||||
nop 0x02
|
||||
mov r16=ip // for jump back from save_tf_rse_switch
|
||||
br.sptk save_tf_rse_switch
|
||||
;;
|
||||
}
|
||||
add sp=-16,r18 // the new stack
|
||||
alloc r15=ar.pfs,0,0,1,0 // 1 out for do_hypervisor_callback
|
||||
;;
|
||||
mov out0=r18 // the trap frame
|
||||
movl r22=XSI_PSR_IC
|
||||
mov r23=1;;
|
||||
st8 [r22]=r23 // ssm psr.ic
|
||||
;;
|
||||
br.call.sptk.few rp = do_hypervisor_callback
|
||||
|
||||
movl r22=XSI_PSR_IC
|
||||
;;
|
||||
st4 [r22]=r0 // rsm psr.ic
|
||||
add r18=16,sp // load EF-pointer again
|
||||
;;
|
||||
// must have r18-efp, calls rfi at the end.
|
||||
br.sptk restore_tf_rse_switch
|
||||
;;
|
||||
END(hypervisor_callback)
|
||||
|
||||
/*
|
||||
* In: r30 - trap number
|
||||
*/
|
||||
ENTRY(trap_error)
|
||||
// Calculate the stack address for storing.
|
||||
add r18=-TF_SIZE,sp
|
||||
;;
|
||||
add r20=TF_TRAP_NUM,r18
|
||||
;;
|
||||
st2 [r20]=r30 // save trap number
|
||||
;;
|
||||
|
||||
{ .mib
|
||||
nop 0x02
|
||||
mov r16=ip // for jumping back from save_tf_rse_switch
|
||||
// Used register: r16, r18, r19, r20, r21, r22 of bank 0
|
||||
br.sptk save_tf_rse_switch
|
||||
;;
|
||||
}
|
||||
|
||||
alloc r15=ar.pfs,0,0,1,0 // 1 out for do_trap_error
|
||||
;;
|
||||
mov out0=r18 // the trap frame
|
||||
add sp=-16,r18 // C-call abi
|
||||
;;
|
||||
movl r30=XSI_BANKNUM // bsw.1
|
||||
mov r31=1;;
|
||||
st4 [r30]=r31;;
|
||||
|
||||
/* Save extra interrupt registers to the trap frame. */
|
||||
br.call.sptk.few rp = save_special_regs
|
||||
;;
|
||||
|
||||
movl r22=XSI_PSR_IC
|
||||
movl r23=XSI_PSR_I_ADDR
|
||||
;;
|
||||
ld8 r23=[r23]
|
||||
mov r25=1
|
||||
;;
|
||||
st4 [r22]=r25 // ssm psr.ic
|
||||
st1 [r23]=r0 // ssm psr.i
|
||||
;;
|
||||
|
||||
br.call.sptk.few rp = do_trap_error
|
||||
;;
|
||||
// --> currently not reached!!!
|
||||
movl r23=XSI_PSR_I_ADDR
|
||||
movl r22=XSI_PSR_IC
|
||||
;;
|
||||
ld8 r23=[r23]
|
||||
mov r25=1
|
||||
;;
|
||||
st1 [r23]=r25
|
||||
st4 [r22]=r0 // note: clears both vpsr.i and vpsr.ic!
|
||||
;;
|
||||
bsw.0
|
||||
;;
|
||||
add r18=16,sp // load EF-pointer again
|
||||
;;
|
||||
mov sp=r18
|
||||
// must have r18-efp, calls rfi at the end.
|
||||
br.sptk restore_tf_rse_switch
|
||||
;;
|
||||
END(trap_error)
|
||||
|
||||
|
||||
/*
|
||||
* The trap handler stuff.
|
||||
*/
|
||||
|
||||
#define TRAP_ERR(num) \
|
||||
mov r30 = num; \
|
||||
;; ; \
|
||||
br.sptk trap_error \
|
||||
;;
|
||||
|
||||
#define IVT_ENTRY(name, offset) \
|
||||
.org ia64_trap_table + offset; \
|
||||
.global hivt_##name; \
|
||||
.proc hivt_##name; \
|
||||
.prologue; \
|
||||
.body; \
|
||||
hivt_##name:
|
||||
|
||||
#define IVT_END(name) \
|
||||
.endp hivt_##name; \
|
||||
.align 0x100
|
||||
|
||||
#define IVT_ERR(name, num, offset) \
|
||||
IVT_ENTRY(name, offset); \
|
||||
TRAP_ERR(num); \
|
||||
IVT_END(name)
|
||||
/*
|
||||
* The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
|
||||
* bundles per vector and 48 slots with 16 bundles per vector.
|
||||
*/
|
||||
|
||||
.section .text.hivt,"ax"
|
||||
.align 32768
|
||||
.global ia64_trap_table
|
||||
.size ia64_trap_table, 32768
|
||||
ia64_trap_table:
|
||||
|
||||
IVT_ERR(VHPT_Translation, 0, 0x0)
|
||||
IVT_ERR(Instruction_TLB, 1, 0x0400)
|
||||
IVT_ERR(Data_TLB, 2, 0x0800)
|
||||
IVT_ERR(Alternate_Instruction_TLB, 3, 0x0c00)
|
||||
|
||||
|
||||
IVT_ENTRY(Alternate_Data_TLB, 0x1000)
|
||||
mov r30=4 // trap number
|
||||
adt_common:
|
||||
mov r16=cr.ifa // where did it happen
|
||||
mov r31=pr // save predicates
|
||||
;;
|
||||
extr.u r17=r16,IA64_RR_IDX_POS,3 // get region number
|
||||
;;
|
||||
cmp.eq p14,p15=7,r17
|
||||
;;
|
||||
//(p14) br.sptk adt_regf_addr // Check for region 7 - phys addresses
|
||||
// ;;
|
||||
// br.sptk trap_error
|
||||
// // No return
|
||||
//
|
||||
//adt_regf_addr:
|
||||
// extr.u r17=r16,60,4 // get region number
|
||||
// ;;
|
||||
// cmp.eq p14,p15=0xf,r17
|
||||
// ;;
|
||||
(p14) br.sptk adt_reg7_addr // Check for region 7 - phys addresses
|
||||
;;
|
||||
br.sptk trap_error
|
||||
|
||||
adt_reg7_addr:
|
||||
/*
|
||||
* region 7 addresses are only directly mapped physically
|
||||
* addresses. Currently I don't do a check.
|
||||
*/
|
||||
movl r20=~((7 << IA64_RR_IDX_POS) | 0xfff)
|
||||
movl r18=((PTE_PS_16K<<IA64_ITIR_PS)|(IA64_KEY_REG7<<IA64_ITIR_KEY))
|
||||
;;
|
||||
movl r19= ((1<<PTE_OFF_P) | (PTE_MA_WB<<PTE_OFF_MA) | \
|
||||
(1<<PTE_OFF_A) | (1<<PTE_OFF_D) | \
|
||||
(PTE_PL_KERN<<PTE_OFF_PL) | (PTE_AR_RW<<PTE_OFF_AR))
|
||||
// clear the region bits and 0-11
|
||||
// extract the pfn from the ifa
|
||||
mov cr.itir=r18
|
||||
and r20=r20, r16
|
||||
;;
|
||||
or r20=r20,r19 // put pfn into pte
|
||||
;;
|
||||
mov pr=r31,-1 // restore predicates
|
||||
itc.d r20
|
||||
;;
|
||||
XEN_HYPER_RFI;
|
||||
;;
|
||||
|
||||
IVT_END(Alternate_Data_TLB)
|
||||
|
||||
/*
|
||||
* Handling of nested data tlb is needed, because in hypervisor_callback()
|
||||
* the stack is used to store the register trap frame. This stack is allocated
|
||||
* dynamically (as identity mapped address) and therewidth no tr mapped page!
|
||||
*/
|
||||
IVT_ENTRY(Data_Nested_TLB, 0x1400)
|
||||
|
||||
mov r30=5 // trap number
|
||||
add r28=-TF_SIZE,sp // r28 is never used in trap handling
|
||||
;;
|
||||
mov cr.ifa=r28
|
||||
;;
|
||||
br.sptk adt_common
|
||||
IVT_END(Data_Nested_TLB)
|
||||
|
||||
|
||||
|
||||
IVT_ERR(Instruction_Key_Miss, 6, 0x1800)
|
||||
IVT_ERR(Data_Key_Miss, 7, 0x1c00)
|
||||
IVT_ERR(Dirty_Bit, 8, 0x2000)
|
||||
IVT_ERR(Instruction_Access_Bit, 9, 0x2400)
|
||||
IVT_ERR(Data_Access_Bit, 10, 0x2800)
|
||||
IVT_ERR(Break_Instruction, 11, 0x2c00)
|
||||
IVT_ERR(External_Interrupt, 12, 0x3000)
|
||||
IVT_ERR(Reserved_3400, 13, 0x3400)
|
||||
IVT_ERR(Reserved_3800, 14, 0x3800)
|
||||
IVT_ERR(Reserved_3c00, 15, 0x3c00)
|
||||
IVT_ERR(Reserved_4000, 16, 0x4000)
|
||||
IVT_ERR(Reserved_4400, 17, 0x4400)
|
||||
IVT_ERR(Reserved_4800, 18, 0x4800)
|
||||
IVT_ERR(Reserved_4c00, 19, 0x4c00)
|
||||
IVT_ERR(Page_Not_Present, 20, 0x5000)
|
||||
IVT_ERR(Key_Permission, 21, 0x5100)
|
||||
IVT_ERR(Instruction_Access_Rights, 22, 0x5200)
|
||||
IVT_ERR(Data_Access_Rights, 23, 0x5300)
|
||||
IVT_ERR(General_Exception, 24, 0x5400)
|
||||
IVT_ERR(Disabled_FP_Register, 25, 0x5500)
|
||||
IVT_ERR(NaT_Consumption, 26, 0x5600)
|
||||
IVT_ERR(Speculation, 27, 0x5700)
|
||||
IVT_ERR(Reserved_5800, 28, 0x5800)
|
||||
IVT_ERR(Debug, 29, 0x5900)
|
||||
IVT_ERR(Unaligned_Reference, 30, 0x5a00)
|
||||
IVT_ERR(Unsupported_Data_Reference, 31, 0x5b00)
|
||||
IVT_ERR(Floating_Point_Fault, 32, 0x5c00)
|
||||
IVT_ERR(Floating_Point_Trap, 33, 0x5d00)
|
||||
IVT_ERR(Lower_Privilege_Transfer_Trap, 34, 0x5e00)
|
||||
IVT_ERR(Taken_Branch_Trap, 35, 0x5f00)
|
||||
IVT_ERR(Single_Step_Trap, 36, 0x6000)
|
||||
IVT_ERR(Reserved_6100, 37, 0x6100)
|
||||
IVT_ERR(Reserved_6200, 38, 0x6200)
|
||||
IVT_ERR(Reserved_6300, 39, 0x6300)
|
||||
IVT_ERR(Reserved_6400, 40, 0x6400)
|
||||
IVT_ERR(Reserved_6500, 41, 0x6500)
|
||||
IVT_ERR(Reserved_6600, 42, 0x6600)
|
||||
IVT_ERR(Reserved_6700, 43, 0x6700)
|
||||
IVT_ERR(Reserved_6800, 44, 0x6800)
|
||||
IVT_ERR(IA_32_Exception, 45, 0x6900)
|
||||
IVT_ERR(IA_32_Intercept, 46, 0x6a00)
|
||||
IVT_ERR(IA_32_Interrupt, 47, 0x6b00)
|
||||
IVT_ERR(Reserved_6c00, 48, 0x6c00)
|
||||
IVT_ERR(Reserved_6d00, 49, 0x6d00)
|
||||
IVT_ERR(Reserved_6e00, 50, 0x6e00)
|
||||
IVT_ERR(Reserved_6f00, 51, 0x6f00)
|
||||
IVT_ERR(Reserved_7000, 52, 0x7000)
|
||||
IVT_ERR(Reserved_7100, 53, 0x7100)
|
||||
IVT_ERR(Reserved_7200, 54, 0x7200)
|
||||
IVT_ERR(Reserved_7300, 55, 0x7300)
|
||||
IVT_ERR(Reserved_7400, 56, 0x7400)
|
||||
IVT_ERR(Reserved_7500, 57, 0x7500)
|
||||
IVT_ERR(Reserved_7600, 58, 0x7600)
|
||||
IVT_ERR(Reserved_7700, 59, 0x7700)
|
||||
IVT_ERR(Reserved_7800, 60, 0x7800)
|
||||
IVT_ERR(Reserved_7900, 61, 0x7900)
|
||||
IVT_ERR(Reserved_7a00, 62, 0x7a00)
|
||||
IVT_ERR(Reserved_7b00, 63, 0x7b00)
|
||||
IVT_ERR(Reserved_7c00, 64, 0x7c00)
|
||||
IVT_ERR(Reserved_7d00, 65, 0x7d00)
|
||||
IVT_ERR(Reserved_7e00, 66, 0x7e00)
|
||||
IVT_ERR(Reserved_7f00, 67, 0x7f00)
|
||||
@@ -1,86 +0,0 @@
|
||||
OUTPUT_FORMAT("elf64-ia64-little")
|
||||
OUTPUT_ARCH(ia64)
|
||||
|
||||
ENTRY(phys_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
code PT_LOAD;
|
||||
data PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
phys_start = _start - (((5<<(61))+0x100000000) - (1 << 20));
|
||||
|
||||
code : { } :code
|
||||
. = ((5<<(61))+0x100000000);
|
||||
|
||||
_text = .;
|
||||
|
||||
.text : AT(ADDR(.text) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
|
||||
_etext = .;
|
||||
|
||||
data : { } :data
|
||||
.data : AT(ADDR(.data) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.data)
|
||||
}
|
||||
|
||||
.sdata : AT(ADDR(.sdata) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.sdata) *(.sdata1) *(.srdata) }
|
||||
|
||||
.rodata : AT(ADDR(.rodata) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.rodata) }
|
||||
|
||||
.rodata.str1.8 : AT(ADDR(.rodata.str1.8) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.rodata.str1.8) }
|
||||
|
||||
/* newlib initialization functions */
|
||||
. = ALIGN(64 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { *(.preinit_array) }
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { *(.init_array) }
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { *(.fini_array) }
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
.ctors : AT(ADDR(.ctors) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{
|
||||
__CTOR_LIST__ = .;
|
||||
*(.ctors)
|
||||
CONSTRUCTORS
|
||||
QUAD(0)
|
||||
__CTOR_END__ = .;
|
||||
}
|
||||
|
||||
.dtors : AT(ADDR(.dtors) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{
|
||||
__DTOR_LIST__ = .;
|
||||
*(.dtors)
|
||||
QUAD(0)
|
||||
__DTOR_END__ = .;
|
||||
}
|
||||
|
||||
.IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.IA_64.unwind_info) }
|
||||
|
||||
.IA_64.unwind : AT(ADDR(.IA_64.unwind) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{ *(.IA_64.unwind) }
|
||||
|
||||
.bss : AT(ADDR(.bss) - (((5<<(61))+0x100000000) - (1 << 20)))
|
||||
{
|
||||
*(.bss)
|
||||
*(.app.bss)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
* Description: Special ia64 memory management.
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/mm.h>
|
||||
|
||||
|
||||
#define MAX_MEM_AREA 5
|
||||
paddr_t phys_avail[MAX_MEM_AREA * 2];
|
||||
int phys_avail_cnt;
|
||||
uint64_t physmem;
|
||||
|
||||
/*
|
||||
* These variables are defined in the linker script minios_ia64.lds
|
||||
* to get the size of the kernel.
|
||||
*/
|
||||
extern uint64_t _text[], _etext[], _end[], kstack[], phys_start[];
|
||||
|
||||
uint64_t kernstart, kernend, kernsize, kernpstart, kernpend;
|
||||
|
||||
#ifdef HAVE_LIBC
|
||||
uint8_t _heap[512 * 1024];
|
||||
unsigned long heap = (unsigned long)_heap,
|
||||
brk = (unsigned long)_heap,
|
||||
heap_mapped = (unsigned long)_heap + sizeof(_heap),
|
||||
heap_end = (unsigned long)_heap + sizeof(_heap);
|
||||
#endif
|
||||
|
||||
/* Print the available memory chunks. */
|
||||
static void
|
||||
print_phys_avail(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printk("Physical memory chunk(s):\n");
|
||||
for (i = 0; phys_avail[i + 1] != 0; i += 2) {
|
||||
int size = phys_avail[i + 1] - phys_avail[i];
|
||||
printk("0x%08lx - 0x%08lx, %d bytes (%d pages)\n",
|
||||
phys_avail[i], phys_avail[i + 1] - 1,
|
||||
size, size / PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
|
||||
{
|
||||
uint64_t ms, me;
|
||||
int i, j;
|
||||
uint64_t m, n;
|
||||
|
||||
kernstart = trunc_page(_text);
|
||||
kernend = roundup_page(_end);
|
||||
|
||||
kernpstart = trunc_page(ia64_tpa(kernstart));
|
||||
kernpend = roundup_page(kernpstart + (kernend - kernstart));
|
||||
kernsize = kernpend - kernpstart;
|
||||
|
||||
ms = roundup_page(machineFwG.mach_mem_start);
|
||||
me = trunc_page(machineFwG.mach_mem_start+machineFwG.mach_mem_size);
|
||||
memset((void*)phys_avail, 0, sizeof(phys_avail));
|
||||
/* 1. Check where the kernel lies in physical memory. */
|
||||
physmem = me - ms;
|
||||
if ((ms <= kernpend) && (kernpstart <= me)) {
|
||||
if (ms < kernpstart) { /* There is a part before the kernel. */
|
||||
PRINT_BV(" Found chunk before kernel: 0x%lx - 0x%lx\n",
|
||||
ms, kernpstart);
|
||||
phys_avail[phys_avail_cnt] = ms;
|
||||
phys_avail[phys_avail_cnt+1] = kernpstart;
|
||||
phys_avail_cnt += 2;
|
||||
}
|
||||
if (kernpend < me) { /* There is a part behind the kernel. */
|
||||
PRINT_BV(" Found chunk behind kernel: 0x%lx - 0x%lx\n",
|
||||
kernpend, me);
|
||||
phys_avail[phys_avail_cnt] = kernpend;
|
||||
phys_avail[phys_avail_cnt+1] = me;
|
||||
phys_avail_cnt += 2;
|
||||
}
|
||||
} else { /* One big chunk */
|
||||
PRINT_BV(" Found big chunk: 0x%lx - 0x%lx\n", ms, me);
|
||||
phys_avail[phys_avail_cnt] = ms;
|
||||
phys_avail[phys_avail_cnt + 1] = me;
|
||||
phys_avail_cnt += 2;
|
||||
}
|
||||
phys_avail[phys_avail_cnt] = 0;
|
||||
|
||||
print_phys_avail();
|
||||
/*
|
||||
* In this first version I only look for the biggest mem area.
|
||||
*/
|
||||
for (i = j = m = n = 0; i < phys_avail_cnt; i += 2) {
|
||||
n = page_to_pfn(phys_avail[i + 1]) - page_to_pfn(phys_avail[i]);
|
||||
if (n > m) {
|
||||
m = n;
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
*start_pfn_p = page_to_pfn(phys_avail[j]);
|
||||
*max_pfn_p = page_to_pfn(phys_avail[j +1 ]);
|
||||
}
|
||||
|
||||
/* Currently only a dummy function. */
|
||||
void
|
||||
arch_init_demand_mapping_area(unsigned long max_pfn)
|
||||
{
|
||||
max_pfn = max_pfn;
|
||||
}
|
||||
|
||||
unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function used in gnttab.c. */
|
||||
void do_map_frames(unsigned long addr,
|
||||
const unsigned long *f, unsigned long n, unsigned long stride,
|
||||
unsigned long increment, domid_t id, int *err, unsigned long prot)
|
||||
{
|
||||
/* TODO */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
void*
|
||||
map_frames_ex(const unsigned long* frames, unsigned long n, unsigned long stride,
|
||||
unsigned long increment, unsigned long alignment, domid_t id,
|
||||
int *err, unsigned long prot)
|
||||
{
|
||||
/* TODO: incomplete! */
|
||||
ASSERT(n == 1 || (stride == 0 && increment == 1));
|
||||
ASSERT(id == DOMID_SELF);
|
||||
ASSERT(prot == 0);
|
||||
return (void*) __va(frames[0] << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
int unmap_frames(unsigned long virt_addr, unsigned long num_frames)
|
||||
{
|
||||
/* TODO */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
unsigned long alloc_contig_pages(int order, unsigned int addr_bits)
|
||||
{
|
||||
/* TODO */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
void arch_init_p2m(unsigned long max_pfn)
|
||||
{
|
||||
printk("Warn: p2m map not implemented.\n");
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/console.h>
|
||||
#include <mini-os/page.h>
|
||||
|
||||
|
||||
static struct ia64_fdesc sal_fdesc;
|
||||
uint64_t ia64_pal_entry; /* PAL_PROC entrypoint */
|
||||
|
||||
|
||||
struct ia64_sal_result
|
||||
ia64_sal_call(uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
|
||||
uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8)
|
||||
{
|
||||
return ia64_sal_entry(a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
|
||||
static struct ia64_sal_result
|
||||
fake_sal(uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
|
||||
uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8)
|
||||
{
|
||||
struct ia64_sal_result res;
|
||||
res.sal_status = -3;
|
||||
res.sal_result[0] = 0;
|
||||
res.sal_result[1] = 0;
|
||||
res.sal_result[2] = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently only the SAL_DESC_ENTRYPOINT is checked to get
|
||||
* the entry points the pal and sal functions.
|
||||
*/
|
||||
void
|
||||
ia64_sal_init(struct sal_system_table *saltab)
|
||||
{
|
||||
static int sizes[6] = { 48, 32, 16, 32, 16, 16 };
|
||||
uint8_t *p;
|
||||
int i;
|
||||
|
||||
PRINT_BV("Reading SALtable:\n");
|
||||
ia64_sal_entry = fake_sal;
|
||||
|
||||
if (memcmp((void*)(uint64_t)(saltab->sal_signature), SAL_SIGNATURE, 4))
|
||||
{
|
||||
printk("Bad signature for SAL System Table\n");
|
||||
return;
|
||||
}
|
||||
p = (uint8_t *) (saltab + 1);
|
||||
for (i = 0; i < saltab->sal_entry_count; i++) {
|
||||
switch (*p) {
|
||||
case SAL_DESC_ENTRYPOINT: // 0
|
||||
{
|
||||
struct sal_entrypoint_descriptor *dp;
|
||||
|
||||
dp = (struct sal_entrypoint_descriptor*)p;
|
||||
ia64_pal_entry =
|
||||
IA64_PHYS_TO_RR7(dp->sale_pal_proc);
|
||||
PRINT_BV(" PAL Proc at 0x%lx\n", ia64_pal_entry);
|
||||
sal_fdesc.func =
|
||||
IA64_PHYS_TO_RR7(dp->sale_sal_proc);
|
||||
sal_fdesc.gp = IA64_PHYS_TO_RR7(dp->sale_sal_gp);
|
||||
PRINT_BV(" SAL Proc at 0x%lx, GP at 0x%lx\n",
|
||||
sal_fdesc.func, sal_fdesc.gp);
|
||||
ia64_sal_entry = (sal_entry_t *) &sal_fdesc;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p += sizes[*p];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
*
|
||||
* Description: ia64 specific part of the scheduler for mini-os
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/types.h>
|
||||
#include <mini-os/sched.h>
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/xmalloc.h>
|
||||
#include <mini-os/mm.h>
|
||||
|
||||
/* The function is implemented in fw.S */
|
||||
extern void thread_starter(void);
|
||||
|
||||
void stack_walk(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
struct thread*
|
||||
arch_create_thread(char *name, void (*function)(void *), void *data)
|
||||
{
|
||||
struct thread* _thread;
|
||||
|
||||
_thread = (struct thread*)_xmalloc(sizeof(struct thread), 16);
|
||||
/* Allocate pages for stack, stack will be aligned */
|
||||
_thread->stack = (char *)alloc_pages(STACK_SIZE_PAGE_ORDER);
|
||||
_thread->name = name;
|
||||
memset((void*)&(_thread->regs), 0, sizeof(_thread->regs));
|
||||
_thread->regs.sp = ((uint64_t)_thread->stack) + STACK_SIZE - 16;
|
||||
_thread->regs.bsp = ((uint64_t)_thread->stack) + 0x10;
|
||||
_thread->regs.rp = FDESC_FUNC(thread_starter);
|
||||
_thread->regs.pfs = 0x82;
|
||||
_thread->regs.r4 = FDESC_FUNC(function);
|
||||
_thread->regs.r6 = (uint64_t)data;
|
||||
return _thread;
|
||||
}
|
||||
|
||||
extern void restore_context(struct thread*);
|
||||
extern int switch_context(struct thread*, struct thread*);
|
||||
|
||||
void
|
||||
arch_switch_threads(struct thread* prev, struct thread* next)
|
||||
{
|
||||
ia64_set_r13((uint64_t)next);
|
||||
switch_context(prev, next);
|
||||
}
|
||||
|
||||
/* Everything initialised, start idle thread */
|
||||
void
|
||||
run_idle_thread(void)
|
||||
{
|
||||
//do_busy_loop();
|
||||
ia64_set_r13((uint64_t)idle_thread);
|
||||
restore_context(idle_thread);
|
||||
printk("%s: restore_context() returned - bad!\n", __func__);
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Description: simple ia64 specific time handling
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/console.h>
|
||||
#include <mini-os/time.h>
|
||||
#include <mini-os/efi.h>
|
||||
#include <mini-os/events.h>
|
||||
|
||||
struct timespec os_time;
|
||||
static uint64_t itc_alt; /* itc on last update. */
|
||||
static uint64_t itc_at_boot; /* itc on boot */
|
||||
static uint64_t itc_frequency;
|
||||
static uint64_t processor_frequency;
|
||||
static uint64_t itm_val;
|
||||
|
||||
static int is_leap_year(int year)
|
||||
{
|
||||
if( year % 4 == 0 )
|
||||
{
|
||||
if( year % 100 == 0 )
|
||||
{
|
||||
if( year % 400 == 0 ) return 1;
|
||||
else return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int count_leap_years(int epoch, int year)
|
||||
{
|
||||
int i, result = 0;
|
||||
for( i = epoch ; i < year ; i++ ) if( is_leap_year(i) ) result++;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int get_day(int year, int mon, int day) {
|
||||
int result;
|
||||
switch(mon)
|
||||
{
|
||||
case 0: result = 0; break;
|
||||
case 1: result = 31; break; /* 1: 31 */
|
||||
case 2: result = 59; break; /* 2: 31+28 */
|
||||
case 3: result = 90; break; /* 3: 59+31 */
|
||||
case 4: result = 120;break; /* 4: 90+30 */
|
||||
case 5: result = 151;break; /* 5: 120+31 */
|
||||
case 6: result = 181;break; /* 6: 151+30 */
|
||||
case 7: result = 212;break; /* 7: 181+31 */
|
||||
case 8: result = 243;break; /* 8: 212+31 */
|
||||
case 9: result = 273;break; /* 9: 243+30 */
|
||||
case 10:result = 304;break; /* 10:273+31 */
|
||||
case 11:result = 334;break; /* 11:304+30 */
|
||||
default: break;
|
||||
}
|
||||
if( is_leap_year(year) && mon > 2 ) result++;
|
||||
result += day - 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
||||
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
||||
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
||||
*
|
||||
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
|
||||
* machines were long is 32-bit! (However, as time_t is signed, we
|
||||
* will already get problems at other places on 2038-01-19 03:14:08)
|
||||
*/
|
||||
static unsigned long _mktime(const unsigned int year, const unsigned int mon,
|
||||
const unsigned int day, const unsigned int hour,
|
||||
const unsigned int min, const unsigned int sec)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
|
||||
result = sec;
|
||||
result += min * 60;
|
||||
result += hour * 3600;
|
||||
result += get_day(year, mon - 1, day) * 86400;
|
||||
result += (year - 1970) * 31536000;
|
||||
result += count_leap_years(1970, year) * 86400;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ns_from_cycles(uint64_t cycles)
|
||||
{
|
||||
return (cycles * (1000000000 / itc_frequency));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ns_to_cycles(uint64_t ns)
|
||||
{
|
||||
return (ns * (itc_frequency / 1000000000));
|
||||
}
|
||||
|
||||
/*
|
||||
* Block the domain until until(nanoseconds) is over.
|
||||
* If block is called no timerinterrupts are delivered from xen!
|
||||
*/
|
||||
void
|
||||
block_domain(s_time_t until)
|
||||
{
|
||||
struct ia64_pal_result pal_res;
|
||||
uint64_t c, new;
|
||||
|
||||
c = ns_to_cycles(until);
|
||||
new = ia64_get_itc() + c - NOW();
|
||||
ia64_set_itm(new); /* Reload cr.itm */
|
||||
/*
|
||||
* PAL_HALT_LIGHT returns on every external interrupt,
|
||||
* including timer interrupts.
|
||||
*/
|
||||
pal_res = ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
|
||||
if (pal_res.pal_status != 0)
|
||||
printk("%s: PAL_HALT_LIGHT returns an error\n");
|
||||
/* Reload the normal timer interrupt match. */
|
||||
new = ia64_get_itc() + itm_val;
|
||||
ia64_set_itm(new);
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_time(void)
|
||||
{
|
||||
uint64_t itc_new, new;
|
||||
|
||||
itc_new = ia64_get_itc();
|
||||
if (itc_new < itc_alt)
|
||||
new = ~0 - itc_alt + itc_new;
|
||||
else
|
||||
new = itc_new - itc_alt;
|
||||
itc_alt = itc_new;
|
||||
new = ns_from_cycles(new);
|
||||
os_time.tv_nsec += new;
|
||||
if (os_time.tv_nsec > 1000000000) { /* On overflow. */
|
||||
os_time.tv_sec++;
|
||||
os_time.tv_nsec -= 1000000000;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
timer_interrupt(evtchn_port_t port, struct pt_regs* regsP, void *data)
|
||||
{
|
||||
uint64_t new;
|
||||
|
||||
calculate_time();
|
||||
new = ia64_get_itc() + itm_val;
|
||||
ia64_set_itm(new);
|
||||
}
|
||||
|
||||
/*
|
||||
* monotonic_clock(): returns # of nanoseconds passed since time_init()
|
||||
*/
|
||||
uint64_t
|
||||
monotonic_clock(void)
|
||||
{
|
||||
uint64_t delta;
|
||||
|
||||
delta = ia64_get_itc() - itc_at_boot;
|
||||
delta = ns_from_cycles(delta);
|
||||
return delta;
|
||||
}
|
||||
|
||||
int
|
||||
gettimeofday(struct timeval *tv, void *tz)
|
||||
{
|
||||
calculate_time();
|
||||
tv->tv_sec = os_time.tv_sec; /* seconds */
|
||||
tv->tv_usec = NSEC_TO_USEC(os_time.tv_nsec); /* microseconds */
|
||||
return 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Read the clock frequencies from pal and sal for calculating
|
||||
* the clock interrupt.
|
||||
*/
|
||||
static void
|
||||
calculate_frequencies(void)
|
||||
{
|
||||
struct ia64_sal_result sal_res;
|
||||
struct ia64_pal_result pal_res;
|
||||
|
||||
pal_res = ia64_call_pal_static(PAL_FREQ_RATIOS, 0, 0, 0);
|
||||
sal_res = ia64_sal_entry(SAL_FREQ_BASE, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
if (sal_res.sal_status == 0 && pal_res.pal_status == 0) {
|
||||
processor_frequency =
|
||||
sal_res.sal_result[0] * (pal_res.pal_result[0] >> 32)
|
||||
/ (pal_res.pal_result[0] & ((1L << 32) - 1));
|
||||
itc_frequency =
|
||||
sal_res.sal_result[0] * (pal_res.pal_result[2] >> 32)
|
||||
/ (pal_res.pal_result[2] & ((1L << 32) - 1));
|
||||
PRINT_BV("Reading clock frequencies:\n");
|
||||
PRINT_BV(" Platform clock frequency %ld Hz\n",
|
||||
sal_res.sal_result[0]);
|
||||
PRINT_BV(" Processor ratio %ld/%ld, Bus ratio %ld/%ld, "
|
||||
" ITC ratio %ld/%ld\n",
|
||||
pal_res.pal_result[0] >> 32,
|
||||
pal_res.pal_result[0] & ((1L << 32) - 1),
|
||||
pal_res.pal_result[1] >> 32,
|
||||
pal_res.pal_result[1] & ((1L << 32) - 1),
|
||||
pal_res.pal_result[2] >> 32,
|
||||
pal_res.pal_result[2] & ((1L << 32) - 1));
|
||||
|
||||
printk(" ITC frequency %ld\n", itc_frequency);
|
||||
} else {
|
||||
itc_frequency = 1000000000;
|
||||
processor_frequency = 0;
|
||||
printk("Reading clock frequencies failed!!! Using: %ld\n",
|
||||
itc_frequency);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#define HZ 1
|
||||
#define HZ 1000 // 1000 clock ticks per sec
|
||||
#define IA64_TIMER_VECTOR 0xef
|
||||
|
||||
void
|
||||
init_time(void)
|
||||
{
|
||||
uint64_t new;
|
||||
efi_time_t tm;
|
||||
evtchn_port_t port = 0;
|
||||
|
||||
printk("Initialising time\n");
|
||||
calculate_frequencies();
|
||||
|
||||
itm_val = (itc_frequency + HZ/2) / HZ;
|
||||
printk(" itm_val: %ld\n", itm_val);
|
||||
|
||||
os_time.tv_sec = 0;
|
||||
os_time.tv_nsec = 0;
|
||||
|
||||
if (efi_get_time(&tm)) {
|
||||
printk(" EFI-Time: %d.%d.%d %d:%d:%d\n", tm.Day,
|
||||
tm.Month, tm.Year, tm.Hour, tm.Minute, tm.Second);
|
||||
os_time.tv_sec = _mktime(tm.Year, tm.Month,
|
||||
tm.Day, tm.Hour, tm.Minute, tm.Second);
|
||||
os_time.tv_nsec = tm.Nanosecond;
|
||||
} else
|
||||
printk("efi_get_time() failed\n");
|
||||
|
||||
port = bind_virq(VIRQ_ITC, timer_interrupt, NULL);
|
||||
if (port == -1) {
|
||||
printk("XEN timer request chn bind failed %i\n", port);
|
||||
return;
|
||||
}
|
||||
unmask_evtchn(port);
|
||||
itc_alt = ia64_get_itc();
|
||||
itc_at_boot = itc_alt;
|
||||
new = ia64_get_itc() + itm_val;
|
||||
ia64_set_itv(IA64_TIMER_VECTOR);
|
||||
ia64_set_itm(new);
|
||||
ia64_srlz_d();
|
||||
}
|
||||
|
||||
void
|
||||
fini_time(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
@@ -1,394 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
|
||||
* Tristan Gingold <tristan.gingold@bull.net>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is mostly taken from ia64-xen files xcom_mini.c and xencomm.c.
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
*/
|
||||
|
||||
|
||||
#include <mini-os/os.h>
|
||||
#include <mini-os/errno.h>
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/hypervisor.h>
|
||||
#include <xen/xencomm.h>
|
||||
#include <xen/grant_table.h>
|
||||
|
||||
|
||||
#define XENCOMM_MINI_ADDRS 3
|
||||
struct xencomm_mini
|
||||
{
|
||||
struct xencomm_desc _desc;
|
||||
uint64_t address[XENCOMM_MINI_ADDRS];
|
||||
};
|
||||
|
||||
#define xen_guest_handle(hnd) ((hnd).p)
|
||||
|
||||
struct xencomm_handle;
|
||||
|
||||
/* Translate virtual address to physical address. */
|
||||
uint64_t
|
||||
xencomm_vaddr_to_paddr(uint64_t vaddr)
|
||||
{
|
||||
if (IA64_RR_EXTR(vaddr) == 5)
|
||||
return KERN_VIRT_2_PHYS(vaddr);
|
||||
|
||||
if (IA64_RR_EXTR(vaddr) == 7)
|
||||
return __pa(vaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Inline version. To be used only on linear space (kernel space). */
|
||||
static struct xencomm_handle *
|
||||
xencomm_create_inline(void *buffer)
|
||||
{
|
||||
unsigned long paddr;
|
||||
|
||||
paddr = xencomm_vaddr_to_paddr((unsigned long)buffer);
|
||||
return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG);
|
||||
}
|
||||
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
static int
|
||||
xencomm_init_desc(struct xencomm_desc *desc, void *buffer, unsigned long bytes)
|
||||
{
|
||||
unsigned long recorded = 0;
|
||||
int i = 0;
|
||||
|
||||
if ((buffer == NULL) && (bytes > 0))
|
||||
BUG();
|
||||
|
||||
/* record the physical pages used */
|
||||
if (buffer == NULL)
|
||||
desc->nr_addrs = 0;
|
||||
|
||||
while ((recorded < bytes) && (i < desc->nr_addrs)) {
|
||||
unsigned long vaddr = (unsigned long)buffer + recorded;
|
||||
unsigned long paddr;
|
||||
int offset;
|
||||
int chunksz;
|
||||
|
||||
offset = vaddr % PAGE_SIZE; /* handle partial pages */
|
||||
chunksz = min(PAGE_SIZE - offset, bytes - recorded);
|
||||
|
||||
paddr = xencomm_vaddr_to_paddr(vaddr);
|
||||
if (paddr == ~0UL) {
|
||||
printk("%s: couldn't translate vaddr %lx\n",
|
||||
__func__, vaddr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->address[i++] = paddr;
|
||||
recorded += chunksz;
|
||||
}
|
||||
if (recorded < bytes) {
|
||||
printk("%s: could only translate %ld of %ld bytes\n",
|
||||
__func__, recorded, bytes);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* mark remaining addresses invalid (just for safety) */
|
||||
while (i < desc->nr_addrs)
|
||||
desc->address[i++] = XENCOMM_INVALID;
|
||||
desc->magic = XENCOMM_MAGIC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area)
|
||||
{
|
||||
unsigned long base;
|
||||
unsigned int pageoffset;
|
||||
|
||||
while (*nbr_area >= 0) {
|
||||
/* Allocate an area. */
|
||||
(*nbr_area)--;
|
||||
|
||||
base = (unsigned long)(area + *nbr_area);
|
||||
pageoffset = base % PAGE_SIZE;
|
||||
|
||||
/* If the area does not cross a page, use it. */
|
||||
if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini))
|
||||
return &area[*nbr_area];
|
||||
}
|
||||
/* No more area. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
|
||||
void *buffer, unsigned long bytes,
|
||||
struct xencomm_handle **ret)
|
||||
{
|
||||
struct xencomm_desc *desc;
|
||||
int rc;
|
||||
unsigned long res;
|
||||
|
||||
desc = xencomm_alloc_mini(area, nbr_area);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
desc->nr_addrs = XENCOMM_MINI_ADDRS;
|
||||
|
||||
rc = xencomm_init_desc(desc, buffer, bytes);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
res = xencomm_vaddr_to_paddr((unsigned long)desc);
|
||||
if (res == ~0UL)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = (struct xencomm_handle*)res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
|
||||
unsigned int cmd, void *op, unsigned int count,
|
||||
struct xencomm_handle **desc)
|
||||
{
|
||||
struct xencomm_handle *desc1;
|
||||
unsigned int argsize=0;
|
||||
int rc;
|
||||
|
||||
switch (cmd) {
|
||||
case GNTTABOP_map_grant_ref:
|
||||
argsize = sizeof(struct gnttab_map_grant_ref);
|
||||
break;
|
||||
case GNTTABOP_unmap_grant_ref:
|
||||
argsize = sizeof(struct gnttab_unmap_grant_ref);
|
||||
break;
|
||||
case GNTTABOP_setup_table:
|
||||
{
|
||||
struct gnttab_setup_table *setup = op;
|
||||
|
||||
argsize = sizeof(*setup);
|
||||
|
||||
if (count != 1)
|
||||
return -EINVAL;
|
||||
rc = xencomm_create_mini
|
||||
(xc_area, nbr_area,
|
||||
(void*)(uint64_t) xen_guest_handle(setup->frame_list),
|
||||
setup->nr_frames
|
||||
* sizeof(*xen_guest_handle(setup->frame_list)),
|
||||
&desc1);
|
||||
if (rc)
|
||||
return rc;
|
||||
set_xen_guest_handle(setup->frame_list,
|
||||
(void *)(uint64_t)desc1);
|
||||
break;
|
||||
}
|
||||
case GNTTABOP_dump_table:
|
||||
argsize = sizeof(struct gnttab_dump_table);
|
||||
break;
|
||||
case GNTTABOP_transfer:
|
||||
argsize = sizeof(struct gnttab_transfer);
|
||||
break;
|
||||
case GNTTABOP_copy:
|
||||
argsize = sizeof(struct gnttab_copy);
|
||||
break;
|
||||
default:
|
||||
printk("%s: unknown mini grant table op %d\n", __func__, cmd);
|
||||
BUG();
|
||||
}
|
||||
|
||||
rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int
|
||||
xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
|
||||
struct xencomm_handle *uop,
|
||||
unsigned int count)
|
||||
{
|
||||
return _hypercall3(int, grant_table_op, cmd, uop, count);
|
||||
}
|
||||
|
||||
int
|
||||
xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
|
||||
unsigned int count)
|
||||
{
|
||||
int rc;
|
||||
struct xencomm_handle *desc;
|
||||
int nbr_area = 2;
|
||||
struct xencomm_mini xc_area[2];
|
||||
|
||||
rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
|
||||
cmd, op, count, &desc);
|
||||
if (rc)
|
||||
return rc;
|
||||
return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
|
||||
}
|
||||
|
||||
static void
|
||||
gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
flags = uop->flags;
|
||||
|
||||
if (flags & GNTMAP_host_map) {
|
||||
if (flags & GNTMAP_application_map) {
|
||||
printk("GNTMAP_application_map is not supported yet: "
|
||||
"flags 0x%x\n", flags);
|
||||
BUG();
|
||||
}
|
||||
if (flags & GNTMAP_contains_pte) {
|
||||
printk("GNTMAP_contains_pte is not supported yet flags "
|
||||
"0x%x\n", flags);
|
||||
BUG();
|
||||
}
|
||||
} else if (flags & GNTMAP_device_map) {
|
||||
printk("GNTMAP_device_map is not supported yet 0x%x\n", flags);
|
||||
BUG();//XXX not yet. actually this flag is not used.
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
|
||||
{
|
||||
if (cmd == GNTTABOP_map_grant_ref) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
gnttab_map_grant_ref_pre(
|
||||
(struct gnttab_map_grant_ref*)uop + i);
|
||||
}
|
||||
}
|
||||
return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);
|
||||
}
|
||||
|
||||
/* In fw.S */
|
||||
extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
|
||||
int
|
||||
HYPERVISOR_suspend(unsigned long srec)
|
||||
{
|
||||
struct sched_shutdown arg;
|
||||
|
||||
arg.reason = (uint32_t)SHUTDOWN_suspend;
|
||||
|
||||
return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_event_channel_op(int cmd, void *arg)
|
||||
{
|
||||
int rc;
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
rc = _hypercall2(int, event_channel_op, cmd, newArg);
|
||||
if (unlikely(rc == -ENOSYS)) {
|
||||
struct evtchn_op op;
|
||||
|
||||
op.cmd = cmd;
|
||||
memcpy(&op.u, arg, sizeof(op.u));
|
||||
rc = _hypercall1(int, event_channel_op_compat, &op);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xencomm_arch_xen_version(int cmd, struct xencomm_handle *arg)
|
||||
{
|
||||
return _hypercall2(int, xen_version, cmd, arg);
|
||||
}
|
||||
|
||||
static int
|
||||
xencomm_arch_xen_feature(int cmd, struct xencomm_handle *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, xen_version, cmd, newArg);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_xen_version(int cmd, void *arg)
|
||||
{
|
||||
switch(cmd) {
|
||||
case XENVER_version:
|
||||
return xencomm_arch_xen_version(cmd, 0);
|
||||
case XENVER_get_features:
|
||||
return xencomm_arch_xen_feature(cmd, arg);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_console_io(int cmd, int count, char *str)
|
||||
{
|
||||
struct xencomm_handle *newStr;
|
||||
|
||||
newStr = xencomm_create_inline(str);
|
||||
return _hypercall3(int, console_io, cmd, count, newStr);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_sched_op_compat(int cmd, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_compat, cmd, arg);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_sched_op(int cmd, void *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, sched_op, cmd, newArg);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_callback_op(int cmd, void *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, callback_op, cmd, newArg);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_opt_feature(void *arg)
|
||||
{
|
||||
struct xencomm_handle *new_arg;
|
||||
|
||||
new_arg = xencomm_create_inline(arg);
|
||||
|
||||
return _hypercall1(int, opt_feature, new_arg);
|
||||
}
|
||||
|
||||
int
|
||||
HYPERVISOR_shutdown(unsigned int reason)
|
||||
{
|
||||
struct sched_shutdown sched_shutdown = {
|
||||
.reason = reason
|
||||
};
|
||||
|
||||
int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
|
||||
|
||||
if (rc == -ENOSYS)
|
||||
rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,7 @@
|
||||
#define NR_RESERVED_ENTRIES 8
|
||||
|
||||
/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
|
||||
#ifdef __ia64__
|
||||
#define NR_GRANT_FRAMES 1
|
||||
#else
|
||||
#define NR_GRANT_FRAMES 4
|
||||
#endif
|
||||
#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
|
||||
|
||||
static grant_entry_t *gnttab_table;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* Copyright (c) 2002, K A Fraser
|
||||
* Copyright (c) 2005, Grzegorz Milos
|
||||
* Updates: Aravindh Puthiyaparambil <aravindh.puthiyaparambil@unisys.com>
|
||||
* Updates: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> for ia64
|
||||
*/
|
||||
|
||||
#ifndef _HYPERVISOR_H_
|
||||
@@ -19,8 +18,6 @@
|
||||
#include <hypercall-x86_32.h>
|
||||
#elif defined(__x86_64__)
|
||||
#include <hypercall-x86_64.h>
|
||||
#elif defined(__ia64__)
|
||||
#include <hypercall-ia64.h>
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
#ifndef __ARCH_LIMITS_H__
|
||||
#define __ARCH_LIMITS_H__
|
||||
|
||||
/* Commonly 16K pages are used. */
|
||||
#define __PAGE_SHIFT 14 /* 16K pages */
|
||||
#define __PAGE_SIZE (1<<(__PAGE_SHIFT))
|
||||
|
||||
#define __STACK_SIZE_PAGE_ORDER 2
|
||||
#define __STACK_SIZE (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER))
|
||||
|
||||
#endif /* __ARCH_LIMITS_H__ */
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MM_H__
|
||||
#define __ARCH_MM_H__
|
||||
|
||||
#include "page.h"
|
||||
#include "ia64_cpu.h"
|
||||
|
||||
#define PFN_PHYS(x) (pfn_to_page(x))
|
||||
#define PHYS_PFN(x) (page_to_pfn(x))
|
||||
#define to_virt(x) __va(x)
|
||||
#define to_phys(x) __pa(x)
|
||||
|
||||
#define virt_to_mfn(x) virt_to_pfn(x)
|
||||
#define virtual_to_mfn(x) (ia64_tpa((uint64_t)(x)) >> PAGE_SHIFT)
|
||||
|
||||
#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, NULL, 0)
|
||||
/* TODO */
|
||||
#define map_zero(n, a) map_frames_ex(NULL, n, 0, 0, a, DOMID_SELF, NULL, 0)
|
||||
#define do_map_zero(start, n) ASSERT(n == 0)
|
||||
|
||||
#endif /* __ARCH_MM_H__ */
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* The file contains ia64 specific scheduler declarations.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SCHED_H__
|
||||
#define __ARCH_SCHED_H__
|
||||
|
||||
#include "os.h"
|
||||
|
||||
struct thread; /* Only declaration */
|
||||
|
||||
struct thread_regs
|
||||
{
|
||||
unsigned long unat_b; /* NaT before spilling */
|
||||
unsigned long sp;
|
||||
unsigned long rp;
|
||||
unsigned long pr;
|
||||
unsigned long bsp;
|
||||
unsigned long pfs;
|
||||
unsigned long rnat;
|
||||
unsigned long lc;
|
||||
|
||||
unsigned long unat_a; /* NaT after spilling. */
|
||||
unsigned long r4;
|
||||
unsigned long r5;
|
||||
unsigned long r6;
|
||||
unsigned long r7;
|
||||
|
||||
unsigned long b1;
|
||||
unsigned long b2;
|
||||
unsigned long b3;
|
||||
unsigned long b4;
|
||||
unsigned long b5;
|
||||
|
||||
ia64_fpreg_t f2;
|
||||
ia64_fpreg_t f3;
|
||||
ia64_fpreg_t f4;
|
||||
ia64_fpreg_t f5;
|
||||
ia64_fpreg_t f16;
|
||||
ia64_fpreg_t f17;
|
||||
ia64_fpreg_t f18;
|
||||
ia64_fpreg_t f19;
|
||||
ia64_fpreg_t f20;
|
||||
ia64_fpreg_t f21;
|
||||
ia64_fpreg_t f22;
|
||||
ia64_fpreg_t f23;
|
||||
ia64_fpreg_t f24;
|
||||
ia64_fpreg_t f25;
|
||||
ia64_fpreg_t f26;
|
||||
ia64_fpreg_t f27;
|
||||
ia64_fpreg_t f28;
|
||||
ia64_fpreg_t f29;
|
||||
ia64_fpreg_t f30;
|
||||
ia64_fpreg_t f31;
|
||||
};
|
||||
|
||||
typedef struct thread_regs thread_regs_t;
|
||||
|
||||
void arch_switch_threads(struct thread* prev, struct thread* next);
|
||||
|
||||
static inline struct thread* get_current(void)
|
||||
{
|
||||
register struct thread *current asm("r13");
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __ARCH_SCHED_H__ */
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
* The file contains ia64 special spinlock stuff.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _ARCH_SPINLOCK_H_
|
||||
#define _ARCH_SPINLOCK_H_
|
||||
|
||||
#include "atomic.h"
|
||||
|
||||
#define ARCH_SPIN_LOCK_UNLOCKED { 0 }
|
||||
|
||||
#define SPIN_LOCK_UNUSED 0
|
||||
#define SPIN_LOCK_USED 1
|
||||
|
||||
|
||||
static inline void
|
||||
_raw_spin_lock(spinlock_t* lck)
|
||||
{
|
||||
uint32_t ret;
|
||||
do {
|
||||
ret = ia64_cmpxchg_acq_32(&(lck->slock),
|
||||
SPIN_LOCK_UNUSED, SPIN_LOCK_USED);
|
||||
} while (ret == SPIN_LOCK_USED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_raw_spin_unlock(spinlock_t *lck)
|
||||
{
|
||||
asm volatile ("st4.rel.nta [%0] = r0\n\t" :: "r"(&(lck->slock))
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
_raw_spin_trylock(spinlock_t* lck)
|
||||
{
|
||||
uint32_t ret;
|
||||
ret = ia64_cmpxchg_acq_32(&(lck->slock), SPIN_LOCK_USED, SPIN_LOCK_USED);
|
||||
return (ret == SPIN_LOCK_USED);
|
||||
}
|
||||
|
||||
#endif /* _ARCH_SPINLOCK_H_ */
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
*/
|
||||
|
||||
#if !defined(_ASM_H_)
|
||||
#define _ASM_H_
|
||||
|
||||
#define ENTRY(_name_) \
|
||||
.global _name_; \
|
||||
.align 16; \
|
||||
.proc _name_; \
|
||||
_name_:; \
|
||||
|
||||
|
||||
#define END(_name_) \
|
||||
.endp _name_
|
||||
|
||||
#endif /* !defined(_ASM_H_) */
|
||||
@@ -1,504 +0,0 @@
|
||||
/*
|
||||
* This code is mostly taken from FreeBSD machine/atomic.h
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (c) 1998 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_ATOMIC_H_
|
||||
#define _MACHINE_ATOMIC_H_
|
||||
|
||||
/*
|
||||
* Various simple arithmetic on memory which is atomic in the presence
|
||||
* of interrupts and SMP safe.
|
||||
*/
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
#include <mini-os/types.h>
|
||||
|
||||
|
||||
/*
|
||||
* Everything is built out of cmpxchg.
|
||||
*/
|
||||
#define IA64_CMPXCHG(sz, sem, p, cmpval, newval, ret) \
|
||||
__asm __volatile ( \
|
||||
"mov ar.ccv=%2;;\n\t" \
|
||||
"cmpxchg" #sz "." #sem " %0=%4,%3,ar.ccv\n\t" \
|
||||
: "=r" (ret), "=m" (*p) \
|
||||
: "r" (cmpval), "r" (newval), "m" (*p) \
|
||||
: "memory")
|
||||
|
||||
|
||||
/*
|
||||
* Some common forms of cmpxch.
|
||||
*/
|
||||
|
||||
static __inline uint8_t
|
||||
ia64_cmpxchg_acq_8(volatile uint8_t* p, uint8_t cmpval, uint8_t newval)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
IA64_CMPXCHG(1, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
ia64_cmpxchg_acq_16(volatile uint16_t* p, uint16_t cmpval, uint16_t newval)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
IA64_CMPXCHG(2, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
ia64_cmpxchg_acq_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
IA64_CMPXCHG(4, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
ia64_cmpxchg_rel_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
IA64_CMPXCHG(4, rel, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
ia64_cmpxchg_acq_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
IA64_CMPXCHG(8, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
ia64_cmpxchg_rel_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
IA64_CMPXCHG(8, rel, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#define ATOMIC_STORE_LOAD(type, width, size) \
|
||||
static __inline uint##width##_t \
|
||||
ia64_ld_acq_##width(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline uint##width##_t \
|
||||
atomic_load_acq_##width(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline uint##width##_t \
|
||||
atomic_load_acq_##type(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_st_rel_##width(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_store_rel_##width(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_store_rel_##type(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
}
|
||||
|
||||
ATOMIC_STORE_LOAD(char, 8, "1")
|
||||
ATOMIC_STORE_LOAD(short, 16, "2")
|
||||
ATOMIC_STORE_LOAD(int, 32, "4")
|
||||
ATOMIC_STORE_LOAD(long, 64, "8")
|
||||
|
||||
#undef ATOMIC_STORE_LOAD
|
||||
|
||||
#define IA64_ATOMIC(sz, type, name, width, op) \
|
||||
\
|
||||
static __inline type \
|
||||
atomic_##name##_acq_##width(volatile type *p, type v) \
|
||||
{ \
|
||||
type old, ret; \
|
||||
do { \
|
||||
old = *p; \
|
||||
IA64_CMPXCHG(sz, acq, p, old, old op v, ret); \
|
||||
} while (ret != old); \
|
||||
return(ret); \
|
||||
} \
|
||||
\
|
||||
static __inline type \
|
||||
atomic_##name##_rel_##width(volatile type *p, type v) \
|
||||
{ \
|
||||
type old, ret; \
|
||||
do { \
|
||||
old = *p; \
|
||||
IA64_CMPXCHG(sz, rel, p, old, old op v, ret); \
|
||||
} while (ret != old); \
|
||||
return(ret); \
|
||||
}
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, set, 8, |)
|
||||
IA64_ATOMIC(2, uint16_t, set, 16, |)
|
||||
IA64_ATOMIC(4, uint32_t, set, 32, |)
|
||||
IA64_ATOMIC(8, uint64_t, set, 64, |)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, clear, 8, &~)
|
||||
IA64_ATOMIC(2, uint16_t, clear, 16, &~)
|
||||
IA64_ATOMIC(4, uint32_t, clear, 32, &~)
|
||||
IA64_ATOMIC(8, uint64_t, clear, 64, &~)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, add, 8, +)
|
||||
IA64_ATOMIC(2, uint16_t, add, 16, +)
|
||||
IA64_ATOMIC(4, uint32_t, add, 32, +)
|
||||
IA64_ATOMIC(8, uint64_t, add, 64, +)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, subtract, 8, -)
|
||||
IA64_ATOMIC(2, uint16_t, subtract, 16, -)
|
||||
IA64_ATOMIC(4, uint32_t, subtract, 32, -)
|
||||
IA64_ATOMIC(8, uint64_t, subtract, 64, -)
|
||||
|
||||
#undef IA64_ATOMIC
|
||||
#undef IA64_CMPXCHG
|
||||
|
||||
#define atomic_set_8 atomic_set_acq_8
|
||||
#define atomic_clear_8 atomic_clear_acq_8
|
||||
#define atomic_add_8 atomic_add_acq_8
|
||||
#define atomic_subtract_8 atomic_subtract_acq_8
|
||||
|
||||
#define atomic_set_16 atomic_set_acq_16
|
||||
#define atomic_clear_16 atomic_clear_acq_16
|
||||
#define atomic_add_16 atomic_add_acq_16
|
||||
#define atomic_subtract_16 atomic_subtract_acq_16
|
||||
|
||||
#define atomic_set_32 atomic_set_acq_32
|
||||
#define atomic_clear_32 atomic_clear_acq_32
|
||||
#define atomic_add_32 atomic_add_acq_32
|
||||
#define atomic_subtract_32 atomic_subtract_acq_32
|
||||
|
||||
#define atomic_set_64 atomic_set_acq_64
|
||||
#define atomic_clear_64 atomic_clear_acq_64
|
||||
#define atomic_add_64 atomic_add_acq_64
|
||||
#define atomic_subtract_64 atomic_subtract_acq_64
|
||||
|
||||
#define atomic_set_char atomic_set_8
|
||||
#define atomic_clear_char atomic_clear_8
|
||||
#define atomic_add_char atomic_add_8
|
||||
#define atomic_subtract_char atomic_subtract_8
|
||||
#define atomic_set_acq_char atomic_set_acq_8
|
||||
#define atomic_clear_acq_char atomic_clear_acq_8
|
||||
#define atomic_add_acq_char atomic_add_acq_8
|
||||
#define atomic_subtract_acq_char atomic_subtract_acq_8
|
||||
#define atomic_set_rel_char atomic_set_rel_8
|
||||
#define atomic_clear_rel_char atomic_clear_rel_8
|
||||
#define atomic_add_rel_char atomic_add_rel_8
|
||||
#define atomic_subtract_rel_char atomic_subtract_rel_8
|
||||
|
||||
#define atomic_set_short atomic_set_16
|
||||
#define atomic_clear_short atomic_clear_16
|
||||
#define atomic_add_short atomic_add_16
|
||||
#define atomic_subtract_short atomic_subtract_16
|
||||
#define atomic_set_acq_short atomic_set_acq_16
|
||||
#define atomic_clear_acq_short atomic_clear_acq_16
|
||||
#define atomic_add_acq_short atomic_add_acq_16
|
||||
#define atomic_subtract_acq_short atomic_subtract_acq_16
|
||||
#define atomic_set_rel_short atomic_set_rel_16
|
||||
#define atomic_clear_rel_short atomic_clear_rel_16
|
||||
#define atomic_add_rel_short atomic_add_rel_16
|
||||
#define atomic_subtract_rel_short atomic_subtract_rel_16
|
||||
|
||||
#define atomic_set_int atomic_set_32
|
||||
#define atomic_clear_int atomic_clear_32
|
||||
#define atomic_add_int atomic_add_32
|
||||
#define atomic_subtract_int atomic_subtract_32
|
||||
#define atomic_set_acq_int atomic_set_acq_32
|
||||
#define atomic_clear_acq_int atomic_clear_acq_32
|
||||
#define atomic_add_acq_int atomic_add_acq_32
|
||||
#define atomic_subtract_acq_int atomic_subtract_acq_32
|
||||
#define atomic_set_rel_int atomic_set_rel_32
|
||||
#define atomic_clear_rel_int atomic_clear_rel_32
|
||||
#define atomic_add_rel_int atomic_add_rel_32
|
||||
#define atomic_subtract_rel_int atomic_subtract_rel_32
|
||||
|
||||
#define atomic_set_long atomic_set_64
|
||||
#define atomic_clear_long atomic_clear_64
|
||||
#define atomic_add_long atomic_add_64
|
||||
#define atomic_subtract_long atomic_subtract_64
|
||||
#define atomic_set_acq_long atomic_set_acq_64
|
||||
#define atomic_clear_acq_long atomic_clear_acq_64
|
||||
#define atomic_add_acq_long atomic_add_acq_64
|
||||
#define atomic_subtract_acq_long atomic_subtract_acq_64
|
||||
#define atomic_set_rel_long atomic_set_rel_64
|
||||
#define atomic_clear_rel_long atomic_clear_rel_64
|
||||
#define atomic_add_rel_long atomic_add_rel_64
|
||||
#define atomic_subtract_rel_long atomic_subtract_rel_64
|
||||
|
||||
/*
|
||||
* Atomically compare the value stored at *p with cmpval and if the
|
||||
* two values are equal, update the value of *p with newval. Returns
|
||||
* zero if the compare failed, nonzero otherwise.
|
||||
*/
|
||||
static __inline int
|
||||
atomic_cmpset_acq_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_acq_32(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_rel_32(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically compare the value stored at *p with cmpval and if the
|
||||
* two values are equal, update the value of *p with newval. Returns
|
||||
* zero if the compare failed, nonzero otherwise.
|
||||
*/
|
||||
static __inline int
|
||||
atomic_cmpset_acq_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_acq_64(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_rel_64(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
#define atomic_cmpset_32 atomic_cmpset_acq_32
|
||||
#define atomic_cmpset_64 atomic_cmpset_acq_64
|
||||
#define atomic_cmpset_int atomic_cmpset_32
|
||||
#define atomic_cmpset_long atomic_cmpset_64
|
||||
#define atomic_cmpset_acq_int atomic_cmpset_acq_32
|
||||
#define atomic_cmpset_rel_int atomic_cmpset_rel_32
|
||||
#define atomic_cmpset_acq_long atomic_cmpset_acq_64
|
||||
#define atomic_cmpset_rel_long atomic_cmpset_rel_64
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_acq_ptr(volatile void *dst, void *exp, void *src)
|
||||
{
|
||||
return atomic_cmpset_acq_long((volatile u_long *)dst,
|
||||
(u_long)exp, (u_long)src);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src)
|
||||
{
|
||||
return atomic_cmpset_rel_long((volatile u_long *)dst,
|
||||
(u_long)exp, (u_long)src);
|
||||
}
|
||||
|
||||
#define atomic_cmpset_ptr atomic_cmpset_acq_ptr
|
||||
|
||||
static __inline void *
|
||||
atomic_load_acq_ptr(volatile void *p)
|
||||
{
|
||||
return (void *)atomic_load_acq_long((volatile u_long *)p);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_store_rel_ptr(volatile void *p, void *v)
|
||||
{
|
||||
atomic_store_rel_long((volatile u_long *)p, (u_long)v);
|
||||
}
|
||||
|
||||
#define IA64_ATOMIC_PTR(NAME) \
|
||||
static __inline void \
|
||||
atomic_##NAME##_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_long((volatile u_long *)p, v); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_##NAME##_acq_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_acq_long((volatile u_long *)p, v);\
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_##NAME##_rel_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_rel_long((volatile u_long *)p, v);\
|
||||
}
|
||||
|
||||
IA64_ATOMIC_PTR(set)
|
||||
IA64_ATOMIC_PTR(clear)
|
||||
IA64_ATOMIC_PTR(add)
|
||||
IA64_ATOMIC_PTR(subtract)
|
||||
|
||||
#undef IA64_ATOMIC_PTR
|
||||
|
||||
static __inline uint32_t
|
||||
atomic_readandclear_32(volatile uint32_t* p)
|
||||
{
|
||||
uint32_t val;
|
||||
do {
|
||||
val = *p;
|
||||
} while (!atomic_cmpset_32(p, val, 0));
|
||||
return val;
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
atomic_readandclear_64(volatile uint64_t* p)
|
||||
{
|
||||
uint64_t val;
|
||||
do {
|
||||
val = *p;
|
||||
} while (!atomic_cmpset_64(p, val, 0));
|
||||
return val;
|
||||
}
|
||||
|
||||
#define atomic_readandclear_int atomic_readandclear_32
|
||||
#define atomic_readandclear_long atomic_readandclear_64
|
||||
|
||||
|
||||
/* Some bit operations */
|
||||
|
||||
static inline void
|
||||
set_bit(int num, volatile void *addr)
|
||||
{
|
||||
uint32_t bit, old, new;
|
||||
volatile uint32_t *p;
|
||||
p = (volatile uint32_t *) addr + (num >> 5);
|
||||
bit = 1 << (num & 31);
|
||||
do
|
||||
{
|
||||
old = *p;
|
||||
new = old | bit;
|
||||
} while(ia64_cmpxchg_acq_32(p, old, new) != old);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
clear_bit(int num, volatile void *addr)
|
||||
{
|
||||
uint32_t mask, old, new;
|
||||
volatile uint32_t *p;
|
||||
p = (volatile uint32_t *) addr + (num >> 5);
|
||||
mask = ~(1 << (num & 31));
|
||||
do {
|
||||
old = *p;
|
||||
new = old & mask;
|
||||
} while (ia64_cmpxchg_acq_32(p, old, new) != old);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
test_bit(int num, const volatile void *addr)
|
||||
{
|
||||
uint32_t val = 1;
|
||||
return val & (((const volatile uint32_t *) addr)[num >> 5] >> (num & 31));
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_set_bit - Set a bit and return its old value
|
||||
* num: Bit to set
|
||||
* addr: Address to count from
|
||||
*/
|
||||
static inline int
|
||||
test_and_set_bit (int num, volatile void *addr)
|
||||
{
|
||||
uint32_t bit, old, new;
|
||||
volatile uint32_t *m;
|
||||
|
||||
m = (volatile uint32_t *) addr + (num >> 5);
|
||||
bit = 1 << (num & 31);
|
||||
do {
|
||||
old = *m;
|
||||
new = old | bit;
|
||||
} while (ia64_cmpxchg_acq_32(m, old, new) != old);
|
||||
return (old & bit) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* num: Bit to set
|
||||
* addr: Address to count from
|
||||
*/
|
||||
static
|
||||
inline int test_and_clear_bit(int num, volatile unsigned long * addr)
|
||||
{
|
||||
uint32_t bit, old, new;
|
||||
volatile uint32_t* a;
|
||||
|
||||
a = (volatile uint32_t *) addr + (num >> 5);
|
||||
bit = ~(1 << (num & 31));
|
||||
do {
|
||||
old = *a;
|
||||
new = old & bit;
|
||||
} while (ia64_cmpxchg_acq_32(a, old, new) != old);
|
||||
return (old & ~bit) != 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#endif /* ! _MACHINE_ATOMIC_H_ */
|
||||
@@ -1,396 +0,0 @@
|
||||
/*
|
||||
* This is a short summary of declarations and definitions from different
|
||||
* efi header files of Intels' EFI_Toolkit_1.10.14.62
|
||||
* used for the minimal implementation in mini-os.
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (C) 2001-2004, Intel Corporation.
|
||||
* THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO WARRANTIES WHATSOEVER,
|
||||
* INCLUDING ANY WARRANTY OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR
|
||||
* ANY PARTICULAR PURPOSE, OR ANY WARRANTY OTHERWISE ARISING OUT OF ANY
|
||||
* PROPOSAL, SPECIFICATION OR SAMPLE. Except for a limited copyright license
|
||||
* to copy this specification for internal use only, no license, express or
|
||||
* implied, by estoppel or otherwise, to any intellectual property rights is
|
||||
* granted herein. Intel disclaims all liability, including liability for
|
||||
* infringement of any proprietary rights, relating to implementation of
|
||||
* information in this specification. Intel does not warrant or represent
|
||||
* that such implementation(s) will not infringe such rights. Designers must
|
||||
* not rely on the absence or characteristics of any features or instructions
|
||||
* marked "reserved" or "undefined." Intel reserves these for future
|
||||
* definition and shall have no responsibility whatsoever for conflicts or
|
||||
* incompatibilities arising from future changes to them.
|
||||
* This document is an intermediate draft for comment only and is subject to
|
||||
* change without notice. Readers should not design products based on this
|
||||
* document.
|
||||
* Intel, the Intel logo, and Itanium are trademarks or registered trademarks
|
||||
* of Intel Corporation or its subsidiaries in the United States and other
|
||||
* countries.
|
||||
* Other names and brands may be claimed as the property of others.
|
||||
*/
|
||||
|
||||
#ifndef _EFI_H_
|
||||
#define _EFI_H_
|
||||
|
||||
#include <mini-os/types.h>
|
||||
|
||||
|
||||
#define EFIWARN(a) (a)
|
||||
#define EFI_ERROR(a) (((int64_t) a) < 0)
|
||||
|
||||
|
||||
#define EFI_SUCCESS 0
|
||||
#define EFI_LOAD_ERROR EFIERR(1)
|
||||
#define EFI_INVALID_PARAMETER EFIERR(2)
|
||||
#define EFI_UNSUPPORTED EFIERR(3)
|
||||
#define EFI_BAD_BUFFER_SIZE EFIERR(4)
|
||||
#define EFI_BUFFER_TOO_SMALL EFIERR(5)
|
||||
#define EFI_NOT_READY EFIERR(6)
|
||||
#define EFI_DEVICE_ERROR EFIERR(7)
|
||||
#define EFI_WRITE_PROTECTED EFIERR(8)
|
||||
#define EFI_OUT_OF_RESOURCES EFIERR(9)
|
||||
#define EFI_VOLUME_CORRUPTED EFIERR(10)
|
||||
#define EFI_VOLUME_FULL EFIERR(11)
|
||||
#define EFI_NO_MEDIA EFIERR(12)
|
||||
#define EFI_MEDIA_CHANGED EFIERR(13)
|
||||
#define EFI_NOT_FOUND EFIERR(14)
|
||||
#define EFI_ACCESS_DENIED EFIERR(15)
|
||||
#define EFI_NO_RESPONSE EFIERR(16)
|
||||
#define EFI_NO_MAPPING EFIERR(17)
|
||||
#define EFI_TIMEOUT EFIERR(18)
|
||||
#define EFI_NOT_STARTED EFIERR(19)
|
||||
#define EFI_ALREADY_STARTED EFIERR(20)
|
||||
#define EFI_ABORTED EFIERR(21)
|
||||
#define EFI_ICMP_ERROR EFIERR(22)
|
||||
#define EFI_TFTP_ERROR EFIERR(23)
|
||||
#define EFI_PROTOCOL_ERROR EFIERR(24)
|
||||
|
||||
#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1)
|
||||
#define EFI_WARN_DELETE_FAILURE EFIWARN(2)
|
||||
#define EFI_WARN_WRITE_FAILURE EFIWARN(3)
|
||||
#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4)
|
||||
|
||||
|
||||
typedef uint64_t efi_status_t;
|
||||
typedef void* efi_handle_t;
|
||||
typedef void* efi_event_t;
|
||||
typedef uint16_t efi_char16_t;
|
||||
|
||||
|
||||
/*
|
||||
* Standard EFI table header
|
||||
*/
|
||||
|
||||
struct efi_table_header
|
||||
{
|
||||
uint64_t Signature;
|
||||
// Revision of EFI table specification,
|
||||
// upper 16 bit - major revision number
|
||||
// lower 16 bit - minor revision number
|
||||
uint32_t Revision;
|
||||
uint32_t HeaderSize;
|
||||
uint32_t CRC32;
|
||||
uint32_t Reserved;
|
||||
};
|
||||
typedef struct efi_table_header efi_table_header_t;
|
||||
|
||||
/*
|
||||
* EFI Time
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Year; /* 1998 - 20XX */
|
||||
uint8_t Month; /* 1 - 12 */
|
||||
uint8_t Day; /* 1 - 31 */
|
||||
uint8_t Hour; /* 0 - 23 */
|
||||
uint8_t Minute; /* 0 - 59 */
|
||||
uint8_t Second; /* 0 - 59 */
|
||||
uint8_t Pad1;
|
||||
uint32_t Nanosecond; /* 0 - 999,999,999 */
|
||||
int16_t TimeZone; /* -1440 to 1440 or 2047 */
|
||||
uint8_t Daylight;
|
||||
uint8_t Pad2;
|
||||
} efi_time_t;
|
||||
|
||||
/* Bit definitions for efi_time_t.Daylight */
|
||||
#define EFI_TIME_ADJUST_DAYLIGHT 0x01
|
||||
#define EFI_TIME_IN_DAYLIGHT 0x02
|
||||
|
||||
/* Value definition for efi_time_t.TimeZone */
|
||||
#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Resolution; /* 1e-6 parts per million */
|
||||
uint32_t Accuracy; /* hertz */
|
||||
uint8_t SetsToZero; /* Set clears sub-second time */
|
||||
} efi_time_capabilities_t;
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_get_time_t) (efi_time_t*, efi_time_capabilities_t*);
|
||||
typedef efi_status_t (*efi_set_time_t) (efi_time_t*);
|
||||
typedef efi_status_t (*efi_get_wakeup_time_t) (uint8_t*, uint8_t*, efi_time_t*);
|
||||
typedef efi_status_t (*efi_set_wakeup_time_t) (uint8_t, efi_time_t*);
|
||||
|
||||
/*
|
||||
* Memory
|
||||
* Preseve the attr on any range supplied.
|
||||
* ConventialMemory must have WB,SR,SW when supplied.
|
||||
* When allocating from ConventialMemory always make it WB,SR,SW
|
||||
* When returning to ConventialMemory always make it WB,SR,SW
|
||||
* When getting the memory map, or on RT for runtime types
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
EfiReservedMemoryType, /* 0 */
|
||||
EfiLoaderCode,
|
||||
EfiLoaderData,
|
||||
EfiBootServicesCode,
|
||||
EfiBootServicesData,
|
||||
EfiRuntimeServicesCode,
|
||||
EfiRuntimeServicesData, /* 6 */
|
||||
EfiConventionalMemory, /* 7 */
|
||||
EfiUnusableMemory,
|
||||
EfiACPIReclaimMemory, /* 9 */
|
||||
EfiACPIMemoryNVS, /* 10, a */
|
||||
EfiMemoryMappedIO,
|
||||
EfiMemoryMappedIOPortSpace, /* 12, c */
|
||||
EfiPalCode, /* 13, d */
|
||||
EfiMaxMemoryType /* 14, e */
|
||||
} efi_memory_type_t;
|
||||
|
||||
/* possible caching types for the memory range */
|
||||
#define EFI_MEMORY_UC 0x0000000000000001
|
||||
#define EFI_MEMORY_WC 0x0000000000000002
|
||||
#define EFI_MEMORY_WT 0x0000000000000004
|
||||
#define EFI_MEMORY_WB 0x0000000000000008
|
||||
#define EFI_MEMORY_UCE 0x0000000000000010
|
||||
/* physical memory protection on range */
|
||||
#define EFI_MEMORY_WP 0x0000000000001000
|
||||
#define EFI_MEMORY_RP 0x0000000000002000
|
||||
#define EFI_MEMORY_XP 0x0000000000004000
|
||||
/* range requires a runtime mapping */
|
||||
#define EFI_MEMORY_RUNTIME 0x8000000000000000
|
||||
|
||||
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
|
||||
|
||||
typedef uint64_t efi_phys_addr_t;
|
||||
typedef uint64_t efi_virt_addr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Type; /* 32 bit padding */
|
||||
efi_phys_addr_t PhysicalStart;
|
||||
efi_virt_addr_t VirtualStart;
|
||||
uint64_t NumberOfPages;
|
||||
uint64_t Attribute;
|
||||
} efi_memory_descriptor_t;
|
||||
|
||||
#define NextMemoryDescriptor(Ptr,Size) ((efi_memory_descriptor_t*) (((uint8_t*) Ptr) + Size))
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_set_virtual_address_map_t)
|
||||
(
|
||||
uint64_t MemoryMapSize,
|
||||
uint64_t DescriptorSize,
|
||||
uint32_t DescriptorVersion,
|
||||
efi_memory_descriptor_t* VirtualMap
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_convert_pointer_t)
|
||||
(
|
||||
uint64_t DebugDisposition,
|
||||
void** Address
|
||||
);
|
||||
|
||||
/*
|
||||
* A GUID
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Data1;
|
||||
uint16_t Data2;
|
||||
uint16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
} efi_guid_t;
|
||||
|
||||
/*
|
||||
* EFI Configuration Table and GUID definitions
|
||||
*/
|
||||
|
||||
#define MPS_TABLE_GUID \
|
||||
{ 0xeb9d2d2f, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define ACPI_TABLE_GUID \
|
||||
{ 0xeb9d2d30, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define ACPI_20_TABLE_GUID \
|
||||
{ 0x8868e871, 0xe4f1, 0x11d3, \
|
||||
{ 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
|
||||
|
||||
#define SMBIOS_TABLE_GUID \
|
||||
{ 0xeb9d2d31, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define SAL_SYSTEM_TABLE_GUID \
|
||||
{ 0xeb9d2d32, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
/* DIG64 Headless Console & Debug Port Table. */
|
||||
#define HCDP_TABLE_GUID \
|
||||
{0xf951938d, 0x620b, 0x42ef, \
|
||||
{0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } }
|
||||
|
||||
|
||||
typedef struct efi_configuration_table
|
||||
{
|
||||
efi_guid_t VendorGuid;
|
||||
void* VendorTable;
|
||||
} efi_configuration_table_t;
|
||||
|
||||
|
||||
/*
|
||||
* EFI platform variables
|
||||
*/
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
{ 0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, \
|
||||
0xE0, 0x98, 0x03, 0x2B, 0x8C }
|
||||
|
||||
/* Variable attributes */
|
||||
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
|
||||
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
|
||||
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
|
||||
|
||||
/* Variable size limitation */
|
||||
#define EFI_MAXIMUM_VARIABLE_SIZE 1024
|
||||
|
||||
typedef efi_status_t (*efi_get_variable_t)
|
||||
(
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t *VendorGuid,
|
||||
uint32_t* Attributes,
|
||||
uint64_t* DataSize,
|
||||
void* Data
|
||||
);
|
||||
|
||||
typedef
|
||||
efi_status_t (*efi_get_next_variable_name_t)
|
||||
(
|
||||
uint64_t* VariableNameSize,
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t* VendorGuid
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_set_variable_t)
|
||||
(
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t* VendorGuid,
|
||||
uint32_t Attributes,
|
||||
uint64_t DataSize,
|
||||
void* Data
|
||||
);
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EfiResetCold,
|
||||
EfiResetWarm,
|
||||
EfiResetShutdown
|
||||
} efi_reset_type_t;
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_reset_system_t)
|
||||
(
|
||||
efi_reset_type_t ResetType,
|
||||
efi_status_t ResetStatus,
|
||||
uint64_t DataSize,
|
||||
efi_char16_t* ResetData
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_get_next_high_mono_count_t) (uint32_t* HighCount);
|
||||
|
||||
|
||||
/*
|
||||
* EFI Runtime Serivces Table
|
||||
*/
|
||||
|
||||
#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552ULL
|
||||
#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) \
|
||||
| (EFI_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
efi_table_header_t Hdr;
|
||||
/* Time services */
|
||||
efi_get_time_t GetTime;
|
||||
efi_set_time_t SetTime;
|
||||
efi_get_wakeup_time_t GetWakeupTime;
|
||||
efi_set_wakeup_time_t SetWakeupTime;
|
||||
/* Virtual memory services */
|
||||
efi_set_virtual_address_map_t SetVirtualAddressMap;
|
||||
efi_convert_pointer_t ConvertPointer;
|
||||
/* Variable serviers */
|
||||
efi_get_variable_t GetVariable;
|
||||
efi_get_next_variable_name_t GetNextVariableName;
|
||||
efi_set_variable_t SetVariable;
|
||||
/* Misc */
|
||||
efi_get_next_high_mono_count_t GetNextHighMonotonicCount;
|
||||
efi_reset_system_t ResetSystem;
|
||||
|
||||
} efi_runtime_services_t;
|
||||
|
||||
|
||||
#define EFI_SPECIFICATION_MAJOR_REVISION 1
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
|
||||
#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) \
|
||||
| (EFI_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
struct efi_system_table
|
||||
{
|
||||
efi_table_header_t Hdr;
|
||||
|
||||
uint64_t FirmwareVendor; // phys addr of CHAR16
|
||||
uint32_t FirmwareRevision; // Firmware vendor specific
|
||||
|
||||
efi_handle_t ConsoleInHandle;
|
||||
uint64_t ConIn;
|
||||
|
||||
efi_handle_t ConsoleOutHandle;
|
||||
uint64_t ConOut;
|
||||
|
||||
efi_handle_t StandardErrorHandle;
|
||||
uint64_t StdErr;
|
||||
|
||||
uint64_t RuntimeServices; // phys addr
|
||||
uint64_t BootServices; // phys addr
|
||||
|
||||
uint64_t NumberOfTableEntries; // Number of entries in Config
|
||||
uint64_t ConfigurationTable; // phys addr of ConfigTable
|
||||
};
|
||||
|
||||
typedef struct efi_system_table efi_system_table_t;
|
||||
|
||||
|
||||
#define EFI_PAGE_SIZE 4096
|
||||
#define EFI_PAGE_MASK 0xFFF
|
||||
#define EFI_PAGE_SHIFT 12
|
||||
|
||||
#define EFI_SIZE_TO_PAGES(a) \
|
||||
( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) )
|
||||
|
||||
|
||||
void init_efi(void);
|
||||
int efi_get_time(efi_time_t* tmP);
|
||||
efi_status_t ia64_call_efi_physical(void *, ...);
|
||||
|
||||
|
||||
#endif /* _EFI_H_ */
|
||||
@@ -1,135 +0,0 @@
|
||||
/******************************************************************************
|
||||
* hypercall.h
|
||||
*
|
||||
* Mini-OS-specific hypervisor handling for ia64.
|
||||
*
|
||||
* Copyright (c) 2002-2004, K A Fraser
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujiti-siemens.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; or, when distributed
|
||||
* separately from the Linux kernel or incorporated into other
|
||||
* software packages, subject to the following license:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this source file (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __HYPERCALL_H__
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include <xen/event_channel.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/version.h>
|
||||
|
||||
#ifndef _HYPERVISOR_H_
|
||||
# error "please don't include this file directly"
|
||||
#endif
|
||||
|
||||
// See linux/compiler.h
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4,
|
||||
unsigned long a5, unsigned long cmd);
|
||||
/*
|
||||
* Assembler stubs for hyper-calls.
|
||||
*/
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall(0, 0, 0, 0, 0, \
|
||||
__HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall1(type, name, a1) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
0, 0, 0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall2(type, name, a1, a2) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
0, 0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall3(type, name, a1, a2, a3) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall4(type, name, a1, a2, a3, a4) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
(unsigned long)a4, \
|
||||
0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
(unsigned long)a4, \
|
||||
(unsigned long)a5, \
|
||||
__HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
|
||||
int HYPERVISOR_event_channel_op(int cmd, void *arg);
|
||||
|
||||
int HYPERVISOR_xen_version(int cmd, void *arg);
|
||||
|
||||
int HYPERVISOR_console_io(int cmd, int count, char *str);
|
||||
|
||||
int HYPERVISOR_sched_op_compat(int cmd, unsigned long arg);
|
||||
|
||||
int HYPERVISOR_sched_op(int cmd, void *arg);
|
||||
|
||||
int HYPERVISOR_callback_op(int cmd, void *arg);
|
||||
|
||||
int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
|
||||
|
||||
int HYPERVISOR_opt_feature(void *arg);
|
||||
|
||||
int HYPERVISOR_suspend(unsigned long srec);
|
||||
|
||||
int HYPERVISOR_shutdown(unsigned int reason);
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
@@ -1,738 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* This code is mostly taken from FreeBSD.
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (c) 2000 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IA64_CPU_H_
|
||||
#define _IA64_CPU_H_
|
||||
|
||||
#include "ia64_fpu.h"
|
||||
|
||||
/*
|
||||
* Definition of Region Register bits (RR)
|
||||
*
|
||||
* RR bit field positions
|
||||
*/
|
||||
#define IA64_RR_VE 0
|
||||
#define IA64_RR_MBZ0 1
|
||||
#define IA64_RR_PS 2
|
||||
#define IA64_RR_PS_LEN 6
|
||||
#define IA64_RR_RID 8
|
||||
#define IA64_RR_RID_LEN 24
|
||||
#define IA64_RR_MBZ1 32
|
||||
|
||||
#define IA64_RR_IDX_POS 61
|
||||
|
||||
#define IA64_RR_VAL(size,rid) (((size) << IA64_RR_PS) | ((rid) << IA64_RR_RID))
|
||||
|
||||
/*
|
||||
* Define Protection Key Register (PKR)
|
||||
*
|
||||
* PKR bit field positions
|
||||
*/
|
||||
#define IA64_PKR_V 0
|
||||
#define IA64_PKR_WD 1
|
||||
#define IA64_PKR_RD 2
|
||||
#define IA64_PKR_XD 3
|
||||
#define IA64_PKR_MBZ0 4
|
||||
#define IA64_PKR_KEY 8
|
||||
#define IA64_PKR_KEY_LEN 24
|
||||
#define IA64_PKR_MBZ1 32
|
||||
|
||||
#define IA64_PKR_VALID (1 << IA64_PKR_V)
|
||||
|
||||
|
||||
/*
|
||||
* ITIR bit field positions
|
||||
*/
|
||||
|
||||
#define IA64_ITIR_MBZ0 0
|
||||
#define IA64_ITIR_PS 2
|
||||
#define IA64_ITIR_PS_LEN 6
|
||||
#define IA64_ITIR_KEY 8
|
||||
#define IA64_ITIR_KEY_LEN 24
|
||||
#define IA64_ITIR_MBZ1 32
|
||||
#define IA64_ITIR_MBZ1_LEN 16
|
||||
#define IA64_ITIR_PPN 48
|
||||
#define IA64_ITIR_PPN_LEN 15
|
||||
#define IA64_ITIR_MBZ2 63
|
||||
|
||||
/*
|
||||
* Definition of PSR and IPSR bits.
|
||||
*/
|
||||
#define IA64_PSR_BE 0x0000000000000002
|
||||
#define IA64_PSR_UP 0x0000000000000004
|
||||
#define IA64_PSR_AC 0x0000000000000008
|
||||
#define IA64_PSR_MFL 0x0000000000000010
|
||||
#define IA64_PSR_MFH_BIT 5
|
||||
#define IA64_PSR_MFH (1 << IA64_PSR_MFH_BIT)
|
||||
#define IA64_PSR_UMASK (IA64_PSR_BE | IA64_PSR_UP | \
|
||||
IA64_PSR_AC | IA64_PSR_MFL | \
|
||||
IA64_PSR_MFH)
|
||||
#define IA64_PSR_IC_BIT 13
|
||||
#define IA64_PSR_IC (1<<IA64_PSR_IC_BIT) /*0x0000000000002000*/
|
||||
#define IA64_PSR_I_BIT 14
|
||||
#define IA64_PSR_I (1<<IA64_PSR_I_BIT) /*0x0000000000004000*/
|
||||
#define IA64_PSR_PK 0x0000000000008000
|
||||
#define IA64_PSR_DT 0x0000000000020000
|
||||
#define IA64_PSR_DFL 0x0000000000040000
|
||||
#define IA64_PSR_DFH 0x0000000000080000
|
||||
#define IA64_PSR_SP 0x0000000000100000
|
||||
#define IA64_PSR_PP 0x0000000000200000
|
||||
#define IA64_PSR_DI 0x0000000000400000
|
||||
#define IA64_PSR_SI 0x0000000000800000
|
||||
#define IA64_PSR_DB 0x0000000001000000
|
||||
#define IA64_PSR_LP 0x0000000002000000
|
||||
#define IA64_PSR_TB 0x0000000004000000
|
||||
#define IA64_PSR_RT 0x0000000008000000
|
||||
#define IA64_PSR_CPL 0x0000000300000000
|
||||
#define IA64_PSR_CPL_KERN 0x0000000000000000
|
||||
#define IA64_PSR_CPL_1 0x0000000100000000
|
||||
#define IA64_PSR_CPL_2 0x0000000200000000
|
||||
#define IA64_PSR_CPL_USER 0x0000000300000000
|
||||
#define IA64_PSR_IS 0x0000000400000000
|
||||
#define IA64_PSR_MC 0x0000000800000000
|
||||
#define IA64_PSR_IT 0x0000001000000000
|
||||
#define IA64_PSR_ID 0x0000002000000000
|
||||
#define IA64_PSR_DA 0x0000004000000000
|
||||
#define IA64_PSR_DD 0x0000008000000000
|
||||
#define IA64_PSR_SS 0x0000010000000000
|
||||
#define IA64_PSR_RI 0x0000060000000000
|
||||
#define IA64_PSR_RI_0 0x0000000000000000
|
||||
#define IA64_PSR_RI_1 0x0000020000000000
|
||||
#define IA64_PSR_RI_2 0x0000040000000000
|
||||
#define IA64_PSR_RI_SHIFT 41
|
||||
#define IA64_PSR_ED 0x0000080000000000
|
||||
#define IA64_PSR_BN 0x0000100000000000
|
||||
#define IA64_PSR_IA 0x0000200000000000
|
||||
|
||||
|
||||
#define STARTUP_PSR (IA64_PSR_IT | IA64_PSR_PK | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_KERN | IA64_PSR_AC)
|
||||
|
||||
#define MOS_SYS_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_KERN | IA64_PSR_AC)
|
||||
|
||||
#define MOS_USR_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_USER | IA64_PSR_AC)
|
||||
|
||||
/*
|
||||
* Definition of ISR bits.
|
||||
*/
|
||||
#define IA64_ISR_CODE 0x000000000000ffff
|
||||
#define IA64_ISR_VECTOR 0x0000000000ff0000
|
||||
#define IA64_ISR_X 0x0000000100000000
|
||||
#define IA64_ISR_W 0x0000000200000000
|
||||
#define IA64_ISR_R 0x0000000400000000
|
||||
#define IA64_ISR_NA 0x0000000800000000
|
||||
#define IA64_ISR_SP 0x0000001000000000
|
||||
#define IA64_ISR_RS 0x0000002000000000
|
||||
#define IA64_ISR_IR 0x0000004000000000
|
||||
#define IA64_ISR_NI 0x0000008000000000
|
||||
#define IA64_ISR_SO 0x0000010000000000
|
||||
#define IA64_ISR_EI 0x0000060000000000
|
||||
#define IA64_ISR_EI_0 0x0000000000000000
|
||||
#define IA64_ISR_EI_1 0x0000020000000000
|
||||
#define IA64_ISR_EI_2 0x0000040000000000
|
||||
#define IA64_ISR_ED 0x0000080000000000
|
||||
|
||||
/*
|
||||
* DCR bit positions
|
||||
*/
|
||||
#define IA64_DCR_PP 0
|
||||
#define IA64_DCR_BE 1
|
||||
#define IA64_DCR_LC 2
|
||||
#define IA64_DCR_MBZ0 4
|
||||
#define IA64_DCR_MBZ0_V 0xf
|
||||
#define IA64_DCR_DM 8
|
||||
#define IA64_DCR_DP 9
|
||||
#define IA64_DCR_DK 10
|
||||
#define IA64_DCR_DX 11
|
||||
#define IA64_DCR_DR 12
|
||||
#define IA64_DCR_DA 13
|
||||
#define IA64_DCR_DD 14
|
||||
#define IA64_DCR_DEFER_ALL 0x7f00
|
||||
#define IA64_DCR_MBZ1 2
|
||||
#define IA64_DCR_MBZ1_V 0xffffffffffffULL
|
||||
|
||||
|
||||
#define IA64_DCR_DEFAULT (IA64_DCR_BE)
|
||||
|
||||
/*
|
||||
* Vector numbers for various ia64 interrupts.
|
||||
*/
|
||||
#define IA64_VEC_VHPT 0
|
||||
#define IA64_VEC_ITLB 1
|
||||
#define IA64_VEC_DTLB 2
|
||||
#define IA64_VEC_ALT_ITLB 3
|
||||
#define IA64_VEC_ALT_DTLB 4
|
||||
#define IA64_VEC_NESTED_DTLB 5
|
||||
#define IA64_VEC_IKEY_MISS 6
|
||||
#define IA64_VEC_DKEY_MISS 7
|
||||
#define IA64_VEC_DIRTY_BIT 8
|
||||
#define IA64_VEC_INST_ACCESS 9
|
||||
#define IA64_VEC_DATA_ACCESS 10
|
||||
#define IA64_VEC_BREAK 11
|
||||
#define IA64_VEC_EXT_INTR 12
|
||||
#define IA64_VEC_PAGE_NOT_PRESENT 20
|
||||
#define IA64_VEC_KEY_PERMISSION 21
|
||||
#define IA64_VEC_INST_ACCESS_RIGHTS 22
|
||||
#define IA64_VEC_DATA_ACCESS_RIGHTS 23
|
||||
#define IA64_VEC_GENERAL_EXCEPTION 24
|
||||
#define IA64_VEC_DISABLED_FP 25
|
||||
#define IA64_VEC_NAT_CONSUMPTION 26
|
||||
#define IA64_VEC_SPECULATION 27
|
||||
#define IA64_VEC_DEBUG 29
|
||||
#define IA64_VEC_UNALIGNED_REFERENCE 30
|
||||
#define IA64_VEC_UNSUPP_DATA_REFERENCE 31
|
||||
#define IA64_VEC_FLOATING_POINT_FAULT 32
|
||||
#define IA64_VEC_FLOATING_POINT_TRAP 33
|
||||
#define IA64_VEC_LOWER_PRIVILEGE_TRANSFER 34
|
||||
#define IA64_VEC_TAKEN_BRANCH_TRAP 35
|
||||
#define IA64_VEC_SINGLE_STEP_TRAP 36
|
||||
#define IA64_VEC_IA32_EXCEPTION 45
|
||||
#define IA64_VEC_IA32_INTERCEPT 46
|
||||
#define IA64_VEC_IA32_INTERRUPT 47
|
||||
|
||||
/*
|
||||
* Define hardware RSE Configuration Register
|
||||
*
|
||||
* RS Configuration (RSC) bit field positions
|
||||
*/
|
||||
|
||||
#define IA64_RSC_MODE 0
|
||||
#define IA64_RSC_PL 2
|
||||
#define IA64_RSC_BE 4
|
||||
#define IA64_RSC_MBZ0 5
|
||||
#define IA64_RSC_MBZ0_V 0x3ff
|
||||
#define IA64_RSC_LOADRS 16
|
||||
#define IA64_RSC_LOADRS_LEN 14
|
||||
#define IA64_RSC_MBZ1 30
|
||||
#define IA64_RSC_MBZ1_V 0x3ffffffffULL
|
||||
|
||||
/*
|
||||
* RSC modes
|
||||
*/
|
||||
#define IA64_RSC_MODE_LY (0x0) /* Lazy */
|
||||
#define IA64_RSC_MODE_SI (0x1) /* Store intensive */
|
||||
#define IA64_RSC_MODE_LI (0x2) /* Load intensive */
|
||||
#define IA64_RSC_MODE_EA (0x3) /* Eager */
|
||||
|
||||
#define IA64_RSE_EAGER (IA64_RSC_MODE_EA<<IA64_RSC_MODE)
|
||||
#define IA64_RSE_LAZY (IA64_RSC_MODE_LY<<IA64_RSC_MODE)
|
||||
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* ia64 function descriptor and global pointer */
|
||||
struct ia64_fdesc
|
||||
{
|
||||
uint64_t func;
|
||||
uint64_t gp;
|
||||
};
|
||||
typedef struct ia64_fdesc ia64_fdesc_t;
|
||||
|
||||
#define FDESC_FUNC(fn) (((struct ia64_fdesc *) fn)->func)
|
||||
#define FDESC_GP(fn) (((struct ia64_fdesc *) fn)->gp)
|
||||
|
||||
|
||||
/*
|
||||
* Various special ia64 instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory Fence.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_mf(void)
|
||||
{
|
||||
__asm __volatile("mf" ::: "memory");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_mf_a(void)
|
||||
{
|
||||
__asm __volatile("mf.a");
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush Cache.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_fc(uint64_t va)
|
||||
{
|
||||
__asm __volatile("fc %0" :: "r"(va));
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync instruction stream.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_sync_i(void)
|
||||
{
|
||||
__asm __volatile("sync.i");
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate address in VHPT for va.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_thash(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("thash %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate VHPT tag for va.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_ttag(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("ttag %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert virtual address to physical.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_tpa(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("tpa %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.e instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_e(uint64_t v)
|
||||
{
|
||||
__asm __volatile("ptc.e %0;; srlz.d;;" :: "r"(v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.g instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_g(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.g %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.ga instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_ga(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.ga %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.l instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_l(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.l %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the value of psr.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_psr(void)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("mov %0=psr;;" : "=r" (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_set_psr(uint64_t v)
|
||||
{
|
||||
__asm __volatile("mov psr.l=%0" :: "r" (v));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_srlz_d(void)
|
||||
{
|
||||
__asm __volatile("srlz.d;;");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
disable_intr(void)
|
||||
{
|
||||
__asm __volatile ("rsm psr.ic|psr.i");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
enable_intr(void)
|
||||
{
|
||||
__asm __volatile ("ssm psr.ic|psr.i");
|
||||
}
|
||||
|
||||
/*
|
||||
* Define accessors for application registers.
|
||||
*/
|
||||
|
||||
#define IA64_AR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile(";;mov %0=ar." #name ";;" : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov ar." #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_AR(k0)
|
||||
IA64_AR(k1)
|
||||
IA64_AR(k2)
|
||||
IA64_AR(k3)
|
||||
IA64_AR(k4)
|
||||
IA64_AR(k5)
|
||||
IA64_AR(k6)
|
||||
IA64_AR(k7)
|
||||
|
||||
IA64_AR(rsc)
|
||||
IA64_AR(bsp)
|
||||
IA64_AR(bspstore)
|
||||
IA64_AR(rnat)
|
||||
|
||||
IA64_AR(fcr)
|
||||
|
||||
IA64_AR(eflag)
|
||||
IA64_AR(csd)
|
||||
IA64_AR(ssd)
|
||||
IA64_AR(cflg)
|
||||
IA64_AR(fsr)
|
||||
IA64_AR(fir)
|
||||
IA64_AR(fdr)
|
||||
|
||||
IA64_AR(ccv)
|
||||
|
||||
IA64_AR(unat)
|
||||
|
||||
IA64_AR(fpsr)
|
||||
|
||||
IA64_AR(itc)
|
||||
|
||||
IA64_AR(pfs)
|
||||
IA64_AR(lc)
|
||||
IA64_AR(ec)
|
||||
|
||||
/*
|
||||
* Define accessors for control registers.
|
||||
*/
|
||||
|
||||
#define IA64_CR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile("mov %0=cr." #name : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov cr." #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_CR(dcr)
|
||||
IA64_CR(itm)
|
||||
IA64_CR(iva)
|
||||
|
||||
IA64_CR(pta)
|
||||
|
||||
IA64_CR(ipsr)
|
||||
IA64_CR(isr)
|
||||
|
||||
IA64_CR(iip)
|
||||
IA64_CR(ifa)
|
||||
IA64_CR(itir)
|
||||
IA64_CR(iipa)
|
||||
IA64_CR(ifs)
|
||||
IA64_CR(iim)
|
||||
IA64_CR(iha)
|
||||
|
||||
IA64_CR(lid)
|
||||
IA64_CR(ivr)
|
||||
IA64_CR(tpr)
|
||||
IA64_CR(eoi)
|
||||
IA64_CR(irr0)
|
||||
IA64_CR(irr1)
|
||||
IA64_CR(irr2)
|
||||
IA64_CR(irr3)
|
||||
IA64_CR(itv)
|
||||
IA64_CR(pmv)
|
||||
IA64_CR(cmcv)
|
||||
|
||||
IA64_CR(lrr0)
|
||||
IA64_CR(lrr1)
|
||||
|
||||
#define IA64_GR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile("mov %0=" #name : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov " #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_GR(sp)
|
||||
IA64_GR(b0)
|
||||
IA64_GR(r13) // tp
|
||||
|
||||
|
||||
/*
|
||||
* Write a region register.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_set_rr(uint64_t rrbase, uint64_t v)
|
||||
{
|
||||
__asm __volatile("mov rr[%0]=%1;; srlz.d;;"
|
||||
:: "r"(rrbase), "r"(v) : "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a region register.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_rr(uint64_t rrbase)
|
||||
{
|
||||
uint64_t v;
|
||||
__asm __volatile("mov %1=rr[%0];;"
|
||||
: "=r" (v) : "r"(rrbase) : "memory");
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a CPUID register.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_cpuid(int i)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("mov %0=cpuid[%1]"
|
||||
: "=r" (result) : "r"(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct trap_frame
|
||||
{
|
||||
uint64_t rsc;
|
||||
uint64_t ndirty; /* number of dirty regs */
|
||||
uint64_t ssd;
|
||||
uint64_t iip; /* interrupted ip */
|
||||
uint64_t ipsr; /* interrupted psr */
|
||||
uint64_t ifs; /* interruption func status register */
|
||||
|
||||
uint16_t trap_num; /* Trap num, index in trap_vec */
|
||||
uint64_t cfm; /* current frame marker */
|
||||
uint64_t pfs; /* previous function state ar64 */
|
||||
uint64_t bsp; /* backing store pointer ar17 */
|
||||
uint64_t rnat; /* rse nat collection ar19 */
|
||||
uint64_t csd; /* comp and store data reg ar25 */
|
||||
uint64_t ccv; /* comp and xchange val reg ar32 */
|
||||
uint64_t unat; /* */
|
||||
uint64_t fpsr; /* floating point state reg ar40 */
|
||||
uint64_t pr; /* predicate regs 0-63 */
|
||||
|
||||
uint64_t gp; /* the gp pointer */
|
||||
uint64_t sp; /* stack pointer */
|
||||
uint64_t tp; /* thread pointer */
|
||||
|
||||
uint64_t r2; /* global reg 2 */
|
||||
uint64_t r3;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
uint64_t r16;
|
||||
uint64_t r17;
|
||||
uint64_t r18;
|
||||
uint64_t r19;
|
||||
uint64_t r20;
|
||||
uint64_t r21;
|
||||
uint64_t r22;
|
||||
uint64_t r23;
|
||||
uint64_t r24;
|
||||
uint64_t r25;
|
||||
uint64_t r26;
|
||||
uint64_t r27;
|
||||
uint64_t r28;
|
||||
uint64_t r29;
|
||||
uint64_t r30;
|
||||
uint64_t r31;
|
||||
|
||||
uint64_t b0;
|
||||
uint64_t b6;
|
||||
uint64_t b7;
|
||||
|
||||
ia64_fpreg_t f6; /* floating point register 6 */
|
||||
ia64_fpreg_t f7;
|
||||
ia64_fpreg_t f8;
|
||||
ia64_fpreg_t f9;
|
||||
ia64_fpreg_t f10;
|
||||
ia64_fpreg_t f11;
|
||||
|
||||
uint64_t ifa; /* interruption faulting address */
|
||||
uint64_t isr; /* interruption status register */
|
||||
uint64_t iim; /* interruption immediate register */
|
||||
};
|
||||
|
||||
typedef struct trap_frame trap_frame_t;
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Page access parameters. */
|
||||
#define PTE_P_SHIFT 0
|
||||
#define PTE_P 1
|
||||
|
||||
#define PTE_MA_SHIFT 2
|
||||
#define PTE_MA_WB 0
|
||||
|
||||
#define PTE_A_SHIFT 5
|
||||
#define PTE_A 1
|
||||
#define PTE_D_SHIFT 6
|
||||
#define PTE_D 1
|
||||
|
||||
#define PTE_AR_SHIFT 9
|
||||
#define PTE_AR_R 0
|
||||
#define PTE_AR_RX 1
|
||||
#define PTE_AR_RW 2
|
||||
#define PTE_AR_RWX 3
|
||||
#define PTE_AR_R_RW 4
|
||||
#define PTE_AR_RX_RWX 5
|
||||
#define PTE_AR_RWX_RW 6
|
||||
/* privilege level */
|
||||
#define PTE_PL_SHIFT 7
|
||||
#define PTE_PL_KERN 0 /* used for kernel */
|
||||
/* page size */
|
||||
#define PTE_PS_4K 12
|
||||
#define PTE_PS_8K 13
|
||||
#define PTE_PS_16K 14
|
||||
#define PTE_PS_64K 16
|
||||
#define PTE_PS_256K 18
|
||||
#define PTE_PS_1M 20
|
||||
#define PTE_PS_4M 22
|
||||
#define PTE_PS_16M 24
|
||||
#define PTE_PS_64M 26
|
||||
#define PTE_PS_256M 28
|
||||
|
||||
|
||||
/* Some offsets for ia64_pte_t. */
|
||||
#define PTE_OFF_P 0
|
||||
#define PTE_OFF_MA 3
|
||||
#define PTE_OFF_A 5
|
||||
#define PTE_OFF_D 6
|
||||
#define PTE_OFF_PL 7
|
||||
#define PTE_OFF_AR 9
|
||||
#define PTE_OFF_PPN 12
|
||||
#define PTE_OFF_ED 52
|
||||
|
||||
#if !defined(_ASM) && !defined(__ASSEMBLY__)
|
||||
/*
|
||||
* A short-format VHPT entry. Also matches the TLB insertion format.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t pte_p :1; /* bits 0..0 */
|
||||
uint64_t pte_rv1:1; /* bits 1..1 */
|
||||
uint64_t pte_ma :3; /* bits 2..4 */
|
||||
uint64_t pte_a :1; /* bits 5..5 */
|
||||
uint64_t pte_d :1; /* bits 6..6 */
|
||||
uint64_t pte_pl :2; /* bits 7..8 */
|
||||
uint64_t pte_ar :3; /* bits 9..11 */
|
||||
uint64_t pte_ppn:38; /* bits 12..49 */
|
||||
uint64_t pte_rv2:2; /* bits 50..51 */
|
||||
uint64_t pte_ed :1; /* bits 52..52 */
|
||||
uint64_t pte_ig :11; /* bits 53..63 */
|
||||
} ia64_pte_t;
|
||||
|
||||
|
||||
/*
|
||||
* A long-format VHPT entry.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t pte_p :1; /* bits 0..0 */
|
||||
uint64_t pte_rv1 :1; /* bits 1..1 */
|
||||
uint64_t pte_ma :3; /* bits 2..4 */
|
||||
uint64_t pte_a :1; /* bits 5..5 */
|
||||
uint64_t pte_d :1; /* bits 6..6 */
|
||||
uint64_t pte_pl :2; /* bits 7..8 */
|
||||
uint64_t pte_ar :3; /* bits 9..11 */
|
||||
uint64_t pte_ppn :38; /* bits 12..49 */
|
||||
uint64_t pte_rv2 :2; /* bits 50..51 */
|
||||
uint64_t pte_ed :1; /* bits 52..52 */
|
||||
uint64_t pte_ig :11; /* bits 53..63 */
|
||||
uint64_t pte_rv3 :2; /* bits 0..1 */
|
||||
uint64_t pte_ps :6; /* bits 2..7 */
|
||||
uint64_t pte_key :24; /* bits 8..31 */
|
||||
uint64_t pte_rv4 :32; /* bits 32..63 */
|
||||
uint64_t pte_tag; /* includes ti */
|
||||
uint64_t pte_chain; /* pa of collision chain */
|
||||
} ia64_lpte_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _IA64_CPU_H_ */
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* This code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IA64_FPU_H_
|
||||
#define _IA64_FPU_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
* Floating point status register bits.
|
||||
*/
|
||||
#define IA64_FPSR_TRAP_VD UL_CONST(0x0000000000000001)
|
||||
#define IA64_FPSR_TRAP_DD UL_CONST(0x0000000000000002)
|
||||
#define IA64_FPSR_TRAP_ZD UL_CONST(0x0000000000000004)
|
||||
#define IA64_FPSR_TRAP_OD UL_CONST(0x0000000000000008)
|
||||
#define IA64_FPSR_TRAP_UD UL_CONST(0x0000000000000010)
|
||||
#define IA64_FPSR_TRAP_ID UL_CONST(0x0000000000000020)
|
||||
#define IA64_FPSR_SF(i,v) ((v) << ((i)*13+6))
|
||||
|
||||
#define IA64_SF_FTZ UL_CONST(0x0001)
|
||||
#define IA64_SF_WRE UL_CONST(0x0002)
|
||||
#define IA64_SF_PC UL_CONST(0x000c)
|
||||
#define IA64_SF_PC_0 UL_CONST(0x0000)
|
||||
#define IA64_SF_PC_1 UL_CONST(0x0004)
|
||||
#define IA64_SF_PC_2 UL_CONST(0x0008)
|
||||
#define IA64_SF_PC_3 UL_CONST(0x000c)
|
||||
#define IA64_SF_RC UL_CONST(0x0030)
|
||||
#define IA64_SF_RC_NEAREST UL_CONST(0x0000)
|
||||
#define IA64_SF_RC_NEGINF UL_CONST(0x0010)
|
||||
#define IA64_SF_RC_POSINF UL_CONST(0x0020)
|
||||
#define IA64_SF_RC_TRUNC UL_CONST(0x0030)
|
||||
#define IA64_SF_TD UL_CONST(0x0040)
|
||||
#define IA64_SF_V UL_CONST(0x0080)
|
||||
#define IA64_SF_D UL_CONST(0x0100)
|
||||
#define IA64_SF_Z UL_CONST(0x0200)
|
||||
#define IA64_SF_O UL_CONST(0x0400)
|
||||
#define IA64_SF_U UL_CONST(0x0800)
|
||||
#define IA64_SF_I UL_CONST(0x1000)
|
||||
|
||||
#define IA64_SF_DEFAULT (IA64_SF_PC_3 | IA64_SF_RC_NEAREST)
|
||||
|
||||
#define IA64_FPSR_DEFAULT (IA64_FPSR_TRAP_VD \
|
||||
| IA64_FPSR_TRAP_DD \
|
||||
| IA64_FPSR_TRAP_ZD \
|
||||
| IA64_FPSR_TRAP_OD \
|
||||
| IA64_FPSR_TRAP_UD \
|
||||
| IA64_FPSR_TRAP_ID \
|
||||
| IA64_FPSR_SF(0, IA64_SF_DEFAULT) \
|
||||
| IA64_FPSR_SF(1, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD \
|
||||
| IA64_SF_WRE)) \
|
||||
| IA64_FPSR_SF(2, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD)) \
|
||||
| IA64_FPSR_SF(3, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD)))
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This is from sys/cdefs.h in FreeBSD */
|
||||
#define __aligned(x) __attribute__((__aligned__(x)))
|
||||
|
||||
/* A single Floating Point register. */
|
||||
struct ia64_fpreg
|
||||
{
|
||||
uint8_t fpr_bits[16];
|
||||
} __aligned(16);
|
||||
|
||||
typedef struct ia64_fpreg ia64_fpreg_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _IA64_FPU_H_ */
|
||||
@@ -1,295 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__OS_H__)
|
||||
#define __OS_H__
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
#include <mini-os/types.h>
|
||||
#include "ia64_cpu.h"
|
||||
#include "atomic.h"
|
||||
#include "efi.h"
|
||||
#include "sal.h"
|
||||
#include "pal.h"
|
||||
#include <mini-os/hypervisor.h>
|
||||
#include <mini-os/kernel.h>
|
||||
|
||||
|
||||
typedef uint64_t paddr_t; /* Physical address. */
|
||||
#ifndef HAVE_LIBC
|
||||
typedef uint64_t caddr_t; /* rr7/kernel memory address. */
|
||||
#endif
|
||||
|
||||
#include "page.h"
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
void arch_init(start_info_t *si); /* in common.c */
|
||||
void arch_print_info(void); /* in common.c */
|
||||
void arch_fini(void);
|
||||
|
||||
|
||||
/* Size of xen_ia64_boot_param.command_line */
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
|
||||
extern struct xen_ia64_boot_param* ia64_boot_paramP;
|
||||
extern struct xen_ia64_boot_param ia64BootParamG;
|
||||
extern char boot_cmd_line[];
|
||||
extern efi_system_table_t* efiSysTableP;
|
||||
extern int bootverbose;
|
||||
|
||||
extern void ia64_probe_sapics(void);
|
||||
|
||||
|
||||
|
||||
/* Contains the needed stuff from efi. */
|
||||
struct efi
|
||||
{
|
||||
|
||||
efi_system_table_t* efiSysTableP;
|
||||
efi_set_virtual_address_map_t setVirtAddrMapF;
|
||||
efi_get_time_t getTimeF;
|
||||
efi_reset_system_t resetSystemF;
|
||||
|
||||
};
|
||||
|
||||
struct machine_fw
|
||||
{
|
||||
struct efi efi;
|
||||
|
||||
uint64_t ia64_port_base; /* physical address */
|
||||
uint64_t ia64_pal_base; /* virtual rr7 address */
|
||||
|
||||
sal_system_table_t* ia64_sal_tableP;
|
||||
sal_entry_t* ia64_sal_entryP; /* SAL_PROC entrypoint */
|
||||
|
||||
uint64_t ia64_efi_acpi_table; /* physical address */
|
||||
uint64_t ia64_efi_acpi20_table; /* physical address */
|
||||
|
||||
uint64_t mach_mem_start; /* phys start addr of machine memory */
|
||||
uint64_t mach_mem_size; /* size of machine memory */
|
||||
|
||||
uint64_t kernstart; /* virt address of kern text start */
|
||||
uint64_t kernend;
|
||||
uint64_t kernpstart; /* phys address of kern text start */
|
||||
uint64_t kernpend;
|
||||
};
|
||||
|
||||
extern struct machine_fw machineFwG;
|
||||
|
||||
#define ia64_sal_entry machineFwG.ia64_sal_entryP
|
||||
|
||||
#define smp_processor_id() 0
|
||||
|
||||
static inline uint64_t
|
||||
xchg8(uint64_t* ptr, uint64_t x) \
|
||||
{
|
||||
uint64_t oldVal;
|
||||
asm volatile ("xchg8 %0=[%1],%2" : "=r" (oldVal)
|
||||
: "r" (ptr), "r" (x) : "memory");
|
||||
return oldVal;
|
||||
}
|
||||
#define xchg xchg8
|
||||
|
||||
// Counts the number of 1-bits in x.
|
||||
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
# define get_popcnt(x) __builtin_popcountl(x)
|
||||
#else
|
||||
# define get_popcnt(x) \
|
||||
({ \
|
||||
uint64_t num; \
|
||||
asm ("popcnt %0=%1" : "=r" (num) : "r" (x)); \
|
||||
num; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __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 = get_popcnt((x-1) & ~x);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
synch_clear_bit(int num, volatile void *addr)
|
||||
{
|
||||
clear_bit(num, addr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
synch_set_bit(int num, volatile void *addr)
|
||||
{
|
||||
set_bit(num, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
synch_test_bit(int nr, const volatile void *addr)
|
||||
{
|
||||
return test_bit(nr, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
synch_test_and_set_bit(int num, volatile void * addr)
|
||||
{
|
||||
return test_and_set_bit(num, addr);
|
||||
}
|
||||
|
||||
|
||||
#define synch_cmpxchg(ptr, old, new) \
|
||||
((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
|
||||
(unsigned long)(old), \
|
||||
(unsigned long)(new), \
|
||||
sizeof(*(ptr))))
|
||||
|
||||
static inline unsigned long
|
||||
__synch_cmpxchg(volatile void *ptr, uint64_t old, uint64_t new, int size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return ia64_cmpxchg_acq_8(ptr, old, new);
|
||||
case 2:
|
||||
return ia64_cmpxchg_acq_16(ptr, old, new);
|
||||
case 4:
|
||||
return ia64_cmpxchg_acq_32(ptr, old, new);
|
||||
case 8:
|
||||
return ia64_cmpxchg_acq_64(ptr, old, new);
|
||||
}
|
||||
return ia64_cmpxchg_acq_64(ptr, old, new);
|
||||
}
|
||||
|
||||
extern shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
|
||||
/*
|
||||
* This code is from the originally os.h and should be put in a
|
||||
* common header file!
|
||||
*/
|
||||
|
||||
/*
|
||||
* The use of 'barrier' in the following reflects their use as local-lock
|
||||
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
|
||||
* critical operations are executed. All critical operations must complete
|
||||
* /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
|
||||
* includes these barriers, for example.
|
||||
*/
|
||||
|
||||
#define __cli() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = 1; \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define __sti() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = 0; \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if (unlikely(_vcpu->evtchn_upcall_pending)) \
|
||||
force_evtchn_callback(); \
|
||||
} while (0)
|
||||
|
||||
#define __save_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = _vcpu->evtchn_upcall_mask; \
|
||||
} while (0)
|
||||
|
||||
#define __restore_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
|
||||
force_evtchn_callback(); \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define safe_halt() ((void)0)
|
||||
|
||||
#define __save_and_cli(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = _vcpu->evtchn_upcall_mask; \
|
||||
_vcpu->evtchn_upcall_mask = 1; \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_save(x) __save_and_cli(x)
|
||||
#define local_irq_restore(x) __restore_flags(x)
|
||||
#define local_save_flags(x) __save_flags(x)
|
||||
#define local_irq_disable() __cli()
|
||||
#define local_irq_enable() __sti()
|
||||
|
||||
#define irqs_disabled() \
|
||||
(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].evtchn_upcall_mask)
|
||||
|
||||
/* This is a barrier for the compiler only, NOT the processor! */
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#define mb() ia64_mf()
|
||||
#define rmb() mb()
|
||||
#define wmb() mb()
|
||||
|
||||
|
||||
#define BUG() \
|
||||
{ printk("mini-os BUG at %s:%d!\n", __FILE__, __LINE__); do_exit(); }
|
||||
|
||||
#define PRINT_BV(_fmt, _params...) \
|
||||
if (bootverbose) \
|
||||
printk(_fmt , ## _params)
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#if defined(__ASSEMBLY__)
|
||||
|
||||
#define UL_CONST(x) x
|
||||
#define UL_TYPE(x) x
|
||||
|
||||
#else /* defined(__ASSEMBLY__) */
|
||||
|
||||
#define UL_CONST(x) x##UL
|
||||
#define UL_TYPE(x) ((uint64_t)x)
|
||||
|
||||
#endif /* defined(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !defined(__OS_H__) */
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Common stuff for memory and page handling.
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(_PAGE_H_)
|
||||
#define _PAGE_H_
|
||||
|
||||
#include "os.h"
|
||||
#include "ia64_cpu.h"
|
||||
|
||||
#define PTE_KERNEL_ATTR ((PTE_P<<PTE_P_SHIFT) |\
|
||||
(PTE_MA_WB<<PTE_MA_SHIFT) |\
|
||||
(PTE_D<<PTE_D_SHIFT) |\
|
||||
(PTE_A<<PTE_A_SHIFT) |\
|
||||
(PTE_PL_KERN<<PTE_PL_SHIFT) |\
|
||||
(PTE_AR_RWX<<PTE_AR_SHIFT))
|
||||
|
||||
|
||||
/* The kernel tr page size for text and data. */
|
||||
#define KERNEL_TR_PAGE_SIZE PTE_PS_1M
|
||||
/* The efi-pal page size for text and data. */
|
||||
#define PAL_TR_PAGE_SIZE PTE_PS_1M
|
||||
|
||||
#include "arch_limits.h"
|
||||
#define PAGE_SHIFT __PAGE_SHIFT
|
||||
#define PAGE_SIZE __PAGE_SIZE
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#define KSTACK_PAGES 4 /* 4 pages for the kernel stack + bsp */
|
||||
|
||||
#define IA64_TR_KERNEL 0 /* itr0, dtr0: maps kernel image (code) */
|
||||
#define IA64_TR_PAL 1 /* itr1: maps pal code */
|
||||
|
||||
/*
|
||||
* Manipulating region bits of an address.
|
||||
*/
|
||||
#define IA64_RR_BASE(n) ((UL_TYPE(n)) << 61)
|
||||
#define IA64_RR_MASK(x) ((UL_TYPE(x)) & ((1L << 61) - 1))
|
||||
#define IA64_RR_EXTR(x) ((x) >> 61)
|
||||
|
||||
#define IA64_PHYS_TO_RR5(x) ((x) | IA64_RR_BASE(5))
|
||||
#define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7))
|
||||
|
||||
#define __pa(x) IA64_RR_MASK(x)
|
||||
#define __va(x) IA64_PHYS_TO_RR7(x)
|
||||
|
||||
#define roundup_page(x) ((((unsigned long)(x)) + PAGE_SIZE -1) & PAGE_MASK)
|
||||
#define trunc_page(x) ((unsigned long)(x) & PAGE_MASK)
|
||||
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
/* Contains the parts of the physically memory. */
|
||||
extern paddr_t phys_avail[];
|
||||
|
||||
#define page_to_pfn(page) ((uint64_t)(page) >> PAGE_SHIFT)
|
||||
#define pfn_to_page(pfn) ((uint64_t)pfn << PAGE_SHIFT)
|
||||
/* Get phyiscal address of page of virtual address. */
|
||||
#define virt_to_page(addr) ((uint64_t)__pa(addr) & PAGE_MASK)
|
||||
#define virt_to_pfn(addr) (page_to_pfn(virt_to_page(addr)))
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
||||
/* For both see minios-ia64.lds. */
|
||||
/* This is where the kernel virtually starts. */
|
||||
#define KERNEL_START IA64_PHYS_TO_RR5(0x100000000)
|
||||
/* !!!!!
|
||||
* For physical start of kernel
|
||||
* Currently used in arch/ia64/fw.S.
|
||||
* !!!!!
|
||||
*/
|
||||
#define KERNEL_PHYS_START_SHIFT 20
|
||||
|
||||
/* A region 5 address to physical address */
|
||||
#define KERN_VIRT_2_PHYS(x) (((x) - KERNEL_START) + \
|
||||
(1 << KERNEL_PHYS_START_SHIFT))
|
||||
|
||||
/* Some protection keys for region 5 and 7 addresses. */
|
||||
#define IA64_KEY_REG7 0x234 /* Region 7 - identity mapped addresses */
|
||||
#define IA64_KEY_REG5 0x89a /* Region 5 - kernel addresses */
|
||||
|
||||
// This is xen specific !
|
||||
#define PAGE_SHIFT_XEN_16K 14 // For 16KB page size
|
||||
#define mfn_to_virt(mfn) ((void*)__va((mfn) << PAGE_SHIFT_XEN_16K))
|
||||
|
||||
#endif /* !defined(_PAGE_H_) */
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* The code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PAL_H_
|
||||
#define _PAL_H_
|
||||
|
||||
/*
|
||||
* Architected static calling convention procedures.
|
||||
*/
|
||||
#define PAL_CACHE_FLUSH 1
|
||||
#define PAL_CACHE_INFO 2
|
||||
#define PAL_CACHE_INIT 3
|
||||
#define PAL_CACHE_SUMMARY 4
|
||||
#define PAL_MEM_ATTRIB 5
|
||||
#define PAL_PTCE_INFO 6
|
||||
#define PAL_VM_INFO 7
|
||||
#define PAL_VM_SUMMARY 8
|
||||
#define PAL_BUS_GET_FEATURES 9
|
||||
#define PAL_BUS_SET_FEATURES 10
|
||||
#define PAL_DEBUG_INFO 11
|
||||
#define PAL_FIXED_ADDR 12
|
||||
#define PAL_FREQ_BASE 13
|
||||
#define PAL_FREQ_RATIOS 14
|
||||
#define PAL_PERF_MON_INFO 15
|
||||
#define PAL_PLATFORM_ADDR 16
|
||||
#define PAL_PROC_GET_FEATURE 17
|
||||
#define PAL_PROC_SET_FEATURE 18
|
||||
#define PAL_RSE_INFO 19
|
||||
#define PAL_VERSION 20
|
||||
#define PAL_MC_CLEAR_LOG 21
|
||||
#define PAL_MC_DRAIN 22
|
||||
#define PAL_MC_DYNAMIC_STATE 24
|
||||
#define PAL_MC_ERROR_INFO 25
|
||||
#define PAL_MC_EXPECTED 23
|
||||
#define PAL_MC_REGISTER_MEM 27
|
||||
#define PAL_MC_RESUME 26
|
||||
#define PAL_HALT 28
|
||||
#define PAL_HALT_LIGHT 29
|
||||
#define PAL_COPY_INFO 30
|
||||
#define PAL_CACHE_LINE_INIT 31
|
||||
#define PAL_PMI_ENTRYPOINT 32
|
||||
#define PAL_ENTER_IA_32_ENV 33
|
||||
#define PAL_VM_PAGE_SIZE 34
|
||||
#define PAL_MEM_FOR_TEST 37
|
||||
#define PAL_CACHE_PROT_INFO 38
|
||||
#define PAL_REGISTER_INFO 39
|
||||
#define PAL_SHUTDOWN 40
|
||||
#define PAL_PREFETCH_VISIBILITY 41
|
||||
|
||||
|
||||
struct ia64_pal_result
|
||||
{
|
||||
int64_t pal_status;
|
||||
uint64_t pal_result[3];
|
||||
};
|
||||
|
||||
extern struct ia64_pal_result
|
||||
ia64_call_pal_static(uint64_t proc, uint64_t arg1,
|
||||
uint64_t arg2, uint64_t arg3);
|
||||
|
||||
#endif /* _PAL_H_ */
|
||||
@@ -1,97 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Hewlett-Packard Co
|
||||
* Dan Magenheimer <dan.magenheimer@hp.com>
|
||||
*
|
||||
* Paravirtualizations of privileged operations for Xen/ia64
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PRIVOP_H_
|
||||
#define _PRIVOP_H_
|
||||
|
||||
#include <xen/arch-ia64.h>
|
||||
|
||||
#define IA64_PARAVIRTUALIZED
|
||||
|
||||
/* At 1 MB, before per-cpu space but still addressable using addl instead
|
||||
of movl. */
|
||||
#define XSI_BASE 0xfffffffffff00000
|
||||
|
||||
/* Address of mapped regs. */
|
||||
#define XMAPPEDREGS_BASE (XSI_BASE + XSI_SIZE)
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define XEN_HYPER_RFI break HYPERPRIVOP_RFI
|
||||
#define XEN_HYPER_RSM_PSR_DT break HYPERPRIVOP_RSM_DT
|
||||
#define XEN_HYPER_SSM_PSR_DT break HYPERPRIVOP_SSM_DT
|
||||
#define XEN_HYPER_COVER break HYPERPRIVOP_COVER
|
||||
#define XEN_HYPER_ITC_D break HYPERPRIVOP_ITC_D
|
||||
#define XEN_HYPER_ITC_I break HYPERPRIVOP_ITC_I
|
||||
#define XEN_HYPER_SSM_I break HYPERPRIVOP_SSM_I
|
||||
#define XEN_HYPER_GET_IVR break HYPERPRIVOP_GET_IVR
|
||||
#define XEN_HYPER_GET_TPR break HYPERPRIVOP_GET_TPR
|
||||
#define XEN_HYPER_SET_TPR break HYPERPRIVOP_SET_TPR
|
||||
#define XEN_HYPER_EOI break HYPERPRIVOP_EOI
|
||||
#define XEN_HYPER_SET_ITM break HYPERPRIVOP_SET_ITM
|
||||
#define XEN_HYPER_THASH break HYPERPRIVOP_THASH
|
||||
#define XEN_HYPER_PTC_GA break HYPERPRIVOP_PTC_GA
|
||||
#define XEN_HYPER_ITR_D break HYPERPRIVOP_ITR_D
|
||||
#define XEN_HYPER_GET_RR break HYPERPRIVOP_GET_RR
|
||||
#define XEN_HYPER_SET_RR break HYPERPRIVOP_SET_RR
|
||||
#define XEN_HYPER_SET_KR break HYPERPRIVOP_SET_KR
|
||||
#define XEN_HYPER_FC break HYPERPRIVOP_FC
|
||||
#define XEN_HYPER_GET_CPUID break HYPERPRIVOP_GET_CPUID
|
||||
#define XEN_HYPER_GET_PMD break HYPERPRIVOP_GET_PMD
|
||||
#define XEN_HYPER_GET_EFLAG break HYPERPRIVOP_GET_EFLAG
|
||||
#define XEN_HYPER_SET_EFLAG break HYPERPRIVOP_SET_EFLAG
|
||||
#define XEN_HYPER_RSM_BE break HYPERPRIVOP_RSM_BE
|
||||
#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR
|
||||
|
||||
#define XSI_IFS (XSI_BASE + XSI_IFS_OFS)
|
||||
#define XSI_PRECOVER_IFS (XSI_BASE + XSI_PRECOVER_IFS_OFS)
|
||||
#define XSI_INCOMPL_REGFR (XSI_BASE + XSI_INCOMPL_REGFR_OFS)
|
||||
#define XSI_IFA (XSI_BASE + XSI_IFA_OFS)
|
||||
#define XSI_ISR (XSI_BASE + XSI_ISR_OFS)
|
||||
#define XSI_IIM (XSI_BASE + XSI_IIM_OFS)
|
||||
#define XSI_ITIR (XSI_BASE + XSI_ITIR_OFS)
|
||||
#define XSI_PSR_I_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS)
|
||||
#define XSI_PSR_IC (XSI_BASE + XSI_PSR_IC_OFS)
|
||||
#define XSI_IPSR (XSI_BASE + XSI_IPSR_OFS)
|
||||
#define XSI_IIP (XSI_BASE + XSI_IIP_OFS)
|
||||
#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS)
|
||||
#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS)
|
||||
#define XSI_IHA (XSI_BASE + XSI_IHA_OFS)
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define XEN_HYPER_SSM_I asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
|
||||
#define XEN_HYPER_GET_IVR asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
|
||||
|
||||
/************************************************/
|
||||
/* Instructions paravirtualized for performance */
|
||||
/************************************************/
|
||||
|
||||
/* Xen uses memory-mapped virtual privileged registers for access to many
|
||||
* performance-sensitive privileged registers. Some, like the processor
|
||||
* status register (psr), are broken up into multiple memory locations.
|
||||
* Others, like "pend", are abstractions based on privileged registers.
|
||||
* "Pend" is guaranteed to be set if reading cr.ivr would return a
|
||||
* (non-spurious) interrupt. */
|
||||
#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
|
||||
#define XSI_PSR_I \
|
||||
(*XEN_MAPPEDREGS->interrupt_mask_addr)
|
||||
#define xen_get_virtual_psr_i() \
|
||||
(!XSI_PSR_I)
|
||||
#define xen_set_virtual_psr_i(_val) \
|
||||
({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
|
||||
#define xen_get_virtual_psr_ic() \
|
||||
( XEN_MAPPEDREGS->interrupt_collection_enabled )
|
||||
#define xen_set_virtual_psr_ic(_val) \
|
||||
({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
|
||||
#define xen_get_virtual_pend() (XEN_MAPPEDREGS->pending_interruption)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _PRIVOP_H_ */
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* The code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The SAL System Table starts with a header which is described in
|
||||
* sal_system_table_t.
|
||||
* Table header will be followed by a variable number of variable length
|
||||
* entries. The first byte of each entry will identify the entry type and
|
||||
* the entries shall be in ascending order by the entry type. Each entry
|
||||
* type will have a known fixed length. The total length of this table
|
||||
* depends upon the configuration of the system. Operating system software
|
||||
* must step through each entry until it reaches the ENTRY_COUNT. The entries
|
||||
* are sorted on entry type in ascending order.
|
||||
* Unless otherwise stated, there is one entry per entry type.
|
||||
*/
|
||||
|
||||
#ifndef _SAL_H_
|
||||
#define _SAL_H_
|
||||
|
||||
typedef uint64_t u_int64_t;
|
||||
typedef uint32_t u_int32_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
typedef uint8_t u_int8_t;
|
||||
|
||||
struct sal_system_table {
|
||||
char sal_signature[4];
|
||||
#define SAL_SIGNATURE "SST_"
|
||||
uint32_t sal_length;
|
||||
uint8_t sal_rev[2]; /* Byte 8 - Minor, Byte 0 - Major */
|
||||
uint16_t sal_entry_count; // num entries in var part
|
||||
uint8_t sal_checksum;
|
||||
uint8_t sal_reserved1[7];
|
||||
uint8_t sal_a_version[2]; // like sal_rev
|
||||
uint8_t sal_b_version[2]; // like sal_rev
|
||||
char sal_oem_id[32]; // Ascii - manufacturer of HW
|
||||
char sal_product_id[32]; // ascii - identification
|
||||
uint8_t sal_reserved2[8];
|
||||
};
|
||||
|
||||
typedef struct sal_system_table sal_system_table_t;
|
||||
|
||||
#define SAL_DESC_ENTRYPOINT 0
|
||||
#define SAL_DESC_ENTRYPOINT_LENGTH 48
|
||||
#define SAL_DESC_MEMORY 1
|
||||
#define SAL_DESC_MEMORY_LENGTH 32
|
||||
#define SAL_DESC_PLATFORM 2
|
||||
#define SAL_DESC_PLATFORM_LENGT 16
|
||||
#define SAL_DESC_TR_REG 3
|
||||
#define SAL_DESC_TR_REG_LENGTH 32
|
||||
#define SAL_DESC_PURGE_TR_CACHE 4
|
||||
#define SAL_DESC_PURGE_TR_CACHE_LENGTH 16
|
||||
#define SAL_DESC_AP_WAKEUP 5
|
||||
#define SAL_DESC_AP_WAKEUP_LENGTH 16
|
||||
|
||||
|
||||
struct sal_entrypoint_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 0 */
|
||||
uint8_t sale_reserved1[7];
|
||||
uint64_t sale_pal_proc; /* PAL_PROC entry point */
|
||||
uint64_t sale_sal_proc; /* SAL_PROC entry point */
|
||||
uint64_t sale_sal_gp; /* gp for SAL_PROC, PAL_PROC */
|
||||
uint8_t sale_reserved2[16];
|
||||
};
|
||||
|
||||
struct sal_memory_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 1 */
|
||||
uint8_t sale_need_virtual;
|
||||
uint8_t sale_current_attribute;
|
||||
uint8_t sale_access_rights;
|
||||
uint8_t sale_supported_attributes;
|
||||
uint8_t sale_reserved1;
|
||||
uint8_t sale_memory_type[2];
|
||||
uint64_t sale_physical_address;
|
||||
uint32_t sale_length;
|
||||
uint8_t sale_reserved2[12];
|
||||
};
|
||||
|
||||
struct sal_platform_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 2 */
|
||||
uint8_t sale_features;
|
||||
uint8_t sale_reserved[14];
|
||||
};
|
||||
|
||||
struct sal_tr_descriptor
|
||||
{
|
||||
u_int8_t sale_type; /* == 3 */
|
||||
u_int8_t sale_register_type;
|
||||
u_int8_t sale_register_number;
|
||||
u_int8_t sale_reserved1[5];
|
||||
u_int64_t sale_virtual_address;
|
||||
u_int64_t sale_page_size;
|
||||
u_int8_t sale_reserved2[8];
|
||||
};
|
||||
|
||||
struct sal_ptc_cache_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 4 */
|
||||
uint8_t sale_reserved[3];
|
||||
uint32_t sale_domains;
|
||||
uint64_t sale_address;
|
||||
};
|
||||
|
||||
struct sal_ap_wakeup_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 5 */
|
||||
uint8_t sale_mechanism;
|
||||
uint8_t sale_reserved[6];
|
||||
uint64_t sale_vector;
|
||||
};
|
||||
|
||||
/*
|
||||
* SAL Procedure numbers.
|
||||
*/
|
||||
|
||||
#define SAL_SET_VECTORS 0x01000000
|
||||
#define SAL_GET_STATE_INFO 0x01000001
|
||||
#define SAL_GET_STATE_INFO_SIZE 0x01000002
|
||||
#define SAL_CLEAR_STATE_INFO 0x01000003
|
||||
#define SAL_MC_RENDEZ 0x01000004
|
||||
#define SAL_MC_SET_PARAMS 0x01000005
|
||||
#define SAL_REGISTER_PHYSICAL_ADDR 0x01000006
|
||||
#define SAL_CACHE_FLUSH 0x01000008
|
||||
#define SAL_CACHE_INIT 0x01000009
|
||||
#define SAL_PCI_CONFIG_READ 0x01000010
|
||||
#define SAL_PCI_CONFIG_WRITE 0x01000011
|
||||
#define SAL_FREQ_BASE 0x01000012
|
||||
#define SAL_UPDATE_PAL 0x01000020
|
||||
|
||||
/* SAL_SET_VECTORS event handler types */
|
||||
#define SAL_OS_MCA 0
|
||||
#define SAL_OS_INIT 1
|
||||
#define SAL_OS_BOOT_RENDEZ 2
|
||||
|
||||
/* SAL_GET_STATE_INFO, SAL_GET_STATE_INFO_SIZE types */
|
||||
#define SAL_INFO_MCA 0
|
||||
#define SAL_INFO_INIT 1
|
||||
#define SAL_INFO_CMC 2
|
||||
#define SAL_INFO_CPE 3
|
||||
#define SAL_INFO_TYPES 4 /* number of types we know about */
|
||||
|
||||
struct ia64_sal_result
|
||||
{
|
||||
int64_t sal_status;
|
||||
uint64_t sal_result[3];
|
||||
};
|
||||
typedef struct ia64_sal_result ia64_sal_result_t;
|
||||
|
||||
typedef ia64_sal_result_t sal_entry_t
|
||||
( uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t, uint64_t, uint64_t
|
||||
);
|
||||
|
||||
extern ia64_sal_result_t ia64_sal_call(uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
|
||||
extern void ia64_sal_init(sal_system_table_t *saltab);
|
||||
|
||||
#endif /* _SAL_H_ */
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(_TRAPS_H_)
|
||||
#define _TRAPS_H_
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
/* See ia64_cpu.h */
|
||||
struct trap_frame;
|
||||
|
||||
#define pt_regs trap_frame
|
||||
|
||||
/*
|
||||
* A dummy function, which is currently not supported.
|
||||
*/
|
||||
inline static void trap_init(void)
|
||||
{
|
||||
//printk("trap_init() until now not needed!\n");
|
||||
}
|
||||
inline static void trap_fini(void)
|
||||
{
|
||||
//printk("trap_fini() until now not needed!\n");
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#include "ia64_cpu.h"
|
||||
|
||||
void stack_walk(void);
|
||||
|
||||
#endif /* !defined(_TRAPS_H_) */
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <xen/arch-x86_32.h>
|
||||
#elif defined(__x86_64__)
|
||||
#include <xen/arch-x86_64.h>
|
||||
#elif defined(__ia64__)
|
||||
#include <xen/arch-ia64.h>
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define SHRT_MAX 0x7fff
|
||||
#define USHRT_MAX 0xffff
|
||||
|
||||
#if defined(__x86_64__) || defined(__ia64__)
|
||||
#if defined(__x86_64__)
|
||||
# define LONG_MAX 0x7fffffffffffffffL
|
||||
# define ULONG_MAX 0xffffffffffffffffUL
|
||||
#else
|
||||
|
||||
@@ -12,13 +12,9 @@ struct thread
|
||||
{
|
||||
char *name;
|
||||
char *stack;
|
||||
#if !defined(__ia64__)
|
||||
/* keep in that order */
|
||||
unsigned long sp; /* Stack pointer */
|
||||
unsigned long ip; /* Instruction pointer */
|
||||
#else /* !defined(__ia64__) */
|
||||
thread_regs_t regs;
|
||||
#endif /* !defined(__ia64__) */
|
||||
MINIOS_TAILQ_ENTRY(struct thread) thread_list;
|
||||
uint32_t flags;
|
||||
s_time_t wakeup_time;
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef unsigned long long u_quad_t;
|
||||
|
||||
typedef struct { unsigned long pte_low, pte_high; } pte_t;
|
||||
|
||||
#elif defined(__x86_64__) || defined(__ia64__)
|
||||
#elif defined(__x86_64__)
|
||||
typedef long quad_t;
|
||||
typedef unsigned long u_quad_t;
|
||||
|
||||
@@ -54,7 +54,7 @@ typedef struct { unsigned long pte; } pte_t;
|
||||
#ifdef __i386__
|
||||
typedef unsigned int uintptr_t;
|
||||
typedef int intptr_t;
|
||||
#elif defined(__x86_64__) || defined(__ia64__)
|
||||
#elif defined(__x86_64__)
|
||||
typedef unsigned long uintptr_t;
|
||||
typedef long intptr_t;
|
||||
#endif /* __i386__ || __x86_64__ */
|
||||
@@ -67,7 +67,7 @@ typedef signed int int32_t;
|
||||
#ifdef __i386__
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#elif defined(__x86_64__) || defined(__ia64__)
|
||||
#elif defined(__x86_64__)
|
||||
typedef signed long int64_t;
|
||||
typedef unsigned long uint64_t;
|
||||
#endif
|
||||
|
||||
@@ -50,10 +50,6 @@
|
||||
#include <mini-os/lib.h>
|
||||
#include <mini-os/time.h>
|
||||
|
||||
/* On ia64 these functions lead to crashes. These are replaced by
|
||||
* assembler functions. */
|
||||
#if !defined(__ia64__)
|
||||
|
||||
/* XXX RN: Yuck hardcoded endianess :) */
|
||||
#define _QUAD_HIGHWORD 1
|
||||
#define _QUAD_LOWWORD 0
|
||||
@@ -428,7 +424,6 @@ __moddi3(quad_t a, quad_t b)
|
||||
(void)__qdivrem(ua, ub, &ur);
|
||||
return (neg ? -ur : ur);
|
||||
}
|
||||
#endif /* !defined(__ia64__) */
|
||||
|
||||
#ifndef HAVE_LIBC
|
||||
/* Should be random enough for our uses */
|
||||
|
||||
@@ -361,7 +361,6 @@ void free_pages(void *pointer, int order)
|
||||
|
||||
}
|
||||
|
||||
#ifndef __ia64__
|
||||
int free_physical_pages(xen_pfn_t *mfns, int n)
|
||||
{
|
||||
struct xen_memory_reservation reservation;
|
||||
@@ -372,7 +371,6 @@ int free_physical_pages(xen_pfn_t *mfns, int n)
|
||||
reservation.domid = DOMID_SELF;
|
||||
return HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBC
|
||||
void *sbrk(ptrdiff_t increment)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
XEN_ROOT=$(CURDIR)/../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
#CFLAGS += -Werror -g -O0
|
||||
|
||||
CFLAGS += $(CFLAGS_libxenctrl)
|
||||
|
||||
LIBBIN =
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),ia64)
|
||||
LIBBIN += xenitp
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
.PHONY: build
|
||||
build: $(LIBBIN)
|
||||
|
||||
.PHONY: install
|
||||
install: build
|
||||
[ -z "$(LIBBIN)" ] || $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR)
|
||||
[ -z "$(LIBBIN)" ] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)$(PRIVATE_BINDIR)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) *.a *.so *.o *.rpm $(LIBBIN)
|
||||
|
||||
XENITP_OBJS=xenitp.o ia64-dis.o ia64-opc.o cpu-ia64-opc.o
|
||||
|
||||
xenitp: $(XENITP_OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(XENITP_OBJS) $(LDLIBS_libxenctrl)
|
||||
@@ -1,36 +0,0 @@
|
||||
xenitp README
|
||||
*************
|
||||
|
||||
|
||||
Xenitp is a low-level, non-symbolic debugger. It only works on ia64.
|
||||
|
||||
* Building xenitp
|
||||
First do 'make tools' at the top level to build libxc and includes. Then
|
||||
cd to tools/debugger/xenitp and do make.
|
||||
|
||||
* Using xenitp
|
||||
Usage is: xenitp DOM
|
||||
DOM is a domain number.
|
||||
'help' shows all the command available.
|
||||
When the domain is running, C-c stops it.
|
||||
|
||||
* Source origin
|
||||
All these files come from binutils:
|
||||
cpu-ia64-opc.c
|
||||
dis-asm.h
|
||||
ia64-asmtab.c
|
||||
ia64-asmtab.h
|
||||
ia64-dis.c
|
||||
ia64-gen.c
|
||||
ia64.h
|
||||
ia64-opc-a.c
|
||||
ia64-opc-b.c
|
||||
ia64-opc.c
|
||||
ia64-opc-d.c
|
||||
ia64-opc-f.c
|
||||
ia64-opc.h
|
||||
ia64-opc-i.c
|
||||
ia64-opc-m.c
|
||||
ia64-opc-x.c
|
||||
|
||||
xenitp.c is based on xenctxt.c
|
||||
@@ -1,615 +0,0 @@
|
||||
/* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Logically, this code should be part of libopcode but since some of
|
||||
the operand insertion/extraction functions help bfd to implement
|
||||
relocations, this code is included as part of cpu-ia64.c. This
|
||||
avoids circular dependencies between libopcode and libbfd and also
|
||||
obviates the need for applications to link in libopcode when all
|
||||
they really want is libbfd.
|
||||
|
||||
--davidm Mon Apr 13 22:14:02 1998 */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
|
||||
|
||||
static const char*
|
||||
ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
|
||||
ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return "internal error---this shouldn't happen";
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
|
||||
ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return "internal error---this shouldn't happen";
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
|
||||
ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
|
||||
ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
if (value >= 1u << self->field[0].bits)
|
||||
return "register number out of range";
|
||||
|
||||
*code |= value << self->field[0].shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
*valuep = ((code >> self->field[0].shift)
|
||||
& ((1u << self->field[0].bits) - 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
ia64_insn new = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
|
||||
{
|
||||
new |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1))
|
||||
<< self->field[i].shift);
|
||||
value >>= self->field[i].bits;
|
||||
}
|
||||
if (value)
|
||||
return "integer operand out of range";
|
||||
|
||||
*code |= new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
BFD_HOST_U_64_BIT value = 0;
|
||||
int i, bits = 0, total = 0;
|
||||
|
||||
for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
|
||||
{
|
||||
bits = self->field[i].bits;
|
||||
value |= ((code >> self->field[i].shift)
|
||||
& ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
|
||||
total += bits;
|
||||
}
|
||||
*valuep = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immu5b (const struct ia64_operand *self, ia64_insn value,
|
||||
ia64_insn *code)
|
||||
{
|
||||
if (value < 32 || value > 63)
|
||||
return "value must be between 32 and 63";
|
||||
return ins_immu (self, value - 32, code);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_immu5b (const struct ia64_operand *self, ia64_insn code,
|
||||
ia64_insn *valuep)
|
||||
{
|
||||
const char *result;
|
||||
|
||||
result = ext_immu (self, code, valuep);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
*valuep = *valuep + 32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
if (value & 0x7)
|
||||
return "value not an integer multiple of 8";
|
||||
return ins_immu (self, value >> 3, code);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
const char *result;
|
||||
|
||||
result = ext_immu (self, code, valuep);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
*valuep = *valuep << 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
|
||||
ia64_insn *code, int scale)
|
||||
{
|
||||
BFD_HOST_64_BIT svalue = value, sign_bit = 0;
|
||||
ia64_insn new = 0;
|
||||
int i;
|
||||
|
||||
svalue >>= scale;
|
||||
|
||||
for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
|
||||
{
|
||||
new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
|
||||
<< self->field[i].shift);
|
||||
sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
|
||||
svalue >>= self->field[i].bits;
|
||||
}
|
||||
if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
|
||||
return "integer operand out of range";
|
||||
|
||||
*code |= new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
|
||||
ia64_insn *valuep, int scale)
|
||||
{
|
||||
int i, bits = 0, total = 0;
|
||||
BFD_HOST_64_BIT val = 0, sign;
|
||||
|
||||
for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
|
||||
{
|
||||
bits = self->field[i].bits;
|
||||
val |= ((code >> self->field[i].shift)
|
||||
& ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
|
||||
total += bits;
|
||||
}
|
||||
/* sign extend: */
|
||||
sign = (BFD_HOST_64_BIT) 1 << (total - 1);
|
||||
val = (val ^ sign) - sign;
|
||||
|
||||
*valuep = (val << scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
return ins_imms_scaled (self, value, code, 0);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
|
||||
|
||||
return ins_imms_scaled (self, value, code, 0);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
return ext_imms_scaled (self, code, valuep, 0);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
--value;
|
||||
return ins_imms_scaled (self, value, code, 0);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
|
||||
ia64_insn *code)
|
||||
{
|
||||
value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
|
||||
|
||||
--value;
|
||||
return ins_imms_scaled (self, value, code, 0);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
const char *res = ext_imms_scaled (self, code, valuep, 0);
|
||||
|
||||
++*valuep;
|
||||
return res;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
return ins_imms_scaled (self, value, code, 1);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
return ext_imms_scaled (self, code, valuep, 1);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
return ins_imms_scaled (self, value, code, 4);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
return ext_imms_scaled (self, code, valuep, 4);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
return ins_imms_scaled (self, value, code, 16);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
return ext_imms_scaled (self, code, valuep, 16);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
|
||||
return ins_immu (self, value ^ mask, code);
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
const char *result;
|
||||
ia64_insn mask;
|
||||
|
||||
mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
|
||||
result = ext_immu (self, code, valuep);
|
||||
if (!result)
|
||||
{
|
||||
mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
|
||||
*valuep ^= mask;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
--value;
|
||||
if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
|
||||
return "count out of range";
|
||||
|
||||
*code |= value << self->field[0].shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
*valuep = ((code >> self->field[0].shift)
|
||||
& ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
--value;
|
||||
|
||||
if (value > 2)
|
||||
return "count must be in range 1..3";
|
||||
|
||||
*code |= value << self->field[0].shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
*valuep = ((code >> self->field[0].shift) & 0x3) + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: value = 0; break;
|
||||
case 7: value = 1; break;
|
||||
case 15: value = 2; break;
|
||||
case 16: value = 3; break;
|
||||
default: return "count must be 0, 7, 15, or 16";
|
||||
}
|
||||
*code |= value << self->field[0].shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
ia64_insn value;
|
||||
|
||||
value = (code >> self->field[0].shift) & 0x3;
|
||||
switch (value)
|
||||
{
|
||||
case 0: value = 0; break;
|
||||
case 1: value = 7; break;
|
||||
case 2: value = 15; break;
|
||||
case 3: value = 16; break;
|
||||
}
|
||||
*valuep = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
|
||||
{
|
||||
BFD_HOST_64_BIT val = value;
|
||||
BFD_HOST_U_64_BIT sign = 0;
|
||||
|
||||
if (val < 0)
|
||||
{
|
||||
sign = 0x4;
|
||||
value = -value;
|
||||
}
|
||||
switch (value)
|
||||
{
|
||||
case 1: value = 3; break;
|
||||
case 4: value = 2; break;
|
||||
case 8: value = 1; break;
|
||||
case 16: value = 0; break;
|
||||
default: return "count must be +/- 1, 4, 8, or 16";
|
||||
}
|
||||
*code |= (sign | value) << self->field[0].shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
|
||||
{
|
||||
BFD_HOST_64_BIT val;
|
||||
int negate;
|
||||
|
||||
val = (code >> self->field[0].shift) & 0x7;
|
||||
negate = val & 0x4;
|
||||
switch (val & 0x3)
|
||||
{
|
||||
case 0: val = 16; break;
|
||||
case 1: val = 8; break;
|
||||
case 2: val = 4; break;
|
||||
case 3: val = 1; break;
|
||||
}
|
||||
if (negate)
|
||||
val = -val;
|
||||
|
||||
*valuep = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CST IA64_OPND_CLASS_CST
|
||||
#define REG IA64_OPND_CLASS_REG
|
||||
#define IND IA64_OPND_CLASS_IND
|
||||
#define ABS IA64_OPND_CLASS_ABS
|
||||
#define REL IA64_OPND_CLASS_REL
|
||||
|
||||
#define SDEC IA64_OPND_FLAG_DECIMAL_SIGNED
|
||||
#define UDEC IA64_OPND_FLAG_DECIMAL_UNSIGNED
|
||||
|
||||
const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
|
||||
{
|
||||
/* constants: */
|
||||
{ CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "<none>" },
|
||||
{ CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" },
|
||||
{ CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" },
|
||||
{ CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" },
|
||||
{ CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" },
|
||||
{ CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" },
|
||||
{ CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" },
|
||||
{ CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
|
||||
{ CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" },
|
||||
{ CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" },
|
||||
{ CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" },
|
||||
{ CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" },
|
||||
{ CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" },
|
||||
{ CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" },
|
||||
|
||||
/* register operands: */
|
||||
{ REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */
|
||||
"an application register" },
|
||||
{ REG, ins_reg, ext_reg, "b", {{ 3, 6}}, 0, /* B1 */
|
||||
"a branch register" },
|
||||
{ REG, ins_reg, ext_reg, "b", {{ 3, 13}}, 0, /* B2 */
|
||||
"a branch register"},
|
||||
{ REG, ins_reg, ext_reg, "cr", {{ 7, 20}}, 0, /* CR */
|
||||
"a control register"},
|
||||
{ REG, ins_reg, ext_reg, "f", {{ 7, 6}}, 0, /* F1 */
|
||||
"a floating-point register" },
|
||||
{ REG, ins_reg, ext_reg, "f", {{ 7, 13}}, 0, /* F2 */
|
||||
"a floating-point register" },
|
||||
{ REG, ins_reg, ext_reg, "f", {{ 7, 20}}, 0, /* F3 */
|
||||
"a floating-point register" },
|
||||
{ REG, ins_reg, ext_reg, "f", {{ 7, 27}}, 0, /* F4 */
|
||||
"a floating-point register" },
|
||||
{ REG, ins_reg, ext_reg, "p", {{ 6, 6}}, 0, /* P1 */
|
||||
"a predicate register" },
|
||||
{ REG, ins_reg, ext_reg, "p", {{ 6, 27}}, 0, /* P2 */
|
||||
"a predicate register" },
|
||||
{ REG, ins_reg, ext_reg, "r", {{ 7, 6}}, 0, /* R1 */
|
||||
"a general register" },
|
||||
{ REG, ins_reg, ext_reg, "r", {{ 7, 13}}, 0, /* R2 */
|
||||
"a general register" },
|
||||
{ REG, ins_reg, ext_reg, "r", {{ 7, 20}}, 0, /* R3 */
|
||||
"a general register" },
|
||||
{ REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */
|
||||
"a general register r0-r3" },
|
||||
|
||||
/* memory operands: */
|
||||
{ IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */
|
||||
"a memory address" },
|
||||
|
||||
/* indirect operands: */
|
||||
{ IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */
|
||||
"a cpuid register" },
|
||||
{ IND, ins_reg, ext_reg, "dbr", {{7, 20}}, 0, /* DBR_R3 */
|
||||
"a dbr register" },
|
||||
{ IND, ins_reg, ext_reg, "dtr", {{7, 20}}, 0, /* DTR_R3 */
|
||||
"a dtr register" },
|
||||
{ IND, ins_reg, ext_reg, "itr", {{7, 20}}, 0, /* ITR_R3 */
|
||||
"an itr register" },
|
||||
{ IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */
|
||||
"an ibr register" },
|
||||
{ IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */
|
||||
"an msr register" },
|
||||
{ IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */
|
||||
"a pkr register" },
|
||||
{ IND, ins_reg, ext_reg, "pmc", {{7, 20}}, 0, /* PMC_R3 */
|
||||
"a pmc register" },
|
||||
{ IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */
|
||||
"a pmd register" },
|
||||
{ IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */
|
||||
"an rr register" },
|
||||
|
||||
/* immediate operands: */
|
||||
{ ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC, /* CCNT5 */
|
||||
"a 5-bit count (0-31)" },
|
||||
{ ABS, ins_cnt, ext_cnt, 0, {{ 2, 27 }}, UDEC, /* CNT2a */
|
||||
"a 2-bit count (1-4)" },
|
||||
{ ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC, /* CNT2b */
|
||||
"a 2-bit count (1-3)" },
|
||||
{ ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC, /* CNT2c */
|
||||
"a count (0, 7, 15, or 16)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 5, 14}}, UDEC, /* CNT5 */
|
||||
"a 5-bit count (0-31)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 6, 27}}, UDEC, /* CNT6 */
|
||||
"a 6-bit count (0-63)" },
|
||||
{ ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC, /* CPOS6a */
|
||||
"a 6-bit bit pos (0-63)" },
|
||||
{ ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC, /* CPOS6b */
|
||||
"a 6-bit bit pos (0-63)" },
|
||||
{ ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC, /* CPOS6c */
|
||||
"a 6-bit bit pos (0-63)" },
|
||||
{ ABS, ins_imms, ext_imms, 0, {{ 1, 36}}, SDEC, /* IMM1 */
|
||||
"a 1-bit integer (-1, 0)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */
|
||||
"a 2-bit unsigned (0-3)" },
|
||||
{ ABS, ins_immu5b, ext_immu5b, 0, {{ 5, 14}}, UDEC, /* IMMU5b */
|
||||
"a 5-bit unsigned (32 + (0-31))" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */
|
||||
"a 7-bit unsigned (0-127)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */
|
||||
"a 7-bit unsigned (0-127)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, UDEC, /* SOF */
|
||||
"a frame size (register count)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, UDEC, /* SOL */
|
||||
"a local register count" },
|
||||
{ ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC, /* SOR */
|
||||
"a rotating register count (integer multiple of 8)" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM8 */
|
||||
{{ 7, 13}, { 1, 36}}, SDEC,
|
||||
"an 8-bit integer (-128-127)" },
|
||||
{ ABS, ins_immsu4, ext_imms, 0, /* IMM8U4 */
|
||||
{{ 7, 13}, { 1, 36}}, SDEC,
|
||||
"an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
|
||||
{ ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1 */
|
||||
{{ 7, 13}, { 1, 36}}, SDEC,
|
||||
"an 8-bit integer (-127-128)" },
|
||||
{ ABS, ins_immsm1u4, ext_immsm1, 0, /* IMM8M1U4 */
|
||||
{{ 7, 13}, { 1, 36}}, SDEC,
|
||||
"an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
|
||||
{ ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1U8 */
|
||||
{{ 7, 13}, { 1, 36}}, SDEC,
|
||||
"an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 2, 33}, { 7, 20}}, 0, /* IMMU9 */
|
||||
"a 9-bit unsigned (0-511)" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM9a */
|
||||
{{ 7, 6}, { 1, 27}, { 1, 36}}, SDEC,
|
||||
"a 9-bit integer (-256-255)" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM9b */
|
||||
{{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
|
||||
"a 9-bit integer (-256-255)" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM14 */
|
||||
{{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
|
||||
"a 14-bit integer (-8192-8191)" },
|
||||
{ ABS, ins_imms1, ext_imms1, 0, /* IMM17 */
|
||||
{{ 7, 6}, { 8, 24}, { 1, 36}}, 0,
|
||||
"a 17-bit integer (-65536-65535)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */
|
||||
"a 21-bit unsigned" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM22 */
|
||||
{{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
|
||||
"a 22-bit signed integer" },
|
||||
{ ABS, ins_immu, ext_immu, 0, /* IMMU24 */
|
||||
{{21, 6}, { 2, 31}, { 1, 36}}, 0,
|
||||
"a 24-bit unsigned" },
|
||||
{ ABS, ins_imms16,ext_imms16,0, {{27, 6}, { 1, 36}}, 0, /* IMM44 */
|
||||
"a 44-bit unsigned (least 16 bits ignored/zeroes)" },
|
||||
{ ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU62 */
|
||||
"a 62-bit unsigned" },
|
||||
{ ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU64 */
|
||||
"a 64-bit unsigned" },
|
||||
{ ABS, ins_inc3, ext_inc3, 0, {{ 3, 13}}, SDEC, /* INC3 */
|
||||
"an increment (+/- 1, 4, 8, or 16)" },
|
||||
{ ABS, ins_cnt, ext_cnt, 0, {{ 4, 27}}, UDEC, /* LEN4 */
|
||||
"a 4-bit length (1-16)" },
|
||||
{ ABS, ins_cnt, ext_cnt, 0, {{ 6, 27}}, UDEC, /* LEN6 */
|
||||
"a 6-bit length (1-64)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 4, 20}}, 0, /* MBTYPE4 */
|
||||
"a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 8, 20}}, 0, /* MBTYPE8 */
|
||||
"an 8-bit mix type" },
|
||||
{ ABS, ins_immu, ext_immu, 0, {{ 6, 14}}, UDEC, /* POS6 */
|
||||
"a 6-bit bit pos (0-63)" },
|
||||
{ REL, ins_imms4, ext_imms4, 0, {{ 7, 6}, { 2, 33}}, 0, /* TAG13 */
|
||||
"a branch tag" },
|
||||
{ REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0, /* TAG13b */
|
||||
"a branch tag" },
|
||||
{ REL, ins_imms4, ext_imms4, 0, {{20, 6}, { 1, 36}}, 0, /* TGT25 */
|
||||
"a branch target" },
|
||||
{ REL, ins_imms4, ext_imms4, 0, /* TGT25b */
|
||||
{{ 7, 6}, {13, 20}, { 1, 36}}, 0,
|
||||
"a branch target" },
|
||||
{ REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0, /* TGT25c */
|
||||
"a branch target" },
|
||||
{ REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */
|
||||
"a branch target" },
|
||||
|
||||
{ ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */
|
||||
"ldxmov target" },
|
||||
};
|
||||
@@ -1,548 +0,0 @@
|
||||
/* Interface between the opcode library and its callers.
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
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, 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., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
Written by Cygnus Support, 1993.
|
||||
|
||||
The opcode library (libopcodes.a) provides instruction decoders for
|
||||
a large variety of instruction sets, callable with an identical
|
||||
interface, for making instruction-processing programs more independent
|
||||
of the instruction set being processed. */
|
||||
|
||||
#ifndef DIS_ASM_H
|
||||
#define DIS_ASM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define PARAMS(x) x
|
||||
typedef void *PTR;
|
||||
typedef uint64_t bfd_vma;
|
||||
typedef int64_t bfd_signed_vma;
|
||||
typedef uint8_t bfd_byte;
|
||||
typedef int bfd_boolean;
|
||||
#define BFD_HOST_U_64_BIT unsigned long
|
||||
#define BFD_HOST_64_BIT long
|
||||
#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
|
||||
|
||||
extern unsigned long bfd_getl64 (const bfd_byte *addr);
|
||||
|
||||
#define BFD64
|
||||
#define ATTRIBUTE_FPTR_PRINTF_2
|
||||
#define ATTRIBUTE_UNUSED __attribute__((unused))
|
||||
|
||||
enum bfd_flavour {
|
||||
bfd_target_unknown_flavour,
|
||||
bfd_target_aout_flavour,
|
||||
bfd_target_coff_flavour,
|
||||
bfd_target_ecoff_flavour,
|
||||
bfd_target_elf_flavour,
|
||||
bfd_target_ieee_flavour,
|
||||
bfd_target_nlm_flavour,
|
||||
bfd_target_oasys_flavour,
|
||||
bfd_target_tekhex_flavour,
|
||||
bfd_target_srec_flavour,
|
||||
bfd_target_ihex_flavour,
|
||||
bfd_target_som_flavour,
|
||||
bfd_target_os9k_flavour,
|
||||
bfd_target_versados_flavour,
|
||||
bfd_target_msdos_flavour,
|
||||
bfd_target_evax_flavour
|
||||
};
|
||||
|
||||
enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
|
||||
|
||||
enum bfd_architecture
|
||||
{
|
||||
bfd_arch_unknown, /* File arch not known */
|
||||
bfd_arch_obscure, /* Arch known, not one of these */
|
||||
bfd_arch_m68k, /* Motorola 68xxx */
|
||||
#define bfd_mach_m68000 1
|
||||
#define bfd_mach_m68008 2
|
||||
#define bfd_mach_m68010 3
|
||||
#define bfd_mach_m68020 4
|
||||
#define bfd_mach_m68030 5
|
||||
#define bfd_mach_m68040 6
|
||||
#define bfd_mach_m68060 7
|
||||
#define bfd_mach_cpu32 8
|
||||
#define bfd_mach_mcf5200 9
|
||||
#define bfd_mach_mcf5206e 10
|
||||
#define bfd_mach_mcf5307 11
|
||||
#define bfd_mach_mcf5407 12
|
||||
#define bfd_mach_mcf528x 13
|
||||
#define bfd_mach_mcfv4e 14
|
||||
#define bfd_mach_mcf521x 15
|
||||
#define bfd_mach_mcf5249 16
|
||||
#define bfd_mach_mcf547x 17
|
||||
#define bfd_mach_mcf548x 18
|
||||
bfd_arch_vax, /* DEC Vax */
|
||||
bfd_arch_i960, /* Intel 960 */
|
||||
/* The order of the following is important.
|
||||
lower number indicates a machine type that
|
||||
only accepts a subset of the instructions
|
||||
available to machines with higher numbers.
|
||||
The exception is the "ca", which is
|
||||
incompatible with all other machines except
|
||||
"core". */
|
||||
|
||||
#define bfd_mach_i960_core 1
|
||||
#define bfd_mach_i960_ka_sa 2
|
||||
#define bfd_mach_i960_kb_sb 3
|
||||
#define bfd_mach_i960_mc 4
|
||||
#define bfd_mach_i960_xa 5
|
||||
#define bfd_mach_i960_ca 6
|
||||
#define bfd_mach_i960_jx 7
|
||||
#define bfd_mach_i960_hx 8
|
||||
|
||||
bfd_arch_a29k, /* AMD 29000 */
|
||||
bfd_arch_sparc, /* SPARC */
|
||||
#define bfd_mach_sparc 1
|
||||
/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
|
||||
#define bfd_mach_sparc_sparclet 2
|
||||
#define bfd_mach_sparc_sparclite 3
|
||||
#define bfd_mach_sparc_v8plus 4
|
||||
#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
|
||||
#define bfd_mach_sparc_sparclite_le 6
|
||||
#define bfd_mach_sparc_v9 7
|
||||
#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
|
||||
#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
|
||||
#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
|
||||
/* Nonzero if MACH has the v9 instruction set. */
|
||||
#define bfd_mach_sparc_v9_p(mach) \
|
||||
((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
|
||||
&& (mach) != bfd_mach_sparc_sparclite_le)
|
||||
bfd_arch_mips, /* MIPS Rxxxx */
|
||||
#define bfd_mach_mips3000 3000
|
||||
#define bfd_mach_mips3900 3900
|
||||
#define bfd_mach_mips4000 4000
|
||||
#define bfd_mach_mips4010 4010
|
||||
#define bfd_mach_mips4100 4100
|
||||
#define bfd_mach_mips4300 4300
|
||||
#define bfd_mach_mips4400 4400
|
||||
#define bfd_mach_mips4600 4600
|
||||
#define bfd_mach_mips4650 4650
|
||||
#define bfd_mach_mips5000 5000
|
||||
#define bfd_mach_mips6000 6000
|
||||
#define bfd_mach_mips8000 8000
|
||||
#define bfd_mach_mips10000 10000
|
||||
#define bfd_mach_mips16 16
|
||||
bfd_arch_i386, /* Intel 386 */
|
||||
#define bfd_mach_i386_i386 0
|
||||
#define bfd_mach_i386_i8086 1
|
||||
#define bfd_mach_i386_i386_intel_syntax 2
|
||||
#define bfd_mach_x86_64 3
|
||||
#define bfd_mach_x86_64_intel_syntax 4
|
||||
bfd_arch_we32k, /* AT&T WE32xxx */
|
||||
bfd_arch_tahoe, /* CCI/Harris Tahoe */
|
||||
bfd_arch_i860, /* Intel 860 */
|
||||
bfd_arch_romp, /* IBM ROMP PC/RT */
|
||||
bfd_arch_alliant, /* Alliant */
|
||||
bfd_arch_convex, /* Convex */
|
||||
bfd_arch_m88k, /* Motorola 88xxx */
|
||||
bfd_arch_pyramid, /* Pyramid Technology */
|
||||
bfd_arch_h8300, /* Hitachi H8/300 */
|
||||
#define bfd_mach_h8300 1
|
||||
#define bfd_mach_h8300h 2
|
||||
#define bfd_mach_h8300s 3
|
||||
bfd_arch_powerpc, /* PowerPC */
|
||||
#define bfd_mach_ppc 0
|
||||
#define bfd_mach_ppc64 1
|
||||
#define bfd_mach_ppc_403 403
|
||||
#define bfd_mach_ppc_403gc 4030
|
||||
#define bfd_mach_ppc_505 505
|
||||
#define bfd_mach_ppc_601 601
|
||||
#define bfd_mach_ppc_602 602
|
||||
#define bfd_mach_ppc_603 603
|
||||
#define bfd_mach_ppc_ec603e 6031
|
||||
#define bfd_mach_ppc_604 604
|
||||
#define bfd_mach_ppc_620 620
|
||||
#define bfd_mach_ppc_630 630
|
||||
#define bfd_mach_ppc_750 750
|
||||
#define bfd_mach_ppc_860 860
|
||||
#define bfd_mach_ppc_a35 35
|
||||
#define bfd_mach_ppc_rs64ii 642
|
||||
#define bfd_mach_ppc_rs64iii 643
|
||||
#define bfd_mach_ppc_7400 7400
|
||||
bfd_arch_rs6000, /* IBM RS/6000 */
|
||||
bfd_arch_hppa, /* HP PA RISC */
|
||||
bfd_arch_d10v, /* Mitsubishi D10V */
|
||||
bfd_arch_z8k, /* Zilog Z8000 */
|
||||
#define bfd_mach_z8001 1
|
||||
#define bfd_mach_z8002 2
|
||||
bfd_arch_h8500, /* Hitachi H8/500 */
|
||||
bfd_arch_sh, /* Hitachi SH */
|
||||
#define bfd_mach_sh 1
|
||||
#define bfd_mach_sh2 0x20
|
||||
#define bfd_mach_sh_dsp 0x2d
|
||||
#define bfd_mach_sh2a 0x2a
|
||||
#define bfd_mach_sh2a_nofpu 0x2b
|
||||
#define bfd_mach_sh2e 0x2e
|
||||
#define bfd_mach_sh3 0x30
|
||||
#define bfd_mach_sh3_nommu 0x31
|
||||
#define bfd_mach_sh3_dsp 0x3d
|
||||
#define bfd_mach_sh3e 0x3e
|
||||
#define bfd_mach_sh4 0x40
|
||||
#define bfd_mach_sh4_nofpu 0x41
|
||||
#define bfd_mach_sh4_nommu_nofpu 0x42
|
||||
#define bfd_mach_sh4a 0x4a
|
||||
#define bfd_mach_sh4a_nofpu 0x4b
|
||||
#define bfd_mach_sh4al_dsp 0x4d
|
||||
#define bfd_mach_sh5 0x50
|
||||
bfd_arch_alpha, /* Dec Alpha */
|
||||
#define bfd_mach_alpha 1
|
||||
bfd_arch_arm, /* Advanced Risc Machines ARM */
|
||||
#define bfd_mach_arm_2 1
|
||||
#define bfd_mach_arm_2a 2
|
||||
#define bfd_mach_arm_3 3
|
||||
#define bfd_mach_arm_3M 4
|
||||
#define bfd_mach_arm_4 5
|
||||
#define bfd_mach_arm_4T 6
|
||||
bfd_arch_ns32k, /* National Semiconductors ns32000 */
|
||||
bfd_arch_w65, /* WDC 65816 */
|
||||
bfd_arch_tic30, /* Texas Instruments TMS320C30 */
|
||||
bfd_arch_v850, /* NEC V850 */
|
||||
#define bfd_mach_v850 0
|
||||
bfd_arch_arc, /* Argonaut RISC Core */
|
||||
#define bfd_mach_arc_base 0
|
||||
bfd_arch_m32r, /* Mitsubishi M32R/D */
|
||||
#define bfd_mach_m32r 0 /* backwards compatibility */
|
||||
bfd_arch_mn10200, /* Matsushita MN10200 */
|
||||
bfd_arch_mn10300, /* Matsushita MN10300 */
|
||||
bfd_arch_last
|
||||
};
|
||||
|
||||
typedef struct symbol_cache_entry
|
||||
{
|
||||
const char *name;
|
||||
union
|
||||
{
|
||||
PTR p;
|
||||
bfd_vma i;
|
||||
} udata;
|
||||
} asymbol;
|
||||
|
||||
typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
|
||||
|
||||
enum dis_insn_type {
|
||||
dis_noninsn, /* Not a valid instruction */
|
||||
dis_nonbranch, /* Not a branch instruction */
|
||||
dis_branch, /* Unconditional branch */
|
||||
dis_condbranch, /* Conditional branch */
|
||||
dis_jsr, /* Jump to subroutine */
|
||||
dis_condjsr, /* Conditional jump to subroutine */
|
||||
dis_dref, /* Data reference instruction */
|
||||
dis_dref2 /* Two data references in instruction */
|
||||
};
|
||||
|
||||
/* This struct is passed into the instruction decoding routine,
|
||||
and is passed back out into each callback. The various fields are used
|
||||
for conveying information from your main routine into your callbacks,
|
||||
for passing information into the instruction decoders (such as the
|
||||
addresses of the callback functions), or for passing information
|
||||
back from the instruction decoders to their callers.
|
||||
|
||||
It must be initialized before it is first passed; this can be done
|
||||
by hand, or using one of the initialization macros below. */
|
||||
|
||||
typedef struct disassemble_info {
|
||||
fprintf_ftype fprintf_func;
|
||||
void *stream;
|
||||
void *application_data;
|
||||
|
||||
/* Target description. We could replace this with a pointer to the bfd,
|
||||
but that would require one. There currently isn't any such requirement
|
||||
so to avoid introducing one we record these explicitly. */
|
||||
/* The bfd_flavour. This can be bfd_target_unknown_flavour. */
|
||||
enum bfd_flavour flavour;
|
||||
/* The bfd_arch value. */
|
||||
enum bfd_architecture arch;
|
||||
/* The bfd_mach value. */
|
||||
unsigned long mach;
|
||||
/* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
|
||||
enum bfd_endian endian;
|
||||
/* An arch/mach-specific bitmask of selected instruction subsets, mainly
|
||||
for processors with run-time-switchable instruction sets. The default,
|
||||
zero, means that there is no constraint. CGEN-based opcodes ports
|
||||
may use ISA_foo masks. */
|
||||
void *insn_sets;
|
||||
|
||||
/* Some targets need information about the current section to accurately
|
||||
display insns. If this is NULL, the target disassembler function
|
||||
will have to make its best guess. */
|
||||
//asection *section;
|
||||
|
||||
/* An array of pointers to symbols either at the location being disassembled
|
||||
or at the start of the function being disassembled. The array is sorted
|
||||
so that the first symbol is intended to be the one used. The others are
|
||||
present for any misc. purposes. This is not set reliably, but if it is
|
||||
not NULL, it is correct. */
|
||||
asymbol **symbols;
|
||||
/* Number of symbols in array. */
|
||||
int num_symbols;
|
||||
|
||||
/* For use by the disassembler.
|
||||
The top 16 bits are reserved for public use (and are documented here).
|
||||
The bottom 16 bits are for the internal use of the disassembler. */
|
||||
unsigned long flags;
|
||||
#define INSN_HAS_RELOC 0x80000000
|
||||
void *private_data;
|
||||
|
||||
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||
address of the stuff to be disassembled, MYADDR is the address to
|
||||
put the bytes in, and LENGTH is the number of bytes to read.
|
||||
INFO is a pointer to this struct.
|
||||
Returns an errno value or 0 for success. */
|
||||
int (*read_memory_func)
|
||||
(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
|
||||
struct disassemble_info *info);
|
||||
|
||||
/* Function which should be called if we get an error that we can't
|
||||
recover from. STATUS is the errno value from read_memory_func and
|
||||
MEMADDR is the address that we were trying to read. INFO is a
|
||||
pointer to this struct. */
|
||||
void (*memory_error_func)
|
||||
(int status, bfd_vma memaddr, struct disassemble_info *info);
|
||||
|
||||
/* Function called to print ADDR. */
|
||||
void (*print_address_func)
|
||||
(bfd_vma addr, struct disassemble_info *info);
|
||||
|
||||
/* Function called to determine if there is a symbol at the given ADDR.
|
||||
If there is, the function returns 1, otherwise it returns 0.
|
||||
This is used by ports which support an overlay manager where
|
||||
the overlay number is held in the top part of an address. In
|
||||
some circumstances we want to include the overlay number in the
|
||||
address, (normally because there is a symbol associated with
|
||||
that address), but sometimes we want to mask out the overlay bits. */
|
||||
int (* symbol_at_address_func)
|
||||
(bfd_vma addr, struct disassemble_info * info);
|
||||
|
||||
/* Function called to check if a SYMBOL is can be displayed to the user.
|
||||
This is used by some ports that want to hide special symbols when
|
||||
displaying debugging outout. */
|
||||
bfd_boolean (* symbol_is_valid)
|
||||
(asymbol *, struct disassemble_info * info);
|
||||
|
||||
/* These are for buffer_read_memory. */
|
||||
bfd_byte *buffer;
|
||||
bfd_vma buffer_vma;
|
||||
unsigned int buffer_length;
|
||||
|
||||
/* This variable may be set by the instruction decoder. It suggests
|
||||
the number of bytes objdump should display on a single line. If
|
||||
the instruction decoder sets this, it should always set it to
|
||||
the same value in order to get reasonable looking output. */
|
||||
int bytes_per_line;
|
||||
|
||||
/* The next two variables control the way objdump displays the raw data. */
|
||||
/* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
|
||||
/* output will look like this:
|
||||
00: 00000000 00000000
|
||||
with the chunks displayed according to "display_endian". */
|
||||
int bytes_per_chunk;
|
||||
enum bfd_endian display_endian;
|
||||
|
||||
/* Number of octets per incremented target address
|
||||
Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
|
||||
unsigned int octets_per_byte;
|
||||
|
||||
/* The number of zeroes we want to see at the end of a section before we
|
||||
start skipping them. */
|
||||
unsigned int skip_zeroes;
|
||||
|
||||
/* The number of zeroes to skip at the end of a section. If the number
|
||||
of zeroes at the end is between SKIP_ZEROES_AT_END and SKIP_ZEROES,
|
||||
they will be disassembled. If there are fewer than
|
||||
SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
|
||||
attempt to avoid disassembling zeroes inserted by section
|
||||
alignment. */
|
||||
unsigned int skip_zeroes_at_end;
|
||||
|
||||
/* Whether the disassembler always needs the relocations. */
|
||||
bfd_boolean disassembler_needs_relocs;
|
||||
|
||||
/* Results from instruction decoders. Not all decoders yet support
|
||||
this information. This info is set each time an instruction is
|
||||
decoded, and is only valid for the last such instruction.
|
||||
|
||||
To determine whether this decoder supports this information, set
|
||||
insn_info_valid to 0, decode an instruction, then check it. */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
/* Command line options specific to the target disassembler. */
|
||||
char * disassembler_options;
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of octets processed. */
|
||||
typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
|
||||
|
||||
extern int print_insn_big_mips (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_mips (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i386 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i386_att (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i386_intel (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_ia64 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i370 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m68hc11 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m68hc12 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m68k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_z80 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_z8001 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_z8002 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300h (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8300s (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_h8500 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_alpha (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_arm (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_arm (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sparc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_avr (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_bfin (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_d10v (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_d30v (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_dlx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_fr30 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_hppa (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i860 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_i960 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_ip2k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m32r (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m88k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_maxq_little (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_maxq_big (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mcore (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mmix (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mn10200 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mn10300 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mt (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_msp430 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_ns32k (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_crx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_openrisc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_or32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_or32 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_pdp11 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_pj (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_big_powerpc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_little_powerpc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rs6000 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_s390 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_tic30 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_tic4x (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_tic54x (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_tic80 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_v850 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_vax (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_w65 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_xstormy16 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_xtensa (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh64 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh64x_media (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_frv (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_iq2000 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_xc16x (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_m32c (bfd_vma, disassemble_info *);
|
||||
|
||||
extern disassembler_ftype arc_get_disassembler (void *);
|
||||
//extern disassembler_ftype cris_get_disassembler (bfd *);
|
||||
|
||||
extern void print_mips_disassembler_options (FILE *);
|
||||
extern void print_ppc_disassembler_options (FILE *);
|
||||
extern void print_arm_disassembler_options (FILE *);
|
||||
extern void parse_arm_disassembler_option (char *);
|
||||
extern int get_arm_regname_num_options (void);
|
||||
extern int set_arm_regname_option (int);
|
||||
extern int get_arm_regnames (int, const char **, const char **, const char *const **);
|
||||
extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
//extern disassembler_ftype disassembler (bfd *);
|
||||
|
||||
/* Amend the disassemble_info structure as necessary for the target architecture.
|
||||
Should only be called after initialising the info->arch field. */
|
||||
extern void disassemble_init_for_target (struct disassemble_info * info);
|
||||
|
||||
/* Document any target specific options available from the disassembler. */
|
||||
extern void disassembler_usage (FILE *);
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
||||
/* Here is a function which callers may wish to use for read_memory_func.
|
||||
It gets bytes from a buffer. */
|
||||
extern int buffer_read_memory
|
||||
(bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *);
|
||||
|
||||
/* This function goes with buffer_read_memory.
|
||||
It prints a message using info->fprintf_func and info->stream. */
|
||||
extern void perror_memory (int, bfd_vma, struct disassemble_info *);
|
||||
|
||||
|
||||
/* Just print the address in hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
extern void generic_print_address
|
||||
(bfd_vma, struct disassemble_info *);
|
||||
|
||||
/* Always true. */
|
||||
extern int generic_symbol_at_address
|
||||
(bfd_vma, struct disassemble_info *);
|
||||
|
||||
/* Also always true. */
|
||||
extern bfd_boolean generic_symbol_is_valid
|
||||
(asymbol *, struct disassemble_info *);
|
||||
|
||||
/* Method to initialize a disassemble_info struct. This should be
|
||||
called by all applications creating such a struct. */
|
||||
extern void init_disassemble_info (struct disassemble_info *info, void *stream,
|
||||
fprintf_ftype fprintf_func);
|
||||
|
||||
/* For compatibility with existing code. */
|
||||
#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
|
||||
init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC))
|
||||
#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
|
||||
init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! defined (DIS_ASM_H) */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,148 +0,0 @@
|
||||
/* ia64-asmtab.h -- Header for compacted IA-64 opcode tables.
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
Contributed by Bob Manson of Cygnus Support <manson@cygnus.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef IA64_ASMTAB_H
|
||||
#define IA64_ASMTAB_H
|
||||
|
||||
#include "ia64.h"
|
||||
|
||||
/* The primary opcode table is made up of the following: */
|
||||
struct ia64_main_table
|
||||
{
|
||||
/* The entry in the string table that corresponds to the name of this
|
||||
opcode. */
|
||||
unsigned short name_index;
|
||||
|
||||
/* The type of opcode; corresponds to the TYPE field in
|
||||
struct ia64_opcode. */
|
||||
unsigned char opcode_type;
|
||||
|
||||
/* The number of outputs for this opcode. */
|
||||
unsigned char num_outputs;
|
||||
|
||||
/* The base insn value for this opcode. It may be modified by completers. */
|
||||
ia64_insn opcode;
|
||||
|
||||
/* The mask of valid bits in OPCODE. Zeros indicate operand fields. */
|
||||
ia64_insn mask;
|
||||
|
||||
/* The operands of this instruction. Corresponds to the OPERANDS field
|
||||
in struct ia64_opcode. */
|
||||
unsigned char operands[5];
|
||||
|
||||
/* The flags for this instruction. Corresponds to the FLAGS field in
|
||||
struct ia64_opcode. */
|
||||
short flags;
|
||||
|
||||
/* The tree of completers for this instruction; this is an offset into
|
||||
completer_table. */
|
||||
short completers;
|
||||
};
|
||||
|
||||
/* Each instruction has a set of possible "completers", or additional
|
||||
suffixes that can alter the instruction's behavior, and which has
|
||||
potentially different dependencies.
|
||||
|
||||
The completer entries modify certain bits in the instruction opcode.
|
||||
Which bits are to be modified are marked by the BITS, MASK and
|
||||
OFFSET fields. The completer entry may also note dependencies for the
|
||||
opcode.
|
||||
|
||||
These completers are arranged in a DAG; the pointers are indexes
|
||||
into the completer_table array. The completer DAG is searched by
|
||||
find_completer () and ia64_find_matching_opcode ().
|
||||
|
||||
Note that each completer needs to be applied in turn, so that if we
|
||||
have the instruction
|
||||
cmp.lt.unc
|
||||
the completer entries for both "lt" and "unc" would need to be applied
|
||||
to the opcode's value.
|
||||
|
||||
Some instructions do not require any completers; these contain an
|
||||
empty completer entry. Instructions that require a completer do
|
||||
not contain an empty entry.
|
||||
|
||||
Terminal completers (those completers that validly complete an
|
||||
instruction) are marked by having the TERMINAL_COMPLETER flag set.
|
||||
|
||||
Only dependencies listed in the terminal completer for an opcode are
|
||||
considered to apply to that opcode instance. */
|
||||
|
||||
struct ia64_completer_table
|
||||
{
|
||||
/* The bit value that this completer sets. */
|
||||
unsigned int bits;
|
||||
|
||||
/* And its mask. 1s are bits that are to be modified in the
|
||||
instruction. */
|
||||
unsigned int mask;
|
||||
|
||||
/* The entry in the string table that corresponds to the name of this
|
||||
completer. */
|
||||
unsigned short name_index;
|
||||
|
||||
/* An alternative completer, or -1 if this is the end of the chain. */
|
||||
short alternative;
|
||||
|
||||
/* A pointer to the DAG of completers that can potentially follow
|
||||
this one, or -1. */
|
||||
short subentries;
|
||||
|
||||
/* The bit offset in the instruction where BITS and MASK should be
|
||||
applied. */
|
||||
unsigned char offset : 7;
|
||||
|
||||
unsigned char terminal_completer : 1;
|
||||
|
||||
/* Index into the dependency list table */
|
||||
short dependencies;
|
||||
};
|
||||
|
||||
/* This contains sufficient information for the disassembler to resolve
|
||||
the complete name of the original instruction. */
|
||||
struct ia64_dis_names
|
||||
{
|
||||
/* COMPLETER_INDEX represents the tree of completers that make up
|
||||
the instruction. The LSB represents the top of the tree for the
|
||||
specified instruction.
|
||||
|
||||
A 0 bit indicates to go to the next alternate completer via the
|
||||
alternative field; a 1 bit indicates that the current completer
|
||||
is part of the instruction, and to go down the subentries index.
|
||||
We know we've reached the final completer when we run out of 1
|
||||
bits.
|
||||
|
||||
There is always at least one 1 bit. */
|
||||
unsigned int completer_index : 20;
|
||||
|
||||
/* The index in the main_table[] array for the instruction. */
|
||||
unsigned short insn_index : 11;
|
||||
|
||||
/* If set, the next entry in this table is an alternate possibility
|
||||
for this instruction encoding. Which one to use is determined by
|
||||
the instruction type and other factors (see opcode_verify ()). */
|
||||
unsigned int next_flag : 1;
|
||||
|
||||
/* The disassembly priority of this entry among instructions. */
|
||||
unsigned short priority;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,309 +0,0 @@
|
||||
/* ia64-dis.c -- Disassemble ia64 instructions
|
||||
Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "ia64.h"
|
||||
|
||||
#define NELEMS(a) ((int) (sizeof (a) / sizeof (a[0])))
|
||||
|
||||
/* Disassemble ia64 instruction. */
|
||||
|
||||
/* Return the instruction type for OPCODE found in unit UNIT. */
|
||||
|
||||
static enum ia64_insn_type
|
||||
unit_to_type (ia64_insn opcode, enum ia64_unit unit)
|
||||
{
|
||||
enum ia64_insn_type type;
|
||||
int op;
|
||||
|
||||
op = IA64_OP (opcode);
|
||||
|
||||
if (op >= 8 && (unit == IA64_UNIT_I || unit == IA64_UNIT_M))
|
||||
{
|
||||
type = IA64_TYPE_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case IA64_UNIT_I:
|
||||
type = IA64_TYPE_I; break;
|
||||
case IA64_UNIT_M:
|
||||
type = IA64_TYPE_M; break;
|
||||
case IA64_UNIT_B:
|
||||
type = IA64_TYPE_B; break;
|
||||
case IA64_UNIT_F:
|
||||
type = IA64_TYPE_F; break;
|
||||
case IA64_UNIT_L:
|
||||
case IA64_UNIT_X:
|
||||
type = IA64_TYPE_X; break;
|
||||
default:
|
||||
type = -1;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
int
|
||||
print_insn_ia64 (bfd_vma memaddr, struct disassemble_info *info)
|
||||
{
|
||||
ia64_insn t0, t1, slot[3], template, s_bit, insn;
|
||||
int slotnum, j, status, need_comma, retval, slot_multiplier;
|
||||
const struct ia64_operand *odesc;
|
||||
const struct ia64_opcode *idesc;
|
||||
const char *err, *str, *tname;
|
||||
BFD_HOST_U_64_BIT value;
|
||||
bfd_byte bundle[16];
|
||||
enum ia64_unit unit;
|
||||
char regname[16];
|
||||
|
||||
if (info->bytes_per_line == 0)
|
||||
info->bytes_per_line = 6;
|
||||
info->display_endian = info->endian;
|
||||
|
||||
slot_multiplier = info->bytes_per_line;
|
||||
retval = slot_multiplier;
|
||||
|
||||
slotnum = (((long) memaddr) & 0xf) / slot_multiplier;
|
||||
if (slotnum > 2)
|
||||
return -1;
|
||||
|
||||
memaddr -= (memaddr & 0xf);
|
||||
status = (*info->read_memory_func) (memaddr, bundle, sizeof (bundle), info);
|
||||
if (status != 0)
|
||||
{
|
||||
(*info->memory_error_func) (status, memaddr, info);
|
||||
return -1;
|
||||
}
|
||||
/* bundles are always in little-endian byte order */
|
||||
t0 = bfd_getl64 (bundle);
|
||||
t1 = bfd_getl64 (bundle + 8);
|
||||
s_bit = t0 & 1;
|
||||
template = (t0 >> 1) & 0xf;
|
||||
slot[0] = (t0 >> 5) & 0x1ffffffffffLL;
|
||||
slot[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
|
||||
slot[2] = (t1 >> 23) & 0x1ffffffffffLL;
|
||||
|
||||
tname = ia64_templ_desc[template].name;
|
||||
if (slotnum == 0)
|
||||
(*info->fprintf_func) (info->stream, "[%s] ", tname);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, " ");
|
||||
|
||||
unit = ia64_templ_desc[template].exec_unit[slotnum];
|
||||
|
||||
if (template == 2 && slotnum == 1)
|
||||
{
|
||||
/* skip L slot in MLI template: */
|
||||
slotnum = 2;
|
||||
retval += slot_multiplier;
|
||||
}
|
||||
|
||||
insn = slot[slotnum];
|
||||
|
||||
if (unit == IA64_UNIT_NIL)
|
||||
goto decoding_failed;
|
||||
|
||||
idesc = ia64_dis_opcode (insn, unit_to_type (insn, unit));
|
||||
if (idesc == NULL)
|
||||
goto decoding_failed;
|
||||
|
||||
/* print predicate, if any: */
|
||||
|
||||
if ((idesc->flags & IA64_OPCODE_NO_PRED)
|
||||
|| (insn & 0x3f) == 0)
|
||||
(*info->fprintf_func) (info->stream, " ");
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "(p%02d) ", (int)(insn & 0x3f));
|
||||
|
||||
/* now the actual instruction: */
|
||||
|
||||
(*info->fprintf_func) (info->stream, "%s", idesc->name);
|
||||
if (idesc->operands[0])
|
||||
(*info->fprintf_func) (info->stream, " ");
|
||||
|
||||
need_comma = 0;
|
||||
for (j = 0; j < NELEMS (idesc->operands) && idesc->operands[j]; ++j)
|
||||
{
|
||||
odesc = elf64_ia64_operands + idesc->operands[j];
|
||||
|
||||
if (need_comma)
|
||||
(*info->fprintf_func) (info->stream, ",");
|
||||
|
||||
if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
|
||||
{
|
||||
/* special case of 64 bit immediate load: */
|
||||
value = ((insn >> 13) & 0x7f) | (((insn >> 27) & 0x1ff) << 7)
|
||||
| (((insn >> 22) & 0x1f) << 16) | (((insn >> 21) & 0x1) << 21)
|
||||
| (slot[1] << 22) | (((insn >> 36) & 0x1) << 63);
|
||||
}
|
||||
else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
|
||||
{
|
||||
/* 62-bit immediate for nop.x/break.x */
|
||||
value = ((slot[1] & 0x1ffffffffffLL) << 21)
|
||||
| (((insn >> 36) & 0x1) << 20)
|
||||
| ((insn >> 6) & 0xfffff);
|
||||
}
|
||||
else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
|
||||
{
|
||||
/* 60-bit immediate for long branches. */
|
||||
value = (((insn >> 13) & 0xfffff)
|
||||
| (((insn >> 36) & 1) << 59)
|
||||
| (((slot[1] >> 2) & 0x7fffffffffLL) << 20)) << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = (*odesc->extract) (odesc, insn, &value);
|
||||
if (err)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "%s", err);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
switch (odesc->class)
|
||||
{
|
||||
case IA64_OPND_CLASS_CST:
|
||||
(*info->fprintf_func) (info->stream, "%s", odesc->str);
|
||||
break;
|
||||
|
||||
case IA64_OPND_CLASS_REG:
|
||||
if (odesc->str[0] == 'a' && odesc->str[1] == 'r')
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
case 4: case 5: case 6: case 7:
|
||||
sprintf (regname, "ar.k%u", (unsigned int) value);
|
||||
break;
|
||||
case 16: strcpy (regname, "ar.rsc"); break;
|
||||
case 17: strcpy (regname, "ar.bsp"); break;
|
||||
case 18: strcpy (regname, "ar.bspstore"); break;
|
||||
case 19: strcpy (regname, "ar.rnat"); break;
|
||||
case 32: strcpy (regname, "ar.ccv"); break;
|
||||
case 36: strcpy (regname, "ar.unat"); break;
|
||||
case 40: strcpy (regname, "ar.fpsr"); break;
|
||||
case 44: strcpy (regname, "ar.itc"); break;
|
||||
case 64: strcpy (regname, "ar.pfs"); break;
|
||||
case 65: strcpy (regname, "ar.lc"); break;
|
||||
case 66: strcpy (regname, "ar.ec"); break;
|
||||
default:
|
||||
sprintf (regname, "ar%u", (unsigned int) value);
|
||||
break;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%s", regname);
|
||||
}
|
||||
else if (odesc->str[0] == 'c' && odesc->str[1] == 'r')
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: strcpy (regname, "cr.dcr"); break;
|
||||
case 1: strcpy (regname, "cr.itm"); break;
|
||||
case 2: strcpy (regname, "cr.iva"); break;
|
||||
case 8: strcpy (regname, "cr.pta"); break;
|
||||
case 16: strcpy (regname, "cr.ipsr"); break;
|
||||
case 17: strcpy (regname, "cr.isr"); break;
|
||||
case 19: strcpy (regname, "cr.iip"); break;
|
||||
case 20: strcpy (regname, "cr.ifa"); break;
|
||||
case 21: strcpy (regname, "cr.itir"); break;
|
||||
case 22: strcpy (regname, "cr.iipa"); break;
|
||||
case 23: strcpy (regname, "cr.ifs"); break;
|
||||
case 24: strcpy (regname, "cr.iim"); break;
|
||||
case 25: strcpy (regname, "cr.iha"); break;
|
||||
case 64: strcpy (regname, "cr.lid"); break;
|
||||
case 65: strcpy (regname, "cr.ivr"); break;
|
||||
case 66: strcpy (regname, "cr.tpr"); break;
|
||||
case 67: strcpy (regname, "cr.eoi"); break;
|
||||
case 68: strcpy (regname, "cr.irr0"); break;
|
||||
case 69: strcpy (regname, "cr.irr1"); break;
|
||||
case 70: strcpy (regname, "cr.irr2"); break;
|
||||
case 71: strcpy (regname, "cr.irr3"); break;
|
||||
case 72: strcpy (regname, "cr.itv"); break;
|
||||
case 73: strcpy (regname, "cr.pmv"); break;
|
||||
case 74: strcpy (regname, "cr.cmcv"); break;
|
||||
case 80: strcpy (regname, "cr.lrr0"); break;
|
||||
case 81: strcpy (regname, "cr.lrr1"); break;
|
||||
default:
|
||||
sprintf (regname, "cr%u", (unsigned int) value);
|
||||
break;
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, "%s", regname);
|
||||
}
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s%d", odesc->str, (int)value);
|
||||
break;
|
||||
|
||||
case IA64_OPND_CLASS_IND:
|
||||
(*info->fprintf_func) (info->stream, "%s[r%d]", odesc->str, (int)value);
|
||||
break;
|
||||
|
||||
case IA64_OPND_CLASS_ABS:
|
||||
str = 0;
|
||||
if (odesc - elf64_ia64_operands == IA64_OPND_MBTYPE4)
|
||||
switch (value)
|
||||
{
|
||||
case 0x0: str = "@brcst"; break;
|
||||
case 0x8: str = "@mix"; break;
|
||||
case 0x9: str = "@shuf"; break;
|
||||
case 0xa: str = "@alt"; break;
|
||||
case 0xb: str = "@rev"; break;
|
||||
}
|
||||
|
||||
if (str)
|
||||
(*info->fprintf_func) (info->stream, "%s", str);
|
||||
else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_SIGNED)
|
||||
(*info->fprintf_func) (info->stream, "%lld", (long long) value);
|
||||
else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_UNSIGNED)
|
||||
(*info->fprintf_func) (info->stream, "%llu", (long long) value);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "0x%llx", (long long) value);
|
||||
break;
|
||||
|
||||
case IA64_OPND_CLASS_REL:
|
||||
(*info->print_address_func) (memaddr + value, info);
|
||||
break;
|
||||
}
|
||||
|
||||
need_comma = 1;
|
||||
if (j + 1 == idesc->num_outputs)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "=");
|
||||
need_comma = 0;
|
||||
}
|
||||
}
|
||||
if (slotnum + 1 == ia64_templ_desc[template].group_boundary
|
||||
|| ((slotnum == 2) && s_bit))
|
||||
(*info->fprintf_func) (info->stream, ";;");
|
||||
|
||||
done:
|
||||
ia64_free_opcode ((struct ia64_opcode *)idesc);
|
||||
failed:
|
||||
if (slotnum == 2)
|
||||
retval += 16 - 3*slot_multiplier;
|
||||
return retval;
|
||||
|
||||
decoding_failed:
|
||||
(*info->fprintf_func) (info->stream, " data8 %#011llx", (long long) insn);
|
||||
goto failed;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,419 +0,0 @@
|
||||
/* ia64-opc-a.c -- IA-64 `A' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
#define A IA64_TYPE_A, 1
|
||||
#define A2 IA64_TYPE_A, 2
|
||||
|
||||
/* instruction bit fields: */
|
||||
#define bC(x) (((ia64_insn) ((x) & 0x1)) << 12)
|
||||
#define bImm14(x) ((((ia64_insn) (((x) >> 0) & 0x7f)) << 13) | \
|
||||
(((ia64_insn) (((x) >> 7) & 0x3f)) << 27) | \
|
||||
(((ia64_insn) (((x) >> 13) & 0x01)) << 36))
|
||||
#define bR3a(x) (((ia64_insn) ((x) & 0x7f)) << 20)
|
||||
#define bR3b(x) (((ia64_insn) ((x) & 0x3)) << 20)
|
||||
#define bTa(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bTb(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bVe(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bX(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bX2(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bX2a(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bX2b(x) (((ia64_insn) ((x) & 0x3)) << 27)
|
||||
#define bX4(x) (((ia64_insn) ((x) & 0xf)) << 29)
|
||||
#define bZa(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bZb(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
|
||||
/* instruction bit masks: */
|
||||
#define mC bC (-1)
|
||||
#define mImm14 bImm14 (-1)
|
||||
#define mR3a bR3a (-1)
|
||||
#define mR3b bR3b (-1)
|
||||
#define mTa bTa (-1)
|
||||
#define mTb bTb (-1)
|
||||
#define mVe bVe (-1)
|
||||
#define mX bX (-1)
|
||||
#define mX2 bX2 (-1)
|
||||
#define mX2a bX2a (-1)
|
||||
#define mX2b bX2b (-1)
|
||||
#define mX4 bX4 (-1)
|
||||
#define mZa bZa (-1)
|
||||
#define mZb bZb (-1)
|
||||
|
||||
#define OpR3b(a,b) (bOp (a) | bR3b (b)), (mOp | mR3b)
|
||||
#define OpX2aVe(a,b,c) (bOp (a) | bX2a (b) | bVe (c)), \
|
||||
(mOp | mX2a | mVe)
|
||||
#define OpX2aVeR3a(a,b,c,d) (bOp (a) | bX2a (b) | bVe (c) | bR3a (d)), \
|
||||
(mOp | mX2a | mVe | mR3a)
|
||||
#define OpX2aVeImm14(a,b,c,d) (bOp (a) | bX2a (b) | bVe (c) | bImm14 (d)), \
|
||||
(mOp | mX2a | mVe | mImm14)
|
||||
#define OpX2aVeX4(a,b,c,d) (bOp (a) | bX2a (b) | bVe (c) | bX4 (d)), \
|
||||
(mOp | mX2a | mVe | mX4)
|
||||
#define OpX2aVeX4X2b(a,b,c,d,e) \
|
||||
(bOp (a) | bX2a (b) | bVe (c) | bX4 (d) | bX2b (e)), \
|
||||
(mOp | mX2a | mVe | mX4 | mX2b)
|
||||
#define OpX2TbTaC(a,b,c,d,e) \
|
||||
(bOp (a) | bX2 (b) | bTb (c) | bTa (d) | bC (e)), \
|
||||
(mOp | mX2 | mTb | mTa | mC)
|
||||
#define OpX2TaC(a,b,c,d) (bOp (a) | bX2 (b) | bTa (c) | bC (d)), \
|
||||
(mOp | mX2 | mTa | mC)
|
||||
#define OpX2aZaZbX4(a,b,c,d,e) \
|
||||
(bOp (a) | bX2a (b) | bZa (c) | bZb (d) | bX4 (e)), \
|
||||
(mOp | mX2a | mZa | mZb | mX4)
|
||||
#define OpX2aZaZbX4X2b(a,b,c,d,e,f) \
|
||||
(bOp (a) | bX2a (b) | bZa (c) | bZb (d) | bX4 (e) | bX2b (f)), \
|
||||
(mOp | mX2a | mZa | mZb | mX4 | mX2b)
|
||||
|
||||
/* Used to initialise unused fields in ia64_opcode struct,
|
||||
in order to stop gcc from complaining. */
|
||||
#define EMPTY 0,0,NULL
|
||||
|
||||
struct ia64_opcode ia64_opcodes_a[] =
|
||||
{
|
||||
/* A-type instruction encodings (sorted according to major opcode). */
|
||||
|
||||
{"add", A, OpX2aVeX4X2b (8, 0, 0, 0, 0), {R1, R2, R3}, EMPTY},
|
||||
{"add", A, OpX2aVeX4X2b (8, 0, 0, 0, 1), {R1, R2, R3, C1}, EMPTY},
|
||||
{"sub", A, OpX2aVeX4X2b (8, 0, 0, 1, 1), {R1, R2, R3}, EMPTY},
|
||||
{"sub", A, OpX2aVeX4X2b (8, 0, 0, 1, 0), {R1, R2, R3, C1}, EMPTY},
|
||||
{"addp4", A, OpX2aVeX4X2b (8, 0, 0, 2, 0), {R1, R2, R3}, EMPTY},
|
||||
{"and", A, OpX2aVeX4X2b (8, 0, 0, 3, 0), {R1, R2, R3}, EMPTY},
|
||||
{"andcm", A, OpX2aVeX4X2b (8, 0, 0, 3, 1), {R1, R2, R3}, EMPTY},
|
||||
{"or", A, OpX2aVeX4X2b (8, 0, 0, 3, 2), {R1, R2, R3}, EMPTY},
|
||||
{"xor", A, OpX2aVeX4X2b (8, 0, 0, 3, 3), {R1, R2, R3}, EMPTY},
|
||||
{"shladd", A, OpX2aVeX4 (8, 0, 0, 4), {R1, R2, CNT2a, R3}, EMPTY},
|
||||
{"shladdp4", A, OpX2aVeX4 (8, 0, 0, 6), {R1, R2, CNT2a, R3}, EMPTY},
|
||||
{"sub", A, OpX2aVeX4X2b (8, 0, 0, 9, 1), {R1, IMM8, R3}, EMPTY},
|
||||
{"and", A, OpX2aVeX4X2b (8, 0, 0, 0xb, 0), {R1, IMM8, R3}, EMPTY},
|
||||
{"andcm", A, OpX2aVeX4X2b (8, 0, 0, 0xb, 1), {R1, IMM8, R3}, EMPTY},
|
||||
{"or", A, OpX2aVeX4X2b (8, 0, 0, 0xb, 2), {R1, IMM8, R3}, EMPTY},
|
||||
{"xor", A, OpX2aVeX4X2b (8, 0, 0, 0xb, 3), {R1, IMM8, R3}, EMPTY},
|
||||
{"mov", A, OpX2aVeImm14 (8, 2, 0, 0), {R1, R3}, EMPTY},
|
||||
/* A mov immediate pseudo for adds was deleted. It failed for immediate
|
||||
operands requiring relocs, e.g. @pltoff(a). */
|
||||
{"adds", A, OpX2aVe (8, 2, 0), {R1, IMM14, R3}, EMPTY},
|
||||
{"addp4", A, OpX2aVe (8, 3, 0), {R1, IMM14, R3}, EMPTY},
|
||||
{"padd1", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 0, 0), {R1, R2, R3}, EMPTY},
|
||||
{"padd2", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 0, 0), {R1, R2, R3}, EMPTY},
|
||||
{"padd4", A, OpX2aZaZbX4X2b (8, 1, 1, 0, 0, 0), {R1, R2, R3}, EMPTY},
|
||||
{"padd1.sss", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"padd2.sss", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"padd1.uuu", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 0, 2), {R1, R2, R3}, EMPTY},
|
||||
{"padd2.uuu", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 0, 2), {R1, R2, R3}, EMPTY},
|
||||
{"padd1.uus", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 0, 3), {R1, R2, R3}, EMPTY},
|
||||
{"padd2.uus", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 0, 3), {R1, R2, R3}, EMPTY},
|
||||
{"psub1", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 1, 0), {R1, R2, R3}, EMPTY},
|
||||
{"psub2", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 1, 0), {R1, R2, R3}, EMPTY},
|
||||
{"psub4", A, OpX2aZaZbX4X2b (8, 1, 1, 0, 1, 0), {R1, R2, R3}, EMPTY},
|
||||
{"psub1.sss", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 1, 1), {R1, R2, R3}, EMPTY},
|
||||
{"psub2.sss", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 1, 1), {R1, R2, R3}, EMPTY},
|
||||
{"psub1.uuu", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 1, 2), {R1, R2, R3}, EMPTY},
|
||||
{"psub2.uuu", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 1, 2), {R1, R2, R3}, EMPTY},
|
||||
{"psub1.uus", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 1, 3), {R1, R2, R3}, EMPTY},
|
||||
{"psub2.uus", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 1, 3), {R1, R2, R3}, EMPTY},
|
||||
{"pavg1", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 2, 2), {R1, R2, R3}, EMPTY},
|
||||
{"pavg2", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 2, 2), {R1, R2, R3}, EMPTY},
|
||||
{"pavg1.raz", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 2, 3), {R1, R2, R3}, EMPTY},
|
||||
{"pavg2.raz", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 2, 3), {R1, R2, R3}, EMPTY},
|
||||
{"pavgsub1", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 3, 2), {R1, R2, R3}, EMPTY},
|
||||
{"pavgsub2", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 3, 2), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp1.eq", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 9, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp2.eq", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 9, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp4.eq", A, OpX2aZaZbX4X2b (8, 1, 1, 0, 9, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp1.gt", A, OpX2aZaZbX4X2b (8, 1, 0, 0, 9, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp2.gt", A, OpX2aZaZbX4X2b (8, 1, 0, 1, 9, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pcmp4.gt", A, OpX2aZaZbX4X2b (8, 1, 1, 0, 9, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pshladd2", A, OpX2aZaZbX4 (8, 1, 0, 1, 4), {R1, R2, CNT2b, R3}, EMPTY},
|
||||
{"pshradd2", A, OpX2aZaZbX4 (8, 1, 0, 1, 6), {R1, R2, CNT2b, R3}, EMPTY},
|
||||
|
||||
{"mov", A, OpR3b (9, 0), {R1, IMM22}, PSEUDO, 0, NULL},
|
||||
{"addl", A, Op (9), {R1, IMM22, R3_2}, EMPTY},
|
||||
|
||||
{"cmp.lt", A2, OpX2TbTaC (0xc, 0, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.le", A2, OpX2TbTaC (0xc, 0, 0, 0, 0), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp.gt", A2, OpX2TbTaC (0xc, 0, 0, 0, 0), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp.ge", A2, OpX2TbTaC (0xc, 0, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.lt.unc", A2, OpX2TbTaC (0xc, 0, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.le.unc", A2, OpX2TbTaC (0xc, 0, 0, 0, 1), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp.gt.unc", A2, OpX2TbTaC (0xc, 0, 0, 0, 1), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp.ge.unc", A2, OpX2TbTaC (0xc, 0, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.eq.and", A2, OpX2TbTaC (0xc, 0, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.ne.andcm", A2, OpX2TbTaC (0xc, 0, 0, 1, 0), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.and", A2, OpX2TbTaC (0xc, 0, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.eq.andcm", A2, OpX2TbTaC (0xc, 0, 0, 1, 1), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt", A2, OpX2TbTaC (0xc, 1, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.le", A2, OpX2TbTaC (0xc, 1, 0, 0, 0), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp4.gt", A2, OpX2TbTaC (0xc, 1, 0, 0, 0), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp4.ge", A2, OpX2TbTaC (0xc, 1, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.lt.unc", A2, OpX2TbTaC (0xc, 1, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.le.unc", A2, OpX2TbTaC (0xc, 1, 0, 0, 1), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp4.gt.unc", A2, OpX2TbTaC (0xc, 1, 0, 0, 1), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp4.ge.unc", A2, OpX2TbTaC (0xc, 1, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.and", A2, OpX2TbTaC (0xc, 1, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.ne.andcm", A2, OpX2TbTaC (0xc, 1, 0, 1, 0), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.and", A2, OpX2TbTaC (0xc, 1, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.andcm", A2, OpX2TbTaC (0xc, 1, 0, 1, 1), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.and", A2, OpX2TbTaC (0xc, 0, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.lt.and", A2, OpX2TbTaC (0xc, 0, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.andcm", A2, OpX2TbTaC (0xc, 0, 1, 0, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.andcm", A2, OpX2TbTaC (0xc, 0, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.and", A2, OpX2TbTaC (0xc, 0, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.ge.and", A2, OpX2TbTaC (0xc, 0, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.andcm", A2, OpX2TbTaC (0xc, 0, 1, 0, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.andcm", A2, OpX2TbTaC (0xc, 0, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.and", A2, OpX2TbTaC (0xc, 0, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.le.and", A2, OpX2TbTaC (0xc, 0, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.andcm", A2, OpX2TbTaC (0xc, 0, 1, 1, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.andcm", A2, OpX2TbTaC (0xc, 0, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.and", A2, OpX2TbTaC (0xc, 0, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.gt.and", A2, OpX2TbTaC (0xc, 0, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.andcm", A2, OpX2TbTaC (0xc, 0, 1, 1, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.andcm", A2, OpX2TbTaC (0xc, 0, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.and", A2, OpX2TbTaC (0xc, 1, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.lt.and", A2, OpX2TbTaC (0xc, 1, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.andcm", A2, OpX2TbTaC (0xc, 1, 1, 0, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.andcm", A2, OpX2TbTaC (0xc, 1, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.and", A2, OpX2TbTaC (0xc, 1, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.ge.and", A2, OpX2TbTaC (0xc, 1, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.andcm", A2, OpX2TbTaC (0xc, 1, 1, 0, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.andcm", A2, OpX2TbTaC (0xc, 1, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.and", A2, OpX2TbTaC (0xc, 1, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.le.and", A2, OpX2TbTaC (0xc, 1, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.andcm", A2, OpX2TbTaC (0xc, 1, 1, 1, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.andcm", A2, OpX2TbTaC (0xc, 1, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.and", A2, OpX2TbTaC (0xc, 1, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.gt.and", A2, OpX2TbTaC (0xc, 1, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.andcm", A2, OpX2TbTaC (0xc, 1, 1, 1, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.andcm", A2, OpX2TbTaC (0xc, 1, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt", A2, OpX2TaC (0xc, 2, 0, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.le", A2, OpX2TaC (0xc, 2, 0, 0), {P1, P2, IMM8M1, R3}, EMPTY},
|
||||
{"cmp.gt", A2, OpX2TaC (0xc, 2, 0, 0), {P2, P1, IMM8M1, R3}, EMPTY},
|
||||
{"cmp.ge", A2, OpX2TaC (0xc, 2, 0, 0), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.lt.unc", A2, OpX2TaC (0xc, 2, 0, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.le.unc", A2, OpX2TaC (0xc, 2, 0, 1), {P1, P2, IMM8M1, R3}, EMPTY},
|
||||
{"cmp.gt.unc", A2, OpX2TaC (0xc, 2, 0, 1), {P2, P1, IMM8M1, R3}, EMPTY},
|
||||
{"cmp.ge.unc", A2, OpX2TaC (0xc, 2, 0, 1), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.and", A2, OpX2TaC (0xc, 2, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.ne.andcm", A2, OpX2TaC (0xc, 2, 1, 0), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.and", A2, OpX2TaC (0xc, 2, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.andcm", A2, OpX2TaC (0xc, 2, 1, 1), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt", A2, OpX2TaC (0xc, 3, 0, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.le", A2, OpX2TaC (0xc, 3, 0, 0), {P1, P2, IMM8M1, R3}, EMPTY},
|
||||
{"cmp4.gt", A2, OpX2TaC (0xc, 3, 0, 0), {P2, P1, IMM8M1, R3}, EMPTY},
|
||||
{"cmp4.ge", A2, OpX2TaC (0xc, 3, 0, 0), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp4.lt.unc", A2, OpX2TaC (0xc, 3, 0, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.le.unc", A2, OpX2TaC (0xc, 3, 0, 1), {P1, P2, IMM8M1, R3}, EMPTY},
|
||||
{"cmp4.gt.unc", A2, OpX2TaC (0xc, 3, 0, 1), {P2, P1, IMM8M1, R3}, EMPTY},
|
||||
{"cmp4.ge.unc", A2, OpX2TaC (0xc, 3, 0, 1), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.and", A2, OpX2TaC (0xc, 3, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.ne.andcm", A2, OpX2TaC (0xc, 3, 1, 0), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.and", A2, OpX2TaC (0xc, 3, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.andcm", A2, OpX2TaC (0xc, 3, 1, 1), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ltu", A2, OpX2TbTaC (0xd, 0, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.leu", A2, OpX2TbTaC (0xd, 0, 0, 0, 0), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp.gtu", A2, OpX2TbTaC (0xd, 0, 0, 0, 0), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp.geu", A2, OpX2TbTaC (0xd, 0, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.ltu.unc", A2, OpX2TbTaC (0xd, 0, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.leu.unc", A2, OpX2TbTaC (0xd, 0, 0, 0, 1), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp.gtu.unc", A2, OpX2TbTaC (0xd, 0, 0, 0, 1), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp.geu.unc", A2, OpX2TbTaC (0xd, 0, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.eq.or", A2, OpX2TbTaC (0xd, 0, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.ne.orcm", A2, OpX2TbTaC (0xd, 0, 0, 1, 0), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.or", A2, OpX2TbTaC (0xd, 0, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.eq.orcm", A2, OpX2TbTaC (0xd, 0, 0, 1, 1), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ltu", A2, OpX2TbTaC (0xd, 1, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.leu", A2, OpX2TbTaC (0xd, 1, 0, 0, 0), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp4.gtu", A2, OpX2TbTaC (0xd, 1, 0, 0, 0), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp4.geu", A2, OpX2TbTaC (0xd, 1, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.ltu.unc", A2, OpX2TbTaC (0xd, 1, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.leu.unc", A2, OpX2TbTaC (0xd, 1, 0, 0, 1), {P2, P1, R3, R2}, EMPTY},
|
||||
{"cmp4.gtu.unc", A2, OpX2TbTaC (0xd, 1, 0, 0, 1), {P1, P2, R3, R2}, EMPTY},
|
||||
{"cmp4.geu.unc", A2, OpX2TbTaC (0xd, 1, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.or", A2, OpX2TbTaC (0xd, 1, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.ne.orcm", A2, OpX2TbTaC (0xd, 1, 0, 1, 0), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.or", A2, OpX2TbTaC (0xd, 1, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.orcm", A2, OpX2TbTaC (0xd, 1, 0, 1, 1), {P1, P2, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.or", A2, OpX2TbTaC (0xd, 0, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.lt.or", A2, OpX2TbTaC (0xd, 0, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.orcm", A2, OpX2TbTaC (0xd, 0, 1, 0, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.orcm", A2, OpX2TbTaC (0xd, 0, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.or", A2, OpX2TbTaC (0xd, 0, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.ge.or", A2, OpX2TbTaC (0xd, 0, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.orcm", A2, OpX2TbTaC (0xd, 0, 1, 0, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.orcm", A2, OpX2TbTaC (0xd, 0, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.or", A2, OpX2TbTaC (0xd, 0, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.le.or", A2, OpX2TbTaC (0xd, 0, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.orcm", A2, OpX2TbTaC (0xd, 0, 1, 1, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.orcm", A2, OpX2TbTaC (0xd, 0, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.or", A2, OpX2TbTaC (0xd, 0, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.gt.or", A2, OpX2TbTaC (0xd, 0, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.orcm", A2, OpX2TbTaC (0xd, 0, 1, 1, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.orcm", A2, OpX2TbTaC (0xd, 0, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.or", A2, OpX2TbTaC (0xd, 1, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.lt.or", A2, OpX2TbTaC (0xd, 1, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.orcm", A2, OpX2TbTaC (0xd, 1, 1, 0, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.orcm", A2, OpX2TbTaC (0xd, 1, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.or", A2, OpX2TbTaC (0xd, 1, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.ge.or", A2, OpX2TbTaC (0xd, 1, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.orcm", A2, OpX2TbTaC (0xd, 1, 1, 0, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.orcm", A2, OpX2TbTaC (0xd, 1, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.or", A2, OpX2TbTaC (0xd, 1, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.le.or", A2, OpX2TbTaC (0xd, 1, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.orcm", A2, OpX2TbTaC (0xd, 1, 1, 1, 0), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.orcm", A2, OpX2TbTaC (0xd, 1, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.or", A2, OpX2TbTaC (0xd, 1, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.gt.or", A2, OpX2TbTaC (0xd, 1, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.orcm", A2, OpX2TbTaC (0xd, 1, 1, 1, 1), {P1, P2, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.orcm", A2, OpX2TbTaC (0xd, 1, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ltu", A2, OpX2TaC (0xd, 2, 0, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.leu", A2, OpX2TaC (0xd, 2, 0, 0), {P1, P2, IMM8M1U8, R3}, EMPTY},
|
||||
{"cmp.gtu", A2, OpX2TaC (0xd, 2, 0, 0), {P2, P1, IMM8M1U8, R3}, EMPTY},
|
||||
{"cmp.geu", A2, OpX2TaC (0xd, 2, 0, 0), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.ltu.unc", A2, OpX2TaC (0xd, 2, 0, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.leu.unc", A2, OpX2TaC (0xd, 2, 0, 1), {P1, P2, IMM8M1U8, R3}, EMPTY},
|
||||
{"cmp.gtu.unc", A2, OpX2TaC (0xd, 2, 0, 1), {P2, P1, IMM8M1U8, R3}, EMPTY},
|
||||
{"cmp.geu.unc", A2, OpX2TaC (0xd, 2, 0, 1), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.or", A2, OpX2TaC (0xd, 2, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.ne.orcm", A2, OpX2TaC (0xd, 2, 1, 0), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.or", A2, OpX2TaC (0xd, 2, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.orcm", A2, OpX2TaC (0xd, 2, 1, 1), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ltu", A2, OpX2TaC (0xd, 3, 0, 0), {P1, P2, IMM8U4, R3}, EMPTY},
|
||||
{"cmp4.leu", A2, OpX2TaC (0xd, 3, 0, 0), {P1, P2, IMM8M1U4, R3}, EMPTY},
|
||||
{"cmp4.gtu", A2, OpX2TaC (0xd, 3, 0, 0), {P2, P1, IMM8M1U4, R3}, EMPTY},
|
||||
{"cmp4.geu", A2, OpX2TaC (0xd, 3, 0, 0), {P2, P1, IMM8U4, R3}, EMPTY},
|
||||
{"cmp4.ltu.unc", A2, OpX2TaC (0xd, 3, 0, 1), {P1, P2, IMM8U4, R3}, EMPTY},
|
||||
{"cmp4.leu.unc", A2, OpX2TaC (0xd, 3, 0, 1), {P1, P2, IMM8M1U4, R3}, EMPTY},
|
||||
{"cmp4.gtu.unc", A2, OpX2TaC (0xd, 3, 0, 1), {P2, P1, IMM8M1U4, R3}, EMPTY},
|
||||
{"cmp4.geu.unc", A2, OpX2TaC (0xd, 3, 0, 1), {P2, P1, IMM8U4, R3}, EMPTY},
|
||||
{"cmp4.eq.or", A2, OpX2TaC (0xd, 3, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.ne.orcm", A2, OpX2TaC (0xd, 3, 1, 0), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.or", A2, OpX2TaC (0xd, 3, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.orcm", A2, OpX2TaC (0xd, 3, 1, 1), {P1, P2, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.eq", A2, OpX2TbTaC (0xe, 0, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.ne", A2, OpX2TbTaC (0xe, 0, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.eq.unc", A2, OpX2TbTaC (0xe, 0, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.ne.unc", A2, OpX2TbTaC (0xe, 0, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp.eq.or.andcm", A2, OpX2TbTaC (0xe, 0, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.ne.and.orcm", A2, OpX2TbTaC (0xe, 0, 0, 1, 0), {P2, P1, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.or.andcm", A2, OpX2TbTaC (0xe, 0, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp.eq.and.orcm", A2, OpX2TbTaC (0xe, 0, 0, 1, 1), {P2, P1, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.eq", A2, OpX2TbTaC (0xe, 1, 0, 0, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.ne", A2, OpX2TbTaC (0xe, 1, 0, 0, 0), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.unc", A2, OpX2TbTaC (0xe, 1, 0, 0, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.ne.unc", A2, OpX2TbTaC (0xe, 1, 0, 0, 1), {P2, P1, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.or.andcm", A2, OpX2TbTaC (0xe, 1, 0, 1, 0), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.ne.and.orcm", A2, OpX2TbTaC (0xe, 1, 0, 1, 0), {P2, P1, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.or.andcm", A2, OpX2TbTaC (0xe, 1, 0, 1, 1), {P1, P2, R2, R3}, EMPTY},
|
||||
{"cmp4.eq.and.orcm", A2, OpX2TbTaC (0xe, 1, 0, 1, 1), {P2, P1, R2, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.lt.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 0), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 0), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.ge.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 1), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 0, 1), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.le.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 0), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.gt.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 0), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.lt.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp.gt.or.andcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.ge.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 1), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.le.and.orcm", A2, OpX2TbTaC (0xe, 0, 1, 1, 1), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.lt.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 0), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 0), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.ge.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 1), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 0, 1), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 0), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.le.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 0), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 0), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.gt.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 0), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.lt.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 1), {P1, P2, GR0, R3}, EMPTY},
|
||||
{"cmp4.gt.or.andcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 1), {P1, P2, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ge.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 1), {P2, P1, GR0, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.le.and.orcm", A2, OpX2TbTaC (0xe, 1, 1, 1, 1), {P2, P1, R3, GR0}, PSEUDO, 0, NULL},
|
||||
{"cmp.eq", A2, OpX2TaC (0xe, 2, 0, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.ne", A2, OpX2TaC (0xe, 2, 0, 0), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.unc", A2, OpX2TaC (0xe, 2, 0, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.ne.unc", A2, OpX2TaC (0xe, 2, 0, 1), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.or.andcm", A2, OpX2TaC (0xe, 2, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.ne.and.orcm", A2, OpX2TaC (0xe, 2, 1, 0), {P2, P1, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp.ne.or.andcm", A2, OpX2TaC (0xe, 2, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp.eq.and.orcm", A2, OpX2TaC (0xe, 2, 1, 1), {P2, P1, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.eq", A2, OpX2TaC (0xe, 3, 0, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.ne", A2, OpX2TaC (0xe, 3, 0, 0), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.unc", A2, OpX2TaC (0xe, 3, 0, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.ne.unc", A2, OpX2TaC (0xe, 3, 0, 1), {P2, P1, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.or.andcm", A2, OpX2TaC (0xe, 3, 1, 0), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.ne.and.orcm", A2, OpX2TaC (0xe, 3, 1, 0), {P2, P1, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
{"cmp4.ne.or.andcm", A2, OpX2TaC (0xe, 3, 1, 1), {P1, P2, IMM8, R3}, EMPTY},
|
||||
{"cmp4.eq.and.orcm", A2, OpX2TaC (0xe, 3, 1, 1), {P2, P1, IMM8, R3}, PSEUDO, 0, NULL},
|
||||
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#undef A
|
||||
#undef A2
|
||||
#undef bC
|
||||
#undef bImm14
|
||||
#undef bR3a
|
||||
#undef bR3b
|
||||
#undef bTa
|
||||
#undef bTb
|
||||
#undef bVe
|
||||
#undef bX
|
||||
#undef bX2
|
||||
#undef bX2a
|
||||
#undef bX2b
|
||||
#undef bX4
|
||||
#undef bZa
|
||||
#undef bZb
|
||||
#undef mC
|
||||
#undef mImm14
|
||||
#undef mR3a
|
||||
#undef mR3b
|
||||
#undef mTa
|
||||
#undef mTb
|
||||
#undef mVe
|
||||
#undef mX
|
||||
#undef mX2
|
||||
#undef mX2a
|
||||
#undef mX2b
|
||||
#undef mX4
|
||||
#undef mZa
|
||||
#undef mZb
|
||||
#undef OpR3a
|
||||
#undef OpR3b
|
||||
#undef OpX2aVe
|
||||
#undef OpX2aVeImm14
|
||||
#undef OpX2aVeX4
|
||||
#undef OpX2aVeX4X2b
|
||||
#undef OpX2TbTaC
|
||||
#undef OpX2TaC
|
||||
#undef OpX2aZaZbX4
|
||||
#undef OpX2aZaZbX4X2b
|
||||
#undef EMPTY
|
||||
@@ -1,512 +0,0 @@
|
||||
/* ia64-opc-b.c -- IA-64 `B' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2002, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
#define B0 IA64_TYPE_B, 0
|
||||
#define B IA64_TYPE_B, 1
|
||||
|
||||
/* instruction bit fields: */
|
||||
#define bBtype(x) (((ia64_insn) ((x) & 0x7)) << 6)
|
||||
#define bD(x) (((ia64_insn) ((x) & 0x1)) << 35)
|
||||
#define bIh(x) (((ia64_insn) ((x) & 0x1)) << 35)
|
||||
#define bPa(x) (((ia64_insn) ((x) & 0x1)) << 12)
|
||||
#define bPr(x) (((ia64_insn) ((x) & 0x3f)) << 0)
|
||||
#define bWha(x) (((ia64_insn) ((x) & 0x3)) << 33)
|
||||
#define bWhb(x) (((ia64_insn) ((x) & 0x3)) << 3)
|
||||
#define bWhc(x) (((ia64_insn) ((x) & 0x7)) << 32)
|
||||
#define bX6(x) (((ia64_insn) ((x) & 0x3f)) << 27)
|
||||
|
||||
#define mBtype bBtype (-1)
|
||||
#define mD bD (-1)
|
||||
#define mIh bIh (-1)
|
||||
#define mPa bPa (-1)
|
||||
#define mPr bPr (-1)
|
||||
#define mWha bWha (-1)
|
||||
#define mWhb bWhb (-1)
|
||||
#define mWhc bWhc (-1)
|
||||
#define mX6 bX6 (-1)
|
||||
|
||||
#define OpX6(a,b) (bOp (a) | bX6 (b)), (mOp | mX6)
|
||||
#define OpPaWhaD(a,b,c,d) \
|
||||
(bOp (a) | bPa (b) | bWha (c) | bD (d)), (mOp | mPa | mWha | mD)
|
||||
#define OpPaWhcD(a,b,c,d) \
|
||||
(bOp (a) | bPa (b) | bWhc (c) | bD (d)), (mOp | mPa | mWhc | mD)
|
||||
#define OpBtypePaWhaD(a,b,c,d,e) \
|
||||
(bOp (a) | bBtype (b) | bPa (c) | bWha (d) | bD (e)), \
|
||||
(mOp | mBtype | mPa | mWha | mD)
|
||||
#define OpBtypePaWhaDPr(a,b,c,d,e,f) \
|
||||
(bOp (a) | bBtype (b) | bPa (c) | bWha (d) | bD (e) | bPr (f)), \
|
||||
(mOp | mBtype | mPa | mWha | mD | mPr)
|
||||
#define OpX6BtypePaWhaD(a,b,c,d,e,f) \
|
||||
(bOp (a) | bX6 (b) | bBtype (c) | bPa (d) | bWha (e) | bD (f)), \
|
||||
(mOp | mX6 | mBtype | mPa | mWha | mD)
|
||||
#define OpX6BtypePaWhaDPr(a,b,c,d,e,f,g) \
|
||||
(bOp (a) | bX6 (b) | bBtype (c) | bPa (d) | bWha (e) | bD (f) | bPr (g)), \
|
||||
(mOp | mX6 | mBtype | mPa | mWha | mD | mPr)
|
||||
#define OpIhWhb(a,b,c) \
|
||||
(bOp (a) | bIh (b) | bWhb (c)), \
|
||||
(mOp | mIh | mWhb)
|
||||
#define OpX6IhWhb(a,b,c,d) \
|
||||
(bOp (a) | bX6 (b) | bIh (c) | bWhb (d)), \
|
||||
(mOp | mX6 | mIh | mWhb)
|
||||
|
||||
/* Used to initialise unused fields in ia64_opcode struct,
|
||||
in order to stop gcc from complaining. */
|
||||
#define EMPTY 0,0,NULL
|
||||
|
||||
struct ia64_opcode ia64_opcodes_b[] =
|
||||
{
|
||||
/* B-type instruction encodings (sorted according to major opcode) */
|
||||
|
||||
#define BR(a,b) \
|
||||
B0, OpX6BtypePaWhaDPr (0, 0x20, 0, a, 0, b, 0), {B2}, PSEUDO, 0, NULL
|
||||
{"br.few", BR (0, 0)},
|
||||
{"br", BR (0, 0)},
|
||||
{"br.few.clr", BR (0, 1)},
|
||||
{"br.clr", BR (0, 1)},
|
||||
{"br.many", BR (1, 0)},
|
||||
{"br.many.clr", BR (1, 1)},
|
||||
#undef BR
|
||||
|
||||
#define BR(a,b,c,d,e) B0, OpX6BtypePaWhaD (0, a, b, c, d, e), {B2}, EMPTY
|
||||
#define BRP(a,b,c,d,e) B0, OpX6BtypePaWhaD (0, a, b, c, d, e), {B2}, PSEUDO, 0, NULL
|
||||
#define BRT(a,b,c,d,e,f) B0, OpX6BtypePaWhaD (0, a, b, c, d, e), {B2}, f, 0, NULL
|
||||
{"br.cond.sptk.few", BR (0x20, 0, 0, 0, 0)},
|
||||
{"br.cond.sptk", BRP (0x20, 0, 0, 0, 0)},
|
||||
{"br.cond.sptk.few.clr", BR (0x20, 0, 0, 0, 1)},
|
||||
{"br.cond.sptk.clr", BRP (0x20, 0, 0, 0, 1)},
|
||||
{"br.cond.spnt.few", BR (0x20, 0, 0, 1, 0)},
|
||||
{"br.cond.spnt", BRP (0x20, 0, 0, 1, 0)},
|
||||
{"br.cond.spnt.few.clr", BR (0x20, 0, 0, 1, 1)},
|
||||
{"br.cond.spnt.clr", BRP (0x20, 0, 0, 1, 1)},
|
||||
{"br.cond.dptk.few", BR (0x20, 0, 0, 2, 0)},
|
||||
{"br.cond.dptk", BRP (0x20, 0, 0, 2, 0)},
|
||||
{"br.cond.dptk.few.clr", BR (0x20, 0, 0, 2, 1)},
|
||||
{"br.cond.dptk.clr", BRP (0x20, 0, 0, 2, 1)},
|
||||
{"br.cond.dpnt.few", BR (0x20, 0, 0, 3, 0)},
|
||||
{"br.cond.dpnt", BRP (0x20, 0, 0, 3, 0)},
|
||||
{"br.cond.dpnt.few.clr", BR (0x20, 0, 0, 3, 1)},
|
||||
{"br.cond.dpnt.clr", BRP (0x20, 0, 0, 3, 1)},
|
||||
{"br.cond.sptk.many", BR (0x20, 0, 1, 0, 0)},
|
||||
{"br.cond.sptk.many.clr", BR (0x20, 0, 1, 0, 1)},
|
||||
{"br.cond.spnt.many", BR (0x20, 0, 1, 1, 0)},
|
||||
{"br.cond.spnt.many.clr", BR (0x20, 0, 1, 1, 1)},
|
||||
{"br.cond.dptk.many", BR (0x20, 0, 1, 2, 0)},
|
||||
{"br.cond.dptk.many.clr", BR (0x20, 0, 1, 2, 1)},
|
||||
{"br.cond.dpnt.many", BR (0x20, 0, 1, 3, 0)},
|
||||
{"br.cond.dpnt.many.clr", BR (0x20, 0, 1, 3, 1)},
|
||||
{"br.sptk.few", BR (0x20, 0, 0, 0, 0)},
|
||||
{"br.sptk", BRP (0x20, 0, 0, 0, 0)},
|
||||
{"br.sptk.few.clr", BR (0x20, 0, 0, 0, 1)},
|
||||
{"br.sptk.clr", BRP (0x20, 0, 0, 0, 1)},
|
||||
{"br.spnt.few", BR (0x20, 0, 0, 1, 0)},
|
||||
{"br.spnt", BRP (0x20, 0, 0, 1, 0)},
|
||||
{"br.spnt.few.clr", BR (0x20, 0, 0, 1, 1)},
|
||||
{"br.spnt.clr", BRP (0x20, 0, 0, 1, 1)},
|
||||
{"br.dptk.few", BR (0x20, 0, 0, 2, 0)},
|
||||
{"br.dptk", BRP (0x20, 0, 0, 2, 0)},
|
||||
{"br.dptk.few.clr", BR (0x20, 0, 0, 2, 1)},
|
||||
{"br.dptk.clr", BRP (0x20, 0, 0, 2, 1)},
|
||||
{"br.dpnt.few", BR (0x20, 0, 0, 3, 0)},
|
||||
{"br.dpnt", BRP (0x20, 0, 0, 3, 0)},
|
||||
{"br.dpnt.few.clr", BR (0x20, 0, 0, 3, 1)},
|
||||
{"br.dpnt.clr", BRP (0x20, 0, 0, 3, 1)},
|
||||
{"br.sptk.many", BR (0x20, 0, 1, 0, 0)},
|
||||
{"br.sptk.many.clr", BR (0x20, 0, 1, 0, 1)},
|
||||
{"br.spnt.many", BR (0x20, 0, 1, 1, 0)},
|
||||
{"br.spnt.many.clr", BR (0x20, 0, 1, 1, 1)},
|
||||
{"br.dptk.many", BR (0x20, 0, 1, 2, 0)},
|
||||
{"br.dptk.many.clr", BR (0x20, 0, 1, 2, 1)},
|
||||
{"br.dpnt.many", BR (0x20, 0, 1, 3, 0)},
|
||||
{"br.dpnt.many.clr", BR (0x20, 0, 1, 3, 1)},
|
||||
{"br.ia.sptk.few", BR (0x20, 1, 0, 0, 0)},
|
||||
{"br.ia.sptk", BRP (0x20, 1, 0, 0, 0)},
|
||||
{"br.ia.sptk.few.clr", BR (0x20, 1, 0, 0, 1)},
|
||||
{"br.ia.sptk.clr", BRP (0x20, 1, 0, 0, 1)},
|
||||
{"br.ia.spnt.few", BR (0x20, 1, 0, 1, 0)},
|
||||
{"br.ia.spnt", BRP (0x20, 1, 0, 1, 0)},
|
||||
{"br.ia.spnt.few.clr", BR (0x20, 1, 0, 1, 1)},
|
||||
{"br.ia.spnt.clr", BRP (0x20, 1, 0, 1, 1)},
|
||||
{"br.ia.dptk.few", BR (0x20, 1, 0, 2, 0)},
|
||||
{"br.ia.dptk", BRP (0x20, 1, 0, 2, 0)},
|
||||
{"br.ia.dptk.few.clr", BR (0x20, 1, 0, 2, 1)},
|
||||
{"br.ia.dptk.clr", BRP (0x20, 1, 0, 2, 1)},
|
||||
{"br.ia.dpnt.few", BR (0x20, 1, 0, 3, 0)},
|
||||
{"br.ia.dpnt", BRP (0x20, 1, 0, 3, 0)},
|
||||
{"br.ia.dpnt.few.clr", BR (0x20, 1, 0, 3, 1)},
|
||||
{"br.ia.dpnt.clr", BRP (0x20, 1, 0, 3, 1)},
|
||||
{"br.ia.sptk.many", BR (0x20, 1, 1, 0, 0)},
|
||||
{"br.ia.sptk.many.clr", BR (0x20, 1, 1, 0, 1)},
|
||||
{"br.ia.spnt.many", BR (0x20, 1, 1, 1, 0)},
|
||||
{"br.ia.spnt.many.clr", BR (0x20, 1, 1, 1, 1)},
|
||||
{"br.ia.dptk.many", BR (0x20, 1, 1, 2, 0)},
|
||||
{"br.ia.dptk.many.clr", BR (0x20, 1, 1, 2, 1)},
|
||||
{"br.ia.dpnt.many", BR (0x20, 1, 1, 3, 0)},
|
||||
{"br.ia.dpnt.many.clr", BR (0x20, 1, 1, 3, 1)},
|
||||
{"br.ret.sptk.few", BRT (0x21, 4, 0, 0, 0, MOD_RRBS)},
|
||||
{"br.ret.sptk", BRT (0x21, 4, 0, 0, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.sptk.few.clr", BRT (0x21, 4, 0, 0, 1, MOD_RRBS)},
|
||||
{"br.ret.sptk.clr", BRT (0x21, 4, 0, 0, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.spnt.few", BRT (0x21, 4, 0, 1, 0, MOD_RRBS)},
|
||||
{"br.ret.spnt", BRT (0x21, 4, 0, 1, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.spnt.few.clr", BRT (0x21, 4, 0, 1, 1, MOD_RRBS)},
|
||||
{"br.ret.spnt.clr", BRT (0x21, 4, 0, 1, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.dptk.few", BRT (0x21, 4, 0, 2, 0, MOD_RRBS)},
|
||||
{"br.ret.dptk", BRT (0x21, 4, 0, 2, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.dptk.few.clr", BRT (0x21, 4, 0, 2, 1, MOD_RRBS)},
|
||||
{"br.ret.dptk.clr", BRT (0x21, 4, 0, 2, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.dpnt.few", BRT (0x21, 4, 0, 3, 0, MOD_RRBS)},
|
||||
{"br.ret.dpnt", BRT (0x21, 4, 0, 3, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.dpnt.few.clr", BRT (0x21, 4, 0, 3, 1, MOD_RRBS)},
|
||||
{"br.ret.dpnt.clr", BRT (0x21, 4, 0, 3, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ret.sptk.many", BRT (0x21, 4, 1, 0, 0, MOD_RRBS)},
|
||||
{"br.ret.sptk.many.clr", BRT (0x21, 4, 1, 0, 1, MOD_RRBS)},
|
||||
{"br.ret.spnt.many", BRT (0x21, 4, 1, 1, 0, MOD_RRBS)},
|
||||
{"br.ret.spnt.many.clr", BRT (0x21, 4, 1, 1, 1, MOD_RRBS)},
|
||||
{"br.ret.dptk.many", BRT (0x21, 4, 1, 2, 0, MOD_RRBS)},
|
||||
{"br.ret.dptk.many.clr", BRT (0x21, 4, 1, 2, 1, MOD_RRBS)},
|
||||
{"br.ret.dpnt.many", BRT (0x21, 4, 1, 3, 0, MOD_RRBS)},
|
||||
{"br.ret.dpnt.many.clr", BRT (0x21, 4, 1, 3, 1, MOD_RRBS)},
|
||||
#undef BR
|
||||
#undef BRP
|
||||
#undef BRT
|
||||
|
||||
{"cover", B0, OpX6 (0, 0x02), {0, }, NO_PRED | LAST | MOD_RRBS, 0, NULL},
|
||||
{"clrrrb", B0, OpX6 (0, 0x04), {0, }, NO_PRED | LAST | MOD_RRBS, 0, NULL},
|
||||
{"clrrrb.pr", B0, OpX6 (0, 0x05), {0, }, NO_PRED | LAST | MOD_RRBS, 0, NULL},
|
||||
{"rfi", B0, OpX6 (0, 0x08), {0, }, NO_PRED | LAST | PRIV | MOD_RRBS, 0, NULL},
|
||||
{"bsw.0", B0, OpX6 (0, 0x0c), {0, }, NO_PRED | LAST | PRIV, 0, NULL},
|
||||
{"bsw.1", B0, OpX6 (0, 0x0d), {0, }, NO_PRED | LAST | PRIV, 0, NULL},
|
||||
{"epc", B0, OpX6 (0, 0x10), {0, }, NO_PRED, 0, NULL},
|
||||
{"vmsw.0", B0, OpX6 (0, 0x18), {0, }, NO_PRED | PRIV, 0, NULL},
|
||||
{"vmsw.1", B0, OpX6 (0, 0x19), {0, }, NO_PRED | PRIV, 0, NULL},
|
||||
|
||||
{"break.b", B0, OpX6 (0, 0x00), {IMMU21}, EMPTY},
|
||||
|
||||
{"br.call.sptk.few", B, OpPaWhcD (1, 0, 1, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.sptk", B, OpPaWhcD (1, 0, 1, 0), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.sptk.few.clr", B, OpPaWhcD (1, 0, 1, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.sptk.clr", B, OpPaWhcD (1, 0, 1, 1), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.spnt.few", B, OpPaWhcD (1, 0, 3, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.spnt", B, OpPaWhcD (1, 0, 3, 0), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.spnt.few.clr", B, OpPaWhcD (1, 0, 3, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.spnt.clr", B, OpPaWhcD (1, 0, 3, 1), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.dptk.few", B, OpPaWhcD (1, 0, 5, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.dptk", B, OpPaWhcD (1, 0, 5, 0), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.dptk.few.clr", B, OpPaWhcD (1, 0, 5, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.dptk.clr", B, OpPaWhcD (1, 0, 5, 1), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.dpnt.few", B, OpPaWhcD (1, 0, 7, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.dpnt", B, OpPaWhcD (1, 0, 7, 0), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.dpnt.few.clr", B, OpPaWhcD (1, 0, 7, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.dpnt.clr", B, OpPaWhcD (1, 0, 7, 1), {B1, B2}, PSEUDO, 0, NULL},
|
||||
{"br.call.sptk.many", B, OpPaWhcD (1, 1, 1, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.sptk.many.clr", B, OpPaWhcD (1, 1, 1, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.spnt.many", B, OpPaWhcD (1, 1, 3, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.spnt.many.clr", B, OpPaWhcD (1, 1, 3, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.dptk.many", B, OpPaWhcD (1, 1, 5, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.dptk.many.clr", B, OpPaWhcD (1, 1, 5, 1), {B1, B2}, EMPTY},
|
||||
{"br.call.dpnt.many", B, OpPaWhcD (1, 1, 7, 0), {B1, B2}, EMPTY},
|
||||
{"br.call.dpnt.many.clr", B, OpPaWhcD (1, 1, 7, 1), {B1, B2}, EMPTY},
|
||||
|
||||
#define BRP(a,b,c) \
|
||||
B0, OpX6IhWhb (2, a, b, c), {B2, TAG13}, NO_PRED, 0, NULL
|
||||
{"brp.sptk", BRP (0x10, 0, 0)},
|
||||
{"brp.dptk", BRP (0x10, 0, 2)},
|
||||
{"brp.sptk.imp", BRP (0x10, 1, 0)},
|
||||
{"brp.dptk.imp", BRP (0x10, 1, 2)},
|
||||
{"brp.ret.sptk", BRP (0x11, 0, 0)},
|
||||
{"brp.ret.dptk", BRP (0x11, 0, 2)},
|
||||
{"brp.ret.sptk.imp", BRP (0x11, 1, 0)},
|
||||
{"brp.ret.dptk.imp", BRP (0x11, 1, 2)},
|
||||
#undef BRP
|
||||
|
||||
{"nop.b", B0, OpX6 (2, 0x00), {IMMU21}, EMPTY},
|
||||
{"hint.b", B0, OpX6 (2, 0x01), {IMMU21}, EMPTY},
|
||||
|
||||
#define BR(a,b) \
|
||||
B0, OpBtypePaWhaDPr (4, 0, a, 0, b, 0), {TGT25c}, PSEUDO, 0, NULL
|
||||
{"br.few", BR (0, 0)},
|
||||
{"br", BR (0, 0)},
|
||||
{"br.few.clr", BR (0, 1)},
|
||||
{"br.clr", BR (0, 1)},
|
||||
{"br.many", BR (1, 0)},
|
||||
{"br.many.clr", BR (1, 1)},
|
||||
#undef BR
|
||||
|
||||
#define BR(a,b,c) \
|
||||
B0, OpBtypePaWhaD (4, 0, a, b, c), {TGT25c}, EMPTY
|
||||
#define BRP(a,b,c) \
|
||||
B0, OpBtypePaWhaD (4, 0, a, b, c), {TGT25c}, PSEUDO, 0, NULL
|
||||
{"br.cond.sptk.few", BR (0, 0, 0)},
|
||||
{"br.cond.sptk", BRP (0, 0, 0)},
|
||||
{"br.cond.sptk.few.clr", BR (0, 0, 1)},
|
||||
{"br.cond.sptk.clr", BRP (0, 0, 1)},
|
||||
{"br.cond.spnt.few", BR (0, 1, 0)},
|
||||
{"br.cond.spnt", BRP (0, 1, 0)},
|
||||
{"br.cond.spnt.few.clr", BR (0, 1, 1)},
|
||||
{"br.cond.spnt.clr", BRP (0, 1, 1)},
|
||||
{"br.cond.dptk.few", BR (0, 2, 0)},
|
||||
{"br.cond.dptk", BRP (0, 2, 0)},
|
||||
{"br.cond.dptk.few.clr", BR (0, 2, 1)},
|
||||
{"br.cond.dptk.clr", BRP (0, 2, 1)},
|
||||
{"br.cond.dpnt.few", BR (0, 3, 0)},
|
||||
{"br.cond.dpnt", BRP (0, 3, 0)},
|
||||
{"br.cond.dpnt.few.clr", BR (0, 3, 1)},
|
||||
{"br.cond.dpnt.clr", BRP (0, 3, 1)},
|
||||
{"br.cond.sptk.many", BR (1, 0, 0)},
|
||||
{"br.cond.sptk.many.clr", BR (1, 0, 1)},
|
||||
{"br.cond.spnt.many", BR (1, 1, 0)},
|
||||
{"br.cond.spnt.many.clr", BR (1, 1, 1)},
|
||||
{"br.cond.dptk.many", BR (1, 2, 0)},
|
||||
{"br.cond.dptk.many.clr", BR (1, 2, 1)},
|
||||
{"br.cond.dpnt.many", BR (1, 3, 0)},
|
||||
{"br.cond.dpnt.many.clr", BR (1, 3, 1)},
|
||||
{"br.sptk.few", BR (0, 0, 0)},
|
||||
{"br.sptk", BRP (0, 0, 0)},
|
||||
{"br.sptk.few.clr", BR (0, 0, 1)},
|
||||
{"br.sptk.clr", BRP (0, 0, 1)},
|
||||
{"br.spnt.few", BR (0, 1, 0)},
|
||||
{"br.spnt", BRP (0, 1, 0)},
|
||||
{"br.spnt.few.clr", BR (0, 1, 1)},
|
||||
{"br.spnt.clr", BRP (0, 1, 1)},
|
||||
{"br.dptk.few", BR (0, 2, 0)},
|
||||
{"br.dptk", BRP (0, 2, 0)},
|
||||
{"br.dptk.few.clr", BR (0, 2, 1)},
|
||||
{"br.dptk.clr", BRP (0, 2, 1)},
|
||||
{"br.dpnt.few", BR (0, 3, 0)},
|
||||
{"br.dpnt", BRP (0, 3, 0)},
|
||||
{"br.dpnt.few.clr", BR (0, 3, 1)},
|
||||
{"br.dpnt.clr", BRP (0, 3, 1)},
|
||||
{"br.sptk.many", BR (1, 0, 0)},
|
||||
{"br.sptk.many.clr", BR (1, 0, 1)},
|
||||
{"br.spnt.many", BR (1, 1, 0)},
|
||||
{"br.spnt.many.clr", BR (1, 1, 1)},
|
||||
{"br.dptk.many", BR (1, 2, 0)},
|
||||
{"br.dptk.many.clr", BR (1, 2, 1)},
|
||||
{"br.dpnt.many", BR (1, 3, 0)},
|
||||
{"br.dpnt.many.clr", BR (1, 3, 1)},
|
||||
#undef BR
|
||||
#undef BRP
|
||||
|
||||
#define BR(a,b,c,d, e) \
|
||||
B0, OpBtypePaWhaD (4, a, b, c, d), {TGT25c}, SLOT2 | e, 0, NULL
|
||||
{"br.wexit.sptk.few", BR (2, 0, 0, 0, MOD_RRBS)},
|
||||
{"br.wexit.sptk", BR (2, 0, 0, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.sptk.few.clr", BR (2, 0, 0, 1, MOD_RRBS)},
|
||||
{"br.wexit.sptk.clr", BR (2, 0, 0, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.spnt.few", BR (2, 0, 1, 0, MOD_RRBS)},
|
||||
{"br.wexit.spnt", BR (2, 0, 1, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.spnt.few.clr", BR (2, 0, 1, 1, MOD_RRBS)},
|
||||
{"br.wexit.spnt.clr", BR (2, 0, 1, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.dptk.few", BR (2, 0, 2, 0, MOD_RRBS)},
|
||||
{"br.wexit.dptk", BR (2, 0, 2, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.dptk.few.clr", BR (2, 0, 2, 1, MOD_RRBS)},
|
||||
{"br.wexit.dptk.clr", BR (2, 0, 2, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.dpnt.few", BR (2, 0, 3, 0, MOD_RRBS)},
|
||||
{"br.wexit.dpnt", BR (2, 0, 3, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.dpnt.few.clr", BR (2, 0, 3, 1, MOD_RRBS)},
|
||||
{"br.wexit.dpnt.clr", BR (2, 0, 3, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wexit.sptk.many", BR (2, 1, 0, 0, MOD_RRBS)},
|
||||
{"br.wexit.sptk.many.clr", BR (2, 1, 0, 1, MOD_RRBS)},
|
||||
{"br.wexit.spnt.many", BR (2, 1, 1, 0, MOD_RRBS)},
|
||||
{"br.wexit.spnt.many.clr", BR (2, 1, 1, 1, MOD_RRBS)},
|
||||
{"br.wexit.dptk.many", BR (2, 1, 2, 0, MOD_RRBS)},
|
||||
{"br.wexit.dptk.many.clr", BR (2, 1, 2, 1, MOD_RRBS)},
|
||||
{"br.wexit.dpnt.many", BR (2, 1, 3, 0, MOD_RRBS)},
|
||||
{"br.wexit.dpnt.many.clr", BR (2, 1, 3, 1, MOD_RRBS)},
|
||||
{"br.wtop.sptk.few", BR (3, 0, 0, 0, MOD_RRBS)},
|
||||
{"br.wtop.sptk", BR (3, 0, 0, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.sptk.few.clr", BR (3, 0, 0, 1, MOD_RRBS)},
|
||||
{"br.wtop.sptk.clr", BR (3, 0, 0, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.spnt.few", BR (3, 0, 1, 0, MOD_RRBS)},
|
||||
{"br.wtop.spnt", BR (3, 0, 1, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.spnt.few.clr", BR (3, 0, 1, 1, MOD_RRBS)},
|
||||
{"br.wtop.spnt.clr", BR (3, 0, 1, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.dptk.few", BR (3, 0, 2, 0, MOD_RRBS)},
|
||||
{"br.wtop.dptk", BR (3, 0, 2, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.dptk.few.clr", BR (3, 0, 2, 1, MOD_RRBS)},
|
||||
{"br.wtop.dptk.clr", BR (3, 0, 2, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.dpnt.few", BR (3, 0, 3, 0, MOD_RRBS)},
|
||||
{"br.wtop.dpnt", BR (3, 0, 3, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.dpnt.few.clr", BR (3, 0, 3, 1, MOD_RRBS)},
|
||||
{"br.wtop.dpnt.clr", BR (3, 0, 3, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.wtop.sptk.many", BR (3, 1, 0, 0, MOD_RRBS)},
|
||||
{"br.wtop.sptk.many.clr", BR (3, 1, 0, 1, MOD_RRBS)},
|
||||
{"br.wtop.spnt.many", BR (3, 1, 1, 0, MOD_RRBS)},
|
||||
{"br.wtop.spnt.many.clr", BR (3, 1, 1, 1, MOD_RRBS)},
|
||||
{"br.wtop.dptk.many", BR (3, 1, 2, 0, MOD_RRBS)},
|
||||
{"br.wtop.dptk.many.clr", BR (3, 1, 2, 1, MOD_RRBS)},
|
||||
{"br.wtop.dpnt.many", BR (3, 1, 3, 0, MOD_RRBS)},
|
||||
{"br.wtop.dpnt.many.clr", BR (3, 1, 3, 1, MOD_RRBS)},
|
||||
|
||||
#undef BR
|
||||
#define BR(a,b,c,d) \
|
||||
B0, OpBtypePaWhaD (4, a, b, c, d), {TGT25c}, SLOT2 | NO_PRED, 0, NULL
|
||||
#define BRT(a,b,c,d,e) \
|
||||
B0, OpBtypePaWhaD (4, a, b, c, d), {TGT25c}, SLOT2 | NO_PRED | e, 0, NULL
|
||||
{"br.cloop.sptk.few", BR (5, 0, 0, 0)},
|
||||
{"br.cloop.sptk", BRT (5, 0, 0, 0, PSEUDO)},
|
||||
{"br.cloop.sptk.few.clr", BR (5, 0, 0, 1)},
|
||||
{"br.cloop.sptk.clr", BRT (5, 0, 0, 1, PSEUDO)},
|
||||
{"br.cloop.spnt.few", BR (5, 0, 1, 0)},
|
||||
{"br.cloop.spnt", BRT (5, 0, 1, 0, PSEUDO)},
|
||||
{"br.cloop.spnt.few.clr", BR (5, 0, 1, 1)},
|
||||
{"br.cloop.spnt.clr", BRT (5, 0, 1, 1, PSEUDO)},
|
||||
{"br.cloop.dptk.few", BR (5, 0, 2, 0)},
|
||||
{"br.cloop.dptk", BRT (5, 0, 2, 0, PSEUDO)},
|
||||
{"br.cloop.dptk.few.clr", BR (5, 0, 2, 1)},
|
||||
{"br.cloop.dptk.clr", BRT (5, 0, 2, 1, PSEUDO)},
|
||||
{"br.cloop.dpnt.few", BR (5, 0, 3, 0)},
|
||||
{"br.cloop.dpnt", BRT (5, 0, 3, 0, PSEUDO)},
|
||||
{"br.cloop.dpnt.few.clr", BR (5, 0, 3, 1)},
|
||||
{"br.cloop.dpnt.clr", BRT (5, 0, 3, 1, PSEUDO)},
|
||||
{"br.cloop.sptk.many", BR (5, 1, 0, 0)},
|
||||
{"br.cloop.sptk.many.clr", BR (5, 1, 0, 1)},
|
||||
{"br.cloop.spnt.many", BR (5, 1, 1, 0)},
|
||||
{"br.cloop.spnt.many.clr", BR (5, 1, 1, 1)},
|
||||
{"br.cloop.dptk.many", BR (5, 1, 2, 0)},
|
||||
{"br.cloop.dptk.many.clr", BR (5, 1, 2, 1)},
|
||||
{"br.cloop.dpnt.many", BR (5, 1, 3, 0)},
|
||||
{"br.cloop.dpnt.many.clr", BR (5, 1, 3, 1)},
|
||||
{"br.cexit.sptk.few", BRT (6, 0, 0, 0, MOD_RRBS)},
|
||||
{"br.cexit.sptk", BRT (6, 0, 0, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.sptk.few.clr", BRT (6, 0, 0, 1, MOD_RRBS)},
|
||||
{"br.cexit.sptk.clr", BRT (6, 0, 0, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.spnt.few", BRT (6, 0, 1, 0, MOD_RRBS)},
|
||||
{"br.cexit.spnt", BRT (6, 0, 1, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.spnt.few.clr", BRT (6, 0, 1, 1, MOD_RRBS)},
|
||||
{"br.cexit.spnt.clr", BRT (6, 0, 1, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.dptk.few", BRT (6, 0, 2, 0, MOD_RRBS)},
|
||||
{"br.cexit.dptk", BRT (6, 0, 2, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.dptk.few.clr", BRT (6, 0, 2, 1, MOD_RRBS)},
|
||||
{"br.cexit.dptk.clr", BRT (6, 0, 2, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.dpnt.few", BRT (6, 0, 3, 0, MOD_RRBS)},
|
||||
{"br.cexit.dpnt", BRT (6, 0, 3, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.dpnt.few.clr", BRT (6, 0, 3, 1, MOD_RRBS)},
|
||||
{"br.cexit.dpnt.clr", BRT (6, 0, 3, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.cexit.sptk.many", BRT (6, 1, 0, 0, MOD_RRBS)},
|
||||
{"br.cexit.sptk.many.clr", BRT (6, 1, 0, 1, MOD_RRBS)},
|
||||
{"br.cexit.spnt.many", BRT (6, 1, 1, 0, MOD_RRBS)},
|
||||
{"br.cexit.spnt.many.clr", BRT (6, 1, 1, 1, MOD_RRBS)},
|
||||
{"br.cexit.dptk.many", BRT (6, 1, 2, 0, MOD_RRBS)},
|
||||
{"br.cexit.dptk.many.clr", BRT (6, 1, 2, 1, MOD_RRBS)},
|
||||
{"br.cexit.dpnt.many", BRT (6, 1, 3, 0, MOD_RRBS)},
|
||||
{"br.cexit.dpnt.many.clr", BRT (6, 1, 3, 1, MOD_RRBS)},
|
||||
{"br.ctop.sptk.few", BRT (7, 0, 0, 0, MOD_RRBS)},
|
||||
{"br.ctop.sptk", BRT (7, 0, 0, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.sptk.few.clr", BRT (7, 0, 0, 1, MOD_RRBS)},
|
||||
{"br.ctop.sptk.clr", BRT (7, 0, 0, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.spnt.few", BRT (7, 0, 1, 0, MOD_RRBS)},
|
||||
{"br.ctop.spnt", BRT (7, 0, 1, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.spnt.few.clr", BRT (7, 0, 1, 1, MOD_RRBS)},
|
||||
{"br.ctop.spnt.clr", BRT (7, 0, 1, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.dptk.few", BRT (7, 0, 2, 0, MOD_RRBS)},
|
||||
{"br.ctop.dptk", BRT (7, 0, 2, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.dptk.few.clr", BRT (7, 0, 2, 1, MOD_RRBS)},
|
||||
{"br.ctop.dptk.clr", BRT (7, 0, 2, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.dpnt.few", BRT (7, 0, 3, 0, MOD_RRBS)},
|
||||
{"br.ctop.dpnt", BRT (7, 0, 3, 0, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.dpnt.few.clr", BRT (7, 0, 3, 1, MOD_RRBS)},
|
||||
{"br.ctop.dpnt.clr", BRT (7, 0, 3, 1, PSEUDO | MOD_RRBS)},
|
||||
{"br.ctop.sptk.many", BRT (7, 1, 0, 0, MOD_RRBS)},
|
||||
{"br.ctop.sptk.many.clr", BRT (7, 1, 0, 1, MOD_RRBS)},
|
||||
{"br.ctop.spnt.many", BRT (7, 1, 1, 0, MOD_RRBS)},
|
||||
{"br.ctop.spnt.many.clr", BRT (7, 1, 1, 1, MOD_RRBS)},
|
||||
{"br.ctop.dptk.many", BRT (7, 1, 2, 0, MOD_RRBS)},
|
||||
{"br.ctop.dptk.many.clr", BRT (7, 1, 2, 1, MOD_RRBS)},
|
||||
{"br.ctop.dpnt.many", BRT (7, 1, 3, 0, MOD_RRBS)},
|
||||
{"br.ctop.dpnt.many.clr", BRT (7, 1, 3, 1, MOD_RRBS)},
|
||||
#undef BR
|
||||
#undef BRT
|
||||
|
||||
{"br.call.sptk.few", B, OpPaWhaD (5, 0, 0, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.sptk", B, OpPaWhaD (5, 0, 0, 0), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.sptk.few.clr", B, OpPaWhaD (5, 0, 0, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.sptk.clr", B, OpPaWhaD (5, 0, 0, 1), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.spnt.few", B, OpPaWhaD (5, 0, 1, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.spnt", B, OpPaWhaD (5, 0, 1, 0), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.spnt.few.clr", B, OpPaWhaD (5, 0, 1, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.spnt.clr", B, OpPaWhaD (5, 0, 1, 1), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.dptk.few", B, OpPaWhaD (5, 0, 2, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dptk", B, OpPaWhaD (5, 0, 2, 0), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.dptk.few.clr", B, OpPaWhaD (5, 0, 2, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dptk.clr", B, OpPaWhaD (5, 0, 2, 1), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.dpnt.few", B, OpPaWhaD (5, 0, 3, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dpnt", B, OpPaWhaD (5, 0, 3, 0), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.dpnt.few.clr", B, OpPaWhaD (5, 0, 3, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dpnt.clr", B, OpPaWhaD (5, 0, 3, 1), {B1, TGT25c}, PSEUDO, 0, NULL},
|
||||
{"br.call.sptk.many", B, OpPaWhaD (5, 1, 0, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.sptk.many.clr", B, OpPaWhaD (5, 1, 0, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.spnt.many", B, OpPaWhaD (5, 1, 1, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.spnt.many.clr", B, OpPaWhaD (5, 1, 1, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dptk.many", B, OpPaWhaD (5, 1, 2, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dptk.many.clr", B, OpPaWhaD (5, 1, 2, 1), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dpnt.many", B, OpPaWhaD (5, 1, 3, 0), {B1, TGT25c}, EMPTY},
|
||||
{"br.call.dpnt.many.clr", B, OpPaWhaD (5, 1, 3, 1), {B1, TGT25c}, EMPTY},
|
||||
|
||||
/* Branch predict. */
|
||||
#define BRP(a,b) \
|
||||
B0, OpIhWhb (7, a, b), {TGT25c, TAG13}, NO_PRED, 0, NULL
|
||||
{"brp.sptk", BRP (0, 0)},
|
||||
{"brp.loop", BRP (0, 1)},
|
||||
{"brp.dptk", BRP (0, 2)},
|
||||
{"brp.exit", BRP (0, 3)},
|
||||
{"brp.sptk.imp", BRP (1, 0)},
|
||||
{"brp.loop.imp", BRP (1, 1)},
|
||||
{"brp.dptk.imp", BRP (1, 2)},
|
||||
{"brp.exit.imp", BRP (1, 3)},
|
||||
#undef BRP
|
||||
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#undef B0
|
||||
#undef B
|
||||
#undef bBtype
|
||||
#undef bD
|
||||
#undef bIh
|
||||
#undef bPa
|
||||
#undef bPr
|
||||
#undef bWha
|
||||
#undef bWhb
|
||||
#undef bWhc
|
||||
#undef bX6
|
||||
#undef mBtype
|
||||
#undef mD
|
||||
#undef mIh
|
||||
#undef mPa
|
||||
#undef mPr
|
||||
#undef mWha
|
||||
#undef mWhb
|
||||
#undef mWhc
|
||||
#undef mX6
|
||||
#undef OpX6
|
||||
#undef OpPaWhaD
|
||||
#undef OpPaWhcD
|
||||
#undef OpBtypePaWhaD
|
||||
#undef OpBtypePaWhaDPr
|
||||
#undef OpX6BtypePaWhaD
|
||||
#undef OpX6BtypePaWhaDPr
|
||||
#undef OpIhWhb
|
||||
#undef OpX6IhWhb
|
||||
#undef EMPTY
|
||||
@@ -1,34 +0,0 @@
|
||||
/* ia64-opc-d.c -- IA-64 `D' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
struct ia64_opcode ia64_opcodes_d[] =
|
||||
{
|
||||
{"add", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_R1, IA64_OPND_IMM22, IA64_OPND_R3_2}, 0, 0, NULL},
|
||||
{"add", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_R1, IA64_OPND_IMM14, IA64_OPND_R3}, 0, 0, NULL},
|
||||
{"break", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_IMMU21}, 0, 0, NULL},
|
||||
{"chk.s", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_R2, IA64_OPND_TGT25b}, 0, 0, NULL},
|
||||
{"hint", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_IMMU21}, 0, 0, NULL},
|
||||
{"mov", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_R1, IA64_OPND_AR3}, 0, 0, NULL},
|
||||
{"mov", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_AR3, IA64_OPND_IMM8}, 0, 0, NULL},
|
||||
{"mov", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_AR3, IA64_OPND_R2}, 0, 0, NULL},
|
||||
{"nop", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_IMMU21}, 0, 0, NULL},
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
@@ -1,656 +0,0 @@
|
||||
/* ia64-opc-f.c -- IA-64 `F' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
#define f0 IA64_TYPE_F, 0
|
||||
#define f IA64_TYPE_F, 1
|
||||
#define f2 IA64_TYPE_F, 2
|
||||
|
||||
#define bF2(x) (((ia64_insn) ((x) & 0x7f)) << 13)
|
||||
#define bF4(x) (((ia64_insn) ((x) & 0x7f)) << 27)
|
||||
#define bQ(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bRa(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bRb(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bSf(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bTa(x) (((ia64_insn) ((x) & 0x1)) << 12)
|
||||
#define bXa(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bXb(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bX2(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bX6(x) (((ia64_insn) ((x) & 0x3f)) << 27)
|
||||
#define bY(x) (((ia64_insn) ((x) & 0x1)) << 26)
|
||||
|
||||
#define mF2 bF2 (-1)
|
||||
#define mF4 bF4 (-1)
|
||||
#define mQ bQ (-1)
|
||||
#define mRa bRa (-1)
|
||||
#define mRb bRb (-1)
|
||||
#define mSf bSf (-1)
|
||||
#define mTa bTa (-1)
|
||||
#define mXa bXa (-1)
|
||||
#define mXb bXb (-1)
|
||||
#define mX2 bX2 (-1)
|
||||
#define mX6 bX6 (-1)
|
||||
#define mY bY (-1)
|
||||
|
||||
#define OpXa(a,b) (bOp (a) | bXa (b)), (mOp | mXa)
|
||||
#define OpXaSf(a,b,c) (bOp (a) | bXa (b) | bSf (c)), (mOp | mXa | mSf)
|
||||
#define OpXaSfF2(a,b,c,d) \
|
||||
(bOp (a) | bXa (b) | bSf (c) | bF2 (d)), (mOp | mXa | mSf | mF2)
|
||||
#define OpXaSfF4(a,b,c,d) \
|
||||
(bOp (a) | bXa (b) | bSf (c) | bF4 (d)), (mOp | mXa | mSf | mF4)
|
||||
#define OpXaSfF2F4(a,b,c,d,e) \
|
||||
(bOp (a) | bXa (b) | bSf (c) | bF2 (d) | bF4 (e)), \
|
||||
(mOp | mXa | mSf | mF2 | mF4)
|
||||
#define OpXaX2(a,b,c) (bOp (a) | bXa (b) | bX2 (c)), (mOp | mXa | mX2)
|
||||
#define OpXaX2F2(a,b,c,d) \
|
||||
(bOp (a) | bXa (b) | bX2 (c) | bF2 (d)), (mOp | mXa | mX2 | mF2)
|
||||
#define OpRaRbTaSf(a,b,c,d,e) \
|
||||
(bOp (a) | bRa (b) | bRb (c) | bTa (d) | bSf (e)), \
|
||||
(mOp | mRa | mRb | mTa | mSf)
|
||||
#define OpTa(a,b) (bOp (a) | bTa (b)), (mOp | mTa)
|
||||
#define OpXbQSf(a,b,c,d) \
|
||||
(bOp (a) | bXb (b) | bQ (c) | bSf (d)), (mOp | mXb | mQ | mSf)
|
||||
#define OpXbX6(a,b,c) \
|
||||
(bOp (a) | bXb (b) | bX6 (c)), (mOp | mXb | mX6)
|
||||
#define OpXbX6Y(a,b,c,d) \
|
||||
(bOp (a) | bXb (b) | bX6 (c) | bY (d)), (mOp | mXb | mX6 | mY)
|
||||
#define OpXbX6F2(a,b,c,d) \
|
||||
(bOp (a) | bXb (b) | bX6 (c) | bF2 (d)), (mOp | mXb | mX6 | mF2)
|
||||
#define OpXbX6Sf(a,b,c,d) \
|
||||
(bOp (a) | bXb (b) | bX6 (c) | bSf (d)), (mOp | mXb | mX6 | mSf)
|
||||
|
||||
/* Used to initialise unused fields in ia64_opcode struct,
|
||||
in order to stop gcc from complaining. */
|
||||
#define EMPTY 0,0,NULL
|
||||
|
||||
struct ia64_opcode ia64_opcodes_f[] =
|
||||
{
|
||||
/* F-type instruction encodings (sorted according to major opcode). */
|
||||
|
||||
{"frcpa.s0", f2, OpXbQSf (0, 1, 0, 0), {F1, P2, F2, F3}, EMPTY},
|
||||
{"frcpa", f2, OpXbQSf (0, 1, 0, 0), {F1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"frcpa.s1", f2, OpXbQSf (0, 1, 0, 1), {F1, P2, F2, F3}, EMPTY},
|
||||
{"frcpa.s2", f2, OpXbQSf (0, 1, 0, 2), {F1, P2, F2, F3}, EMPTY},
|
||||
{"frcpa.s3", f2, OpXbQSf (0, 1, 0, 3), {F1, P2, F2, F3}, EMPTY},
|
||||
|
||||
{"frsqrta.s0", f2, OpXbQSf (0, 1, 1, 0), {F1, P2, F3}, EMPTY},
|
||||
{"frsqrta", f2, OpXbQSf (0, 1, 1, 0), {F1, P2, F3}, PSEUDO, 0, NULL},
|
||||
{"frsqrta.s1", f2, OpXbQSf (0, 1, 1, 1), {F1, P2, F3}, EMPTY},
|
||||
{"frsqrta.s2", f2, OpXbQSf (0, 1, 1, 2), {F1, P2, F3}, EMPTY},
|
||||
{"frsqrta.s3", f2, OpXbQSf (0, 1, 1, 3), {F1, P2, F3}, EMPTY},
|
||||
|
||||
{"fmin.s0", f, OpXbX6Sf (0, 0, 0x14, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fmin", f, OpXbX6Sf (0, 0, 0x14, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fmin.s1", f, OpXbX6Sf (0, 0, 0x14, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fmin.s2", f, OpXbX6Sf (0, 0, 0x14, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fmin.s3", f, OpXbX6Sf (0, 0, 0x14, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fmax.s0", f, OpXbX6Sf (0, 0, 0x15, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fmax", f, OpXbX6Sf (0, 0, 0x15, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fmax.s1", f, OpXbX6Sf (0, 0, 0x15, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fmax.s2", f, OpXbX6Sf (0, 0, 0x15, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fmax.s3", f, OpXbX6Sf (0, 0, 0x15, 3), {F1, F2, F3}, EMPTY},
|
||||
{"famin.s0", f, OpXbX6Sf (0, 0, 0x16, 0), {F1, F2, F3}, EMPTY},
|
||||
{"famin", f, OpXbX6Sf (0, 0, 0x16, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"famin.s1", f, OpXbX6Sf (0, 0, 0x16, 1), {F1, F2, F3}, EMPTY},
|
||||
{"famin.s2", f, OpXbX6Sf (0, 0, 0x16, 2), {F1, F2, F3}, EMPTY},
|
||||
{"famin.s3", f, OpXbX6Sf (0, 0, 0x16, 3), {F1, F2, F3}, EMPTY},
|
||||
{"famax.s0", f, OpXbX6Sf (0, 0, 0x17, 0), {F1, F2, F3}, EMPTY},
|
||||
{"famax", f, OpXbX6Sf (0, 0, 0x17, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"famax.s1", f, OpXbX6Sf (0, 0, 0x17, 1), {F1, F2, F3}, EMPTY},
|
||||
{"famax.s2", f, OpXbX6Sf (0, 0, 0x17, 2), {F1, F2, F3}, EMPTY},
|
||||
{"famax.s3", f, OpXbX6Sf (0, 0, 0x17, 3), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"mov", f, OpXbX6 (0, 0, 0x10), {F1, F3}, PSEUDO | F2_EQ_F3, 0, NULL},
|
||||
{"fabs", f, OpXbX6F2 (0, 0, 0x10, 0), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fneg", f, OpXbX6 (0, 0, 0x11), {F1, F3}, PSEUDO | F2_EQ_F3, 0, NULL},
|
||||
{"fnegabs", f, OpXbX6F2 (0, 0, 0x11, 0), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fmerge.s", f, OpXbX6 (0, 0, 0x10), {F1, F2, F3}, EMPTY},
|
||||
{"fmerge.ns", f, OpXbX6 (0, 0, 0x11), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"fmerge.se", f, OpXbX6 (0, 0, 0x12), {F1, F2, F3}, EMPTY},
|
||||
{"fmix.lr", f, OpXbX6 (0, 0, 0x39), {F1, F2, F3}, EMPTY},
|
||||
{"fmix.r", f, OpXbX6 (0, 0, 0x3a), {F1, F2, F3}, EMPTY},
|
||||
{"fmix.l", f, OpXbX6 (0, 0, 0x3b), {F1, F2, F3}, EMPTY},
|
||||
{"fsxt.r", f, OpXbX6 (0, 0, 0x3c), {F1, F2, F3}, EMPTY},
|
||||
{"fsxt.l", f, OpXbX6 (0, 0, 0x3d), {F1, F2, F3}, EMPTY},
|
||||
{"fpack", f, OpXbX6 (0, 0, 0x28), {F1, F2, F3}, EMPTY},
|
||||
{"fswap", f, OpXbX6 (0, 0, 0x34), {F1, F2, F3}, EMPTY},
|
||||
{"fswap.nl", f, OpXbX6 (0, 0, 0x35), {F1, F2, F3}, EMPTY},
|
||||
{"fswap.nr", f, OpXbX6 (0, 0, 0x36), {F1, F2, F3}, EMPTY},
|
||||
{"fand", f, OpXbX6 (0, 0, 0x2c), {F1, F2, F3}, EMPTY},
|
||||
{"fandcm", f, OpXbX6 (0, 0, 0x2d), {F1, F2, F3}, EMPTY},
|
||||
{"for", f, OpXbX6 (0, 0, 0x2e), {F1, F2, F3}, EMPTY},
|
||||
{"fxor", f, OpXbX6 (0, 0, 0x2f), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"fcvt.fx.s0", f, OpXbX6Sf (0, 0, 0x18, 0), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx", f, OpXbX6Sf (0, 0, 0x18, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fcvt.fx.s1", f, OpXbX6Sf (0, 0, 0x18, 1), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.s2", f, OpXbX6Sf (0, 0, 0x18, 2), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.s3", f, OpXbX6Sf (0, 0, 0x18, 3), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.s0", f, OpXbX6Sf (0, 0, 0x19, 0), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu", f, OpXbX6Sf (0, 0, 0x19, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fcvt.fxu.s1", f, OpXbX6Sf (0, 0, 0x19, 1), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.s2", f, OpXbX6Sf (0, 0, 0x19, 2), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.s3", f, OpXbX6Sf (0, 0, 0x19, 3), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.trunc.s0", f, OpXbX6Sf (0, 0, 0x1a, 0), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.trunc", f, OpXbX6Sf (0, 0, 0x1a, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fcvt.fx.trunc.s1", f, OpXbX6Sf (0, 0, 0x1a, 1), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.trunc.s2", f, OpXbX6Sf (0, 0, 0x1a, 2), {F1, F2}, EMPTY},
|
||||
{"fcvt.fx.trunc.s3", f, OpXbX6Sf (0, 0, 0x1a, 3), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.trunc.s0", f, OpXbX6Sf (0, 0, 0x1b, 0), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.trunc", f, OpXbX6Sf (0, 0, 0x1b, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fcvt.fxu.trunc.s1", f, OpXbX6Sf (0, 0, 0x1b, 1), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.trunc.s2", f, OpXbX6Sf (0, 0, 0x1b, 2), {F1, F2}, EMPTY},
|
||||
{"fcvt.fxu.trunc.s3", f, OpXbX6Sf (0, 0, 0x1b, 3), {F1, F2}, EMPTY},
|
||||
|
||||
{"fcvt.xf", f, OpXbX6 (0, 0, 0x1c), {F1, F2}, EMPTY},
|
||||
|
||||
{"fsetc.s0", f0, OpXbX6Sf (0, 0, 0x04, 0), {IMMU7a, IMMU7b}, EMPTY},
|
||||
{"fsetc", f0, OpXbX6Sf (0, 0, 0x04, 0), {IMMU7a, IMMU7b}, PSEUDO, 0, NULL},
|
||||
{"fsetc.s1", f0, OpXbX6Sf (0, 0, 0x04, 1), {IMMU7a, IMMU7b}, EMPTY},
|
||||
{"fsetc.s2", f0, OpXbX6Sf (0, 0, 0x04, 2), {IMMU7a, IMMU7b}, EMPTY},
|
||||
{"fsetc.s3", f0, OpXbX6Sf (0, 0, 0x04, 3), {IMMU7a, IMMU7b}, EMPTY},
|
||||
{"fclrf.s0", f0, OpXbX6Sf (0, 0, 0x05, 0), {}, EMPTY},
|
||||
{"fclrf", f0, OpXbX6Sf (0, 0, 0x05, 0), {0}, PSEUDO, 0, NULL},
|
||||
{"fclrf.s1", f0, OpXbX6Sf (0, 0, 0x05, 1), {}, EMPTY},
|
||||
{"fclrf.s2", f0, OpXbX6Sf (0, 0, 0x05, 2), {}, EMPTY},
|
||||
{"fclrf.s3", f0, OpXbX6Sf (0, 0, 0x05, 3), {}, EMPTY},
|
||||
{"fchkf.s0", f0, OpXbX6Sf (0, 0, 0x08, 0), {TGT25}, EMPTY},
|
||||
{"fchkf", f0, OpXbX6Sf (0, 0, 0x08, 0), {TGT25}, PSEUDO, 0, NULL},
|
||||
{"fchkf.s1", f0, OpXbX6Sf (0, 0, 0x08, 1), {TGT25}, EMPTY},
|
||||
{"fchkf.s2", f0, OpXbX6Sf (0, 0, 0x08, 2), {TGT25}, EMPTY},
|
||||
{"fchkf.s3", f0, OpXbX6Sf (0, 0, 0x08, 3), {TGT25}, EMPTY},
|
||||
|
||||
{"break.f", f0, OpXbX6 (0, 0, 0x00), {IMMU21}, EMPTY},
|
||||
{"nop.f", f0, OpXbX6Y (0, 0, 0x01, 0), {IMMU21}, EMPTY},
|
||||
{"hint.f", f0, OpXbX6Y (0, 0, 0x01, 1), {IMMU21}, EMPTY},
|
||||
|
||||
{"fprcpa.s0", f2, OpXbQSf (1, 1, 0, 0), {F1, P2, F2, F3}, EMPTY},
|
||||
{"fprcpa", f2, OpXbQSf (1, 1, 0, 0), {F1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fprcpa.s1", f2, OpXbQSf (1, 1, 0, 1), {F1, P2, F2, F3}, EMPTY},
|
||||
{"fprcpa.s2", f2, OpXbQSf (1, 1, 0, 2), {F1, P2, F2, F3}, EMPTY},
|
||||
{"fprcpa.s3", f2, OpXbQSf (1, 1, 0, 3), {F1, P2, F2, F3}, EMPTY},
|
||||
|
||||
{"fprsqrta.s0", f2, OpXbQSf (1, 1, 1, 0), {F1, P2, F3}, EMPTY},
|
||||
{"fprsqrta", f2, OpXbQSf (1, 1, 1, 0), {F1, P2, F3}, PSEUDO, 0, NULL},
|
||||
{"fprsqrta.s1", f2, OpXbQSf (1, 1, 1, 1), {F1, P2, F3}, EMPTY},
|
||||
{"fprsqrta.s2", f2, OpXbQSf (1, 1, 1, 2), {F1, P2, F3}, EMPTY},
|
||||
{"fprsqrta.s3", f2, OpXbQSf (1, 1, 1, 3), {F1, P2, F3}, EMPTY},
|
||||
|
||||
{"fpmin.s0", f, OpXbX6Sf (1, 0, 0x14, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpmin", f, OpXbX6Sf (1, 0, 0x14, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpmin.s1", f, OpXbX6Sf (1, 0, 0x14, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpmin.s2", f, OpXbX6Sf (1, 0, 0x14, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpmin.s3", f, OpXbX6Sf (1, 0, 0x14, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpmax.s0", f, OpXbX6Sf (1, 0, 0x15, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpmax", f, OpXbX6Sf (1, 0, 0x15, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpmax.s1", f, OpXbX6Sf (1, 0, 0x15, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpmax.s2", f, OpXbX6Sf (1, 0, 0x15, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpmax.s3", f, OpXbX6Sf (1, 0, 0x15, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpamin.s0", f, OpXbX6Sf (1, 0, 0x16, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpamin", f, OpXbX6Sf (1, 0, 0x16, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpamin.s1", f, OpXbX6Sf (1, 0, 0x16, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpamin.s2", f, OpXbX6Sf (1, 0, 0x16, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpamin.s3", f, OpXbX6Sf (1, 0, 0x16, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpamax.s0", f, OpXbX6Sf (1, 0, 0x17, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpamax", f, OpXbX6Sf (1, 0, 0x17, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpamax.s1", f, OpXbX6Sf (1, 0, 0x17, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpamax.s2", f, OpXbX6Sf (1, 0, 0x17, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpamax.s3", f, OpXbX6Sf (1, 0, 0x17, 3), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"fpcmp.eq.s0", f, OpXbX6Sf (1, 0, 0x30, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.eq", f, OpXbX6Sf (1, 0, 0x30, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.eq.s1", f, OpXbX6Sf (1, 0, 0x30, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.eq.s2", f, OpXbX6Sf (1, 0, 0x30, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.eq.s3", f, OpXbX6Sf (1, 0, 0x30, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.lt.s0", f, OpXbX6Sf (1, 0, 0x31, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.lt", f, OpXbX6Sf (1, 0, 0x31, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.lt.s1", f, OpXbX6Sf (1, 0, 0x31, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.lt.s2", f, OpXbX6Sf (1, 0, 0x31, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.lt.s3", f, OpXbX6Sf (1, 0, 0x31, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.le.s0", f, OpXbX6Sf (1, 0, 0x32, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.le", f, OpXbX6Sf (1, 0, 0x32, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.le.s1", f, OpXbX6Sf (1, 0, 0x32, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.le.s2", f, OpXbX6Sf (1, 0, 0x32, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.le.s3", f, OpXbX6Sf (1, 0, 0x32, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.gt.s0", f, OpXbX6Sf (1, 0, 0x31, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.gt", f, OpXbX6Sf (1, 0, 0x31, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.gt.s1", f, OpXbX6Sf (1, 0, 0x31, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.gt.s2", f, OpXbX6Sf (1, 0, 0x31, 2), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.gt.s3", f, OpXbX6Sf (1, 0, 0x31, 3), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ge.s0", f, OpXbX6Sf (1, 0, 0x32, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ge", f, OpXbX6Sf (1, 0, 0x32, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ge.s1", f, OpXbX6Sf (1, 0, 0x32, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ge.s2", f, OpXbX6Sf (1, 0, 0x32, 2), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ge.s3", f, OpXbX6Sf (1, 0, 0x32, 3), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.unord.s0", f, OpXbX6Sf (1, 0, 0x33, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.unord", f, OpXbX6Sf (1, 0, 0x33, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.unord.s1", f, OpXbX6Sf (1, 0, 0x33, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.unord.s2", f, OpXbX6Sf (1, 0, 0x33, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.unord.s3", f, OpXbX6Sf (1, 0, 0x33, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.neq.s0", f, OpXbX6Sf (1, 0, 0x34, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.neq", f, OpXbX6Sf (1, 0, 0x34, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.neq.s1", f, OpXbX6Sf (1, 0, 0x34, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.neq.s2", f, OpXbX6Sf (1, 0, 0x34, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.neq.s3", f, OpXbX6Sf (1, 0, 0x34, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nlt.s0", f, OpXbX6Sf (1, 0, 0x35, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nlt", f, OpXbX6Sf (1, 0, 0x35, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nlt.s1", f, OpXbX6Sf (1, 0, 0x35, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nlt.s2", f, OpXbX6Sf (1, 0, 0x35, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nlt.s3", f, OpXbX6Sf (1, 0, 0x35, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nle.s0", f, OpXbX6Sf (1, 0, 0x36, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nle", f, OpXbX6Sf (1, 0, 0x36, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nle.s1", f, OpXbX6Sf (1, 0, 0x36, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nle.s2", f, OpXbX6Sf (1, 0, 0x36, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.nle.s3", f, OpXbX6Sf (1, 0, 0x36, 3), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.ngt.s0", f, OpXbX6Sf (1, 0, 0x35, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ngt", f, OpXbX6Sf (1, 0, 0x35, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ngt.s1", f, OpXbX6Sf (1, 0, 0x35, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ngt.s2", f, OpXbX6Sf (1, 0, 0x35, 2), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ngt.s3", f, OpXbX6Sf (1, 0, 0x35, 3), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nge.s0", f, OpXbX6Sf (1, 0, 0x36, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nge", f, OpXbX6Sf (1, 0, 0x36, 0), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nge.s1", f, OpXbX6Sf (1, 0, 0x36, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nge.s2", f, OpXbX6Sf (1, 0, 0x36, 2), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.nge.s3", f, OpXbX6Sf (1, 0, 0x36, 3), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ord.s0", f, OpXbX6Sf (1, 0, 0x37, 0), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.ord", f, OpXbX6Sf (1, 0, 0x37, 0), {F1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fpcmp.ord.s1", f, OpXbX6Sf (1, 0, 0x37, 1), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.ord.s2", f, OpXbX6Sf (1, 0, 0x37, 2), {F1, F2, F3}, EMPTY},
|
||||
{"fpcmp.ord.s3", f, OpXbX6Sf (1, 0, 0x37, 3), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"fpabs", f, OpXbX6F2 (1, 0, 0x10, 0), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fpneg", f, OpXbX6 (1, 0, 0x11), {F1, F3}, PSEUDO | F2_EQ_F3, 0, NULL},
|
||||
{"fpnegabs", f, OpXbX6F2 (1, 0, 0x11, 0), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fpmerge.s", f, OpXbX6 (1, 0, 0x10), {F1, F2, F3}, EMPTY},
|
||||
{"fpmerge.ns", f, OpXbX6 (1, 0, 0x11), {F1, F2, F3}, EMPTY},
|
||||
{"fpmerge.se", f, OpXbX6 (1, 0, 0x12), {F1, F2, F3}, EMPTY},
|
||||
|
||||
{"fpcvt.fx.s0", f, OpXbX6Sf (1, 0, 0x18, 0), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx", f, OpXbX6Sf (1, 0, 0x18, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcvt.fx.s1", f, OpXbX6Sf (1, 0, 0x18, 1), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.s2", f, OpXbX6Sf (1, 0, 0x18, 2), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.s3", f, OpXbX6Sf (1, 0, 0x18, 3), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.s0", f, OpXbX6Sf (1, 0, 0x19, 0), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu", f, OpXbX6Sf (1, 0, 0x19, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcvt.fxu.s1", f, OpXbX6Sf (1, 0, 0x19, 1), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.s2", f, OpXbX6Sf (1, 0, 0x19, 2), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.s3", f, OpXbX6Sf (1, 0, 0x19, 3), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.trunc.s0", f, OpXbX6Sf (1, 0, 0x1a, 0), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.trunc", f, OpXbX6Sf (1, 0, 0x1a, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcvt.fx.trunc.s1", f, OpXbX6Sf (1, 0, 0x1a, 1), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.trunc.s2", f, OpXbX6Sf (1, 0, 0x1a, 2), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fx.trunc.s3", f, OpXbX6Sf (1, 0, 0x1a, 3), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.trunc.s0", f, OpXbX6Sf (1, 0, 0x1b, 0), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.trunc", f, OpXbX6Sf (1, 0, 0x1b, 0), {F1, F2}, PSEUDO, 0, NULL},
|
||||
{"fpcvt.fxu.trunc.s1", f, OpXbX6Sf (1, 0, 0x1b, 1), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.trunc.s2", f, OpXbX6Sf (1, 0, 0x1b, 2), {F1, F2}, EMPTY},
|
||||
{"fpcvt.fxu.trunc.s3", f, OpXbX6Sf (1, 0, 0x1b, 3), {F1, F2}, EMPTY},
|
||||
|
||||
{"fcmp.eq.s0", f2, OpRaRbTaSf (4, 0, 0, 0, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq", f2, OpRaRbTaSf (4, 0, 0, 0, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.eq.s1", f2, OpRaRbTaSf (4, 0, 0, 0, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.s2", f2, OpRaRbTaSf (4, 0, 0, 0, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.s3", f2, OpRaRbTaSf (4, 0, 0, 0, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.s0", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.lt.s1", f2, OpRaRbTaSf (4, 0, 1, 0, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.s2", f2, OpRaRbTaSf (4, 0, 1, 0, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.s3", f2, OpRaRbTaSf (4, 0, 1, 0, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.s0", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.le.s1", f2, OpRaRbTaSf (4, 1, 0, 0, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.s2", f2, OpRaRbTaSf (4, 1, 0, 0, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.s3", f2, OpRaRbTaSf (4, 1, 0, 0, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.s0", f2, OpRaRbTaSf (4, 1, 1, 0, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord", f2, OpRaRbTaSf (4, 1, 1, 0, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.unord.s1", f2, OpRaRbTaSf (4, 1, 1, 0, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.s2", f2, OpRaRbTaSf (4, 1, 1, 0, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.s3", f2, OpRaRbTaSf (4, 1, 1, 0, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.unc.s0", f2, OpRaRbTaSf (4, 0, 0, 1, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.unc", f2, OpRaRbTaSf (4, 0, 0, 1, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.eq.unc.s1", f2, OpRaRbTaSf (4, 0, 0, 1, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.unc.s2", f2, OpRaRbTaSf (4, 0, 0, 1, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.eq.unc.s3", f2, OpRaRbTaSf (4, 0, 0, 1, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.unc.s0", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.unc", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.lt.unc.s1", f2, OpRaRbTaSf (4, 0, 1, 1, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.unc.s2", f2, OpRaRbTaSf (4, 0, 1, 1, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.lt.unc.s3", f2, OpRaRbTaSf (4, 0, 1, 1, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.unc.s0", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.unc", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.le.unc.s1", f2, OpRaRbTaSf (4, 1, 0, 1, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.unc.s2", f2, OpRaRbTaSf (4, 1, 0, 1, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.le.unc.s3", f2, OpRaRbTaSf (4, 1, 0, 1, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.unc.s0", f2, OpRaRbTaSf (4, 1, 1, 1, 0), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.unc", f2, OpRaRbTaSf (4, 1, 1, 1, 0), {P1, P2, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.unord.unc.s1", f2, OpRaRbTaSf (4, 1, 1, 1, 1), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.unc.s2", f2, OpRaRbTaSf (4, 1, 1, 1, 2), {P1, P2, F2, F3}, EMPTY},
|
||||
{"fcmp.unord.unc.s3", f2, OpRaRbTaSf (4, 1, 1, 1, 3), {P1, P2, F2, F3}, EMPTY},
|
||||
|
||||
/* pseudo-ops of the above */
|
||||
{"fcmp.gt.s0", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P1, P2, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.gt.s1", f2, OpRaRbTaSf (4, 0, 1, 0, 1), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt.s2", f2, OpRaRbTaSf (4, 0, 1, 0, 2), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt.s3", f2, OpRaRbTaSf (4, 0, 1, 0, 3), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.s0", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P1, P2, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ge.s1", f2, OpRaRbTaSf (4, 1, 0, 0, 1), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.s2", f2, OpRaRbTaSf (4, 1, 0, 0, 2), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.s3", f2, OpRaRbTaSf (4, 1, 0, 0, 3), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.neq.s0", f2, OpRaRbTaSf (4, 0, 0, 0, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq", f2, OpRaRbTaSf (4, 0, 0, 0, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.neq.s1", f2, OpRaRbTaSf (4, 0, 0, 0, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq.s2", f2, OpRaRbTaSf (4, 0, 0, 0, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq.s3", f2, OpRaRbTaSf (4, 0, 0, 0, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.s0", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nlt.s1", f2, OpRaRbTaSf (4, 0, 1, 0, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.s2", f2, OpRaRbTaSf (4, 0, 1, 0, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.s3", f2, OpRaRbTaSf (4, 0, 1, 0, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.s0", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nle.s1", f2, OpRaRbTaSf (4, 1, 0, 0, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.s2", f2, OpRaRbTaSf (4, 1, 0, 0, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.s3", f2, OpRaRbTaSf (4, 1, 0, 0, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ngt.s0", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt", f2, OpRaRbTaSf (4, 0, 1, 0, 0), {P2, P1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ngt.s1", f2, OpRaRbTaSf (4, 0, 1, 0, 1), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt.s2", f2, OpRaRbTaSf (4, 0, 1, 0, 2), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt.s3", f2, OpRaRbTaSf (4, 0, 1, 0, 3), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.s0", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge", f2, OpRaRbTaSf (4, 1, 0, 0, 0), {P2, P1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nge.s1", f2, OpRaRbTaSf (4, 1, 0, 0, 1), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.s2", f2, OpRaRbTaSf (4, 1, 0, 0, 2), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.s3", f2, OpRaRbTaSf (4, 1, 0, 0, 3), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ord.s0", f2, OpRaRbTaSf (4, 1, 1, 0, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord", f2, OpRaRbTaSf (4, 1, 1, 0, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ord.s1", f2, OpRaRbTaSf (4, 1, 1, 0, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord.s2", f2, OpRaRbTaSf (4, 1, 1, 0, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord.s3", f2, OpRaRbTaSf (4, 1, 1, 0, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.gt.unc.s0", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt.unc", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P1, P2, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.gt.unc.s1", f2, OpRaRbTaSf (4, 0, 1, 1, 1), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt.unc.s2", f2, OpRaRbTaSf (4, 0, 1, 1, 2), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.gt.unc.s3", f2, OpRaRbTaSf (4, 0, 1, 1, 3), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.unc.s0", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.unc", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P1, P2, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ge.unc.s1", f2, OpRaRbTaSf (4, 1, 0, 1, 1), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.unc.s2", f2, OpRaRbTaSf (4, 1, 0, 1, 2), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.ge.unc.s3", f2, OpRaRbTaSf (4, 1, 0, 1, 3), {P1, P2, F3, F2}, EMPTY},
|
||||
{"fcmp.neq.unc.s0", f2, OpRaRbTaSf (4, 0, 0, 1, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq.unc", f2, OpRaRbTaSf (4, 0, 0, 1, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.neq.unc.s1", f2, OpRaRbTaSf (4, 0, 0, 1, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq.unc.s2", f2, OpRaRbTaSf (4, 0, 0, 1, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.neq.unc.s3", f2, OpRaRbTaSf (4, 0, 0, 1, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.unc.s0", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.unc", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nlt.unc.s1", f2, OpRaRbTaSf (4, 0, 1, 1, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.unc.s2", f2, OpRaRbTaSf (4, 0, 1, 1, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nlt.unc.s3", f2, OpRaRbTaSf (4, 0, 1, 1, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.unc.s0", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.unc", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nle.unc.s1", f2, OpRaRbTaSf (4, 1, 0, 1, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.unc.s2", f2, OpRaRbTaSf (4, 1, 0, 1, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.nle.unc.s3", f2, OpRaRbTaSf (4, 1, 0, 1, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ngt.unc.s0", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt.unc", f2, OpRaRbTaSf (4, 0, 1, 1, 0), {P2, P1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ngt.unc.s1", f2, OpRaRbTaSf (4, 0, 1, 1, 1), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt.unc.s2", f2, OpRaRbTaSf (4, 0, 1, 1, 2), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ngt.unc.s3", f2, OpRaRbTaSf (4, 0, 1, 1, 3), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.unc.s0", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.unc", f2, OpRaRbTaSf (4, 1, 0, 1, 0), {P2, P1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fcmp.nge.unc.s1", f2, OpRaRbTaSf (4, 1, 0, 1, 1), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.unc.s2", f2, OpRaRbTaSf (4, 1, 0, 1, 2), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.nge.unc.s3", f2, OpRaRbTaSf (4, 1, 0, 1, 3), {P2, P1, F3, F2}, EMPTY},
|
||||
{"fcmp.ord.unc.s0", f2, OpRaRbTaSf (4, 1, 1, 1, 0), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord.unc", f2, OpRaRbTaSf (4, 1, 1, 1, 0), {P2, P1, F2, F3}, PSEUDO, 0, NULL},
|
||||
{"fcmp.ord.unc.s1", f2, OpRaRbTaSf (4, 1, 1, 1, 1), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord.unc.s2", f2, OpRaRbTaSf (4, 1, 1, 1, 2), {P2, P1, F2, F3}, EMPTY},
|
||||
{"fcmp.ord.unc.s3", f2, OpRaRbTaSf (4, 1, 1, 1, 3), {P2, P1, F2, F3}, EMPTY},
|
||||
|
||||
{"fclass.m", f2, OpTa (5, 0), {P1, P2, F2, IMMU9}, EMPTY},
|
||||
{"fclass.nm", f2, OpTa (5, 0), {P2, P1, F2, IMMU9}, PSEUDO, 0, NULL},
|
||||
{"fclass.m.unc", f2, OpTa (5, 1), {P1, P2, F2, IMMU9}, EMPTY},
|
||||
{"fclass.nm.unc", f2, OpTa (5, 1), {P2, P1, F2, IMMU9}, PSEUDO, 0, NULL},
|
||||
|
||||
/* note: fnorm and fcvt.xuf have identical encodings! */
|
||||
{"fnorm.s0", f, OpXaSfF2F4 (0x8, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm", f, OpXaSfF2F4 (0x8, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s1", f, OpXaSfF2F4 (0x8, 0, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s2", f, OpXaSfF2F4 (0x8, 0, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s3", f, OpXaSfF2F4 (0x8, 0, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s.s0", f, OpXaSfF2F4 (0x8, 1, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s", f, OpXaSfF2F4 (0x8, 1, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s.s1", f, OpXaSfF2F4 (0x8, 1, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s.s2", f, OpXaSfF2F4 (0x8, 1, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.s.s3", f, OpXaSfF2F4 (0x8, 1, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s0", f, OpXaSfF2F4 (0x8, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf", f, OpXaSfF2F4 (0x8, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s1", f, OpXaSfF2F4 (0x8, 0, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s2", f, OpXaSfF2F4 (0x8, 0, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s3", f, OpXaSfF2F4 (0x8, 0, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s.s0", f, OpXaSfF2F4 (0x8, 1, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s", f, OpXaSfF2F4 (0x8, 1, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s.s1", f, OpXaSfF2F4 (0x8, 1, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s.s2", f, OpXaSfF2F4 (0x8, 1, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.s.s3", f, OpXaSfF2F4 (0x8, 1, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fadd.s0", f, OpXaSfF4 (0x8, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd", f, OpXaSfF4 (0x8, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s1", f, OpXaSfF4 (0x8, 0, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s2", f, OpXaSfF4 (0x8, 0, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s3", f, OpXaSfF4 (0x8, 0, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s.s0", f, OpXaSfF4 (0x8, 1, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s", f, OpXaSfF4 (0x8, 1, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s.s1", f, OpXaSfF4 (0x8, 1, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s.s2", f, OpXaSfF4 (0x8, 1, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.s.s3", f, OpXaSfF4 (0x8, 1, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s0", f, OpXaSfF2 (0x8, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy", f, OpXaSfF2 (0x8, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s1", f, OpXaSfF2 (0x8, 0, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s2", f, OpXaSfF2 (0x8, 0, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s3", f, OpXaSfF2 (0x8, 0, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s.s0", f, OpXaSfF2 (0x8, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s", f, OpXaSfF2 (0x8, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s.s1", f, OpXaSfF2 (0x8, 1, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s.s2", f, OpXaSfF2 (0x8, 1, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.s.s3", f, OpXaSfF2 (0x8, 1, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fma.s0", f, OpXaSf (0x8, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma", f, OpXaSf (0x8, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fma.s1", f, OpXaSf (0x8, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s2", f, OpXaSf (0x8, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s3", f, OpXaSf (0x8, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s.s0", f, OpXaSf (0x8, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s", f, OpXaSf (0x8, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fma.s.s1", f, OpXaSf (0x8, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s.s2", f, OpXaSf (0x8, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.s.s3", f, OpXaSf (0x8, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fnorm.d.s0", f, OpXaSfF2F4 (0x9, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.d", f, OpXaSfF2F4 (0x9, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.d.s1", f, OpXaSfF2F4 (0x9, 0, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.d.s2", f, OpXaSfF2F4 (0x9, 0, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fnorm.d.s3", f, OpXaSfF2F4 (0x9, 0, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.d.s0", f, OpXaSfF2F4 (0x9, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.d", f, OpXaSfF2F4 (0x9, 0, 0, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.d.s1", f, OpXaSfF2F4 (0x9, 0, 1, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.d.s2", f, OpXaSfF2F4 (0x9, 0, 2, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fcvt.xuf.d.s3", f, OpXaSfF2F4 (0x9, 0, 3, 0, 1), {F1, F3}, PSEUDO, 0, NULL},
|
||||
{"fadd.d.s0", f, OpXaSfF4 (0x9, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.d", f, OpXaSfF4 (0x9, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.d.s1", f, OpXaSfF4 (0x9, 0, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.d.s2", f, OpXaSfF4 (0x9, 0, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fadd.d.s3", f, OpXaSfF4 (0x9, 0, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fmpy.d.s0", f, OpXaSfF2 (0x9, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.d", f, OpXaSfF2 (0x9, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.d.s1", f, OpXaSfF2 (0x9, 0, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.d.s2", f, OpXaSfF2 (0x9, 0, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fmpy.d.s3", f, OpXaSfF2 (0x9, 0, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fma.d.s0", f, OpXaSf (0x9, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.d", f, OpXaSf (0x9, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fma.d.s1", f, OpXaSf (0x9, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.d.s2", f, OpXaSf (0x9, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fma.d.s3", f, OpXaSf (0x9, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fpmpy.s0", f, OpXaSfF2 (0x9, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpmpy", f, OpXaSfF2 (0x9, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpmpy.s1", f, OpXaSfF2 (0x9, 1, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpmpy.s2", f, OpXaSfF2 (0x9, 1, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpmpy.s3", f, OpXaSfF2 (0x9, 1, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpma.s0", f, OpXaSf (0x9, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpma", f, OpXaSf (0x9, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fpma.s1", f, OpXaSf (0x9, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpma.s2", f, OpXaSf (0x9, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpma.s3", f, OpXaSf (0x9, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fsub.s0", f, OpXaSfF4 (0xa, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub", f, OpXaSfF4 (0xa, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s1", f, OpXaSfF4 (0xa, 0, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s2", f, OpXaSfF4 (0xa, 0, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s3", f, OpXaSfF4 (0xa, 0, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s.s0", f, OpXaSfF4 (0xa, 1, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s", f, OpXaSfF4 (0xa, 1, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s.s1", f, OpXaSfF4 (0xa, 1, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s.s2", f, OpXaSfF4 (0xa, 1, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.s.s3", f, OpXaSfF4 (0xa, 1, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fms.s0", f, OpXaSf (0xa, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms", f, OpXaSf (0xa, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fms.s1", f, OpXaSf (0xa, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s2", f, OpXaSf (0xa, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s3", f, OpXaSf (0xa, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s.s0", f, OpXaSf (0xa, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s", f, OpXaSf (0xa, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fms.s.s1", f, OpXaSf (0xa, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s.s2", f, OpXaSf (0xa, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.s.s3", f, OpXaSf (0xa, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fsub.d.s0", f, OpXaSfF4 (0xb, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.d", f, OpXaSfF4 (0xb, 0, 0, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.d.s1", f, OpXaSfF4 (0xb, 0, 1, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.d.s2", f, OpXaSfF4 (0xb, 0, 2, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fsub.d.s3", f, OpXaSfF4 (0xb, 0, 3, 1), {F1, F3, F2}, PSEUDO, 0, NULL},
|
||||
{"fms.d.s0", f, OpXaSf (0xb, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.d", f, OpXaSf (0xb, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fms.d.s1", f, OpXaSf (0xb, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.d.s2", f, OpXaSf (0xb, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fms.d.s3", f, OpXaSf (0xb, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fpms.s0", f, OpXaSf (0xb, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpms", f, OpXaSf (0xb, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fpms.s1", f, OpXaSf (0xb, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpms.s2", f, OpXaSf (0xb, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpms.s3", f, OpXaSf (0xb, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fnmpy.s0", f, OpXaSfF2 (0xc, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy", f, OpXaSfF2 (0xc, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s1", f, OpXaSfF2 (0xc, 0, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s2", f, OpXaSfF2 (0xc, 0, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s3", f, OpXaSfF2 (0xc, 0, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s.s0", f, OpXaSfF2 (0xc, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s", f, OpXaSfF2 (0xc, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s.s1", f, OpXaSfF2 (0xc, 1, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s.s2", f, OpXaSfF2 (0xc, 1, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.s.s3", f, OpXaSfF2 (0xc, 1, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnma.s0", f, OpXaSf (0xc, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma", f, OpXaSf (0xc, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fnma.s1", f, OpXaSf (0xc, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s2", f, OpXaSf (0xc, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s3", f, OpXaSf (0xc, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s.s0", f, OpXaSf (0xc, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s", f, OpXaSf (0xc, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fnma.s.s1", f, OpXaSf (0xc, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s.s2", f, OpXaSf (0xc, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.s.s3", f, OpXaSf (0xc, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnmpy.d.s0", f, OpXaSfF2 (0xd, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.d", f, OpXaSfF2 (0xd, 0, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.d.s1", f, OpXaSfF2 (0xd, 0, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.d.s2", f, OpXaSfF2 (0xd, 0, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnmpy.d.s3", f, OpXaSfF2 (0xd, 0, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fnma.d.s0", f, OpXaSf (0xd, 0, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.d", f, OpXaSf (0xd, 0, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fnma.d.s1", f, OpXaSf (0xd, 0, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.d.s2", f, OpXaSf (0xd, 0, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fnma.d.s3", f, OpXaSf (0xd, 0, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fpnmpy.s0", f, OpXaSfF2 (0xd, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpnmpy", f, OpXaSfF2 (0xd, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpnmpy.s1", f, OpXaSfF2 (0xd, 1, 1, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpnmpy.s2", f, OpXaSfF2 (0xd, 1, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpnmpy.s3", f, OpXaSfF2 (0xd, 1, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"fpnma.s0", f, OpXaSf (0xd, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpnma", f, OpXaSf (0xd, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"fpnma.s1", f, OpXaSf (0xd, 1, 1), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpnma.s2", f, OpXaSf (0xd, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
{"fpnma.s3", f, OpXaSf (0xd, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"xmpy.l", f, OpXaX2F2 (0xe, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"xmpy.lu", f, OpXaX2F2 (0xe, 1, 0, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"xmpy.h", f, OpXaX2F2 (0xe, 1, 3, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"xmpy.hu", f, OpXaX2F2 (0xe, 1, 2, 0), {F1, F3, F4}, PSEUDO, 0, NULL},
|
||||
{"xma.l", f, OpXaX2 (0xe, 1, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
{"xma.lu", f, OpXaX2 (0xe, 1, 0), {F1, F3, F4, F2}, PSEUDO, 0, NULL},
|
||||
{"xma.h", f, OpXaX2 (0xe, 1, 3), {F1, F3, F4, F2}, EMPTY},
|
||||
{"xma.hu", f, OpXaX2 (0xe, 1, 2), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{"fselect", f, OpXa (0xe, 0), {F1, F3, F4, F2}, EMPTY},
|
||||
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#undef f0
|
||||
#undef f
|
||||
#undef f2
|
||||
#undef bF2
|
||||
#undef bF4
|
||||
#undef bQ
|
||||
#undef bRa
|
||||
#undef bRb
|
||||
#undef bSf
|
||||
#undef bTa
|
||||
#undef bXa
|
||||
#undef bXb
|
||||
#undef bX2
|
||||
#undef bX6
|
||||
#undef mF2
|
||||
#undef mF4
|
||||
#undef mQ
|
||||
#undef mRa
|
||||
#undef mRb
|
||||
#undef mSf
|
||||
#undef mTa
|
||||
#undef mXa
|
||||
#undef mXb
|
||||
#undef mX2
|
||||
#undef mX6
|
||||
#undef OpXa
|
||||
#undef OpXaSf
|
||||
#undef OpXaSfF2
|
||||
#undef OpXaSfF4
|
||||
#undef OpXaSfF2F4
|
||||
#undef OpXaX2
|
||||
#undef OpRaRbTaSf
|
||||
#undef OpTa
|
||||
#undef OpXbQSf
|
||||
#undef OpXbX6
|
||||
#undef OpXbX6F2
|
||||
#undef OpXbX6Sf
|
||||
#undef EMPTY
|
||||
@@ -1,338 +0,0 @@
|
||||
/* ia64-opc-i.c -- IA-64 `I' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2002, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
#define I0 IA64_TYPE_I, 0
|
||||
#define I IA64_TYPE_I, 1
|
||||
#define I2 IA64_TYPE_I, 2
|
||||
|
||||
/* instruction bit fields: */
|
||||
#define bC(x) (((ia64_insn) ((x) & 0x1)) << 12)
|
||||
#define bIh(x) (((ia64_insn) ((x) & 0x1)) << 23)
|
||||
#define bTa(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bTag13(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bTb(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bVc(x) (((ia64_insn) ((x) & 0x1)) << 20)
|
||||
#define bVe(x) (((ia64_insn) ((x) & 0x1)) << 32)
|
||||
#define bWh(x) (((ia64_insn) ((x) & 0x3)) << 20)
|
||||
#define bX(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
#define bXb(x) (((ia64_insn) ((x) & 0x1)) << 22)
|
||||
#define bXc(x) (((ia64_insn) ((x) & 0x1)) << 19)
|
||||
#define bX2(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bX2a(x) (((ia64_insn) ((x) & 0x3)) << 34)
|
||||
#define bX2b(x) (((ia64_insn) ((x) & 0x3)) << 28)
|
||||
#define bX2c(x) (((ia64_insn) ((x) & 0x3)) << 30)
|
||||
#define bX3(x) (((ia64_insn) ((x) & 0x7)) << 33)
|
||||
#define bX6(x) (((ia64_insn) ((x) & 0x3f)) << 27)
|
||||
#define bYa(x) (((ia64_insn) ((x) & 0x1)) << 13)
|
||||
#define bYb(x) (((ia64_insn) ((x) & 0x1)) << 26)
|
||||
#define bZa(x) (((ia64_insn) ((x) & 0x1)) << 36)
|
||||
#define bZb(x) (((ia64_insn) ((x) & 0x1)) << 33)
|
||||
|
||||
/* instruction bit masks: */
|
||||
#define mC bC (-1)
|
||||
#define mIh bIh (-1)
|
||||
#define mTa bTa (-1)
|
||||
#define mTag13 bTag13 (-1)
|
||||
#define mTb bTb (-1)
|
||||
#define mVc bVc (-1)
|
||||
#define mVe bVe (-1)
|
||||
#define mWh bWh (-1)
|
||||
#define mX bX (-1)
|
||||
#define mXb bXb (-1)
|
||||
#define mXc bXc (-1)
|
||||
#define mX2 bX2 (-1)
|
||||
#define mX2a bX2a (-1)
|
||||
#define mX2b bX2b (-1)
|
||||
#define mX2c bX2c (-1)
|
||||
#define mX3 bX3 (-1)
|
||||
#define mX6 bX6 (-1)
|
||||
#define mYa bYa (-1)
|
||||
#define mYb bYb (-1)
|
||||
#define mZa bZa (-1)
|
||||
#define mZb bZb (-1)
|
||||
|
||||
#define OpZaZbVeX2aX2b(a,b,c,d,e,f) \
|
||||
(bOp (a) | bZa (b) | bZb (c) | bVe (d) | bX2a (e) | bX2b (f)), \
|
||||
(mOp | mZa | mZb | mVe | mX2a | mX2b)
|
||||
#define OpZaZbVeX2aX2bX2c(a,b,c,d,e,f,g) \
|
||||
(bOp (a) | bZa (b) | bZb (c) | bVe (d) | bX2a (e) | bX2b (f) | bX2c (g)), \
|
||||
(mOp | mZa | mZb | mVe | mX2a | mX2b | mX2c)
|
||||
#define OpX2X(a,b,c) (bOp (a) | bX2 (b) | bX (c)), (mOp | mX2 | mX)
|
||||
#define OpX2XYa(a,b,c,d) (bOp (a) | bX2 (b) | bX (c) | bYa (d)), \
|
||||
(mOp | mX2 | mX | mYa)
|
||||
#define OpX2XYb(a,b,c,d) (bOp (a) | bX2 (b) | bX (c) | bYb (d)), \
|
||||
(mOp | mX2 | mX | mYb)
|
||||
#define OpX2TaTbYaC(a,b,c,d,e,f) \
|
||||
(bOp (a) | bX2 (b) | bTa (c) | bTb (d) | bYa (e) | bC (f)), \
|
||||
(mOp | mX2 | mTa | mTb | mYa | mC)
|
||||
#define OpX2TaTbYaXcC(a,b,c,d,e,f,g) \
|
||||
(bOp (a) | bX2 (b) | bTa (c) | bTb (d) | bYa (e) | bXc (f) | bC (g)), \
|
||||
(mOp | mX2 | mTa | mTb | mYa | mXc | mC)
|
||||
#define OpX3(a,b) (bOp (a) | bX3 (b)), (mOp | mX3)
|
||||
#define OpX3X6(a,b,c) (bOp (a) | bX3 (b) | bX6(c)), \
|
||||
(mOp | mX3 | mX6)
|
||||
#define OpX3X6Yb(a,b,c,d) (bOp (a) | bX3 (b) | bX6(c) | bYb(d)), \
|
||||
(mOp | mX3 | mX6 | mYb)
|
||||
#define OpX3XbIhWh(a,b,c,d,e) \
|
||||
(bOp (a) | bX3 (b) | bXb (c) | bIh (d) | bWh (e)), \
|
||||
(mOp | mX3 | mXb | mIh | mWh)
|
||||
#define OpX3XbIhWhTag13(a,b,c,d,e,f) \
|
||||
(bOp (a) | bX3 (b) | bXb (c) | bIh (d) | bWh (e) | bTag13 (f)), \
|
||||
(mOp | mX3 | mXb | mIh | mWh | mTag13)
|
||||
|
||||
#define FULL17 ((ia64_insn)0x10ff001fc0LL)
|
||||
|
||||
/* Used to initialise unused fields in ia64_opcode struct,
|
||||
in order to stop gcc from complaining. */
|
||||
#define EMPTY 0,0,NULL
|
||||
|
||||
struct ia64_opcode ia64_opcodes_i[] =
|
||||
{
|
||||
/* I-type instruction encodings (sorted according to major opcode). */
|
||||
|
||||
{"break.i", I0, OpX3X6 (0, 0, 0x00), {IMMU21}, X_IN_MLX, 0, NULL},
|
||||
{"nop.i", I0, OpX3X6Yb (0, 0, 0x01, 0), {IMMU21}, X_IN_MLX, 0, NULL},
|
||||
{"hint.i", I0, OpX3X6Yb (0, 0, 0x01, 1), {IMMU21}, X_IN_MLX, 0, NULL},
|
||||
{"chk.s.i", I0, OpX3 (0, 1), {R2, TGT25b}, EMPTY},
|
||||
|
||||
{"mov", I, OpX3XbIhWhTag13 (0, 7, 0, 0, 1, 0), {B1, R2}, PSEUDO, 0, NULL},
|
||||
#define MOV(a,b,c,d) \
|
||||
I, OpX3XbIhWh (0, a, b, c, d), {B1, R2, TAG13b}, EMPTY
|
||||
{"mov.sptk", MOV (7, 0, 0, 0)},
|
||||
{"mov.sptk.imp", MOV (7, 0, 1, 0)},
|
||||
{"mov", MOV (7, 0, 0, 1)},
|
||||
{"mov.imp", MOV (7, 0, 1, 1)},
|
||||
{"mov.dptk", MOV (7, 0, 0, 2)},
|
||||
{"mov.dptk.imp", MOV (7, 0, 1, 2)},
|
||||
{"mov.ret.sptk", MOV (7, 1, 0, 0)},
|
||||
{"mov.ret.sptk.imp", MOV (7, 1, 1, 0)},
|
||||
{"mov.ret", MOV (7, 1, 0, 1)},
|
||||
{"mov.ret.imp", MOV (7, 1, 1, 1)},
|
||||
{"mov.ret.dptk", MOV (7, 1, 0, 2)},
|
||||
{"mov.ret.dptk.imp", MOV (7, 1, 1, 2)},
|
||||
#undef MOV
|
||||
{"mov", I, OpX3X6 (0, 0, 0x31), {R1, B2}, EMPTY},
|
||||
{"mov", I, OpX3 (0, 3), {PR, R2, IMM17}, EMPTY},
|
||||
/* Don't remove one of the seemingly redundant FULL17-s. */
|
||||
{"mov", I, FULL17 | OpX3 (0, 3) | FULL17, {PR, R2}, PSEUDO, 0, NULL},
|
||||
{"mov", I, OpX3 (0, 2), {PR_ROT, IMM44}, EMPTY},
|
||||
{"mov", I, OpX3X6 (0, 0, 0x30), {R1, IP}, EMPTY},
|
||||
{"mov", I, OpX3X6 (0, 0, 0x33), {R1, PR}, EMPTY},
|
||||
{"mov.i", I, OpX3X6 (0, 0, 0x2a), {AR3, R2}, EMPTY},
|
||||
{"mov.i", I, OpX3X6 (0, 0, 0x0a), {AR3, IMM8}, EMPTY},
|
||||
{"mov.i", I, OpX3X6 (0, 0, 0x32), {R1, AR3}, EMPTY},
|
||||
{"zxt1", I, OpX3X6 (0, 0, 0x10), {R1, R3}, EMPTY},
|
||||
{"zxt2", I, OpX3X6 (0, 0, 0x11), {R1, R3}, EMPTY},
|
||||
{"zxt4", I, OpX3X6 (0, 0, 0x12), {R1, R3}, EMPTY},
|
||||
{"sxt1", I, OpX3X6 (0, 0, 0x14), {R1, R3}, EMPTY},
|
||||
{"sxt2", I, OpX3X6 (0, 0, 0x15), {R1, R3}, EMPTY},
|
||||
{"sxt4", I, OpX3X6 (0, 0, 0x16), {R1, R3}, EMPTY},
|
||||
{"czx1.l", I, OpX3X6 (0, 0, 0x18), {R1, R3}, EMPTY},
|
||||
{"czx2.l", I, OpX3X6 (0, 0, 0x19), {R1, R3}, EMPTY},
|
||||
{"czx1.r", I, OpX3X6 (0, 0, 0x1c), {R1, R3}, EMPTY},
|
||||
{"czx2.r", I, OpX3X6 (0, 0, 0x1d), {R1, R3}, EMPTY},
|
||||
|
||||
{"dep", I, Op (4), {R1, R2, R3, CPOS6c, LEN4}, EMPTY},
|
||||
|
||||
{"shrp", I, OpX2X (5, 3, 0), {R1, R2, R3, CNT6}, EMPTY},
|
||||
|
||||
{"shr.u", I, OpX2XYa (5, 1, 0, 0), {R1, R3, POS6},
|
||||
PSEUDO | LEN_EQ_64MCNT, 0, NULL},
|
||||
{"extr.u", I, OpX2XYa (5, 1, 0, 0), {R1, R3, POS6, LEN6}, EMPTY},
|
||||
|
||||
{"shr", I, OpX2XYa (5, 1, 0, 1), {R1, R3, POS6},
|
||||
PSEUDO | LEN_EQ_64MCNT, 0, NULL},
|
||||
{"extr", I, OpX2XYa (5, 1, 0, 1), {R1, R3, POS6, LEN6}, EMPTY},
|
||||
|
||||
{"shl", I, OpX2XYb (5, 1, 1, 0), {R1, R2, CPOS6a},
|
||||
PSEUDO | LEN_EQ_64MCNT, 0, NULL},
|
||||
{"dep.z", I, OpX2XYb (5, 1, 1, 0), {R1, R2, CPOS6a, LEN6}, EMPTY},
|
||||
{"dep.z", I, OpX2XYb (5, 1, 1, 1), {R1, IMM8, CPOS6a, LEN6}, EMPTY},
|
||||
{"dep", I, OpX2X (5, 3, 1), {R1, IMM1, R3, CPOS6b, LEN6}, EMPTY},
|
||||
#define TF(a,b,c) \
|
||||
I2, OpX2TaTbYaXcC (5, 0, a, b, 1, 1, c), {P1, P2, IMMU5b}, EMPTY
|
||||
#define TFCM(a,b,c) \
|
||||
I2, OpX2TaTbYaXcC (5, 0, a, b, 1, 1, c), {P2, P1, IMMU5b}, PSEUDO, 0, NULL
|
||||
{"tf.z", TF (0, 0, 0)},
|
||||
{"tf.nz", TFCM (0, 0, 0)},
|
||||
{"tf.z.unc", TF (0, 0, 1)},
|
||||
{"tf.nz.unc", TFCM (0, 0, 1)},
|
||||
{"tf.z.and", TF (0, 1, 0)},
|
||||
{"tf.nz.andcm", TFCM (0, 1, 0)},
|
||||
{"tf.nz.and", TF (0, 1, 1)},
|
||||
{"tf.z.andcm", TFCM (0, 1, 1)},
|
||||
{"tf.z.or", TF (1, 0, 0)},
|
||||
{"tf.nz.orcm", TFCM (1, 0, 0)},
|
||||
{"tf.nz.or", TF (1, 0, 1)},
|
||||
{"tf.z.orcm", TFCM (1, 0, 1)},
|
||||
{"tf.z.or.andcm", TF (1, 1, 0)},
|
||||
{"tf.nz.and.orcm", TFCM (1, 1, 0)},
|
||||
{"tf.nz.or.andcm", TF (1, 1, 1)},
|
||||
{"tf.z.and.orcm", TFCM (1, 1, 1)},
|
||||
#undef TF
|
||||
#undef TFCM
|
||||
#define TBIT(a,b,c,d) \
|
||||
I2, OpX2TaTbYaC (5, 0, a, b, c, d), {P1, P2, R3, POS6}, EMPTY
|
||||
#define TBITCM(a,b,c,d) \
|
||||
I2, OpX2TaTbYaC (5, 0, a, b, c, d), {P2, P1, R3, POS6}, PSEUDO, 0, NULL
|
||||
{"tbit.z", TBIT (0, 0, 0, 0)},
|
||||
{"tbit.nz", TBITCM (0, 0, 0, 0)},
|
||||
{"tbit.z.unc", TBIT (0, 0, 0, 1)},
|
||||
{"tbit.nz.unc", TBITCM (0, 0, 0, 1)},
|
||||
{"tbit.z.and", TBIT (0, 1, 0, 0)},
|
||||
{"tbit.nz.andcm", TBITCM (0, 1, 0, 0)},
|
||||
{"tbit.nz.and", TBIT (0, 1, 0, 1)},
|
||||
{"tbit.z.andcm", TBITCM (0, 1, 0, 1)},
|
||||
{"tbit.z.or", TBIT (1, 0, 0, 0)},
|
||||
{"tbit.nz.orcm", TBITCM (1, 0, 0, 0)},
|
||||
{"tbit.nz.or", TBIT (1, 0, 0, 1)},
|
||||
{"tbit.z.orcm", TBITCM (1, 0, 0, 1)},
|
||||
{"tbit.z.or.andcm", TBIT (1, 1, 0, 0)},
|
||||
{"tbit.nz.and.orcm", TBITCM (1, 1, 0, 0)},
|
||||
{"tbit.nz.or.andcm", TBIT (1, 1, 0, 1)},
|
||||
{"tbit.z.and.orcm", TBITCM (1, 1, 0, 1)},
|
||||
#undef TBIT
|
||||
#undef TBITCM
|
||||
#define TNAT(a,b,c,d) \
|
||||
I2, OpX2TaTbYaC (5, 0, a, b, c, d), {P1, P2, R3}, EMPTY
|
||||
#define TNATCM(a,b,c,d) \
|
||||
I2, OpX2TaTbYaC (5, 0, a, b, c, d), {P2, P1, R3}, PSEUDO, 0, NULL
|
||||
{"tnat.z", TNAT (0, 0, 1, 0)},
|
||||
{"tnat.nz", TNATCM (0, 0, 1, 0)},
|
||||
{"tnat.z.unc", TNAT (0, 0, 1, 1)},
|
||||
{"tnat.nz.unc", TNATCM (0, 0, 1, 1)},
|
||||
{"tnat.z.and", TNAT (0, 1, 1, 0)},
|
||||
{"tnat.nz.andcm", TNATCM (0, 1, 1, 0)},
|
||||
{"tnat.nz.and", TNAT (0, 1, 1, 1)},
|
||||
{"tnat.z.andcm", TNATCM (0, 1, 1, 1)},
|
||||
{"tnat.z.or", TNAT (1, 0, 1, 0)},
|
||||
{"tnat.nz.orcm", TNATCM (1, 0, 1, 0)},
|
||||
{"tnat.nz.or", TNAT (1, 0, 1, 1)},
|
||||
{"tnat.z.orcm", TNATCM (1, 0, 1, 1)},
|
||||
{"tnat.z.or.andcm", TNAT (1, 1, 1, 0)},
|
||||
{"tnat.nz.and.orcm", TNATCM (1, 1, 1, 0)},
|
||||
{"tnat.nz.or.andcm", TNAT (1, 1, 1, 1)},
|
||||
{"tnat.z.and.orcm", TNATCM (1, 1, 1, 1)},
|
||||
#undef TNAT
|
||||
#undef TNATCM
|
||||
|
||||
{"pmpyshr2", I, OpZaZbVeX2aX2b (7, 0, 1, 0, 0, 3), {R1, R2, R3, CNT2c}, EMPTY},
|
||||
{"pmpyshr2.u", I, OpZaZbVeX2aX2b (7, 0, 1, 0, 0, 1), {R1, R2, R3, CNT2c}, EMPTY},
|
||||
{"pmpy2.r", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 1, 3), {R1, R2, R3}, EMPTY},
|
||||
{"pmpy2.l", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 3, 3), {R1, R2, R3}, EMPTY},
|
||||
{"mix1.r", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 0, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mix2.r", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 0, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mix4.r", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 2, 0, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mix1.l", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 2, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mix2.l", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 2, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mix4.l", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 2, 2, 2), {R1, R2, R3}, EMPTY},
|
||||
{"pack2.uss", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 0, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pack2.sss", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 2, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pack4.sss", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 2, 2, 0), {R1, R2, R3}, EMPTY},
|
||||
{"unpack1.h", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"unpack2.h", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"unpack4.h", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 2, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"unpack1.l", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 2, 1), {R1, R2, R3}, EMPTY},
|
||||
{"unpack2.l", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 2, 1), {R1, R2, R3}, EMPTY},
|
||||
{"unpack4.l", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 2, 2, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pmin1.u", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 1, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pmax1.u", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 1, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pmin2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 3, 0), {R1, R2, R3}, EMPTY},
|
||||
{"pmax2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 2, 3, 1), {R1, R2, R3}, EMPTY},
|
||||
{"psad1", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 2, 3, 2), {R1, R2, R3}, EMPTY},
|
||||
{"mux1", I, OpZaZbVeX2aX2bX2c (7, 0, 0, 0, 3, 2, 2), {R1, R2, MBTYPE4}, EMPTY},
|
||||
{"mux2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 3, 2, 2), {R1, R2, MHTYPE8}, EMPTY},
|
||||
{"pshr2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 0, 2, 0), {R1, R3, R2}, EMPTY},
|
||||
{"pshr4", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 0, 2, 0), {R1, R3, R2}, EMPTY},
|
||||
{"shr", I, OpZaZbVeX2aX2bX2c (7, 1, 1, 0, 0, 2, 0), {R1, R3, R2}, EMPTY},
|
||||
{"pshr2.u", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 0, 0, 0), {R1, R3, R2}, EMPTY},
|
||||
{"pshr4.u", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 0, 0, 0), {R1, R3, R2}, EMPTY},
|
||||
{"shr.u", I, OpZaZbVeX2aX2bX2c (7, 1, 1, 0, 0, 0, 0), {R1, R3, R2}, EMPTY},
|
||||
{"pshr2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 1, 3, 0), {R1, R3, CNT5}, EMPTY},
|
||||
{"pshr4", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 1, 3, 0), {R1, R3, CNT5}, EMPTY},
|
||||
{"pshr2.u", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 1, 1, 0), {R1, R3, CNT5}, EMPTY},
|
||||
{"pshr4.u", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 1, 1, 0), {R1, R3, CNT5}, EMPTY},
|
||||
{"pshl2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 0, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pshl4", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 0, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"shl", I, OpZaZbVeX2aX2bX2c (7, 1, 1, 0, 0, 0, 1), {R1, R2, R3}, EMPTY},
|
||||
{"pshl2", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 3, 1, 1), {R1, R2, CCNT5}, EMPTY},
|
||||
{"pshl4", I, OpZaZbVeX2aX2bX2c (7, 1, 0, 0, 3, 1, 1), {R1, R2, CCNT5}, EMPTY},
|
||||
{"popcnt", I, OpZaZbVeX2aX2bX2c (7, 0, 1, 0, 1, 1, 2), {R1, R3}, EMPTY},
|
||||
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#undef I0
|
||||
#undef I
|
||||
#undef I2
|
||||
#undef L
|
||||
#undef bC
|
||||
#undef bIh
|
||||
#undef bTa
|
||||
#undef bTag13
|
||||
#undef bTb
|
||||
#undef bVc
|
||||
#undef bVe
|
||||
#undef bWh
|
||||
#undef bX
|
||||
#undef bXb
|
||||
#undef bX2
|
||||
#undef bX2a
|
||||
#undef bX2b
|
||||
#undef bX2c
|
||||
#undef bX3
|
||||
#undef bX6
|
||||
#undef bY
|
||||
#undef bZa
|
||||
#undef bZb
|
||||
#undef mC
|
||||
#undef mIh
|
||||
#undef mTa
|
||||
#undef mTag13
|
||||
#undef mTb
|
||||
#undef mVc
|
||||
#undef mVe
|
||||
#undef mWh
|
||||
#undef mX
|
||||
#undef mXb
|
||||
#undef mX2
|
||||
#undef mX2a
|
||||
#undef mX2b
|
||||
#undef mX2c
|
||||
#undef mX3
|
||||
#undef mX6
|
||||
#undef mY
|
||||
#undef mZa
|
||||
#undef mZb
|
||||
#undef OpZaZbVeX2aX2b
|
||||
#undef OpZaZbVeX2aX2bX2c
|
||||
#undef OpX2X
|
||||
#undef OpX2XYa
|
||||
#undef OpX2XYb
|
||||
#undef OpX2TaTbYaC
|
||||
#undef OpX3
|
||||
#undef OpX3X6
|
||||
#undef OpX3XbIhWh
|
||||
#undef OpX3XbIhWhTag13
|
||||
#undef EMPTY
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,188 +0,0 @@
|
||||
/* ia64-opc-x.c -- IA-64 `X' opcode table.
|
||||
Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Timothy Wall <twall@cygnus.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-opc.h"
|
||||
|
||||
/* Identify the specific X-unit type. */
|
||||
#define X0 IA64_TYPE_X, 0
|
||||
#define X IA64_TYPE_X, 1
|
||||
|
||||
/* Instruction bit fields: */
|
||||
#define bBtype(x) (((ia64_insn) ((x) & 0x7)) << 6)
|
||||
#define bD(x) (((ia64_insn) ((x) & 0x1)) << 35)
|
||||
#define bPa(x) (((ia64_insn) ((x) & 0x1)) << 12)
|
||||
#define bPr(x) (((ia64_insn) ((x) & 0x3f)) << 0)
|
||||
#define bVc(x) (((ia64_insn) ((x) & 0x1)) << 20)
|
||||
#define bWha(x) (((ia64_insn) ((x) & 0x3)) << 33)
|
||||
#define bX3(x) (((ia64_insn) ((x) & 0x7)) << 33)
|
||||
#define bX6(x) (((ia64_insn) ((x) & 0x3f)) << 27)
|
||||
#define bY(x) (((ia64_insn) ((x) & 0x1)) << 26)
|
||||
|
||||
#define mBtype bBtype (-1)
|
||||
#define mD bD (-1)
|
||||
#define mPa bPa (-1)
|
||||
#define mPr bPr (-1)
|
||||
#define mVc bVc (-1)
|
||||
#define mWha bWha (-1)
|
||||
#define mX3 bX3 (-1)
|
||||
#define mX6 bX6 (-1)
|
||||
#define mY bY (-1)
|
||||
|
||||
#define OpX3X6(a,b,c) (bOp (a) | bX3 (b) | bX6(c)), \
|
||||
(mOp | mX3 | mX6)
|
||||
#define OpX3X6Y(a,b,c,d) (bOp (a) | bX3 (b) | bX6(c) | bY(d)), \
|
||||
(mOp | mX3 | mX6 | mY)
|
||||
#define OpVc(a,b) (bOp (a) | bVc (b)), (mOp | mVc)
|
||||
#define OpPaWhaD(a,b,c,d) \
|
||||
(bOp (a) | bPa (b) | bWha (c) | bD (d)), (mOp | mPa | mWha | mD)
|
||||
#define OpBtypePaWhaD(a,b,c,d,e) \
|
||||
(bOp (a) | bBtype (b) | bPa (c) | bWha (d) | bD (e)), \
|
||||
(mOp | mBtype | mPa | mWha | mD)
|
||||
#define OpBtypePaWhaDPr(a,b,c,d,e,f) \
|
||||
(bOp (a) | bBtype (b) | bPa (c) | bWha (d) | bD (e) | bPr (f)), \
|
||||
(mOp | mBtype | mPa | mWha | mD | mPr)
|
||||
|
||||
struct ia64_opcode ia64_opcodes_x[] =
|
||||
{
|
||||
{"break.x", X0, OpX3X6 (0, 0, 0x00), {IMMU62}, 0, 0, NULL},
|
||||
{"nop.x", X0, OpX3X6Y (0, 0, 0x01, 0), {IMMU62}, 0, 0, NULL},
|
||||
{"hint.x", X0, OpX3X6Y (0, 0, 0x01, 1), {IMMU62}, 0, 0, NULL},
|
||||
{"movl", X, OpVc (6, 0), {R1, IMMU64}, 0, 0, NULL},
|
||||
#define BRL(a,b) \
|
||||
X0, OpBtypePaWhaDPr (0xC, 0, a, 0, b, 0), {TGT64}, PSEUDO, 0, NULL
|
||||
{"brl.few", BRL (0, 0)},
|
||||
{"brl", BRL (0, 0)},
|
||||
{"brl.few.clr", BRL (0, 1)},
|
||||
{"brl.clr", BRL (0, 1)},
|
||||
{"brl.many", BRL (1, 0)},
|
||||
{"brl.many.clr", BRL (1, 1)},
|
||||
#undef BRL
|
||||
#define BRL(a,b,c) \
|
||||
X0, OpBtypePaWhaD (0xC, 0, a, b, c), {TGT64}, 0, 0, NULL
|
||||
#define BRLP(a,b,c) \
|
||||
X0, OpBtypePaWhaD (0xC, 0, a, b, c), {TGT64}, PSEUDO, 0, NULL
|
||||
{"brl.cond.sptk.few", BRL (0, 0, 0)},
|
||||
{"brl.cond.sptk", BRLP (0, 0, 0)},
|
||||
{"brl.cond.sptk.few.clr", BRL (0, 0, 1)},
|
||||
{"brl.cond.sptk.clr", BRLP (0, 0, 1)},
|
||||
{"brl.cond.spnt.few", BRL (0, 1, 0)},
|
||||
{"brl.cond.spnt", BRLP (0, 1, 0)},
|
||||
{"brl.cond.spnt.few.clr", BRL (0, 1, 1)},
|
||||
{"brl.cond.spnt.clr", BRLP (0, 1, 1)},
|
||||
{"brl.cond.dptk.few", BRL (0, 2, 0)},
|
||||
{"brl.cond.dptk", BRLP (0, 2, 0)},
|
||||
{"brl.cond.dptk.few.clr", BRL (0, 2, 1)},
|
||||
{"brl.cond.dptk.clr", BRLP (0, 2, 1)},
|
||||
{"brl.cond.dpnt.few", BRL (0, 3, 0)},
|
||||
{"brl.cond.dpnt", BRLP (0, 3, 0)},
|
||||
{"brl.cond.dpnt.few.clr", BRL (0, 3, 1)},
|
||||
{"brl.cond.dpnt.clr", BRLP (0, 3, 1)},
|
||||
{"brl.cond.sptk.many", BRL (1, 0, 0)},
|
||||
{"brl.cond.sptk.many.clr", BRL (1, 0, 1)},
|
||||
{"brl.cond.spnt.many", BRL (1, 1, 0)},
|
||||
{"brl.cond.spnt.many.clr", BRL (1, 1, 1)},
|
||||
{"brl.cond.dptk.many", BRL (1, 2, 0)},
|
||||
{"brl.cond.dptk.many.clr", BRL (1, 2, 1)},
|
||||
{"brl.cond.dpnt.many", BRL (1, 3, 0)},
|
||||
{"brl.cond.dpnt.many.clr", BRL (1, 3, 1)},
|
||||
{"brl.sptk.few", BRL (0, 0, 0)},
|
||||
{"brl.sptk", BRLP (0, 0, 0)},
|
||||
{"brl.sptk.few.clr", BRL (0, 0, 1)},
|
||||
{"brl.sptk.clr", BRLP (0, 0, 1)},
|
||||
{"brl.spnt.few", BRL (0, 1, 0)},
|
||||
{"brl.spnt", BRLP (0, 1, 0)},
|
||||
{"brl.spnt.few.clr", BRL (0, 1, 1)},
|
||||
{"brl.spnt.clr", BRLP (0, 1, 1)},
|
||||
{"brl.dptk.few", BRL (0, 2, 0)},
|
||||
{"brl.dptk", BRLP (0, 2, 0)},
|
||||
{"brl.dptk.few.clr", BRL (0, 2, 1)},
|
||||
{"brl.dptk.clr", BRLP (0, 2, 1)},
|
||||
{"brl.dpnt.few", BRL (0, 3, 0)},
|
||||
{"brl.dpnt", BRLP (0, 3, 0)},
|
||||
{"brl.dpnt.few.clr", BRL (0, 3, 1)},
|
||||
{"brl.dpnt.clr", BRLP (0, 3, 1)},
|
||||
{"brl.sptk.many", BRL (1, 0, 0)},
|
||||
{"brl.sptk.many.clr", BRL (1, 0, 1)},
|
||||
{"brl.spnt.many", BRL (1, 1, 0)},
|
||||
{"brl.spnt.many.clr", BRL (1, 1, 1)},
|
||||
{"brl.dptk.many", BRL (1, 2, 0)},
|
||||
{"brl.dptk.many.clr", BRL (1, 2, 1)},
|
||||
{"brl.dpnt.many", BRL (1, 3, 0)},
|
||||
{"brl.dpnt.many.clr", BRL (1, 3, 1)},
|
||||
#undef BRL
|
||||
#undef BRLP
|
||||
#define BRL(a,b,c) X, OpPaWhaD (0xD, a, b, c), {B1, TGT64}, 0, 0, NULL
|
||||
#define BRLP(a,b,c) X, OpPaWhaD (0xD, a, b, c), {B1, TGT64}, PSEUDO, 0, NULL
|
||||
{"brl.call.sptk.few", BRL (0, 0, 0)},
|
||||
{"brl.call.sptk", BRLP (0, 0, 0)},
|
||||
{"brl.call.sptk.few.clr", BRL (0, 0, 1)},
|
||||
{"brl.call.sptk.clr", BRLP (0, 0, 1)},
|
||||
{"brl.call.spnt.few", BRL (0, 1, 0)},
|
||||
{"brl.call.spnt", BRLP (0, 1, 0)},
|
||||
{"brl.call.spnt.few.clr", BRL (0, 1, 1)},
|
||||
{"brl.call.spnt.clr", BRLP (0, 1, 1)},
|
||||
{"brl.call.dptk.few", BRL (0, 2, 0)},
|
||||
{"brl.call.dptk", BRLP (0, 2, 0)},
|
||||
{"brl.call.dptk.few.clr", BRL (0, 2, 1)},
|
||||
{"brl.call.dptk.clr", BRLP (0, 2, 1)},
|
||||
{"brl.call.dpnt.few", BRL (0, 3, 0)},
|
||||
{"brl.call.dpnt", BRLP (0, 3, 0)},
|
||||
{"brl.call.dpnt.few.clr", BRL (0, 3, 1)},
|
||||
{"brl.call.dpnt.clr", BRLP (0, 3, 1)},
|
||||
{"brl.call.sptk.many", BRL (1, 0, 0)},
|
||||
{"brl.call.sptk.many.clr", BRL (1, 0, 1)},
|
||||
{"brl.call.spnt.many", BRL (1, 1, 0)},
|
||||
{"brl.call.spnt.many.clr", BRL (1, 1, 1)},
|
||||
{"brl.call.dptk.many", BRL (1, 2, 0)},
|
||||
{"brl.call.dptk.many.clr", BRL (1, 2, 1)},
|
||||
{"brl.call.dpnt.many", BRL (1, 3, 0)},
|
||||
{"brl.call.dpnt.many.clr", BRL (1, 3, 1)},
|
||||
#undef BRL
|
||||
#undef BRLP
|
||||
{NULL, 0, 0, 0, 0, {0}, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#undef X0
|
||||
#undef X
|
||||
|
||||
#undef bBtype
|
||||
#undef bD
|
||||
#undef bPa
|
||||
#undef bPr
|
||||
#undef bVc
|
||||
#undef bWha
|
||||
#undef bX3
|
||||
#undef bX6
|
||||
|
||||
#undef mBtype
|
||||
#undef mD
|
||||
#undef mPa
|
||||
#undef mPr
|
||||
#undef mVc
|
||||
#undef mWha
|
||||
#undef mX3
|
||||
#undef mX6
|
||||
|
||||
#undef OpX3X6
|
||||
#undef OpVc
|
||||
#undef OpPaWhaD
|
||||
#undef OpBtypePaWhaD
|
||||
#undef OpBtypePaWhaDPr
|
||||
@@ -1,727 +0,0 @@
|
||||
/* ia64-opc.c -- Functions to access the compacted opcode table
|
||||
Copyright 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "ia64-asmtab.h"
|
||||
#include "ia64-asmtab.c"
|
||||
|
||||
static void get_opc_prefix (const char **, char *);
|
||||
static short int find_string_ent (const char *);
|
||||
static short int find_main_ent (short int);
|
||||
static short int find_completer (short int, short int, const char *);
|
||||
static ia64_insn apply_completer (ia64_insn, int);
|
||||
static int extract_op_bits (int, int, int);
|
||||
static int extract_op (int, int *, unsigned int *);
|
||||
static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
|
||||
static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
|
||||
static struct ia64_opcode *make_ia64_opcode
|
||||
(ia64_insn, const char *, int, int);
|
||||
static struct ia64_opcode *ia64_find_matching_opcode
|
||||
(const char *, short int);
|
||||
|
||||
const struct ia64_templ_desc ia64_templ_desc[16] =
|
||||
{
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, /* 0 */
|
||||
{ 2, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_L, IA64_UNIT_X }, "MLX" },
|
||||
{ 0, { 0, }, "-3-" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" }, /* 4 */
|
||||
{ 1, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_I }, "MFI" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_F }, "MMF" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_B }, "MIB" }, /* 8 */
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_B, IA64_UNIT_B }, "MBB" },
|
||||
{ 0, { 0, }, "-a-" },
|
||||
{ 0, { IA64_UNIT_B, IA64_UNIT_B, IA64_UNIT_B }, "BBB" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_B }, "MMB" }, /* c */
|
||||
{ 0, { 0, }, "-d-" },
|
||||
{ 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" },
|
||||
{ 0, { 0, }, "-f-" },
|
||||
};
|
||||
|
||||
|
||||
/* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST.
|
||||
PTR will be adjusted to point to the start of the next portion
|
||||
of the opcode, or at the NUL character. */
|
||||
|
||||
static void
|
||||
get_opc_prefix (const char **ptr, char *dest)
|
||||
{
|
||||
char *c = strchr (*ptr, '.');
|
||||
if (c != NULL)
|
||||
{
|
||||
memcpy (dest, *ptr, c - *ptr);
|
||||
dest[c - *ptr] = '\0';
|
||||
*ptr = c + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int l = strlen (*ptr);
|
||||
memcpy (dest, *ptr, l);
|
||||
dest[l] = '\0';
|
||||
*ptr += l;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the index of the entry in the string table corresponding to
|
||||
STR; return -1 if one does not exist. */
|
||||
|
||||
static short
|
||||
find_string_ent (const char *str)
|
||||
{
|
||||
short start = 0;
|
||||
short end = sizeof (ia64_strings) / sizeof (const char *);
|
||||
short i = (start + end) / 2;
|
||||
|
||||
if (strcmp (str, ia64_strings[end - 1]) > 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
while (start <= end)
|
||||
{
|
||||
int c = strcmp (str, ia64_strings[i]);
|
||||
if (c < 0)
|
||||
{
|
||||
end = i - 1;
|
||||
}
|
||||
else if (c == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = i + 1;
|
||||
}
|
||||
i = (start + end) / 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the opcode in the main opcode table whose name is STRINGINDEX, or
|
||||
return -1 if one does not exist. */
|
||||
|
||||
static short
|
||||
find_main_ent (short nameindex)
|
||||
{
|
||||
short start = 0;
|
||||
short end = sizeof (main_table) / sizeof (struct ia64_main_table);
|
||||
short i = (start + end) / 2;
|
||||
|
||||
if (nameindex < main_table[0].name_index
|
||||
|| nameindex > main_table[end - 1].name_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
while (start <= end)
|
||||
{
|
||||
if (nameindex < main_table[i].name_index)
|
||||
{
|
||||
end = i - 1;
|
||||
}
|
||||
else if (nameindex == main_table[i].name_index)
|
||||
{
|
||||
while (i > 0 && main_table[i - 1].name_index == nameindex)
|
||||
{
|
||||
i--;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = i + 1;
|
||||
}
|
||||
i = (start + end) / 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the index of the entry in the completer table that is part of
|
||||
MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
|
||||
return -1 if one does not exist. */
|
||||
|
||||
static short
|
||||
find_completer (short main_ent, short prev_completer, const char *name)
|
||||
{
|
||||
short name_index = find_string_ent (name);
|
||||
|
||||
if (name_index < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (prev_completer == -1)
|
||||
{
|
||||
prev_completer = main_table[main_ent].completers;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_completer = completer_table[prev_completer].subentries;
|
||||
}
|
||||
|
||||
while (prev_completer != -1)
|
||||
{
|
||||
if (completer_table[prev_completer].name_index == name_index)
|
||||
{
|
||||
return prev_completer;
|
||||
}
|
||||
prev_completer = completer_table[prev_completer].alternative;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
|
||||
return the result. */
|
||||
|
||||
static ia64_insn
|
||||
apply_completer (ia64_insn opcode, int completer_index)
|
||||
{
|
||||
ia64_insn mask = completer_table[completer_index].mask;
|
||||
ia64_insn bits = completer_table[completer_index].bits;
|
||||
int shiftamt = (completer_table[completer_index].offset & 63);
|
||||
|
||||
mask = mask << shiftamt;
|
||||
bits = bits << shiftamt;
|
||||
opcode = (opcode & ~mask) | bits;
|
||||
return opcode;
|
||||
}
|
||||
|
||||
/* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
|
||||
the dis_table array, and return its value. (BITOFFSET is numbered
|
||||
starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
|
||||
first byte in OP_POINTER.) */
|
||||
|
||||
static int
|
||||
extract_op_bits (int op_pointer, int bitoffset, int bits)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
op_pointer += (bitoffset / 8);
|
||||
|
||||
if (bitoffset % 8)
|
||||
{
|
||||
unsigned int op = dis_table[op_pointer++];
|
||||
int numb = 8 - (bitoffset % 8);
|
||||
int mask = (1 << numb) - 1;
|
||||
int bata = (bits < numb) ? bits : numb;
|
||||
int delta = numb - bata;
|
||||
|
||||
res = (res << bata) | ((op & mask) >> delta);
|
||||
bitoffset += bata;
|
||||
bits -= bata;
|
||||
}
|
||||
while (bits >= 8)
|
||||
{
|
||||
res = (res << 8) | (dis_table[op_pointer++] & 255);
|
||||
bits -= 8;
|
||||
}
|
||||
if (bits > 0)
|
||||
{
|
||||
unsigned int op = (dis_table[op_pointer++] & 255);
|
||||
res = (res << bits) | (op >> (8 - bits));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Examine the state machine entry at OP_POINTER in the dis_table
|
||||
array, and extract its values into OPVAL and OP. The length of the
|
||||
state entry in bits is returned. */
|
||||
|
||||
static int
|
||||
extract_op (int op_pointer, int *opval, unsigned int *op)
|
||||
{
|
||||
int oplen = 5;
|
||||
|
||||
*op = dis_table[op_pointer];
|
||||
|
||||
if ((*op) & 0x40)
|
||||
{
|
||||
opval[0] = extract_op_bits (op_pointer, oplen, 5);
|
||||
oplen += 5;
|
||||
}
|
||||
switch ((*op) & 0x30)
|
||||
{
|
||||
case 0x10:
|
||||
{
|
||||
opval[1] = extract_op_bits (op_pointer, oplen, 8);
|
||||
oplen += 8;
|
||||
opval[1] += op_pointer;
|
||||
break;
|
||||
}
|
||||
case 0x20:
|
||||
{
|
||||
opval[1] = extract_op_bits (op_pointer, oplen, 16);
|
||||
if (! (opval[1] & 32768))
|
||||
{
|
||||
opval[1] += op_pointer;
|
||||
}
|
||||
oplen += 16;
|
||||
break;
|
||||
}
|
||||
case 0x30:
|
||||
{
|
||||
oplen--;
|
||||
opval[2] = extract_op_bits (op_pointer, oplen, 12);
|
||||
oplen += 12;
|
||||
opval[2] |= 32768;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
|
||||
{
|
||||
opval[2] = extract_op_bits (op_pointer, oplen, 16);
|
||||
oplen += 16;
|
||||
if (! (opval[2] & 32768))
|
||||
{
|
||||
opval[2] += op_pointer;
|
||||
}
|
||||
}
|
||||
return oplen;
|
||||
}
|
||||
|
||||
/* Returns a non-zero value if the opcode in the main_table list at
|
||||
PLACE matches OPCODE and is of type TYPE. */
|
||||
|
||||
static int
|
||||
opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
|
||||
{
|
||||
if (main_table[place].opcode_type != type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (main_table[place].flags
|
||||
& (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
|
||||
{
|
||||
const struct ia64_operand *o1, *o2;
|
||||
ia64_insn f2, f3;
|
||||
|
||||
if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
|
||||
{
|
||||
o1 = elf64_ia64_operands + IA64_OPND_F2;
|
||||
o2 = elf64_ia64_operands + IA64_OPND_F3;
|
||||
(*o1->extract) (o1, opcode, &f2);
|
||||
(*o2->extract) (o2, opcode, &f3);
|
||||
if (f2 != f3)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ia64_insn len, count;
|
||||
|
||||
/* length must equal 64-count: */
|
||||
o1 = elf64_ia64_operands + IA64_OPND_LEN6;
|
||||
o2 = elf64_ia64_operands + main_table[place].operands[2];
|
||||
(*o1->extract) (o1, opcode, &len);
|
||||
(*o2->extract) (o2, opcode, &count);
|
||||
if (len != 64 - count)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find an instruction entry in the ia64_dis_names array that matches
|
||||
opcode OPCODE and is of type TYPE. Returns either a positive index
|
||||
into the array, or a negative value if an entry for OPCODE could
|
||||
not be found. Checks all matches and returns the one with the highest
|
||||
priority. */
|
||||
|
||||
static int
|
||||
locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
|
||||
{
|
||||
int currtest[41];
|
||||
int bitpos[41];
|
||||
int op_ptr[41];
|
||||
int currstatenum = 0;
|
||||
short found_disent = -1;
|
||||
short found_priority = -1;
|
||||
|
||||
currtest[currstatenum] = 0;
|
||||
op_ptr[currstatenum] = 0;
|
||||
bitpos[currstatenum] = 40;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int op_pointer = op_ptr[currstatenum];
|
||||
unsigned int op;
|
||||
int currbitnum = bitpos[currstatenum];
|
||||
int oplen;
|
||||
int opval[3] = {0};
|
||||
int next_op;
|
||||
int currbit;
|
||||
|
||||
oplen = extract_op (op_pointer, opval, &op);
|
||||
|
||||
bitpos[currstatenum] = currbitnum;
|
||||
|
||||
/* Skip opval[0] bits in the instruction. */
|
||||
if (op & 0x40)
|
||||
{
|
||||
currbitnum -= opval[0];
|
||||
}
|
||||
|
||||
/* The value of the current bit being tested. */
|
||||
currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
|
||||
next_op = -1;
|
||||
|
||||
/* We always perform the tests specified in the current state in
|
||||
a particular order, falling through to the next test if the
|
||||
previous one failed. */
|
||||
switch (currtest[currstatenum])
|
||||
{
|
||||
case 0:
|
||||
currtest[currstatenum]++;
|
||||
if (currbit == 0 && (op & 0x80))
|
||||
{
|
||||
/* Check for a zero bit. If this test solely checks for
|
||||
a zero bit, we can check for up to 8 consecutive zero
|
||||
bits (the number to check is specified by the lower 3
|
||||
bits in the state code.)
|
||||
|
||||
If the state instruction matches, we go to the very
|
||||
next state instruction; otherwise, try the next test. */
|
||||
|
||||
if ((op & 0xf8) == 0x80)
|
||||
{
|
||||
int count = op & 0x7;
|
||||
int x;
|
||||
|
||||
for (x = 0; x <= count; x++)
|
||||
{
|
||||
int i =
|
||||
opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
|
||||
if (i)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x > count)
|
||||
{
|
||||
next_op = op_pointer + ((oplen + 7) / 8);
|
||||
currbitnum -= count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (! currbit)
|
||||
{
|
||||
next_op = op_pointer + ((oplen + 7) / 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
/* If the bit in the instruction is one, go to the state
|
||||
instruction specified by opval[1]. */
|
||||
currtest[currstatenum]++;
|
||||
if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
|
||||
{
|
||||
next_op = opval[1];
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
/* Don't care. Skip the current bit and go to the state
|
||||
instruction specified by opval[2].
|
||||
|
||||
An encoding of 0x30 is special; this means that a 12-bit
|
||||
offset into the ia64_dis_names[] array is specified. */
|
||||
currtest[currstatenum]++;
|
||||
if ((op & 0x08) || ((op & 0x30) == 0x30))
|
||||
{
|
||||
next_op = opval[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If bit 15 is set in the address of the next state, an offset
|
||||
in the ia64_dis_names array was specified instead. We then
|
||||
check to see if an entry in the list of opcodes matches the
|
||||
opcode we were given; if so, we have succeeded. */
|
||||
|
||||
if ((next_op >= 0) && (next_op & 32768))
|
||||
{
|
||||
short disent = next_op & 32767;
|
||||
short priority = -1;
|
||||
|
||||
if (next_op > 65535)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Run through the list of opcodes to check, trying to find
|
||||
one that matches. */
|
||||
while (disent >= 0)
|
||||
{
|
||||
int place = ia64_dis_names[disent].insn_index;
|
||||
|
||||
priority = ia64_dis_names[disent].priority;
|
||||
|
||||
if (opcode_verify (opcode, place, type)
|
||||
&& priority > found_priority)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ia64_dis_names[disent].next_flag)
|
||||
{
|
||||
disent++;
|
||||
}
|
||||
else
|
||||
{
|
||||
disent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (disent >= 0)
|
||||
{
|
||||
found_disent = disent;
|
||||
found_priority = priority;
|
||||
}
|
||||
/* Try the next test in this state, regardless of whether a match
|
||||
was found. */
|
||||
next_op = -2;
|
||||
}
|
||||
|
||||
/* next_op == -1 is "back up to the previous state".
|
||||
next_op == -2 is "stay in this state and try the next test".
|
||||
Otherwise, transition to the state indicated by next_op. */
|
||||
|
||||
if (next_op == -1)
|
||||
{
|
||||
currstatenum--;
|
||||
if (currstatenum < 0)
|
||||
{
|
||||
return found_disent;
|
||||
}
|
||||
}
|
||||
else if (next_op >= 0)
|
||||
{
|
||||
currstatenum++;
|
||||
bitpos[currstatenum] = currbitnum - 1;
|
||||
op_ptr[currstatenum] = next_op;
|
||||
currtest[currstatenum] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
|
||||
|
||||
static struct ia64_opcode *
|
||||
make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
|
||||
{
|
||||
struct ia64_opcode *res =
|
||||
(struct ia64_opcode *) malloc (sizeof (struct ia64_opcode));
|
||||
res->name = strdup (name);
|
||||
res->type = main_table[place].opcode_type;
|
||||
res->num_outputs = main_table[place].num_outputs;
|
||||
res->opcode = opcode;
|
||||
res->mask = main_table[place].mask;
|
||||
res->operands[0] = main_table[place].operands[0];
|
||||
res->operands[1] = main_table[place].operands[1];
|
||||
res->operands[2] = main_table[place].operands[2];
|
||||
res->operands[3] = main_table[place].operands[3];
|
||||
res->operands[4] = main_table[place].operands[4];
|
||||
res->flags = main_table[place].flags;
|
||||
res->ent_index = place;
|
||||
res->dependencies = &op_dependencies[depind];
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Determine the ia64_opcode entry for the opcode specified by INSN
|
||||
and TYPE. If a valid entry is not found, return NULL. */
|
||||
struct ia64_opcode *
|
||||
ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
|
||||
{
|
||||
int disent = locate_opcode_ent (insn, type);
|
||||
|
||||
if (disent < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int cb = ia64_dis_names[disent].completer_index;
|
||||
static char name[128];
|
||||
int place = ia64_dis_names[disent].insn_index;
|
||||
int ci = main_table[place].completers;
|
||||
ia64_insn tinsn = main_table[place].opcode;
|
||||
|
||||
strcpy (name, ia64_strings [main_table[place].name_index]);
|
||||
|
||||
while (cb)
|
||||
{
|
||||
if (cb & 1)
|
||||
{
|
||||
int cname = completer_table[ci].name_index;
|
||||
|
||||
tinsn = apply_completer (tinsn, ci);
|
||||
|
||||
if (ia64_strings[cname][0] != '\0')
|
||||
{
|
||||
strcat (name, ".");
|
||||
strcat (name, ia64_strings[cname]);
|
||||
}
|
||||
if (cb != 1)
|
||||
{
|
||||
ci = completer_table[ci].subentries;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ci = completer_table[ci].alternative;
|
||||
}
|
||||
if (ci < 0)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
cb = cb >> 1;
|
||||
}
|
||||
if (tinsn != (insn & main_table[place].mask))
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
return make_ia64_opcode (insn, name, place,
|
||||
completer_table[ci].dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the main_opcode table starting from PLACE for an opcode that
|
||||
matches NAME. Return NULL if one is not found. */
|
||||
|
||||
static struct ia64_opcode *
|
||||
ia64_find_matching_opcode (const char *name, short place)
|
||||
{
|
||||
char op[129];
|
||||
const char *suffix;
|
||||
short name_index;
|
||||
|
||||
if (strlen (name) > 128)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
suffix = name;
|
||||
get_opc_prefix (&suffix, op);
|
||||
name_index = find_string_ent (op);
|
||||
if (name_index < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (main_table[place].name_index == name_index)
|
||||
{
|
||||
const char *curr_suffix = suffix;
|
||||
ia64_insn curr_insn = main_table[place].opcode;
|
||||
short completer = -1;
|
||||
|
||||
do {
|
||||
if (suffix[0] == '\0')
|
||||
{
|
||||
completer = find_completer (place, completer, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_opc_prefix (&curr_suffix, op);
|
||||
completer = find_completer (place, completer, op);
|
||||
}
|
||||
if (completer != -1)
|
||||
{
|
||||
curr_insn = apply_completer (curr_insn, completer);
|
||||
}
|
||||
} while (completer != -1 && curr_suffix[0] != '\0');
|
||||
|
||||
if (completer != -1 && curr_suffix[0] == '\0'
|
||||
&& completer_table[completer].terminal_completer)
|
||||
{
|
||||
int depind = completer_table[completer].dependencies;
|
||||
return make_ia64_opcode (curr_insn, name, place, depind);
|
||||
}
|
||||
else
|
||||
{
|
||||
place++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
|
||||
if one does not exist.
|
||||
|
||||
It is the caller's responsibility to invoke ia64_free_opcode () to
|
||||
release any resources used by the returned entry. */
|
||||
|
||||
struct ia64_opcode *
|
||||
ia64_find_next_opcode (struct ia64_opcode *prev_ent)
|
||||
{
|
||||
return ia64_find_matching_opcode (prev_ent->name,
|
||||
prev_ent->ent_index + 1);
|
||||
}
|
||||
|
||||
/* Find the first opcode that matches NAME, or return NULL if it does
|
||||
not exist.
|
||||
|
||||
It is the caller's responsibility to invoke ia64_free_opcode () to
|
||||
release any resources used by the returned entry. */
|
||||
|
||||
struct ia64_opcode *
|
||||
ia64_find_opcode (const char *name)
|
||||
{
|
||||
char op[129];
|
||||
const char *suffix;
|
||||
short place;
|
||||
short name_index;
|
||||
|
||||
if (strlen (name) > 128)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
suffix = name;
|
||||
get_opc_prefix (&suffix, op);
|
||||
name_index = find_string_ent (op);
|
||||
if (name_index < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
place = find_main_ent (name_index);
|
||||
|
||||
if (place < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ia64_find_matching_opcode (name, place);
|
||||
}
|
||||
|
||||
/* Free any resources used by ENT. */
|
||||
void
|
||||
ia64_free_opcode (struct ia64_opcode *ent)
|
||||
{
|
||||
free ((void *)ent->name);
|
||||
free (ent);
|
||||
}
|
||||
|
||||
const struct ia64_dependency *
|
||||
ia64_find_dependency (int index)
|
||||
{
|
||||
index = DEP(index);
|
||||
|
||||
if (index < 0
|
||||
|| index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
|
||||
return NULL;
|
||||
|
||||
return &dependencies[index];
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/* ia64-opc.h -- IA-64 opcode table.
|
||||
Copyright 1998, 1999, 2000, 2002, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef IA64_OPC_H
|
||||
#define IA64_OPC_H
|
||||
|
||||
#include "ia64.h"
|
||||
|
||||
/* define a couple of abbreviations: */
|
||||
|
||||
#define bOp(x) (((ia64_insn) ((x) & 0xf)) << 37)
|
||||
#define mOp bOp (-1)
|
||||
#define Op(x) bOp (x), mOp
|
||||
|
||||
#define FIRST IA64_OPCODE_FIRST
|
||||
#define X_IN_MLX IA64_OPCODE_X_IN_MLX
|
||||
#define LAST IA64_OPCODE_LAST
|
||||
#define PRIV IA64_OPCODE_PRIV
|
||||
#define NO_PRED IA64_OPCODE_NO_PRED
|
||||
#define SLOT2 IA64_OPCODE_SLOT2
|
||||
#define PSEUDO IA64_OPCODE_PSEUDO
|
||||
#define F2_EQ_F3 IA64_OPCODE_F2_EQ_F3
|
||||
#define LEN_EQ_64MCNT IA64_OPCODE_LEN_EQ_64MCNT
|
||||
#define MOD_RRBS IA64_OPCODE_MOD_RRBS
|
||||
#define POSTINC IA64_OPCODE_POSTINC
|
||||
|
||||
#define AR_CCV IA64_OPND_AR_CCV
|
||||
#define AR_PFS IA64_OPND_AR_PFS
|
||||
#define AR_CSD IA64_OPND_AR_CSD
|
||||
#define C1 IA64_OPND_C1
|
||||
#define C8 IA64_OPND_C8
|
||||
#define C16 IA64_OPND_C16
|
||||
#define GR0 IA64_OPND_GR0
|
||||
#define IP IA64_OPND_IP
|
||||
#define PR IA64_OPND_PR
|
||||
#define PR_ROT IA64_OPND_PR_ROT
|
||||
#define PSR IA64_OPND_PSR
|
||||
#define PSR_L IA64_OPND_PSR_L
|
||||
#define PSR_UM IA64_OPND_PSR_UM
|
||||
|
||||
#define AR3 IA64_OPND_AR3
|
||||
#define B1 IA64_OPND_B1
|
||||
#define B2 IA64_OPND_B2
|
||||
#define CR3 IA64_OPND_CR3
|
||||
#define F1 IA64_OPND_F1
|
||||
#define F2 IA64_OPND_F2
|
||||
#define F3 IA64_OPND_F3
|
||||
#define F4 IA64_OPND_F4
|
||||
#define P1 IA64_OPND_P1
|
||||
#define P2 IA64_OPND_P2
|
||||
#define R1 IA64_OPND_R1
|
||||
#define R2 IA64_OPND_R2
|
||||
#define R3 IA64_OPND_R3
|
||||
#define R3_2 IA64_OPND_R3_2
|
||||
|
||||
#define CPUID_R3 IA64_OPND_CPUID_R3
|
||||
#define DBR_R3 IA64_OPND_DBR_R3
|
||||
#define DTR_R3 IA64_OPND_DTR_R3
|
||||
#define ITR_R3 IA64_OPND_ITR_R3
|
||||
#define IBR_R3 IA64_OPND_IBR_R3
|
||||
#define MR3 IA64_OPND_MR3
|
||||
#define MSR_R3 IA64_OPND_MSR_R3
|
||||
#define PKR_R3 IA64_OPND_PKR_R3
|
||||
#define PMC_R3 IA64_OPND_PMC_R3
|
||||
#define PMD_R3 IA64_OPND_PMD_R3
|
||||
#define RR_R3 IA64_OPND_RR_R3
|
||||
|
||||
#define CCNT5 IA64_OPND_CCNT5
|
||||
#define CNT2a IA64_OPND_CNT2a
|
||||
#define CNT2b IA64_OPND_CNT2b
|
||||
#define CNT2c IA64_OPND_CNT2c
|
||||
#define CNT5 IA64_OPND_CNT5
|
||||
#define CNT6 IA64_OPND_CNT6
|
||||
#define CPOS6a IA64_OPND_CPOS6a
|
||||
#define CPOS6b IA64_OPND_CPOS6b
|
||||
#define CPOS6c IA64_OPND_CPOS6c
|
||||
#define IMM1 IA64_OPND_IMM1
|
||||
#define IMM14 IA64_OPND_IMM14
|
||||
#define IMM17 IA64_OPND_IMM17
|
||||
#define IMM22 IA64_OPND_IMM22
|
||||
#define IMM44 IA64_OPND_IMM44
|
||||
#define SOF IA64_OPND_SOF
|
||||
#define SOL IA64_OPND_SOL
|
||||
#define SOR IA64_OPND_SOR
|
||||
#define IMM8 IA64_OPND_IMM8
|
||||
#define IMM8U4 IA64_OPND_IMM8U4
|
||||
#define IMM8M1 IA64_OPND_IMM8M1
|
||||
#define IMM8M1U4 IA64_OPND_IMM8M1U4
|
||||
#define IMM8M1U8 IA64_OPND_IMM8M1U8
|
||||
#define IMM9a IA64_OPND_IMM9a
|
||||
#define IMM9b IA64_OPND_IMM9b
|
||||
#define IMMU2 IA64_OPND_IMMU2
|
||||
#define IMMU21 IA64_OPND_IMMU21
|
||||
#define IMMU24 IA64_OPND_IMMU24
|
||||
#define IMMU62 IA64_OPND_IMMU62
|
||||
#define IMMU64 IA64_OPND_IMMU64
|
||||
#define IMMU5b IA64_OPND_IMMU5b
|
||||
#define IMMU7a IA64_OPND_IMMU7a
|
||||
#define IMMU7b IA64_OPND_IMMU7b
|
||||
#define IMMU9 IA64_OPND_IMMU9
|
||||
#define INC3 IA64_OPND_INC3
|
||||
#define LEN4 IA64_OPND_LEN4
|
||||
#define LEN6 IA64_OPND_LEN6
|
||||
#define MBTYPE4 IA64_OPND_MBTYPE4
|
||||
#define MHTYPE8 IA64_OPND_MHTYPE8
|
||||
#define POS6 IA64_OPND_POS6
|
||||
#define TAG13 IA64_OPND_TAG13
|
||||
#define TAG13b IA64_OPND_TAG13b
|
||||
#define TGT25 IA64_OPND_TGT25
|
||||
#define TGT25b IA64_OPND_TGT25b
|
||||
#define TGT25c IA64_OPND_TGT25c
|
||||
#define TGT64 IA64_OPND_TGT64
|
||||
|
||||
#endif
|
||||
@@ -1,396 +0,0 @@
|
||||
/* ia64.h -- Header file for ia64 opcode table
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> */
|
||||
|
||||
#ifndef opcode_ia64_h
|
||||
#define opcode_ia64_h
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dis-asm.h"
|
||||
|
||||
|
||||
typedef BFD_HOST_U_64_BIT ia64_insn;
|
||||
|
||||
enum ia64_insn_type
|
||||
{
|
||||
IA64_TYPE_NIL = 0, /* illegal type */
|
||||
IA64_TYPE_A, /* integer alu (I- or M-unit) */
|
||||
IA64_TYPE_I, /* non-alu integer (I-unit) */
|
||||
IA64_TYPE_M, /* memory (M-unit) */
|
||||
IA64_TYPE_B, /* branch (B-unit) */
|
||||
IA64_TYPE_F, /* floating-point (F-unit) */
|
||||
IA64_TYPE_X, /* long encoding (X-unit) */
|
||||
IA64_TYPE_DYN, /* Dynamic opcode */
|
||||
IA64_NUM_TYPES
|
||||
};
|
||||
|
||||
enum ia64_unit
|
||||
{
|
||||
IA64_UNIT_NIL = 0, /* illegal unit */
|
||||
IA64_UNIT_I, /* integer unit */
|
||||
IA64_UNIT_M, /* memory unit */
|
||||
IA64_UNIT_B, /* branching unit */
|
||||
IA64_UNIT_F, /* floating-point unit */
|
||||
IA64_UNIT_L, /* long "unit" */
|
||||
IA64_UNIT_X, /* may be integer or branch unit */
|
||||
IA64_NUM_UNITS
|
||||
};
|
||||
|
||||
/* Changes to this enumeration must be propagated to the operand table in
|
||||
bfd/cpu-ia64-opc.c
|
||||
*/
|
||||
enum ia64_opnd
|
||||
{
|
||||
IA64_OPND_NIL, /* no operand---MUST BE FIRST!*/
|
||||
|
||||
/* constants */
|
||||
IA64_OPND_AR_CSD, /* application register csd (ar.csd) */
|
||||
IA64_OPND_AR_CCV, /* application register ccv (ar.ccv) */
|
||||
IA64_OPND_AR_PFS, /* application register pfs (ar.pfs) */
|
||||
IA64_OPND_C1, /* the constant 1 */
|
||||
IA64_OPND_C8, /* the constant 8 */
|
||||
IA64_OPND_C16, /* the constant 16 */
|
||||
IA64_OPND_GR0, /* gr0 */
|
||||
IA64_OPND_IP, /* instruction pointer (ip) */
|
||||
IA64_OPND_PR, /* predicate register (pr) */
|
||||
IA64_OPND_PR_ROT, /* rotating predicate register (pr.rot) */
|
||||
IA64_OPND_PSR, /* processor status register (psr) */
|
||||
IA64_OPND_PSR_L, /* processor status register L (psr.l) */
|
||||
IA64_OPND_PSR_UM, /* processor status register UM (psr.um) */
|
||||
|
||||
/* register operands: */
|
||||
IA64_OPND_AR3, /* third application register # (bits 20-26) */
|
||||
IA64_OPND_B1, /* branch register # (bits 6-8) */
|
||||
IA64_OPND_B2, /* branch register # (bits 13-15) */
|
||||
IA64_OPND_CR3, /* third control register # (bits 20-26) */
|
||||
IA64_OPND_F1, /* first floating-point register # */
|
||||
IA64_OPND_F2, /* second floating-point register # */
|
||||
IA64_OPND_F3, /* third floating-point register # */
|
||||
IA64_OPND_F4, /* fourth floating-point register # */
|
||||
IA64_OPND_P1, /* first predicate # */
|
||||
IA64_OPND_P2, /* second predicate # */
|
||||
IA64_OPND_R1, /* first register # */
|
||||
IA64_OPND_R2, /* second register # */
|
||||
IA64_OPND_R3, /* third register # */
|
||||
IA64_OPND_R3_2, /* third register # (limited to gr0-gr3) */
|
||||
|
||||
/* memory operands: */
|
||||
IA64_OPND_MR3, /* memory at addr of third register # */
|
||||
|
||||
/* indirect operands: */
|
||||
IA64_OPND_CPUID_R3, /* cpuid[reg] */
|
||||
IA64_OPND_DBR_R3, /* dbr[reg] */
|
||||
IA64_OPND_DTR_R3, /* dtr[reg] */
|
||||
IA64_OPND_ITR_R3, /* itr[reg] */
|
||||
IA64_OPND_IBR_R3, /* ibr[reg] */
|
||||
IA64_OPND_MSR_R3, /* msr[reg] */
|
||||
IA64_OPND_PKR_R3, /* pkr[reg] */
|
||||
IA64_OPND_PMC_R3, /* pmc[reg] */
|
||||
IA64_OPND_PMD_R3, /* pmd[reg] */
|
||||
IA64_OPND_RR_R3, /* rr[reg] */
|
||||
|
||||
/* immediate operands: */
|
||||
IA64_OPND_CCNT5, /* 5-bit count (31 - bits 20-24) */
|
||||
IA64_OPND_CNT2a, /* 2-bit count (1 + bits 27-28) */
|
||||
IA64_OPND_CNT2b, /* 2-bit count (bits 27-28): 1, 2, 3 */
|
||||
IA64_OPND_CNT2c, /* 2-bit count (bits 30-31): 0, 7, 15, or 16 */
|
||||
IA64_OPND_CNT5, /* 5-bit count (bits 14-18) */
|
||||
IA64_OPND_CNT6, /* 6-bit count (bits 27-32) */
|
||||
IA64_OPND_CPOS6a, /* 6-bit count (63 - bits 20-25) */
|
||||
IA64_OPND_CPOS6b, /* 6-bit count (63 - bits 14-19) */
|
||||
IA64_OPND_CPOS6c, /* 6-bit count (63 - bits 31-36) */
|
||||
IA64_OPND_IMM1, /* signed 1-bit immediate (bit 36) */
|
||||
IA64_OPND_IMMU2, /* unsigned 2-bit immediate (bits 13-14) */
|
||||
IA64_OPND_IMMU5b, /* unsigned 5-bit immediate (32 + bits 14-18) */
|
||||
IA64_OPND_IMMU7a, /* unsigned 7-bit immediate (bits 13-19) */
|
||||
IA64_OPND_IMMU7b, /* unsigned 7-bit immediate (bits 20-26) */
|
||||
IA64_OPND_SOF, /* 8-bit stack frame size */
|
||||
IA64_OPND_SOL, /* 8-bit size of locals */
|
||||
IA64_OPND_SOR, /* 6-bit number of rotating registers (scaled by 8) */
|
||||
IA64_OPND_IMM8, /* signed 8-bit immediate (bits 13-19 & 36) */
|
||||
IA64_OPND_IMM8U4, /* cmp4*u signed 8-bit immediate (bits 13-19 & 36) */
|
||||
IA64_OPND_IMM8M1, /* signed 8-bit immediate -1 (bits 13-19 & 36) */
|
||||
IA64_OPND_IMM8M1U4, /* cmp4*u signed 8-bit immediate -1 (bits 13-19 & 36)*/
|
||||
IA64_OPND_IMM8M1U8, /* cmp*u signed 8-bit immediate -1 (bits 13-19 & 36) */
|
||||
IA64_OPND_IMMU9, /* unsigned 9-bit immediate (bits 33-34, 20-26) */
|
||||
IA64_OPND_IMM9a, /* signed 9-bit immediate (bits 6-12, 27, 36) */
|
||||
IA64_OPND_IMM9b, /* signed 9-bit immediate (bits 13-19, 27, 36) */
|
||||
IA64_OPND_IMM14, /* signed 14-bit immediate (bits 13-19, 27-32, 36) */
|
||||
IA64_OPND_IMM17, /* signed 17-bit immediate (2*bits 6-12, 24-31, 36) */
|
||||
IA64_OPND_IMMU21, /* unsigned 21-bit immediate (bits 6-25, 36) */
|
||||
IA64_OPND_IMM22, /* signed 22-bit immediate (bits 13-19, 22-36) */
|
||||
IA64_OPND_IMMU24, /* unsigned 24-bit immediate (bits 6-26, 31-32, 36) */
|
||||
IA64_OPND_IMM44, /* signed 44-bit immediate (2^16*bits 6-32, 36) */
|
||||
IA64_OPND_IMMU62, /* unsigned 62-bit immediate */
|
||||
IA64_OPND_IMMU64, /* unsigned 64-bit immediate (lotsa bits...) */
|
||||
IA64_OPND_INC3, /* signed 3-bit (bits 13-15): +/-1, 4, 8, 16 */
|
||||
IA64_OPND_LEN4, /* 4-bit count (bits 27-30 + 1) */
|
||||
IA64_OPND_LEN6, /* 6-bit count (bits 27-32 + 1) */
|
||||
IA64_OPND_MBTYPE4, /* 4-bit mux type (bits 20-23) */
|
||||
IA64_OPND_MHTYPE8, /* 8-bit mux type (bits 20-27) */
|
||||
IA64_OPND_POS6, /* 6-bit count (bits 14-19) */
|
||||
IA64_OPND_TAG13, /* signed 13-bit tag (ip + 16*bits 6-12, 33-34) */
|
||||
IA64_OPND_TAG13b, /* signed 13-bit tag (ip + 16*bits 24-32) */
|
||||
IA64_OPND_TGT25, /* signed 25-bit (ip + 16*bits 6-25, 36) */
|
||||
IA64_OPND_TGT25b, /* signed 25-bit (ip + 16*bits 6-12, 20-32, 36) */
|
||||
IA64_OPND_TGT25c, /* signed 25-bit (ip + 16*bits 13-32, 36) */
|
||||
IA64_OPND_TGT64, /* 64-bit (ip + 16*bits 13-32, 36, 2-40(L)) */
|
||||
IA64_OPND_LDXMOV, /* any symbol, generates R_IA64_LDXMOV. */
|
||||
|
||||
IA64_OPND_COUNT /* # of operand types (MUST BE LAST!) */
|
||||
};
|
||||
|
||||
enum ia64_dependency_mode
|
||||
{
|
||||
IA64_DV_RAW,
|
||||
IA64_DV_WAW,
|
||||
IA64_DV_WAR,
|
||||
};
|
||||
|
||||
enum ia64_dependency_semantics
|
||||
{
|
||||
IA64_DVS_NONE,
|
||||
IA64_DVS_IMPLIED,
|
||||
IA64_DVS_IMPLIEDF,
|
||||
IA64_DVS_DATA,
|
||||
IA64_DVS_INSTR,
|
||||
IA64_DVS_SPECIFIC,
|
||||
IA64_DVS_STOP,
|
||||
IA64_DVS_OTHER,
|
||||
};
|
||||
|
||||
enum ia64_resource_specifier
|
||||
{
|
||||
IA64_RS_ANY,
|
||||
IA64_RS_AR_K,
|
||||
IA64_RS_AR_UNAT,
|
||||
IA64_RS_AR, /* 8-15, 20, 22-23, 31, 33-35, 37-39, 41-43, 45-47, 67-111 */
|
||||
IA64_RS_ARb, /* 48-63, 112-127 */
|
||||
IA64_RS_BR,
|
||||
IA64_RS_CFM,
|
||||
IA64_RS_CPUID,
|
||||
IA64_RS_CR_IRR,
|
||||
IA64_RS_CR_LRR,
|
||||
IA64_RS_CR, /* 3-7,10-15,18,26-63,75-79,82-127 */
|
||||
IA64_RS_DBR,
|
||||
IA64_RS_FR,
|
||||
IA64_RS_FRb,
|
||||
IA64_RS_GR0,
|
||||
IA64_RS_GR,
|
||||
IA64_RS_IBR,
|
||||
IA64_RS_INSERVICE, /* CR[EOI] or CR[IVR] */
|
||||
IA64_RS_MSR,
|
||||
IA64_RS_PKR,
|
||||
IA64_RS_PMC,
|
||||
IA64_RS_PMD,
|
||||
IA64_RS_PR, /* non-rotating, 1-15 */
|
||||
IA64_RS_PRr, /* rotating, 16-62 */
|
||||
IA64_RS_PR63,
|
||||
IA64_RS_RR,
|
||||
|
||||
IA64_RS_ARX, /* ARs not in RS_AR or RS_ARb */
|
||||
IA64_RS_CRX, /* CRs not in RS_CR */
|
||||
IA64_RS_PSR, /* PSR bits */
|
||||
IA64_RS_RSE, /* implementation-specific RSE resources */
|
||||
IA64_RS_AR_FPSR,
|
||||
};
|
||||
|
||||
enum ia64_rse_resource
|
||||
{
|
||||
IA64_RSE_N_STACKED_PHYS,
|
||||
IA64_RSE_BOF,
|
||||
IA64_RSE_STORE_REG,
|
||||
IA64_RSE_LOAD_REG,
|
||||
IA64_RSE_BSPLOAD,
|
||||
IA64_RSE_RNATBITINDEX,
|
||||
IA64_RSE_CFLE,
|
||||
IA64_RSE_NDIRTY,
|
||||
};
|
||||
|
||||
/* Information about a given resource dependency */
|
||||
struct ia64_dependency
|
||||
{
|
||||
/* Name of the resource */
|
||||
const char *name;
|
||||
/* Does this dependency need further specification? */
|
||||
enum ia64_resource_specifier specifier;
|
||||
/* Mode of dependency */
|
||||
enum ia64_dependency_mode mode;
|
||||
/* Dependency semantics */
|
||||
enum ia64_dependency_semantics semantics;
|
||||
/* Register index, if applicable (distinguishes AR, CR, and PSR deps) */
|
||||
#define REG_NONE (-1)
|
||||
int regindex;
|
||||
/* Special info on semantics */
|
||||
const char *info;
|
||||
};
|
||||
|
||||
/* Two arrays of indexes into the ia64_dependency table.
|
||||
chks are dependencies to check for conflicts when an opcode is
|
||||
encountered; regs are dependencies to register (mark as used) when an
|
||||
opcode is used. chks correspond to readers (RAW) or writers (WAW or
|
||||
WAR) of a resource, while regs correspond to writers (RAW or WAW) and
|
||||
readers (WAR) of a resource. */
|
||||
struct ia64_opcode_dependency
|
||||
{
|
||||
int nchks;
|
||||
const unsigned short *chks;
|
||||
int nregs;
|
||||
const unsigned short *regs;
|
||||
};
|
||||
|
||||
/* encode/extract the note/index for a dependency */
|
||||
#define RDEP(N,X) (((N)<<11)|(X))
|
||||
#define NOTE(X) (((X)>>11)&0x1F)
|
||||
#define DEP(X) ((X)&0x7FF)
|
||||
|
||||
/* A template descriptor describes the execution units that are active
|
||||
for each of the three slots. It also specifies the location of
|
||||
instruction group boundaries that may be present between two slots. */
|
||||
struct ia64_templ_desc
|
||||
{
|
||||
int group_boundary; /* 0=no boundary, 1=between slot 0 & 1, etc. */
|
||||
enum ia64_unit exec_unit[3];
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* The opcode table is an array of struct ia64_opcode. */
|
||||
|
||||
struct ia64_opcode
|
||||
{
|
||||
/* The opcode name. */
|
||||
const char *name;
|
||||
|
||||
/* The type of the instruction: */
|
||||
enum ia64_insn_type type;
|
||||
|
||||
/* Number of output operands: */
|
||||
int num_outputs;
|
||||
|
||||
/* The opcode itself. Those bits which will be filled in with
|
||||
operands are zeroes. */
|
||||
ia64_insn opcode;
|
||||
|
||||
/* The opcode mask. This is used by the disassembler. This is a
|
||||
mask containing ones indicating those bits which must match the
|
||||
opcode field, and zeroes indicating those bits which need not
|
||||
match (and are presumably filled in by operands). */
|
||||
ia64_insn mask;
|
||||
|
||||
/* An array of operand codes. Each code is an index into the
|
||||
operand table. They appear in the order which the operands must
|
||||
appear in assembly code, and are terminated by a zero. */
|
||||
enum ia64_opnd operands[5];
|
||||
|
||||
/* One bit flags for the opcode. These are primarily used to
|
||||
indicate specific processors and environments support the
|
||||
instructions. The defined values are listed below. */
|
||||
unsigned int flags;
|
||||
|
||||
/* Used by ia64_find_next_opcode (). */
|
||||
short ent_index;
|
||||
|
||||
/* Opcode dependencies. */
|
||||
const struct ia64_opcode_dependency *dependencies;
|
||||
};
|
||||
|
||||
/* Values defined for the flags field of a struct ia64_opcode. */
|
||||
|
||||
#define IA64_OPCODE_FIRST (1<<0) /* must be first in an insn group */
|
||||
#define IA64_OPCODE_X_IN_MLX (1<<1) /* insn is allowed in X slot of MLX */
|
||||
#define IA64_OPCODE_LAST (1<<2) /* must be last in an insn group */
|
||||
#define IA64_OPCODE_PRIV (1<<3) /* privileged instruct */
|
||||
#define IA64_OPCODE_SLOT2 (1<<4) /* insn allowed in slot 2 only */
|
||||
#define IA64_OPCODE_NO_PRED (1<<5) /* insn cannot be predicated */
|
||||
#define IA64_OPCODE_PSEUDO (1<<6) /* insn is a pseudo-op */
|
||||
#define IA64_OPCODE_F2_EQ_F3 (1<<7) /* constraint: F2 == F3 */
|
||||
#define IA64_OPCODE_LEN_EQ_64MCNT (1<<8) /* constraint: LEN == 64-CNT */
|
||||
#define IA64_OPCODE_MOD_RRBS (1<<9) /* modifies all rrbs in CFM */
|
||||
#define IA64_OPCODE_POSTINC (1<<10) /* postincrement MR3 operand */
|
||||
|
||||
/* A macro to extract the major opcode from an instruction. */
|
||||
#define IA64_OP(i) (((i) >> 37) & 0xf)
|
||||
|
||||
enum ia64_operand_class
|
||||
{
|
||||
IA64_OPND_CLASS_CST, /* constant */
|
||||
IA64_OPND_CLASS_REG, /* register */
|
||||
IA64_OPND_CLASS_IND, /* indirect register */
|
||||
IA64_OPND_CLASS_ABS, /* absolute value */
|
||||
IA64_OPND_CLASS_REL, /* IP-relative value */
|
||||
};
|
||||
|
||||
/* The operands table is an array of struct ia64_operand. */
|
||||
|
||||
struct ia64_operand
|
||||
{
|
||||
enum ia64_operand_class class;
|
||||
|
||||
/* Set VALUE as the operand bits for the operand of type SELF in the
|
||||
instruction pointed to by CODE. If an error occurs, *CODE is not
|
||||
modified and the returned string describes the cause of the
|
||||
error. If no error occurs, NULL is returned. */
|
||||
const char *(*insert) (const struct ia64_operand *self, ia64_insn value,
|
||||
ia64_insn *code);
|
||||
|
||||
/* Extract the operand bits for an operand of type SELF from
|
||||
instruction CODE store them in *VALUE. If an error occurs, the
|
||||
cause of the error is described by the string returned. If no
|
||||
error occurs, NULL is returned. */
|
||||
const char *(*extract) (const struct ia64_operand *self, ia64_insn code,
|
||||
ia64_insn *value);
|
||||
|
||||
/* A string whose meaning depends on the operand class. */
|
||||
|
||||
const char *str;
|
||||
|
||||
struct bit_field
|
||||
{
|
||||
/* The number of bits in the operand. */
|
||||
int bits;
|
||||
|
||||
/* How far the operand is left shifted in the instruction. */
|
||||
int shift;
|
||||
}
|
||||
field[4]; /* no operand has more than this many bit-fields */
|
||||
|
||||
unsigned int flags;
|
||||
|
||||
const char *desc; /* brief description */
|
||||
};
|
||||
|
||||
/* Values defined for the flags field of a struct ia64_operand. */
|
||||
|
||||
/* Disassemble as signed decimal (instead of hex): */
|
||||
#define IA64_OPND_FLAG_DECIMAL_SIGNED (1<<0)
|
||||
/* Disassemble as unsigned decimal (instead of hex): */
|
||||
#define IA64_OPND_FLAG_DECIMAL_UNSIGNED (1<<1)
|
||||
|
||||
extern const struct ia64_templ_desc ia64_templ_desc[16];
|
||||
|
||||
/* The tables are sorted by major opcode number and are otherwise in
|
||||
the order in which the disassembler should consider instructions. */
|
||||
extern struct ia64_opcode ia64_opcodes_a[];
|
||||
extern struct ia64_opcode ia64_opcodes_i[];
|
||||
extern struct ia64_opcode ia64_opcodes_m[];
|
||||
extern struct ia64_opcode ia64_opcodes_b[];
|
||||
extern struct ia64_opcode ia64_opcodes_f[];
|
||||
extern struct ia64_opcode ia64_opcodes_d[];
|
||||
|
||||
|
||||
extern struct ia64_opcode *ia64_find_opcode (const char *name);
|
||||
extern struct ia64_opcode *ia64_find_next_opcode (struct ia64_opcode *ent);
|
||||
|
||||
extern struct ia64_opcode *ia64_dis_opcode (ia64_insn insn,
|
||||
enum ia64_insn_type type);
|
||||
|
||||
extern void ia64_free_opcode (struct ia64_opcode *ent);
|
||||
extern const struct ia64_dependency *ia64_find_dependency (int index);
|
||||
|
||||
/* To avoid circular library dependencies, this array is implemented
|
||||
in bfd/cpu-ia64-opc.c: */
|
||||
extern const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT];
|
||||
|
||||
#endif /* opcode_ia64_h */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -13,7 +13,7 @@ xen/.dir:
|
||||
mkdir -p xen/libelf
|
||||
ln -sf $(XEN_ROOT)/xen/include/public/COPYING xen
|
||||
ln -sf $(wildcard $(XEN_ROOT)/xen/include/public/*.h) xen
|
||||
ln -sf $(addprefix $(XEN_ROOT)/xen/include/public/,arch-ia64 arch-x86 hvm io xsm) xen
|
||||
ln -sf $(addprefix $(XEN_ROOT)/xen/include/public/,arch-x86 hvm io xsm) xen
|
||||
ln -sf ../xen-sys/$(XEN_OS) xen/sys
|
||||
ln -sf $(addprefix $(XEN_ROOT)/xen/include/xen/,libelf.h elfstructs.h) xen/libelf/
|
||||
ln -s ../xen-foreign xen/foreign
|
||||
@@ -21,8 +21,6 @@ xen/.dir:
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/arch-ia64
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/arch-ia64/hvm
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86/hvm
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/foreign
|
||||
@@ -32,8 +30,6 @@ install: all
|
||||
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/xsm
|
||||
$(INSTALL_DATA) xen/COPYING $(DESTDIR)$(INCLUDEDIR)/xen
|
||||
$(INSTALL_DATA) xen/*.h $(DESTDIR)$(INCLUDEDIR)/xen
|
||||
$(INSTALL_DATA) xen/arch-ia64/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-ia64
|
||||
$(INSTALL_DATA) xen/arch-ia64/hvm/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-ia64/hvm
|
||||
$(INSTALL_DATA) xen/arch-x86/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86
|
||||
$(INSTALL_DATA) xen/arch-x86/hvm/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86/hvm
|
||||
$(INSTALL_DATA) xen/foreign/*.h $(DESTDIR)$(INCLUDEDIR)/xen/foreign
|
||||
|
||||
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
ROOT = $(XEN_ROOT)/xen/include/public
|
||||
|
||||
architectures := x86_32 x86_64 ia64
|
||||
architectures := x86_32 x86_64
|
||||
headers := $(patsubst %, %.h, $(architectures))
|
||||
|
||||
.PHONY: all clean check-headers
|
||||
@@ -28,8 +28,5 @@ x86_32.h: mkheader.py structs.py $(ROOT)/arch-x86/xen-x86_32.h $(ROOT)/arch-x86/
|
||||
x86_64.h: mkheader.py structs.py $(ROOT)/arch-x86/xen-x86_64.h $(ROOT)/arch-x86/xen.h $(ROOT)/xen.h
|
||||
$(PYTHON) $< $* $@ $(filter %.h,$^)
|
||||
|
||||
ia64.h: mkheader.py structs.py $(ROOT)/arch-ia64.h $(ROOT)/xen.h
|
||||
$(PYTHON) $< $* $@ $(filter %.h,$^)
|
||||
|
||||
checker.c: mkchecker.py structs.py
|
||||
$(PYTHON) $< $@ $(architectures)
|
||||
@@ -47,20 +47,6 @@ header["x86_64"] = """
|
||||
#define __x86_64___X86_64 1
|
||||
""";
|
||||
|
||||
# ia64
|
||||
inttypes["ia64"] = {
|
||||
"unsigned long" : "__align8__ uint64_t",
|
||||
"long" : "__align8__ uint64_t",
|
||||
"xen_pfn_t" : "__align8__ uint64_t",
|
||||
"long double" : "__align16__ ldouble_t",
|
||||
};
|
||||
header["ia64"] = """
|
||||
#define __align8__ __attribute__((aligned (8)))
|
||||
#define __align16__ __attribute__((aligned (16)))
|
||||
typedef unsigned char ldouble_t[16];
|
||||
""";
|
||||
|
||||
|
||||
###########################################################################
|
||||
# main
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
|
||||
structs | x86_32 x86_64 ia64
|
||||
structs | x86_32 x86_64
|
||||
|
||||
start_info | 1112 1168 1168
|
||||
trap_info | 8 16 -
|
||||
pt_fpreg | - - 16
|
||||
cpu_user_regs | 68 200 -
|
||||
xen_ia64_boot_param | - - 96
|
||||
ia64_tr_entry | - - 32
|
||||
vcpu_tr_regs | - - 768
|
||||
vcpu_guest_context_regs | - - 22176
|
||||
vcpu_guest_context | 2800 5168 22208
|
||||
arch_vcpu_info | 24 16 0
|
||||
vcpu_time_info | 32 32 32
|
||||
vcpu_info | 64 64 48
|
||||
arch_shared_info | 268 280 272
|
||||
shared_info | 2584 3368 4384
|
||||
start_info | 1112 1168
|
||||
trap_info | 8 16
|
||||
pt_fpreg | - -
|
||||
cpu_user_regs | 68 200
|
||||
xen_ia64_boot_param | - -
|
||||
ia64_tr_entry | - -
|
||||
vcpu_tr_regs | - -
|
||||
vcpu_guest_context_regs | - -
|
||||
vcpu_guest_context | 2800 5168
|
||||
arch_vcpu_info | 24 16
|
||||
vcpu_time_info | 32 32
|
||||
vcpu_info | 64 64
|
||||
arch_shared_info | 268 280
|
||||
shared_info | 2584 3368
|
||||
|
||||
@@ -7,7 +7,6 @@ MINOR = 0
|
||||
CTRL_SRCS-y :=
|
||||
CTRL_SRCS-y += xc_core.c
|
||||
CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
|
||||
CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
|
||||
CTRL_SRCS-$(CONFIG_ARM) += xc_core_arm.c
|
||||
CTRL_SRCS-y += xc_cpupool.c
|
||||
CTRL_SRCS-y += xc_domain.c
|
||||
@@ -65,7 +64,6 @@ GUEST_SRCS-y += xc_dom_compat_linux.c
|
||||
GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c
|
||||
GUEST_SRCS-$(CONFIG_X86) += xc_cpuid_x86.c
|
||||
GUEST_SRCS-$(CONFIG_X86) += xc_hvm_build_x86.c
|
||||
GUEST_SRCS-$(CONFIG_IA64) += xc_dom_ia64.c
|
||||
GUEST_SRCS-$(CONFIG_ARM) += xc_dom_arm.c
|
||||
GUEST_SRCS-$(CONFIG_ARM) += xc_hvm_build_arm.c
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
ifneq ($(stubdom),y)
|
||||
CTRL_SRCS-y += ia64/xc_ia64_stubs.c
|
||||
|
||||
GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c
|
||||
GUEST_SRCS-y += ia64/xc_ia64_linux_save.c
|
||||
GUEST_SRCS-y += ia64/xc_ia64_linux_restore.c
|
||||
|
||||
GUEST_SRCS-y += ia64/xc_dom_ia64_util.c
|
||||
GUEST_SRCS-y += ia64/dom_fw_acpi.c
|
||||
|
||||
GUEST_SRCS-y += ia64/xc_ia64_dom_fwloader.c
|
||||
|
||||
DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S
|
||||
endif
|
||||
DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE))
|
||||
$(DOMFW_SRCS):
|
||||
ln -sf $(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@
|
||||
|
||||
GUEST_SRCS-y += $(patsubst %.S, %.c, $(DOMFW_SRCS))
|
||||
|
||||
CFLAGS += -Iia64
|
||||
|
||||
DOMFW_ASM_HDRS_BASE := bundle.h dom_fw.h dom_fw_common.h dom_fw_domu.h
|
||||
DOMFW_ASM_HDRS := $(addprefix ia64/asm/, $(DOMFW_ASM_HDRS_BASE))
|
||||
$(DOMFW_ASM_HDRS): ia64/asm
|
||||
ln -sf $(XEN_ROOT)/xen/include/asm-ia64/$(@F) $@
|
||||
build: $(DOMFW_ASM_HDR)
|
||||
|
||||
.PHONY: mk-symlinks-acpi mk-symlinks-misc ia64-clean
|
||||
|
||||
IA64_HDR_DIRS := ia64/asm ia64/xen ia64/acpi ia64/acpi/platform
|
||||
$(IA64_HDR_DIRS):
|
||||
mkdir -p $@
|
||||
|
||||
IA64_EMPTY_FILES := ia64/asm/acpi.h ia64/xen/list.h
|
||||
$(IA64_EMPTY_FILES): $(IA64_HDR_DIRS)
|
||||
echo "/* automatically created dummy empty header file. */" > $@
|
||||
|
||||
mk-symlinks-acpi: $(IA64_HDR_DIRS) $(IA64_EMPTY_FILES) $(DOMFW_ASM_HDRS)
|
||||
( cd ia64/acpi && ln -sf $(XEN_ROOT)/xen/include/acpi/*.h .)
|
||||
( cd ia64/acpi/platform && ln -sf $(XEN_ROOT)/xen/include/acpi/platform/*.h .)
|
||||
( cd ia64/xen && ln -sf $(XEN_ROOT)/xen/include/xen/acpi.h .)
|
||||
mk-symlinks-misc: $(IA64_HDR_DIRS)
|
||||
( cd ia64/asm && ln -sf $(XEN_ROOT)/xen/include/asm-ia64/linux-xen/asm/kregs.h .)
|
||||
( cd ia64/asm && ln -sf $(XEN_ROOT)/xen/include/asm-ia64/linux/asm/fpswa.h .)
|
||||
build: mk-symlinks-acpi mk-symlinks-misc
|
||||
|
||||
clean: ia64-clean
|
||||
ia64-clean:
|
||||
rm -rf $(DOMFW_SRCS) $(DOMFW_ASM_HDRS) $(IA64_EMPTY_FILES) $(IA64_HDR_DIRS)
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* ac_ia64_tools.h
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AC_IA64_TOOLS_H
|
||||
#define AC_IA64_TOOLS_H
|
||||
|
||||
#define ACPI_MACHINE_WIDTH 64
|
||||
#define COMPILER_DEPENDENT_UINT64 unsigned long long
|
||||
#define COMPILER_DEPENDENT_INT64 long long
|
||||
typedef unsigned long long u64;
|
||||
typedef long long s64;
|
||||
typedef unsigned u32;
|
||||
typedef int s32;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
#define __iomem
|
||||
#define asmlinkage
|
||||
#define CONFIG_ACPI_BOOT
|
||||
|
||||
#endif /* AC_IA64_TOOLS_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,45 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_checksum
|
||||
*
|
||||
* PARAMETERS: Buffer - Pointer to memory region to be checked
|
||||
* Length - Length of this memory region
|
||||
*
|
||||
* RETURN: Checksum (u8)
|
||||
*
|
||||
* DESCRIPTION: Calculates circular checksum of memory region.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* stolen from xen/drivers/acpi/tables/tbutils.c */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "xc_dom_ia64_util.h"
|
||||
#include <xen/acpi.h>
|
||||
#include <acpi/actables.h>
|
||||
|
||||
u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
|
||||
{
|
||||
u8 sum = 0;
|
||||
u8 *end = buffer + length;
|
||||
|
||||
while (buffer < end) {
|
||||
sum = (u8) (sum + *(buffer++));
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* definitions from
|
||||
* xen/include/asm-ia64/linux/asm/sal.h
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef XC_IA64_SAL_H
|
||||
#define XC_IA64_SAL_H
|
||||
|
||||
/*
|
||||
* The SAL system table is followed by a variable number of variable
|
||||
* length descriptors. The structure of these descriptors follows
|
||||
* below.
|
||||
* The defininition follows SAL specs from July 2000
|
||||
*/
|
||||
struct ia64_sal_systab {
|
||||
uint8_t signature[4]; /* should be "SST_" */
|
||||
uint32_t size; /* size of this table in bytes */
|
||||
uint8_t sal_rev_minor;
|
||||
uint8_t sal_rev_major;
|
||||
uint16_t entry_count; /* # of entries in variable portion */
|
||||
uint8_t checksum;
|
||||
uint8_t reserved1[7];
|
||||
uint8_t sal_a_rev_minor;
|
||||
uint8_t sal_a_rev_major;
|
||||
uint8_t sal_b_rev_minor;
|
||||
uint8_t sal_b_rev_major;
|
||||
/* oem_id & product_id: terminating NUL is missing if string is exactly 32 bytes long. */
|
||||
uint8_t oem_id[32];
|
||||
uint8_t product_id[32]; /* ASCII product id */
|
||||
uint8_t reserved2[8];
|
||||
};
|
||||
|
||||
enum sal_systab_entry_type {
|
||||
SAL_DESC_ENTRY_POINT = 0,
|
||||
SAL_DESC_MEMORY = 1,
|
||||
SAL_DESC_PLATFORM_FEATURE = 2,
|
||||
SAL_DESC_TR = 3,
|
||||
SAL_DESC_PTC = 4,
|
||||
SAL_DESC_AP_WAKEUP = 5
|
||||
};
|
||||
|
||||
typedef struct ia64_sal_desc_entry_point {
|
||||
uint8_t type;
|
||||
uint8_t reserved1[7];
|
||||
uint64_t pal_proc;
|
||||
uint64_t sal_proc;
|
||||
uint64_t gp;
|
||||
uint8_t reserved2[16];
|
||||
}ia64_sal_desc_entry_point_t;
|
||||
|
||||
#define IA64_SAL_AP_EXTERNAL_INT 0
|
||||
|
||||
typedef struct ia64_sal_desc_ap_wakeup {
|
||||
uint8_t type;
|
||||
uint8_t mechanism; /* 0 == external interrupt */
|
||||
uint8_t reserved1[6];
|
||||
uint64_t vector; /* interrupt vector in range 0x10-0xff */
|
||||
} ia64_sal_desc_ap_wakeup_t ;
|
||||
|
||||
//XXX should move xen_sal_data to arch-ia64.h?
|
||||
/* These are data in domain memory for SAL emulator. */
|
||||
struct xen_sal_data {
|
||||
/* OS boot rendez vous. */
|
||||
unsigned long boot_rdv_ip;
|
||||
unsigned long boot_rdv_r1;
|
||||
|
||||
/* There are these for EFI_SET_VIRTUAL_ADDRESS_MAP emulation. */
|
||||
int efi_virt_mode; /* phys : 0 , virt : 1 */
|
||||
};
|
||||
|
||||
#endif /* XC_IA64_SAL_H */
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "xg_private.h"
|
||||
#include "xc_dom.h"
|
||||
#include "asm/dom_fw.h"
|
||||
#include "asm/dom_fw_common.h"
|
||||
#include "ia64/xc_dom_ia64_util.h"
|
||||
|
||||
uint32_t
|
||||
xen_ia64_version(struct xc_dom_image *dom)
|
||||
{
|
||||
return xc_version(dom->xch, XENVER_version, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision)
|
||||
{
|
||||
int ret;
|
||||
DECLARE_HYPERCALL;
|
||||
DECLARE_HYPERCALL_BOUNCE(revision, sizeof(*revision), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
|
||||
if (xc_hypercall_bounce_pre(dom->xch, revision) )
|
||||
{
|
||||
PERROR("Could not lock memory for xen fpswa hypercall");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
|
||||
hypercall.arg[0] = IA64_DOM0VP_fpswa_revision;
|
||||
hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(revision);
|
||||
|
||||
ret = do_xen_hypercall(dom->xch, &hypercall);
|
||||
|
||||
xc_hypercall_bounce_post(dom->xch, revision);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xen_ia64_is_running_on_sim(struct xc_dom_image *dom)
|
||||
{
|
||||
/*
|
||||
* This is only used by dom_fw_init() as
|
||||
* "!xen_ia64_is_dom0() || xen_ia64_is_running_on_sim()".
|
||||
* So this doesn't affect the result.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xen_ia64_is_dom0(struct xc_dom_image *unused)
|
||||
{
|
||||
/* libxc is for non-dom0 domain builder */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr)
|
||||
{
|
||||
unsigned long page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
void* ret;
|
||||
|
||||
ret = xc_map_foreign_range(dom->xch, dom->guest_domid,
|
||||
page_size, PROT_READ | PROT_WRITE,
|
||||
mpaddr / page_size);
|
||||
if (ret != NULL)
|
||||
ret = (void*)((unsigned long)ret | (mpaddr & (page_size - 1)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *vaddr)
|
||||
{
|
||||
unsigned long page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
munmap((void*)((unsigned long)vaddr & ~(page_size - 1)), page_size);
|
||||
}
|
||||
|
||||
int
|
||||
xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu)
|
||||
{
|
||||
// return d->vcpu[vcpu] != NULL;
|
||||
|
||||
int rc;
|
||||
xc_vcpuinfo_t info;
|
||||
xc_interface *xch = dom->xch;
|
||||
|
||||
rc = xc_vcpu_getinfo(xch, dom->guest_domid,
|
||||
vcpu, &info);
|
||||
if (rc == 0)
|
||||
return 1;
|
||||
|
||||
if (errno != ESRCH)
|
||||
PERROR("Could not get vcpu info");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm,
|
||||
unsigned long bp_mpa, unsigned long maxmem)
|
||||
{
|
||||
int rc = 0;
|
||||
void *imva_hypercall_base = NULL;
|
||||
struct fw_tables *fw_tables = NULL;
|
||||
struct fake_acpi_tables *imva = NULL;
|
||||
struct xen_ia64_boot_param *bp = NULL;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct fw_tables) >
|
||||
(FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR));
|
||||
|
||||
/* Create page for hypercalls. */
|
||||
imva_hypercall_base = xen_ia64_dom_fw_map(d, FW_HYPERCALL_BASE_PADDR);
|
||||
if (imva_hypercall_base == NULL) {
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create page for FW tables. */
|
||||
fw_tables = (struct fw_tables*)xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR);
|
||||
if (fw_tables == NULL) {
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
memset(fw_tables, 0, FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR);
|
||||
BUILD_BUG_ON(FW_END_PADDR_MIN != FW_TABLES_END_PADDR_MIN);
|
||||
fw_tables->fw_tables_size = FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR;
|
||||
fw_tables->fw_end_paddr = FW_END_PADDR_MIN;
|
||||
fw_tables->fw_tables_end_paddr = FW_TABLES_END_PADDR_MIN;
|
||||
fw_tables->num_mds = 0;
|
||||
|
||||
/* Create page for acpi tables. */
|
||||
imva = (struct fake_acpi_tables *)
|
||||
xen_ia64_dom_fw_map(d, FW_ACPI_BASE_PADDR);
|
||||
if (imva == NULL) {
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
dom_fw_fake_acpi(d, imva);
|
||||
|
||||
/* Create page for boot_param. */
|
||||
bp = xen_ia64_dom_fw_map(d, bp_mpa);
|
||||
if (bp == NULL) {
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
rc = dom_fw_init(d, brkimm, bp, fw_tables,
|
||||
(unsigned long)imva_hypercall_base, maxmem);
|
||||
BUG_ON(fw_tables->fw_tables_size < sizeof(*fw_tables) +
|
||||
sizeof(fw_tables->efi_memmap[0]) * fw_tables->num_mds);
|
||||
|
||||
/* clear domain builder internal use member */
|
||||
fw_tables->fw_tables_size = 0;
|
||||
fw_tables->fw_end_paddr = 0;
|
||||
fw_tables->fw_tables_end_paddr = 0;
|
||||
fw_tables->num_mds = 0;
|
||||
|
||||
out:
|
||||
if (imva_hypercall_base != NULL)
|
||||
xen_ia64_dom_fw_unmap(d, imva_hypercall_base);
|
||||
if (fw_tables != NULL)
|
||||
xen_ia64_dom_fw_unmap(d, fw_tables);
|
||||
if (imva != NULL)
|
||||
xen_ia64_dom_fw_unmap(d, imva);
|
||||
if (bp != NULL)
|
||||
xen_ia64_dom_fw_unmap(d, bp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef XC_IA64_DOM_IA64_UTIL_H
|
||||
#define XC_IA64_DOM_IA64_UTIL_H
|
||||
|
||||
struct xc_dom_image;
|
||||
uint32_t xen_ia64_version(struct xc_dom_image *dom);
|
||||
void* xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr);
|
||||
void xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *addr);
|
||||
int xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision);
|
||||
int xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu);
|
||||
int xen_ia64_is_running_on_sim(struct xc_dom_image *dom);
|
||||
int xen_ia64_is_dom0(struct xc_dom_image *dom);
|
||||
|
||||
int
|
||||
xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm,
|
||||
unsigned long bp_mpa, unsigned long maxmem);
|
||||
#define efi_systable_init_dom0(tables) assert(0)
|
||||
#define complete_dom0_memmap(d, tables) ({assert(0);0;})
|
||||
|
||||
/* Defined in xc_dom_ia64.c */
|
||||
extern int start_info_ia64(struct xc_dom_image *dom);
|
||||
extern int shared_info_ia64(struct xc_dom_image *dom, void *ptr);
|
||||
|
||||
#define FW_MEM_BASE 0xff000000UL
|
||||
#define FW_MEM_SIZE 0x01000000UL
|
||||
|
||||
#ifdef __XEN_TOOLS__
|
||||
/* Necessary for including the acpi header chain when not in kernel context */
|
||||
typedef struct { } spinlock_t;
|
||||
#endif
|
||||
#endif /* XC_IA64_DOM_IA64_UTIL_H */
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _XC_IA64_H_
|
||||
#define _XC_IA64_H_
|
||||
|
||||
int xc_ia64_copy_memmap(xc_interface *xc_handle, uint32_t domid,
|
||||
shared_info_t *live_shinfo,
|
||||
xen_ia64_memmap_info_t **memmap_info_p,
|
||||
unsigned long *memmap_info_num_pages_p);
|
||||
|
||||
struct xen_ia64_p2m_table {
|
||||
unsigned long size;
|
||||
unsigned long *p2m;
|
||||
};
|
||||
|
||||
void xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table);
|
||||
int xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, xc_interface *xc_handle,
|
||||
uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
|
||||
unsigned long flag);
|
||||
void xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table);
|
||||
int xc_ia64_p2m_present(struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned long gpfn);
|
||||
int xc_ia64_p2m_allocated(struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned long gpfn);
|
||||
|
||||
unsigned long xc_ia64_p2m_mfn(struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned long gpfn);
|
||||
|
||||
|
||||
#endif /* _XC_IA64_H_ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <asm/kregs.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/foreign/ia64.h>
|
||||
#include <xen/io/protocols.h>
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_dom.h"
|
||||
|
||||
#include "ia64/xc_dom_ia64_util.h"
|
||||
|
||||
static const char fw_magic[16] = {'X', 'e', 'n', '-',
|
||||
'i', 'a', '6', '4',
|
||||
'-', 'f', 'w', 0,
|
||||
0, 0, 0, 0};
|
||||
#define FW_LOAD 0xff800000UL
|
||||
#define FW_SIZE (8 * 1024 * 1024)
|
||||
|
||||
static int xc_dom_probe_fw_kernel(struct xc_dom_image *dom)
|
||||
{
|
||||
if (dom->kernel_size != FW_SIZE)
|
||||
return -EINVAL;
|
||||
if (memcmp (dom->kernel_blob, fw_magic, sizeof (fw_magic)))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc_dom_parse_fw_kernel(struct xc_dom_image *dom)
|
||||
{
|
||||
dom->kernel_seg.vstart = FW_LOAD;
|
||||
dom->kernel_seg.vend = FW_LOAD + FW_SIZE;
|
||||
dom->parms.virt_base = FW_MEM_BASE;
|
||||
dom->parms.virt_entry = FW_LOAD + sizeof (fw_magic);
|
||||
dom->ramdisk_blob = NULL; /* No ramdisk yet. */
|
||||
dom->guest_type = "hvm-3.0-ia64-sioemu";
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xc_dom_load_fw_kernel(struct xc_dom_image *dom)
|
||||
{
|
||||
char *dest;
|
||||
unsigned long i;
|
||||
|
||||
dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
|
||||
memcpy(dest, dom->kernel_blob, FW_SIZE);
|
||||
|
||||
/* Synchronize cache. */
|
||||
for (i = 0; i < FW_SIZE; i += 32)
|
||||
asm volatile ("fc.i %0" :: "r"(dest + i) : "memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
{
|
||||
/* allocate special pages */
|
||||
/* Note: do not use 0 for console or xenstore otherwise clear_page won't
|
||||
clear the page. */
|
||||
dom->start_info_pfn = 0;
|
||||
dom->console_pfn = 1;
|
||||
dom->xenstore_pfn = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned long xc_ia64_fpsr_default(void);
|
||||
|
||||
static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
|
||||
{
|
||||
vcpu_guest_context_ia64_t *ctxt = ptr;
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
/* clear everything */
|
||||
memset(ctxt, 0, sizeof(*ctxt));
|
||||
|
||||
ctxt->flags = 0;
|
||||
ctxt->regs.ip = dom->parms.virt_entry;
|
||||
#ifdef __ia64__ /* FIXME */
|
||||
ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();
|
||||
#endif
|
||||
ctxt->regs.cr.isr = 1UL << 63;
|
||||
ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_BN;
|
||||
ctxt->regs.cr.dcr = 0;
|
||||
ctxt->regs.cr.pta = 15 << 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xc_dom_arch xc_dom_arch_ia64_fw = {
|
||||
.guest_type = "hvm-3.0-ia64-sioemu",
|
||||
.native_protocol = XEN_IO_PROTO_ABI_IA64,
|
||||
.page_shift = PAGE_SHIFT_IA64,
|
||||
.alloc_magic_pages = alloc_magic_pages,
|
||||
.start_info = start_info_ia64,
|
||||
.shared_info = shared_info_ia64,
|
||||
.vcpu = vcpu_ia64,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static struct xc_dom_loader fw_loader = {
|
||||
.name = "xen-ia64-fw",
|
||||
.probe = xc_dom_probe_fw_kernel,
|
||||
.parser = xc_dom_parse_fw_kernel,
|
||||
.loader = xc_dom_load_fw_kernel,
|
||||
};
|
||||
|
||||
static void __init register_fwloader(void)
|
||||
{
|
||||
xc_dom_register_arch_hooks(&xc_dom_arch_ia64_fw);
|
||||
xc_dom_register_loader(&fw_loader);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,739 +0,0 @@
|
||||
/******************************************************************************
|
||||
* xc_ia64_linux_restore.c
|
||||
*
|
||||
* Restore the state of a Linux session.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2003, K A Fraser.
|
||||
* Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net>
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp>
|
||||
* Use foreign p2m exposure.
|
||||
* VTi domain support
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_ia64_save_restore.h"
|
||||
#include "xc_ia64.h"
|
||||
#include "xc_efi.h"
|
||||
#include "xen/hvm/params.h"
|
||||
|
||||
#define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10))
|
||||
|
||||
/* number of pfns this guest has (i.e. number of entries in the P2M) */
|
||||
static unsigned long p2m_size;
|
||||
|
||||
/* number of 'in use' pfns in the guest (i.e. #P2M entries with a valid mfn) */
|
||||
static unsigned long nr_pfns;
|
||||
|
||||
static int
|
||||
populate_page_if_necessary(xc_interface *xch, uint32_t dom, unsigned long gmfn,
|
||||
struct xen_ia64_p2m_table *p2m_table)
|
||||
{
|
||||
if (xc_ia64_p2m_present(p2m_table, gmfn))
|
||||
return 0;
|
||||
|
||||
return xc_domain_populate_physmap_exact(xch, dom, 1, 0, 0, &gmfn);
|
||||
}
|
||||
|
||||
static int
|
||||
read_page(xc_interface *xch, int io_fd, uint32_t dom, unsigned long pfn)
|
||||
{
|
||||
void *mem;
|
||||
|
||||
mem = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE, pfn);
|
||||
if (mem == NULL) {
|
||||
ERROR("cannot map page");
|
||||
return -1;
|
||||
}
|
||||
if (read_exact(io_fd, mem, PAGE_SIZE)) {
|
||||
ERROR("Error when reading from state file (5)");
|
||||
munmap(mem, PAGE_SIZE);
|
||||
return -1;
|
||||
}
|
||||
munmap(mem, PAGE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the list of PFNs that are not in the psuedo-phys map.
|
||||
* Although we allocate pages on demand, balloon driver may
|
||||
* decreased simaltenously. So we have to free the freed
|
||||
* pages here.
|
||||
*/
|
||||
static int
|
||||
xc_ia64_recv_unallocated_list(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
struct xen_ia64_p2m_table *p2m_table)
|
||||
{
|
||||
int rc = -1;
|
||||
unsigned int i;
|
||||
unsigned int count;
|
||||
unsigned long *pfntab = NULL;
|
||||
unsigned int nr_frees;
|
||||
|
||||
if (read_exact(io_fd, &count, sizeof(count))) {
|
||||
ERROR("Error when reading pfn count");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pfntab = malloc(sizeof(unsigned long) * count);
|
||||
if (pfntab == NULL) {
|
||||
ERROR("Out of memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_exact(io_fd, pfntab, sizeof(unsigned long)*count)) {
|
||||
ERROR("Error when reading pfntab");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nr_frees = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (xc_ia64_p2m_allocated(p2m_table, pfntab[i])) {
|
||||
pfntab[nr_frees] = pfntab[i];
|
||||
nr_frees++;
|
||||
}
|
||||
}
|
||||
if (nr_frees > 0) {
|
||||
if (xc_domain_decrease_reservation_exact(xch, dom, nr_frees,
|
||||
0, pfntab) < 0) {
|
||||
PERROR("Could not decrease reservation");
|
||||
goto out;
|
||||
} else
|
||||
DPRINTF("Decreased reservation by %d / %d pages\n",
|
||||
nr_frees, count);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (pfntab != NULL)
|
||||
free(pfntab);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_recv_vcpu_context(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any)
|
||||
{
|
||||
vcpu_guest_context_t *ctxt = &ctxt_any->c;
|
||||
if (read_exact(io_fd, ctxt, sizeof(*ctxt))) {
|
||||
ERROR("Error when reading ctxt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);
|
||||
|
||||
/* Initialize and set registers. */
|
||||
ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online |
|
||||
VGCF_SET_AR_ITC;
|
||||
if (xc_vcpu_setcontext(xch, dom, vcpu, ctxt_any) != 0) {
|
||||
ERROR("Couldn't set vcpu context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Just a check. */
|
||||
ctxt->flags = 0;
|
||||
if (xc_vcpu_getcontext(xch, dom, vcpu, ctxt_any)) {
|
||||
ERROR("Could not get vcpu context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read shared info. */
|
||||
static int
|
||||
xc_ia64_recv_shared_info(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
unsigned long *start_info_pfn)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* The new domain's shared-info frame. */
|
||||
shared_info_t *shared_info;
|
||||
|
||||
/* Read shared info. */
|
||||
shared_info = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
shared_info_frame);
|
||||
if (shared_info == NULL) {
|
||||
ERROR("cannot map page");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_exact(io_fd, shared_info, PAGE_SIZE)) {
|
||||
ERROR("Error when reading shared_info page");
|
||||
munmap(shared_info, PAGE_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear any pending events and the selector */
|
||||
memset(&(shared_info->evtchn_pending[0]), 0,
|
||||
sizeof (shared_info->evtchn_pending));
|
||||
for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++)
|
||||
shared_info->vcpu_info[i].evtchn_pending_sel = 0;
|
||||
|
||||
if (start_info_pfn != NULL)
|
||||
*start_info_pfn = shared_info->arch.start_info_pfn;
|
||||
|
||||
munmap (shared_info, PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_recv_vcpumap(xc_interface *xch,
|
||||
const xc_dominfo_t *info, int io_fd, uint64_t **vcpumapp)
|
||||
{
|
||||
uint64_t max_virt_cpus;
|
||||
unsigned long vcpumap_size;
|
||||
uint64_t *vcpumap = NULL;
|
||||
|
||||
*vcpumapp = NULL;
|
||||
|
||||
if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {
|
||||
ERROR("error reading max_virt_cpus");
|
||||
return -1;
|
||||
}
|
||||
if (max_virt_cpus < info->max_vcpu_id) {
|
||||
ERROR("too large max_virt_cpus %i < %i\n",
|
||||
max_virt_cpus, info->max_vcpu_id);
|
||||
return -1;
|
||||
}
|
||||
vcpumap_size = bitmap_size(max_virt_cpus);
|
||||
rc = bitmap_alloc(&vcpumap, max_virt_cpus);
|
||||
if (rc < 0) {
|
||||
ERROR("memory alloc for vcpumap");
|
||||
return rc;
|
||||
}
|
||||
if (read_exact(io_fd, vcpumap, vcpumap_size)) {
|
||||
ERROR("read vcpumap");
|
||||
free(vcpumap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*vcpumapp = vcpumap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_pv_recv_vcpu_context(xc_interface *xch, int io_fd, int32_t dom,
|
||||
uint32_t vcpu)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
/* A copy of the CPU context of the guest. */
|
||||
vcpu_guest_context_any_t ctxt_any;
|
||||
vcpu_guest_context_t *ctxt = &ctxt_any.c;
|
||||
|
||||
if (xc_ia64_recv_vcpu_context(xch, io_fd, dom, vcpu, &ctxt_any))
|
||||
goto out;
|
||||
|
||||
/* Then get privreg page. */
|
||||
if (read_page(xch, io_fd, dom, ctxt->privregs_pfn) < 0) {
|
||||
ERROR("Could not read vcpu privregs");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_pv_recv_shared_info(xc_interface *xch, int io_fd, int32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
unsigned long gmfn;
|
||||
|
||||
/* A temporary mapping of the guest's start_info page. */
|
||||
start_info_t *start_info;
|
||||
|
||||
/* Read shared info. */
|
||||
if (xc_ia64_recv_shared_info(xch, io_fd, dom,
|
||||
shared_info_frame, &gmfn))
|
||||
return -1;
|
||||
|
||||
/* Uncanonicalise the suspend-record frame number and poke resume rec. */
|
||||
if (populate_page_if_necessary(xch, dom, gmfn, p2m_table)) {
|
||||
ERROR("cannot populate page 0x%lx", gmfn);
|
||||
return -1;
|
||||
}
|
||||
start_info = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, gmfn);
|
||||
if (start_info == NULL) {
|
||||
ERROR("cannot map start_info page");
|
||||
return -1;
|
||||
}
|
||||
start_info->nr_pages = p2m_size;
|
||||
start_info->shared_info = shared_info_frame << PAGE_SHIFT;
|
||||
start_info->flags = 0;
|
||||
*store_mfn = start_info->store_mfn;
|
||||
start_info->store_evtchn = store_evtchn;
|
||||
*console_mfn = start_info->console.domU.mfn;
|
||||
start_info->console.domU.evtchn = console_evtchn;
|
||||
munmap(start_info, PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_pv_recv_context_ver_one_or_two(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* vcpu 0 context */
|
||||
rc = xc_ia64_pv_recv_vcpu_context(xch, io_fd, dom, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
/* shared_info */
|
||||
rc = xc_ia64_pv_recv_shared_info(xch, io_fd, dom, shared_info_frame,
|
||||
p2m_table, store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_pv_recv_context_ver_three(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
int rc = -1;
|
||||
xc_dominfo_t info;
|
||||
unsigned int i;
|
||||
|
||||
/* vcpu map */
|
||||
uint64_t *vcpumap = NULL;
|
||||
|
||||
if (xc_domain_getinfo(xch, dom, 1, &info) != 1) {
|
||||
ERROR("Could not get domain info");
|
||||
return -1;
|
||||
}
|
||||
rc = xc_ia64_recv_vcpumap(xch, &info, io_fd, &vcpumap);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
/* vcpu context */
|
||||
for (i = 0; i <= info.max_vcpu_id; i++) {
|
||||
if (!test_bit(i, vcpumap))
|
||||
continue;
|
||||
|
||||
rc = xc_ia64_pv_recv_vcpu_context(xch, io_fd, dom, i);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* shared_info */
|
||||
rc = xc_ia64_pv_recv_shared_info(xch, io_fd, dom, shared_info_frame,
|
||||
p2m_table, store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
out:
|
||||
if (vcpumap != NULL)
|
||||
free(vcpumap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_pv_recv_context(unsigned long format_version,
|
||||
xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
int rc;
|
||||
switch (format_version) {
|
||||
case XC_IA64_SR_FORMAT_VER_ONE:
|
||||
case XC_IA64_SR_FORMAT_VER_TWO:
|
||||
rc = xc_ia64_pv_recv_context_ver_one_or_two(xch, io_fd, dom,
|
||||
shared_info_frame,
|
||||
p2m_table, store_evtchn,
|
||||
store_mfn, console_evtchn,
|
||||
console_mfn);
|
||||
break;
|
||||
case XC_IA64_SR_FORMAT_VER_THREE:
|
||||
rc = xc_ia64_pv_recv_context_ver_three(xch, io_fd, dom,
|
||||
shared_info_frame,
|
||||
p2m_table, store_evtchn,
|
||||
store_mfn, console_evtchn,
|
||||
console_mfn);
|
||||
break;
|
||||
default:
|
||||
ERROR("Unsupported format version");
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_hvm_recv_context(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned long shared_info_frame,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
unsigned int store_evtchn, unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
int rc = -1;
|
||||
xc_dominfo_t info;
|
||||
unsigned int i;
|
||||
|
||||
/* cpumap */
|
||||
uint64_t *vcpumap = NULL;
|
||||
|
||||
/* HVM: magic frames for ioreqs and xenstore comms */
|
||||
const int hvm_params[] = {
|
||||
HVM_PARAM_STORE_PFN,
|
||||
HVM_PARAM_IOREQ_PFN,
|
||||
HVM_PARAM_BUFIOREQ_PFN,
|
||||
HVM_PARAM_BUFPIOREQ_PFN,
|
||||
};
|
||||
const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]);
|
||||
/* ioreq_pfn, bufioreq_pfn, store_pfn */
|
||||
uint64_t magic_pfns[NR_PARAMS];
|
||||
|
||||
/* HVM: a buffer for holding HVM contxt */
|
||||
uint64_t rec_size = 0;
|
||||
uint8_t *hvm_buf = NULL;
|
||||
|
||||
/* Read shared info. */
|
||||
if (xc_ia64_recv_shared_info(xch, io_fd, dom, shared_info_frame,
|
||||
NULL))
|
||||
goto out;
|
||||
|
||||
/* vcpu map */
|
||||
if (xc_domain_getinfo(xch, dom, 1, &info) != 1) {
|
||||
ERROR("Could not get domain info");
|
||||
goto out;
|
||||
}
|
||||
if (xc_ia64_recv_vcpumap(xch, &info, io_fd, &vcpumap))
|
||||
goto out;
|
||||
|
||||
/* vcpu context */
|
||||
for (i = 0; i <= info.max_vcpu_id; i++) {
|
||||
/* A copy of the CPU context of the guest. */
|
||||
vcpu_guest_context_any_t ctxt_any;
|
||||
|
||||
if (!test_bit(i, vcpumap))
|
||||
continue;
|
||||
|
||||
if (xc_ia64_recv_vcpu_context(xch, io_fd, dom, i, &ctxt_any))
|
||||
goto out;
|
||||
|
||||
/* system context of vcpu is recieved as hvm context. */
|
||||
}
|
||||
|
||||
/* Set HVM-specific parameters */
|
||||
if (read_exact(io_fd, magic_pfns, sizeof(magic_pfns))) {
|
||||
ERROR("error reading magic page addresses");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* These comms pages need to be zeroed at the start of day */
|
||||
for (i = 0; i < NR_PARAMS; i++) {
|
||||
rc = xc_clear_domain_page(xch, dom, magic_pfns[i]);
|
||||
if (rc != 0) {
|
||||
ERROR("error zeroing magic pages: %i", rc);
|
||||
goto out;
|
||||
}
|
||||
rc = xc_set_hvm_param(xch, dom, hvm_params[i], magic_pfns[i]);
|
||||
if (rc != 0) {
|
||||
ERROR("error setting HVM params: %i", rc);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
rc = xc_set_hvm_param(xch, dom,
|
||||
HVM_PARAM_STORE_EVTCHN, store_evtchn);
|
||||
if (rc != 0) {
|
||||
ERROR("error setting HVM params: %i", rc);
|
||||
goto out;
|
||||
}
|
||||
rc = -1;
|
||||
*store_mfn = magic_pfns[0];
|
||||
|
||||
/* Read HVM context */
|
||||
if (read_exact(io_fd, &rec_size, sizeof(rec_size))) {
|
||||
ERROR("error read hvm context size!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
hvm_buf = malloc(rec_size);
|
||||
if (hvm_buf == NULL) {
|
||||
ERROR("memory alloc for hvm context buffer failed");
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_exact(io_fd, hvm_buf, rec_size)) {
|
||||
ERROR("error loading the HVM context");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = xc_domain_hvm_setcontext(xch, dom, hvm_buf, rec_size);
|
||||
if (rc != 0) {
|
||||
ERROR("error setting the HVM context");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (vcpumap != NULL)
|
||||
free(vcpumap);
|
||||
if (hvm_buf != NULL)
|
||||
free(hvm_buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* hvm domain requires IO pages allocated when XEN_DOMCTL_arch_setup
|
||||
*/
|
||||
static int
|
||||
xc_ia64_hvm_domain_setup(xc_interface *xch, uint32_t dom)
|
||||
{
|
||||
int rc;
|
||||
xen_pfn_t pfn_list[] = {
|
||||
IO_PAGE_START >> PAGE_SHIFT,
|
||||
BUFFER_IO_PAGE_START >> PAGE_SHIFT,
|
||||
BUFFER_PIO_PAGE_START >> PAGE_SHIFT,
|
||||
};
|
||||
unsigned long nr_pages = sizeof(pfn_list) / sizeof(pfn_list[0]);
|
||||
|
||||
rc = xc_domain_populate_physmap_exact(xch, dom, nr_pages,
|
||||
0, 0, &pfn_list[0]);
|
||||
if (rc != 0)
|
||||
PERROR("Could not allocate IO page or buffer io page.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
unsigned int store_evtchn, unsigned long *store_mfn,
|
||||
unsigned int console_evtchn, unsigned long *console_mfn,
|
||||
unsigned int hvm, unsigned int pae, int superpages,
|
||||
int no_incr_generationid,
|
||||
unsigned long *vm_generationid_addr)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
int rc = 1;
|
||||
unsigned long ver;
|
||||
|
||||
/* The new domain's shared-info frame number. */
|
||||
unsigned long shared_info_frame;
|
||||
|
||||
struct xen_ia64_p2m_table p2m_table;
|
||||
xc_ia64_p2m_init(&p2m_table);
|
||||
|
||||
/* For info only */
|
||||
nr_pfns = 0;
|
||||
|
||||
if ( read_exact(io_fd, &p2m_size, sizeof(unsigned long)) )
|
||||
{
|
||||
ERROR("read: p2m_size");
|
||||
goto out;
|
||||
}
|
||||
DPRINTF("xc_linux_restore start: p2m_size = %lx\n", p2m_size);
|
||||
|
||||
if (read_exact(io_fd, &ver, sizeof(unsigned long))) {
|
||||
ERROR("Error when reading version");
|
||||
goto out;
|
||||
}
|
||||
if (ver != XC_IA64_SR_FORMAT_VER_ONE &&
|
||||
ver != XC_IA64_SR_FORMAT_VER_TWO &&
|
||||
ver != XC_IA64_SR_FORMAT_VER_THREE) {
|
||||
ERROR("version of save doesn't match");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_exact(io_fd, &domctl.u.arch_setup, sizeof(domctl.u.arch_setup))) {
|
||||
ERROR("read: domain setup");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hvm && xc_ia64_hvm_domain_setup(xch, dom) != 0)
|
||||
goto out;
|
||||
|
||||
/* Build firmware (will be overwritten). */
|
||||
domctl.domain = (domid_t)dom;
|
||||
domctl.u.arch_setup.flags &= ~XEN_DOMAINSETUP_query;
|
||||
domctl.u.arch_setup.bp = 0; /* indicate domain restore */
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_arch_setup;
|
||||
if (xc_domctl(xch, &domctl))
|
||||
goto out;
|
||||
|
||||
/* Get the domain's shared-info frame. */
|
||||
domctl.cmd = XEN_DOMCTL_getdomaininfo;
|
||||
domctl.domain = (domid_t)dom;
|
||||
if (xc_domctl(xch, &domctl) < 0) {
|
||||
ERROR("Could not get information on new domain");
|
||||
goto out;
|
||||
}
|
||||
shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
|
||||
|
||||
if (ver == XC_IA64_SR_FORMAT_VER_THREE ||
|
||||
ver == XC_IA64_SR_FORMAT_VER_TWO) {
|
||||
unsigned int memmap_info_num_pages;
|
||||
unsigned long memmap_size;
|
||||
xen_ia64_memmap_info_t *memmap_info;
|
||||
|
||||
if (read_exact(io_fd, &memmap_info_num_pages,
|
||||
sizeof(memmap_info_num_pages))) {
|
||||
ERROR("read: memmap_info_num_pages");
|
||||
goto out;
|
||||
}
|
||||
memmap_size = memmap_info_num_pages * PAGE_SIZE;
|
||||
memmap_info = malloc(memmap_size);
|
||||
if (memmap_info == NULL) {
|
||||
ERROR("Could not allocate memory for memmap_info");
|
||||
goto out;
|
||||
}
|
||||
if (read_exact(io_fd, memmap_info, memmap_size)) {
|
||||
ERROR("read: memmap_info");
|
||||
goto out;
|
||||
}
|
||||
if (xc_ia64_p2m_map(&p2m_table, xch,
|
||||
dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) {
|
||||
ERROR("p2m mapping");
|
||||
goto out;
|
||||
}
|
||||
free(memmap_info);
|
||||
} else if (ver == XC_IA64_SR_FORMAT_VER_ONE) {
|
||||
xen_ia64_memmap_info_t *memmap_info;
|
||||
efi_memory_desc_t *memdesc;
|
||||
uint64_t buffer[(sizeof(*memmap_info) + sizeof(*memdesc) +
|
||||
sizeof(uint64_t) - 1) / sizeof(uint64_t)];
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memmap_info = (xen_ia64_memmap_info_t *)buffer;
|
||||
memdesc = (efi_memory_desc_t*)&memmap_info->memdesc[0];
|
||||
memmap_info->efi_memmap_size = sizeof(*memdesc);
|
||||
memmap_info->efi_memdesc_size = sizeof(*memdesc);
|
||||
memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
|
||||
|
||||
memdesc->type = EFI_MEMORY_DESCRIPTOR_VERSION;
|
||||
memdesc->phys_addr = 0;
|
||||
memdesc->virt_addr = 0;
|
||||
memdesc->num_pages = nr_pfns << (PAGE_SHIFT - EFI_PAGE_SHIFT);
|
||||
memdesc->attribute = EFI_MEMORY_WB;
|
||||
|
||||
if (xc_ia64_p2m_map(&p2m_table, xch,
|
||||
dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) {
|
||||
ERROR("p2m mapping");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ERROR("unknown version");
|
||||
goto out;
|
||||
}
|
||||
|
||||
DPRINTF("Reloading memory pages: 0%%\n");
|
||||
|
||||
while (1) {
|
||||
unsigned long gmfn;
|
||||
if (read_exact(io_fd, &gmfn, sizeof(unsigned long))) {
|
||||
ERROR("Error when reading batch size");
|
||||
goto out;
|
||||
}
|
||||
if (gmfn == INVALID_MFN)
|
||||
break;
|
||||
|
||||
if (populate_page_if_necessary(xch, dom, gmfn, &p2m_table) < 0) {
|
||||
ERROR("can not populate page 0x%lx", gmfn);
|
||||
goto out;
|
||||
}
|
||||
if (read_page(xch, io_fd, dom, gmfn) < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
DPRINTF("Received all pages\n");
|
||||
|
||||
if (xc_ia64_recv_unallocated_list(xch, io_fd, dom, &p2m_table))
|
||||
goto out;
|
||||
|
||||
if (!hvm)
|
||||
rc = xc_ia64_pv_recv_context(ver,
|
||||
xch, io_fd, dom, shared_info_frame,
|
||||
&p2m_table, store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
else
|
||||
rc = xc_ia64_hvm_recv_context(xch, io_fd, dom, shared_info_frame,
|
||||
&p2m_table, store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Safety checking of saved context:
|
||||
* 1. user_regs is fine, as Xen checks that on context switch.
|
||||
* 2. fpu_ctxt is fine, as it can't hurt Xen.
|
||||
* 3. trap_ctxt needs the code selectors checked.
|
||||
* 4. ldt base must be page-aligned, no more than 8192 ents, ...
|
||||
* 5. gdt already done, and further checking is done by Xen.
|
||||
* 6. check that kernel_ss is safe.
|
||||
* 7. pt_base is already done.
|
||||
* 8. debugregs are checked by Xen.
|
||||
* 9. callback code selectors need checking.
|
||||
*/
|
||||
DPRINTF("Domain ready to be built.\n");
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
xc_ia64_p2m_unmap(&p2m_table);
|
||||
|
||||
if ((rc != 0) && (dom != 0))
|
||||
xc_domain_destroy(xch, dom);
|
||||
|
||||
DPRINTF("Restore exit with rc=%d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,801 +0,0 @@
|
||||
/******************************************************************************
|
||||
* xc_ia64_linux_save.c
|
||||
*
|
||||
* Save the state of a running Linux session.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2003, K A Fraser.
|
||||
* Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net>
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp>
|
||||
* Use foreign p2m exposure.
|
||||
* VTi domain support.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_bitops.h"
|
||||
#include "xc_ia64.h"
|
||||
#include "xc_ia64_save_restore.h"
|
||||
#include "xc_efi.h"
|
||||
#include "xen/hvm/params.h"
|
||||
|
||||
/*
|
||||
** Default values for important tuning parameters. Can override by passing
|
||||
** non-zero replacement values to xc_linux_save().
|
||||
**
|
||||
** XXX SMH: should consider if want to be able to override MAX_MBIT_RATE too.
|
||||
**
|
||||
*/
|
||||
#define DEF_MAX_ITERS (4 - 1) /* limit us to 4 times round loop */
|
||||
#define DEF_MAX_FACTOR 3 /* never send more than 3x nr_pfns */
|
||||
|
||||
/*
|
||||
** During (live) save/migrate, we maintain a number of bitmaps to track
|
||||
** which pages we have to send, and to skip.
|
||||
*/
|
||||
|
||||
static int
|
||||
suspend_and_state(int (*suspend)(void*), void* data,
|
||||
xc_interface *xch, int io_fd,
|
||||
int dom, xc_dominfo_t *info)
|
||||
{
|
||||
if ( !(*suspend)(data) ) {
|
||||
ERROR("Suspend request failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( (xc_domain_getinfo(xch, dom, 1, info) != 1) ||
|
||||
!info->shutdown || (info->shutdown_reason != SHUTDOWN_suspend) ) {
|
||||
ERROR("Could not get domain info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
md_is_not_ram(const efi_memory_desc_t *md)
|
||||
{
|
||||
return ((md->type != EFI_CONVENTIONAL_MEMORY) ||
|
||||
(md->attribute != EFI_MEMORY_WB) ||
|
||||
(md->num_pages == 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send through a list of all the PFNs that were not in map at the close.
|
||||
* We send pages which was allocated. However balloon driver may
|
||||
* decreased after sending page. So we have to check the freed
|
||||
* page after pausing the domain.
|
||||
*/
|
||||
static int
|
||||
xc_ia64_send_unallocated_list(xc_interface *xch, int io_fd,
|
||||
struct xen_ia64_p2m_table *p2m_table,
|
||||
xen_ia64_memmap_info_t *memmap_info,
|
||||
void *memmap_desc_start, void *memmap_desc_end)
|
||||
{
|
||||
void *p;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
unsigned long N;
|
||||
unsigned long pfntab[1024];
|
||||
unsigned int j;
|
||||
|
||||
j = 0;
|
||||
for (p = memmap_desc_start;
|
||||
p < memmap_desc_end;
|
||||
p += memmap_info->efi_memdesc_size) {
|
||||
md = p;
|
||||
|
||||
if (md_is_not_ram(md))
|
||||
continue;
|
||||
|
||||
for (N = md->phys_addr >> PAGE_SHIFT;
|
||||
N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>
|
||||
PAGE_SHIFT;
|
||||
N++) {
|
||||
if (!xc_ia64_p2m_allocated(p2m_table, N))
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (write_exact(io_fd, &j, sizeof(unsigned int))) {
|
||||
ERROR("Error when writing to state file (6a)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (p = memmap_desc_start;
|
||||
p < memmap_desc_end;
|
||||
p += memmap_info->efi_memdesc_size) {
|
||||
md = p;
|
||||
|
||||
if (md_is_not_ram(md))
|
||||
continue;
|
||||
|
||||
for (N = md->phys_addr >> PAGE_SHIFT;
|
||||
N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>
|
||||
PAGE_SHIFT;
|
||||
N++) {
|
||||
if (!xc_ia64_p2m_allocated(p2m_table, N))
|
||||
pfntab[j++] = N;
|
||||
if (j == sizeof(pfntab)/sizeof(pfntab[0])) {
|
||||
if (write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) {
|
||||
ERROR("Error when writing to state file (6b)");
|
||||
return -1;
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j > 0) {
|
||||
if (write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) {
|
||||
ERROR("Error when writing to state file (6c)");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_send_vcpu_context(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any)
|
||||
{
|
||||
vcpu_guest_context_t *ctxt = &ctxt_any->c;
|
||||
if (xc_vcpu_getcontext(xch, dom, vcpu, ctxt_any)) {
|
||||
ERROR("Could not get vcpu context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, ctxt, sizeof(*ctxt))) {
|
||||
ERROR("Error when writing to state file (1)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_send_shared_info(xc_interface *xch, int io_fd, shared_info_t *live_shinfo)
|
||||
{
|
||||
if (write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
|
||||
ERROR("Error when writing to state file (1)");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_send_vcpumap(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
const xc_dominfo_t *info, uint64_t max_virt_cpus,
|
||||
uint64_t **vcpumapp)
|
||||
{
|
||||
int rc = -1;
|
||||
unsigned int i;
|
||||
unsigned long vcpumap_size;
|
||||
uint64_t *vcpumap = NULL;
|
||||
|
||||
vcpumap_size = bitmap_size(max_virt_cpus);
|
||||
vcpumap = bitmap_alloc(max_virt_cpus);
|
||||
if (!vcpumap) {
|
||||
ERROR("memory alloc for vcpumap");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i <= info->max_vcpu_id; i++) {
|
||||
xc_vcpuinfo_t vinfo;
|
||||
if ((xc_vcpu_getinfo(xch, dom, i, &vinfo) == 0) && vinfo.online)
|
||||
set_bit(i, vcpumap);
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {
|
||||
ERROR("write max_virt_cpus");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, vcpumap, vcpumap_size)) {
|
||||
ERROR("write vcpumap");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (rc != 0 && vcpumap != NULL) {
|
||||
free(vcpumap);
|
||||
vcpumap = NULL;
|
||||
}
|
||||
*vcpumapp = vcpumap;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xc_ia64_pv_send_context(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
const xc_dominfo_t *info, shared_info_t *live_shinfo)
|
||||
{
|
||||
int rc = -1;
|
||||
unsigned int i;
|
||||
|
||||
/* vcpu map */
|
||||
uint64_t *vcpumap = NULL;
|
||||
if (xc_ia64_send_vcpumap(xch, io_fd, dom, info, XEN_LEGACY_MAX_VCPUS,
|
||||
&vcpumap))
|
||||
goto out;
|
||||
|
||||
/* vcpu context */
|
||||
for (i = 0; i <= info->max_vcpu_id; i++) {
|
||||
/* A copy of the CPU context of the guest. */
|
||||
vcpu_guest_context_any_t ctxt_any;
|
||||
vcpu_guest_context_t *ctxt = &ctxt_any.c;
|
||||
|
||||
char *mem;
|
||||
|
||||
if (!test_bit(i, vcpumap))
|
||||
continue;
|
||||
|
||||
if (xc_ia64_send_vcpu_context(xch, io_fd, dom, i, &ctxt_any))
|
||||
goto out;
|
||||
|
||||
mem = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE, ctxt->privregs_pfn);
|
||||
if (mem == NULL) {
|
||||
ERROR("cannot map privreg page");
|
||||
goto out;
|
||||
}
|
||||
if (write_exact(io_fd, mem, PAGE_SIZE)) {
|
||||
ERROR("Error when writing privreg to state file (5)");
|
||||
munmap(mem, PAGE_SIZE);
|
||||
goto out;
|
||||
}
|
||||
munmap(mem, PAGE_SIZE);
|
||||
}
|
||||
|
||||
rc = xc_ia64_send_shared_info(xch, io_fd, live_shinfo);
|
||||
|
||||
out:
|
||||
if (vcpumap != NULL)
|
||||
free(vcpumap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
xc_ia64_hvm_send_context(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
const xc_dominfo_t *info, shared_info_t *live_shinfo)
|
||||
{
|
||||
int rc = -1;
|
||||
unsigned int i;
|
||||
|
||||
/* vcpu map */
|
||||
uint64_t *vcpumap = NULL;
|
||||
|
||||
/* HVM: magic frames for ioreqs and xenstore comms */
|
||||
const int hvm_params[] = {
|
||||
HVM_PARAM_STORE_PFN,
|
||||
HVM_PARAM_IOREQ_PFN,
|
||||
HVM_PARAM_BUFIOREQ_PFN,
|
||||
HVM_PARAM_BUFPIOREQ_PFN,
|
||||
};
|
||||
const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]);
|
||||
/* ioreq_pfn, bufioreq_pfn, store_pfn */
|
||||
uint64_t magic_pfns[NR_PARAMS];
|
||||
|
||||
/* HVM: a buffer for holding HVM contxt */
|
||||
uint64_t rec_size;
|
||||
uint64_t hvm_buf_size = 0;
|
||||
uint8_t *hvm_buf = NULL;
|
||||
|
||||
if (xc_ia64_send_shared_info(xch, io_fd, live_shinfo))
|
||||
return -1;
|
||||
|
||||
/* vcpu map */
|
||||
if (xc_ia64_send_vcpumap(xch, io_fd, dom, info, XEN_LEGACY_MAX_VCPUS,
|
||||
&vcpumap))
|
||||
goto out;
|
||||
|
||||
/* vcpu context */
|
||||
for (i = 0; i <= info->max_vcpu_id; i++) {
|
||||
/* A copy of the CPU context of the guest. */
|
||||
vcpu_guest_context_any_t ctxt_any;
|
||||
|
||||
if (!test_bit(i, vcpumap))
|
||||
continue;
|
||||
|
||||
if (xc_ia64_send_vcpu_context(xch, io_fd, dom, i, &ctxt_any))
|
||||
goto out;
|
||||
|
||||
/* system context of vcpu is sent as hvm context. */
|
||||
}
|
||||
|
||||
/* Save magic-page locations. */
|
||||
memset(magic_pfns, 0, sizeof(magic_pfns));
|
||||
for (i = 0; i < NR_PARAMS; i++) {
|
||||
if (xc_get_hvm_param(xch, dom, hvm_params[i], &magic_pfns[i])) {
|
||||
PERROR("Error when xc_get_hvm_param");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, magic_pfns, sizeof(magic_pfns))) {
|
||||
ERROR("Error when writing to state file (7)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Need another buffer for HVM context */
|
||||
hvm_buf_size = xc_domain_hvm_getcontext(xch, dom, 0, 0);
|
||||
if (hvm_buf_size == -1) {
|
||||
ERROR("Couldn't get HVM context size from Xen");
|
||||
goto out;
|
||||
}
|
||||
|
||||
hvm_buf = malloc(hvm_buf_size);
|
||||
if (!hvm_buf) {
|
||||
ERROR("Couldn't allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get HVM context from Xen and save it too */
|
||||
rec_size = xc_domain_hvm_getcontext(xch, dom, hvm_buf, hvm_buf_size);
|
||||
if (rec_size == -1) {
|
||||
ERROR("HVM:Could not get hvm buffer");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, &rec_size, sizeof(rec_size))) {
|
||||
ERROR("error write hvm buffer size");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, hvm_buf, rec_size)) {
|
||||
ERROR("write HVM info failed!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
if (hvm_buf != NULL)
|
||||
free(hvm_buf);
|
||||
if (vcpumap != NULL)
|
||||
free(vcpumap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
uint32_t max_factor, uint32_t flags,
|
||||
struct save_callbacks* callbacks, int hvm,
|
||||
unsigned long vm_generationid_addr)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
xc_dominfo_t info;
|
||||
|
||||
int rc = 1;
|
||||
|
||||
int debug = (flags & XCFLAGS_DEBUG);
|
||||
int live = (flags & XCFLAGS_LIVE);
|
||||
|
||||
/* The new domain's shared-info frame number. */
|
||||
unsigned long shared_info_frame;
|
||||
|
||||
/* Live mapping of shared info structure */
|
||||
shared_info_t *live_shinfo = NULL;
|
||||
|
||||
/* Iteration number. */
|
||||
int iter;
|
||||
|
||||
/* Number of pages sent in the last iteration (live only). */
|
||||
unsigned int sent_last_iter;
|
||||
|
||||
/* Number of pages sent (live only). */
|
||||
unsigned int total_sent = 0;
|
||||
|
||||
/* total number of pages used by the current guest */
|
||||
unsigned long p2m_size;
|
||||
|
||||
/* Size of the shadow bitmap (live only). */
|
||||
unsigned int bitmap_size = 0;
|
||||
|
||||
/* True if last iteration. */
|
||||
int last_iter = 0;
|
||||
|
||||
/* Bitmap of pages to be sent. */
|
||||
DECLARE_HYPERCALL_BUFFER(unsigned long, to_send);
|
||||
/* Bitmap of pages not to be sent (because dirtied). */
|
||||
DECLARE_HYPERCALL_BUFFER(unsigned long, to_skip);
|
||||
|
||||
char *mem;
|
||||
|
||||
/* for foreign p2m exposure */
|
||||
unsigned long memmap_info_num_pages;
|
||||
/* Unsigned int was used before. To keep file format compatibility. */
|
||||
unsigned int memmap_info_num_pages_to_send;
|
||||
unsigned long memmap_size = 0;
|
||||
xen_ia64_memmap_info_t *memmap_info = NULL;
|
||||
void *memmap_desc_start;
|
||||
void *memmap_desc_end;
|
||||
void *p;
|
||||
efi_memory_desc_t *md;
|
||||
struct xen_ia64_p2m_table p2m_table;
|
||||
|
||||
if ( hvm && !callbacks->switch_qemu_logdirty )
|
||||
{
|
||||
ERROR("No switch_qemu_logdirty callback given.");
|
||||
errno = EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
xc_ia64_p2m_init(&p2m_table);
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "xc_linux_save (ia64): started dom=%d\n", dom);
|
||||
|
||||
/* If no explicit control parameters given, use defaults */
|
||||
if (!max_iters)
|
||||
max_iters = DEF_MAX_ITERS;
|
||||
if (!max_factor)
|
||||
max_factor = DEF_MAX_FACTOR;
|
||||
|
||||
//initialize_mbit_rate();
|
||||
|
||||
if (xc_domain_getinfo(xch, dom, 1, &info) != 1) {
|
||||
ERROR("Could not get domain info");
|
||||
return 1;
|
||||
}
|
||||
|
||||
shared_info_frame = info.shared_info_frame;
|
||||
|
||||
#if 0
|
||||
/* cheesy sanity check */
|
||||
if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {
|
||||
ERROR("Invalid state record -- pfn count out of range: %lu",
|
||||
(info.max_memkb >> (PAGE_SHIFT - 10)));
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map the shared info frame */
|
||||
live_shinfo = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ, shared_info_frame);
|
||||
if (!live_shinfo) {
|
||||
ERROR("Couldn't map live_shinfo");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p2m_size = xc_domain_maximum_gpfn(xch, dom) + 1;
|
||||
|
||||
/* This is expected by xm restore. */
|
||||
if (write_exact(io_fd, &p2m_size, sizeof(unsigned long))) {
|
||||
ERROR("write: p2m_size");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* xc_linux_restore starts to read here. */
|
||||
/* Write a version number. This can avoid searching for a stupid bug
|
||||
if the format change.
|
||||
The version is hard-coded, don't forget to change the restore code
|
||||
too! */
|
||||
{
|
||||
unsigned long version = XC_IA64_SR_FORMAT_VER_CURRENT;
|
||||
|
||||
if (write_exact(io_fd, &version, sizeof(unsigned long))) {
|
||||
ERROR("write: version");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_arch_setup;
|
||||
domctl.domain = (domid_t)dom;
|
||||
domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;
|
||||
if (xc_domctl(xch, &domctl) < 0) {
|
||||
ERROR("Could not get domain setup");
|
||||
goto out;
|
||||
}
|
||||
if (write_exact(io_fd, &domctl.u.arch_setup,
|
||||
sizeof(domctl.u.arch_setup))) {
|
||||
ERROR("write: domain setup");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Domain is still running at this point */
|
||||
if (live) {
|
||||
|
||||
if (xc_shadow_control(xch, dom,
|
||||
XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
|
||||
NULL, 0, NULL, 0, NULL ) < 0) {
|
||||
ERROR("Couldn't enable shadow mode");
|
||||
goto out;
|
||||
}
|
||||
|
||||
last_iter = 0;
|
||||
|
||||
bitmap_size = ((p2m_size + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
|
||||
to_send = xc_hypercall_buffer_alloc(xch, to_send, bitmap_size);
|
||||
to_skip = xc_hypercall_buffer_alloc(xch, to_skip, bitmap_size);
|
||||
|
||||
if (!to_send || !to_skip) {
|
||||
ERROR("Couldn't allocate bitmap array");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Initially all the pages must be sent. */
|
||||
memset(to_send, 0xff, bitmap_size);
|
||||
|
||||
/* Enable qemu-dm logging dirty pages to xen */
|
||||
if (hvm && callbacks->switch_qemu_logdirty(dom, 1, callbacks->data)) {
|
||||
ERROR("Unable to enable qemu log-dirty mode");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* This is a non-live suspend. Issue the call back to get the
|
||||
domain suspended */
|
||||
|
||||
last_iter = 1;
|
||||
|
||||
if (suspend_and_state(callbacks->suspend, callbacks->data, xch,
|
||||
io_fd, dom, &info)) {
|
||||
ERROR("Domain appears not to have suspended");
|
||||
goto out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* copy before use in case someone updating them */
|
||||
if (xc_ia64_copy_memmap(xch, info.domid, live_shinfo,
|
||||
&memmap_info, &memmap_info_num_pages) != 0) {
|
||||
PERROR("Could not copy memmap");
|
||||
goto out;
|
||||
}
|
||||
memmap_size = memmap_info_num_pages << PAGE_SHIFT;
|
||||
|
||||
if (xc_ia64_p2m_map(&p2m_table, xch, dom, memmap_info, 0) < 0) {
|
||||
PERROR("xc_ia64_p2m_map");
|
||||
goto out;
|
||||
}
|
||||
memmap_info_num_pages_to_send = memmap_info_num_pages;
|
||||
if (write_exact(io_fd, &memmap_info_num_pages_to_send,
|
||||
sizeof(memmap_info_num_pages_to_send))) {
|
||||
PERROR("write: arch.memmap_info_num_pages");
|
||||
goto out;
|
||||
}
|
||||
if (write_exact(io_fd, memmap_info, memmap_size)) {
|
||||
PERROR("write: memmap_info");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sent_last_iter = p2m_size;
|
||||
|
||||
copypages:
|
||||
for (iter = 1; ; iter++) {
|
||||
unsigned int sent_this_iter, skip_this_iter;
|
||||
unsigned long N;
|
||||
|
||||
sent_this_iter = 0;
|
||||
skip_this_iter = 0;
|
||||
|
||||
/* Dirtied pages won't be saved.
|
||||
slightly wasteful to peek the whole array evey time,
|
||||
but this is fast enough for the moment. */
|
||||
if (!last_iter) {
|
||||
if (xc_shadow_control(xch, dom,
|
||||
XEN_DOMCTL_SHADOW_OP_PEEK,
|
||||
HYPERCALL_BUFFER(to_skip), p2m_size,
|
||||
NULL, 0, NULL) != p2m_size) {
|
||||
ERROR("Error peeking shadow bitmap");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start writing out the saved-domain record. */
|
||||
memmap_desc_start = &memmap_info->memdesc;
|
||||
memmap_desc_end = memmap_desc_start + memmap_info->efi_memmap_size;
|
||||
for (p = memmap_desc_start;
|
||||
p < memmap_desc_end;
|
||||
p += memmap_info->efi_memdesc_size) {
|
||||
md = p;
|
||||
if (md_is_not_ram(md))
|
||||
continue;
|
||||
|
||||
for (N = md->phys_addr >> PAGE_SHIFT;
|
||||
N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>
|
||||
PAGE_SHIFT;
|
||||
N++) {
|
||||
|
||||
if (!xc_ia64_p2m_allocated(&p2m_table, N))
|
||||
continue;
|
||||
|
||||
if (!last_iter) {
|
||||
if (test_bit(N, to_skip) && test_bit(N, to_send))
|
||||
skip_this_iter++;
|
||||
if (test_bit(N, to_skip) || !test_bit(N, to_send))
|
||||
continue;
|
||||
} else if (live) {
|
||||
if (!test_bit(N, to_send))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n",
|
||||
xc_ia64_p2m_mfn(&p2m_table, N),
|
||||
N, p2m_size);
|
||||
|
||||
mem = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE, N);
|
||||
if (mem == NULL) {
|
||||
/* The page may have move.
|
||||
It will be remarked dirty.
|
||||
FIXME: to be tracked. */
|
||||
fprintf(stderr, "cannot map mfn page %lx gpfn %lx: %s\n",
|
||||
xc_ia64_p2m_mfn(&p2m_table, N),
|
||||
N, xc_strerror(xch, errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (write_exact(io_fd, &N, sizeof(N))) {
|
||||
ERROR("write: p2m_size");
|
||||
munmap(mem, PAGE_SIZE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (write(io_fd, mem, PAGE_SIZE) != PAGE_SIZE) {
|
||||
ERROR("Error when writing to state file (5)");
|
||||
munmap(mem, PAGE_SIZE);
|
||||
goto out;
|
||||
}
|
||||
munmap(mem, PAGE_SIZE);
|
||||
sent_this_iter++;
|
||||
total_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_iter)
|
||||
break;
|
||||
|
||||
DPRINTF(" %d: sent %d, skipped %d\n",
|
||||
iter, sent_this_iter, skip_this_iter );
|
||||
|
||||
if (live) {
|
||||
if ( /* ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) || */
|
||||
(iter >= max_iters) || (sent_this_iter+skip_this_iter < 50) ||
|
||||
(total_sent > p2m_size*max_factor)) {
|
||||
DPRINTF("Start last iteration\n");
|
||||
last_iter = 1;
|
||||
|
||||
if (suspend_and_state(callbacks->suspend, callbacks->data,
|
||||
xch, io_fd, dom, &info)) {
|
||||
ERROR("Domain appears not to have suspended");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pages to be sent are pages which were dirty. */
|
||||
if (xc_shadow_control(xch, dom,
|
||||
XEN_DOMCTL_SHADOW_OP_CLEAN,
|
||||
HYPERCALL_BUFFER(to_send), p2m_size,
|
||||
NULL, 0, NULL ) != p2m_size) {
|
||||
ERROR("Error flushing shadow PT");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sent_last_iter = sent_this_iter;
|
||||
|
||||
//print_stats(xch, dom, sent_this_iter, &stats, 1);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "All memory is saved\n");
|
||||
|
||||
/* terminate */
|
||||
{
|
||||
unsigned long pfn = INVALID_MFN;
|
||||
if (write_exact(io_fd, &pfn, sizeof(pfn))) {
|
||||
ERROR("Error when writing to state file (6)");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (xc_ia64_send_unallocated_list(xch, io_fd, &p2m_table,
|
||||
memmap_info,
|
||||
memmap_desc_start, memmap_desc_end))
|
||||
goto out;
|
||||
|
||||
if (!hvm)
|
||||
rc = xc_ia64_pv_send_context(xch, io_fd,
|
||||
dom, &info, live_shinfo);
|
||||
else
|
||||
rc = xc_ia64_hvm_send_context(xch, io_fd,
|
||||
dom, &info, live_shinfo);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
/* Success! */
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if ( !rc && callbacks->postcopy )
|
||||
callbacks->postcopy(callbacks->data);
|
||||
|
||||
/* Flush last write and discard cache for file. */
|
||||
discard_file_cache(xch, io_fd, 1 /* flush */);
|
||||
|
||||
/* checkpoint_cb can spend arbitrarily long in between rounds */
|
||||
if (!rc && callbacks->checkpoint &&
|
||||
callbacks->checkpoint(callbacks->data) > 0)
|
||||
{
|
||||
/* reset stats timer */
|
||||
//print_stats(xch, dom, 0, &stats, 0);
|
||||
|
||||
rc = 1;
|
||||
/* last_iter = 1; */
|
||||
if ( suspend_and_state(callbacks->suspend, callbacks->data, xch,
|
||||
io_fd, dom, &info) )
|
||||
{
|
||||
ERROR("Domain appears not to have suspended");
|
||||
goto out;
|
||||
}
|
||||
DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
|
||||
//print_stats(xch, dom, 0, &stats, 1);
|
||||
|
||||
if ( xc_shadow_control(xch, dom,
|
||||
XEN_DOMCTL_SHADOW_OP_CLEAN, HYPERCALL_BUFFER(to_send),
|
||||
p2m_size, NULL, 0, NULL) != p2m_size )
|
||||
{
|
||||
ERROR("Error flushing shadow PT");
|
||||
}
|
||||
|
||||
goto copypages;
|
||||
}
|
||||
|
||||
if (live) {
|
||||
if (xc_shadow_control(xch, dom,
|
||||
XEN_DOMCTL_SHADOW_OP_OFF,
|
||||
NULL, 0, NULL, 0, NULL ) < 0) {
|
||||
DPRINTF("Warning - couldn't disable shadow mode");
|
||||
}
|
||||
if ( hvm &&
|
||||
callbacks->switch_qemu_logdirty(dom, 0, callbacks->data) ) {
|
||||
DPRINTF("Warning - couldn't disable qemu log-dirty mode");
|
||||
}
|
||||
}
|
||||
|
||||
xc_hypercall_buffer_free(xch, to_send);
|
||||
xc_hypercall_buffer_free(xch, to_skip);
|
||||
if (live_shinfo)
|
||||
munmap(live_shinfo, PAGE_SIZE);
|
||||
if (memmap_info)
|
||||
free(memmap_info);
|
||||
xc_ia64_p2m_unmap(&p2m_table);
|
||||
|
||||
fprintf(stderr,"Save exit rc=%d\n",rc);
|
||||
|
||||
return !!rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,47 +0,0 @@
|
||||
/******************************************************************************
|
||||
* xc_ia64_save_restore.h
|
||||
*
|
||||
* Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XC_IA64_SAVE_RESTORE_H
|
||||
#define XC_IA64_SR_H
|
||||
|
||||
/* introduced changeset 10692:306d7857928c of xen-ia64-unstable.ht */
|
||||
#define XC_IA64_SR_FORMAT_VER_ONE 1UL
|
||||
/* using foreign p2m exposure version */
|
||||
#define XC_IA64_SR_FORMAT_VER_TWO 2UL
|
||||
/* only pv change: send vcpumap and all vcpu context */
|
||||
#define XC_IA64_SR_FORMAT_VER_THREE 3UL
|
||||
#define XC_IA64_SR_FORMAT_VER_MAX 3UL
|
||||
|
||||
#define XC_IA64_SR_FORMAT_VER_CURRENT XC_IA64_SR_FORMAT_VER_THREE
|
||||
|
||||
|
||||
#endif /* XC_IA64_SAVE_RESTORE_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_efi.h"
|
||||
#include "xc_ia64.h"
|
||||
|
||||
/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
|
||||
* mysteriously declared in two places: /usr/include/asm/fpu.h and
|
||||
* /usr/include/bits/sigcontext.h. The former also defines FPSR_DEFAULT,
|
||||
* the latter doesn't but is included (indirectly) by xg_private.h */
|
||||
#define __ASSEMBLY__
|
||||
#include <asm/fpu.h>
|
||||
#undef __IA64_UL
|
||||
#define __IA64_UL(x) ((unsigned long)(x))
|
||||
#undef __ASSEMBLY__
|
||||
|
||||
unsigned long
|
||||
xc_ia64_fpsr_default(void)
|
||||
{
|
||||
return FPSR_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/* It is possible to get memmap_info and memmap by
|
||||
foreign domain page mapping. But it's racy. Use hypercall to avoid race. */
|
||||
static int
|
||||
xc_ia64_get_memmap(xc_interface *xch,
|
||||
uint32_t domid, char *buf, unsigned long bufsize)
|
||||
{
|
||||
privcmd_hypercall_t hypercall;
|
||||
DECLARE_HYPERCALL_BOUNCE(buf, bufsize, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
|
||||
int ret;
|
||||
|
||||
if ( xc_hypercall_bounce_pre(xch, pfn_buf) )
|
||||
{
|
||||
PERROR("xc_get_pfn_list: pfn_buf bounce failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
|
||||
hypercall.arg[0] = IA64_DOM0VP_get_memmap;
|
||||
hypercall.arg[1] = domid;
|
||||
hypercall.arg[2] = HYPERCALL_BUFFER_AS_ARG(buf);
|
||||
hypercall.arg[3] = bufsize;
|
||||
hypercall.arg[4] = 0;
|
||||
|
||||
ret = do_xen_hypercall(xch, &hypercall);
|
||||
xc_hypercall_bounce_post(xc, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
xc_ia64_copy_memmap(xc_interface *xch, uint32_t domid, shared_info_t *live_shinfo,
|
||||
xen_ia64_memmap_info_t **memmap_info_p,
|
||||
unsigned long *memmap_info_num_pages_p)
|
||||
{
|
||||
unsigned long gpfn_max_prev;
|
||||
unsigned long gpfn_max_post;
|
||||
|
||||
unsigned long num_pages;
|
||||
unsigned long num_pages_post;
|
||||
unsigned long memmap_size;
|
||||
xen_ia64_memmap_info_t *memmap_info;
|
||||
|
||||
int ret;
|
||||
|
||||
gpfn_max_prev = xc_domain_maximum_gpfn(xch, domid);
|
||||
if (gpfn_max_prev < 0)
|
||||
return -1;
|
||||
|
||||
again:
|
||||
num_pages = live_shinfo->arch.memmap_info_num_pages;
|
||||
if (num_pages == 0) {
|
||||
ERROR("num_pages 0x%x", num_pages);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memmap_size = num_pages << PAGE_SHIFT;
|
||||
memmap_info = malloc(memmap_size);
|
||||
if (memmap_info == NULL)
|
||||
return -1;
|
||||
ret = xc_ia64_get_memmap(xch,
|
||||
domid, (char*)memmap_info, memmap_size);
|
||||
if (ret != 0) {
|
||||
free(memmap_info);
|
||||
return -1;
|
||||
}
|
||||
xen_rmb();
|
||||
num_pages_post = live_shinfo->arch.memmap_info_num_pages;
|
||||
if (num_pages != num_pages_post) {
|
||||
free(memmap_info);
|
||||
num_pages = num_pages_post;
|
||||
goto again;
|
||||
}
|
||||
|
||||
gpfn_max_post = xc_domain_maximum_gpfn(xch, domid);
|
||||
if (gpfn_max_prev < 0) {
|
||||
free(memmap_info);
|
||||
return -1;
|
||||
}
|
||||
if (gpfn_max_post > gpfn_max_prev) {
|
||||
free(memmap_info);
|
||||
gpfn_max_prev = gpfn_max_post;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* reject unknown memmap */
|
||||
if (memmap_info->efi_memdesc_size != sizeof(efi_memory_desc_t) ||
|
||||
(memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size) == 0 ||
|
||||
memmap_info->efi_memmap_size >
|
||||
(num_pages << PAGE_SHIFT) - sizeof(memmap_info) ||
|
||||
memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION) {
|
||||
PERROR("unknown memmap header. defaulting to compat mode.");
|
||||
free(memmap_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*memmap_info_p = memmap_info;
|
||||
if (memmap_info_num_pages_p != NULL)
|
||||
*memmap_info_num_pages_p = num_pages;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
|
||||
* Should PTRS_PER_PTE be exported by arch-ia64.h?
|
||||
*/
|
||||
#define PTRS_PER_PTE (1UL << (PAGE_SHIFT - 3))
|
||||
|
||||
static void*
|
||||
xc_ia64_map_foreign_p2m(xc_interface *xch, uint32_t dom,
|
||||
struct xen_ia64_memmap_info *memmap_info,
|
||||
unsigned long flags, unsigned long *p2m_size_p)
|
||||
{
|
||||
DECLARE_HYPERCALL_BOUNCE(memmap_info, sizeof(*memmap_info) + memmap_info->efi_memmap_size, XC_HYPERCALL_BOUNCE_BUFFER_IN);
|
||||
unsigned long gpfn_max;
|
||||
unsigned long p2m_size;
|
||||
void *addr;
|
||||
privcmd_hypercall_t hypercall;
|
||||
int ret;
|
||||
int saved_errno;
|
||||
|
||||
gpfn_max = xc_domain_maximum_gpfn(xch, dom);
|
||||
if (gpfn_max < 0)
|
||||
return NULL;
|
||||
p2m_size =
|
||||
(((gpfn_max + 1) + PTRS_PER_PTE - 1) / PTRS_PER_PTE) << PAGE_SHIFT;
|
||||
addr = mmap(NULL, p2m_size, PROT_READ, MAP_SHARED, xch->fd, 0);
|
||||
if (addr == MAP_FAILED)
|
||||
return NULL;
|
||||
if (xc_hypercall_bounce_pre(xc, memmap_info)) {
|
||||
saved_errno = errno;
|
||||
munmap(addr, p2m_size);
|
||||
errno = saved_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
|
||||
hypercall.arg[0] = IA64_DOM0VP_expose_foreign_p2m;
|
||||
hypercall.arg[1] = (unsigned long)addr;
|
||||
hypercall.arg[2] = dom;
|
||||
hypercall.arg[3] = HYPERCALL_BUFFER_AS_ARG(memmap_info);
|
||||
hypercall.arg[4] = flags;
|
||||
|
||||
ret = do_xen_hypercall(xch, &hypercall);
|
||||
saved_errno = errno;
|
||||
xc_hypercall_bounce_post(xch, memmap_info);
|
||||
if (ret < 0) {
|
||||
munmap(addr, p2m_size);
|
||||
errno = saved_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*p2m_size_p = p2m_size;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table)
|
||||
{
|
||||
p2m_table->size = 0;
|
||||
p2m_table->p2m = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, xc_interface *xch,
|
||||
uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
|
||||
unsigned long flag)
|
||||
{
|
||||
p2m_table->p2m = xc_ia64_map_foreign_p2m(xch, domid, memmap_info,
|
||||
flag, &p2m_table->size);
|
||||
if (p2m_table->p2m == NULL) {
|
||||
PERROR("Could not map foreign p2m. falling back to old method");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table)
|
||||
{
|
||||
if (p2m_table->p2m == NULL)
|
||||
return;
|
||||
munmap(p2m_table->p2m, p2m_table->size);
|
||||
//p2m_table->p2m = NULL;
|
||||
//p2m_table->size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
|
||||
* Should those be exported by arch-ia64.h?
|
||||
*/
|
||||
#define _PAGE_P_BIT 0
|
||||
#define _PAGE_P (1UL << _PAGE_P_BIT) /* page present bit */
|
||||
#define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */
|
||||
#define _PAGE_PGC_ALLOCATED (1UL << _PAGE_PGC_ALLOCATED_BIT)
|
||||
#define _PAGE_IO_BIT 60
|
||||
#define _PAGE_IO (1UL << _PAGE_IO_BIT)
|
||||
|
||||
#define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */
|
||||
#define _PAGE_PPN_MASK (((1UL << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
|
||||
|
||||
int
|
||||
xc_ia64_p2m_present(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
|
||||
{
|
||||
if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size) {
|
||||
unsigned long pte = p2m_table->p2m[gpfn];
|
||||
return !!((pte & _PAGE_P) && !(pte & _PAGE_IO));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_ia64_p2m_allocated(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
|
||||
{
|
||||
if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size) {
|
||||
unsigned long pte = p2m_table->p2m[gpfn];
|
||||
return !!((pte & _PAGE_P) && (pte & _PAGE_PGC_ALLOCATED) &&
|
||||
!(pte & _PAGE_IO));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
xc_ia64_p2m_mfn(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
|
||||
{
|
||||
unsigned long pte;
|
||||
|
||||
if (sizeof(p2m_table->p2m[0]) * gpfn >= p2m_table->size)
|
||||
return INVALID_MFN;
|
||||
pte = p2m_table->p2m[gpfn];
|
||||
if (pte & _PAGE_IO)
|
||||
return INVALID_MFN;
|
||||
if (!(pte & _PAGE_P))
|
||||
return INVALID_MFN;
|
||||
return (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -31,7 +31,6 @@
|
||||
* | .shstrtab |
|
||||
* | .note.Xen |
|
||||
* | .xen_prstatus |
|
||||
* | .xen_ia64_mmapped_regs if ia64 |
|
||||
* | .xen_shared_info if present |
|
||||
* | .xen_pages |
|
||||
* | .xen_p2m or .xen_pfn |
|
||||
@@ -48,9 +47,6 @@
|
||||
* |.xen_prstatus |
|
||||
* | vcpu_guest_context_t[nr_vcpus] |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_ia64_mmapped_regs if ia64 pv |
|
||||
* | mmapped_regs_t[nr_vcpus] |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_shared_info if possible |
|
||||
* +--------------------------------------------------------+
|
||||
* |.xen_pages |
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#define XEN_DUMPCORE_SEC_PFN ".xen_pfn"
|
||||
#define XEN_DUMPCORE_SEC_PAGES ".xen_pages"
|
||||
|
||||
#define XEN_DUMPCORE_SEC_IA64_MAPPED_REGS ".xen_ia64_mapped_regs"
|
||||
|
||||
/* elf note name */
|
||||
#define XEN_DUMPCORE_ELFNOTE_NAME "Xen"
|
||||
/* note numbers are defined in xen/elfnote.h */
|
||||
@@ -153,8 +151,6 @@ int xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width,
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
# include "xc_core_x86.h"
|
||||
#elif defined (__ia64__)
|
||||
# include "xc_core_ia64.h"
|
||||
#elif defined (__arm__)
|
||||
# include "xc_core_arm.h"
|
||||
#else
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_core.h"
|
||||
#include "xc_efi.h"
|
||||
#include "xc_dom.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
int
|
||||
xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
|
||||
unsigned long pfn)
|
||||
{
|
||||
if (arch_ctxt->p2m_table.p2m == NULL)
|
||||
return 1; /* default to trying to map the page */
|
||||
|
||||
return xc_ia64_p2m_present(&arch_ctxt->p2m_table, pfn);
|
||||
}
|
||||
|
||||
static int
|
||||
xc_memory_map_cmp(const void *lhs__, const void *rhs__)
|
||||
{
|
||||
const struct xc_core_memory_map *lhs =
|
||||
(const struct xc_core_memory_map *)lhs__;
|
||||
const struct xc_core_memory_map *rhs =
|
||||
(const struct xc_core_memory_map *)rhs__;
|
||||
|
||||
if (lhs->addr < rhs->addr)
|
||||
return -1;
|
||||
if (lhs->addr > rhs->addr)
|
||||
return 1;
|
||||
|
||||
/* memory map overlap isn't allowed. complain */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "duplicated addresses are detected "
|
||||
"(0x%" PRIx64 ", 0x%" PRIx64 "), "
|
||||
"(0x%" PRIx64 ", 0x%" PRIx64 ")\n",
|
||||
lhs->addr, lhs->size, rhs->addr, rhs->size);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
|
||||
{
|
||||
/*
|
||||
* on ia64, both paravirtualize domain and hvm domain are
|
||||
* auto_translated_physmap mode
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* see setup_guest() @ xc_linux_build.c */
|
||||
static int
|
||||
memory_map_get_old_domu(xc_interface *xch, xc_dominfo_t *info,
|
||||
shared_info_any_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
xc_core_memory_map_t *map = NULL;
|
||||
|
||||
map = malloc(sizeof(*map));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
map->addr = 0;
|
||||
map->size = info->max_memkb * 1024;
|
||||
|
||||
*mapp = map;
|
||||
*nr_entries = 1;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if ( map != NULL )
|
||||
free(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* see setup_guest() @ xc_ia64_hvm_build.c */
|
||||
static int
|
||||
memory_map_get_old_hvm(xc_interface *xch, xc_dominfo_t *info,
|
||||
shared_info_any_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
const xc_core_memory_map_t gfw_map[] = {
|
||||
{IO_PAGE_START, IO_PAGE_SIZE},
|
||||
{STORE_PAGE_START, STORE_PAGE_SIZE},
|
||||
{BUFFER_IO_PAGE_START, BUFFER_IO_PAGE_SIZE},
|
||||
{BUFFER_PIO_PAGE_START, BUFFER_PIO_PAGE_SIZE},
|
||||
{GFW_START, GFW_SIZE},
|
||||
};
|
||||
const unsigned int nr_gfw_map = sizeof(gfw_map)/sizeof(gfw_map[0]);
|
||||
xc_core_memory_map_t *map = NULL;
|
||||
unsigned int i;
|
||||
|
||||
#define VGA_IO_END (VGA_IO_START + VGA_IO_SIZE)
|
||||
/* [0, VGA_IO_START) [VGA_IO_END, 3GB), [4GB, ...) + gfw_map */
|
||||
map = malloc((3 + nr_gfw_map) * sizeof(*map));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for ( i = 0; i < nr_gfw_map; i++ )
|
||||
map[i] = gfw_map[i];
|
||||
map[i].addr = 0;
|
||||
map[i].size = info->max_memkb * 1024;
|
||||
i++;
|
||||
if ( map[i - 1].size < VGA_IO_END )
|
||||
{
|
||||
map[i - 1].size = VGA_IO_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[i].addr = VGA_IO_END;
|
||||
map[i].size = map[i - 1].size - VGA_IO_END;
|
||||
map[i - 1].size = VGA_IO_START;
|
||||
i++;
|
||||
if ( map[i - 1].addr + map[i - 1].size > MMIO_START )
|
||||
{
|
||||
map[i].addr = MMIO_START + 1 * MEM_G;
|
||||
map[i].size = map[i - 1].addr + map[i - 1].size - MMIO_START;
|
||||
map[i - 1].size = MMIO_START - map[i - 1].addr;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
*mapp = map;
|
||||
*nr_entries = i;
|
||||
qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if ( map != NULL )
|
||||
free(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
memory_map_get_old(xc_interface *xch, xc_dominfo_t *info,
|
||||
shared_info_any_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp, unsigned int *nr_entries)
|
||||
{
|
||||
if ( info->hvm )
|
||||
return memory_map_get_old_hvm(xch, info, live_shinfo,
|
||||
mapp, nr_entries);
|
||||
if ( live_shinfo == NULL )
|
||||
return -1;
|
||||
return memory_map_get_old_domu(xch, info, live_shinfo,
|
||||
mapp, nr_entries);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_memory_map_get(xc_interface *xch,
|
||||
struct xc_core_arch_context *arch_ctxt,
|
||||
xc_dominfo_t *info,
|
||||
shared_info_any_t *live_shinfo,
|
||||
xc_core_memory_map_t **mapp,
|
||||
unsigned int *nr_entries)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
xen_ia64_memmap_info_t *memmap_info = NULL;
|
||||
xc_core_memory_map_t *map;
|
||||
char *start;
|
||||
char *end;
|
||||
char *p;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
if ( live_shinfo == NULL )
|
||||
{
|
||||
ERROR("can't access shared info");
|
||||
goto old;
|
||||
}
|
||||
|
||||
/* copy before use in case someone updating them */
|
||||
if (xc_ia64_copy_memmap(xch, info->domid, &live_shinfo->s,
|
||||
&memmap_info, NULL)) {
|
||||
goto old;
|
||||
}
|
||||
|
||||
*nr_entries = memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size;
|
||||
map = malloc(*nr_entries * sizeof(*md));
|
||||
if ( map == NULL )
|
||||
{
|
||||
PERROR("Could not allocate memory for memmap.");
|
||||
free(memmap_info);
|
||||
return -1;
|
||||
}
|
||||
*mapp = map;
|
||||
|
||||
*nr_entries = 0;
|
||||
start = (char*)&memmap_info->memdesc;
|
||||
end = start + memmap_info->efi_memmap_size;
|
||||
for ( p = start; p < end; p += memmap_info->efi_memdesc_size )
|
||||
{
|
||||
md = (efi_memory_desc_t*)p;
|
||||
if ( md->type != EFI_CONVENTIONAL_MEMORY ||
|
||||
md->attribute != EFI_MEMORY_WB ||
|
||||
md->num_pages == 0 )
|
||||
continue;
|
||||
|
||||
map[*nr_entries].addr = md->phys_addr;
|
||||
map[*nr_entries].size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
(*nr_entries)++;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
xc_ia64_p2m_map(&arch_ctxt->p2m_table, xch, info->domid,
|
||||
memmap_info, 0);
|
||||
if ( memmap_info != NULL )
|
||||
free(memmap_info);
|
||||
qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp);
|
||||
return ret;
|
||||
|
||||
old:
|
||||
DPRINTF("Falling back old method.\n");
|
||||
return memory_map_get_old(xch, info, live_shinfo, mapp, nr_entries);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width, xc_dominfo_t *info,
|
||||
shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
|
||||
unsigned long *pfnp)
|
||||
{
|
||||
/*
|
||||
* on ia64, both paravirtualize domain and hvm domain are
|
||||
* auto_translated_physmap mode
|
||||
*/
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt)
|
||||
{
|
||||
arch_ctxt->mapped_regs_size =
|
||||
(XMAPPEDREGS_SIZE < PAGE_SIZE) ? PAGE_SIZE: XMAPPEDREGS_SIZE;
|
||||
arch_ctxt->nr_vcpus = 0;
|
||||
arch_ctxt->mapped_regs = NULL;
|
||||
|
||||
xc_ia64_p2m_init(&arch_ctxt->p2m_table);
|
||||
}
|
||||
|
||||
void
|
||||
xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
|
||||
if ( arch_ctxt->mapped_regs[i] != NULL )
|
||||
munmap(arch_ctxt->mapped_regs[i], arch_ctxt->mapped_regs_size);
|
||||
free(arch_ctxt->mapped_regs);
|
||||
xc_ia64_p2m_unmap(&arch_ctxt->p2m_table);
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
|
||||
vcpu_guest_context_any_t* ctxt_any,
|
||||
xc_interface *xch, uint32_t domid)
|
||||
{
|
||||
vcpu_guest_context_t *ctxt = &ctxt_any->c;
|
||||
mapped_regs_t* mapped_regs;
|
||||
|
||||
if ( ctxt->privregs_pfn == VGC_PRIVREGS_HVM )
|
||||
return 0; /* VTi domain case */
|
||||
|
||||
if ( ctxt->privregs_pfn == INVALID_P2M_ENTRY )
|
||||
{
|
||||
PERROR("Could not get mmapped privregs gmfn");
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
if ( !(arch_ctxt->nr_vcpus & (arch_ctxt->nr_vcpus - 1)) ) {
|
||||
unsigned int nr = arch_ctxt->nr_vcpus ? arch_ctxt->nr_vcpus << 1 : 1;
|
||||
mapped_regs_t** new = realloc(arch_ctxt->mapped_regs,
|
||||
nr * sizeof(*new));
|
||||
|
||||
if ( !new )
|
||||
{
|
||||
PERROR("Could not alloc mapped regs pointer array");
|
||||
return -1;
|
||||
}
|
||||
memset(new + arch_ctxt->nr_vcpus, 0,
|
||||
(nr - arch_ctxt->nr_vcpus) * sizeof(*new));
|
||||
arch_ctxt->mapped_regs = new;
|
||||
}
|
||||
|
||||
mapped_regs = xc_map_foreign_range(xch, domid,
|
||||
arch_ctxt->mapped_regs_size,
|
||||
PROT_READ, ctxt->privregs_pfn);
|
||||
if ( mapped_regs == NULL )
|
||||
{
|
||||
PERROR("Could not map mapped privregs");
|
||||
return -1;
|
||||
}
|
||||
arch_ctxt->mapped_regs[arch_ctxt->nr_vcpus] = mapped_regs;
|
||||
arch_ctxt->nr_vcpus++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_get_shdr(xc_interface *xch,
|
||||
struct xc_core_arch_context *arch_ctxt,
|
||||
struct xc_core_section_headers *sheaders,
|
||||
struct xc_core_strtab *strtab,
|
||||
uint64_t *filesz, uint64_t offset)
|
||||
{
|
||||
int sts = -1;
|
||||
Elf64_Shdr *shdr;
|
||||
|
||||
if ( arch_ctxt->nr_vcpus == 0 )
|
||||
{
|
||||
/* VTi domain case */
|
||||
*filesz = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* mmapped priv regs */
|
||||
shdr = xc_core_shdr_get(xch, sheaders);
|
||||
if ( shdr == NULL )
|
||||
{
|
||||
PERROR("Could not get section header for .xen_ia64_mapped_regs");
|
||||
return sts;
|
||||
}
|
||||
*filesz = arch_ctxt->mapped_regs_size * arch_ctxt->nr_vcpus;
|
||||
sts = xc_core_shdr_set(xch, shdr, strtab,
|
||||
XEN_DUMPCORE_SEC_IA64_MAPPED_REGS,
|
||||
SHT_PROGBITS, offset, *filesz,
|
||||
__alignof__(*arch_ctxt->mapped_regs[0]),
|
||||
arch_ctxt->mapped_regs_size);
|
||||
return sts;
|
||||
}
|
||||
|
||||
int
|
||||
xc_core_arch_context_dump(xc_interface *xch,
|
||||
struct xc_core_arch_context* arch_ctxt,
|
||||
void* args, dumpcore_rtn_t dump_rtn)
|
||||
{
|
||||
int sts = 0;
|
||||
int i;
|
||||
|
||||
/* ia64 mapped_regs: .xen_ia64_mapped_regs */
|
||||
for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
|
||||
{
|
||||
sts = dump_rtn(xch, args, (char*)arch_ctxt->mapped_regs[i],
|
||||
arch_ctxt->mapped_regs_size);
|
||||
if ( sts != 0 )
|
||||
break;
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XC_CORE_IA64_H
|
||||
#define XC_CORE_IA64_H
|
||||
|
||||
#include "ia64/xc_ia64.h"
|
||||
|
||||
#define ELF_ARCH_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH_MACHINE EM_IA_64
|
||||
|
||||
struct xc_core_arch_context {
|
||||
size_t mapped_regs_size;
|
||||
int nr_vcpus;
|
||||
mapped_regs_t** mapped_regs;
|
||||
|
||||
struct xen_ia64_p2m_table p2m_table;
|
||||
};
|
||||
|
||||
void
|
||||
xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt);
|
||||
void
|
||||
xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt);
|
||||
int
|
||||
xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
|
||||
vcpu_guest_context_any_t* ctxt,
|
||||
xc_interface *xch, uint32_t domid);
|
||||
int
|
||||
xc_core_arch_context_get_shdr(xc_interface *xch,
|
||||
struct xc_core_arch_context* arch_ctxt,
|
||||
struct xc_core_section_headers *sheaders,
|
||||
struct xc_core_strtab *strtab,
|
||||
uint64_t *filesz, uint64_t offset);
|
||||
int
|
||||
xc_core_arch_context_dump(xc_interface *xch,
|
||||
struct xc_core_arch_context* arch_ctxt,
|
||||
void* args, dumpcore_rtn_t dump_rtn);
|
||||
|
||||
int
|
||||
xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
|
||||
unsigned long pfn);
|
||||
|
||||
#endif /* XC_CORE_IA64_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -213,7 +213,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
/* misc ia64 stuff*/
|
||||
/* misc stuff*/
|
||||
if ( (rc = arch_setup_bootearly(dom)) != 0 )
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -74,8 +74,6 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
|
||||
}
|
||||
case EM_X86_64:
|
||||
return "xen-3.0-x86_64";
|
||||
case EM_IA_64:
|
||||
return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64";
|
||||
default:
|
||||
return "xen-3.0-unknown";
|
||||
}
|
||||
|
||||
@@ -1,334 +0,0 @@
|
||||
/*
|
||||
* Xen domain builder -- ia64 bits.
|
||||
*
|
||||
* Most architecture-specific code for ia64 goes here.
|
||||
* - fill architecture-specific structs.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* written 2006 by Gerd Hoffmann <kraxel@suse.de>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
#include <asm/kregs.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/foreign/ia64.h>
|
||||
#include <xen/io/protocols.h>
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_dom.h"
|
||||
#include "xenctrl.h"
|
||||
|
||||
#include <asm/dom_fw_common.h>
|
||||
#include "ia64/xc_dom_ia64_util.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
{
|
||||
/* allocate special pages */
|
||||
dom->console_pfn = dom->total_pages -1;
|
||||
dom->xenstore_pfn = dom->total_pages -2;
|
||||
dom->start_info_pfn = dom->total_pages -3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int start_info_ia64(struct xc_dom_image *dom)
|
||||
{
|
||||
start_info_ia64_t *start_info =
|
||||
xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
|
||||
struct xen_ia64_boot_param_ia64 *bp =
|
||||
(struct xen_ia64_boot_param_ia64 *)(start_info + 1);
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
sprintf(start_info->magic, dom->guest_type);
|
||||
start_info->flags = dom->flags;
|
||||
start_info->nr_pages = dom->total_pages;
|
||||
start_info->store_mfn = dom->xenstore_pfn;
|
||||
start_info->store_evtchn = dom->xenstore_evtchn;
|
||||
start_info->console.domU.mfn = dom->console_pfn;
|
||||
start_info->console.domU.evtchn = dom->console_evtchn;
|
||||
|
||||
/*
|
||||
* domain_start and domain_size are abused for arch_setup hypercall
|
||||
* so that we need to clear them here.
|
||||
*/
|
||||
XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = 0;
|
||||
XEN_IA64_MEMMAP_INFO_PFN(bp) = 0;
|
||||
|
||||
if ( dom->ramdisk_blob )
|
||||
{
|
||||
start_info->mod_start = dom->ramdisk_seg.vstart;
|
||||
start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
|
||||
bp->initrd_start = start_info->mod_start;
|
||||
bp->initrd_size = start_info->mod_len;
|
||||
}
|
||||
bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64)
|
||||
+ offsetof(start_info_t, cmd_line);
|
||||
if ( dom->cmdline )
|
||||
{
|
||||
strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
|
||||
start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
|
||||
{
|
||||
shared_info_ia64_t *shared_info = ptr;
|
||||
int i;
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
memset(shared_info, 0, sizeof(*shared_info));
|
||||
for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++)
|
||||
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
|
||||
shared_info->arch.start_info_pfn = dom->start_info_pfn;
|
||||
shared_info->arch.memmap_info_num_pages = 1; //XXX
|
||||
shared_info->arch.memmap_info_pfn = dom->start_info_pfn - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned long xc_ia64_fpsr_default(void);
|
||||
|
||||
static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
|
||||
{
|
||||
vcpu_guest_context_ia64_t *ctxt = ptr;
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
/* clear everything */
|
||||
memset(ctxt, 0, sizeof(*ctxt));
|
||||
|
||||
ctxt->flags = 0;
|
||||
/* PSR is set according to SAL 3.2.4: AC, IC and BN are set. */
|
||||
ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_IC | IA64_PSR_BN;
|
||||
ctxt->regs.ip = dom->parms.virt_entry;
|
||||
ctxt->regs.cfm = 1UL << 63;
|
||||
#ifdef __ia64__ /* FIXME */
|
||||
ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();
|
||||
#endif
|
||||
ctxt->regs.r[28] = (dom->start_info_pfn << PAGE_SHIFT_IA64)
|
||||
+ sizeof(start_info_ia64_t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static struct xc_dom_arch xc_dom_arch = {
|
||||
.guest_type = "xen-3.0-ia64",
|
||||
.native_protocol = XEN_IO_PROTO_ABI_IA64,
|
||||
.page_shift = PAGE_SHIFT_IA64,
|
||||
.alloc_magic_pages = alloc_magic_pages,
|
||||
.start_info = start_info_ia64,
|
||||
.shared_info = shared_info_ia64,
|
||||
.vcpu = vcpu_ia64,
|
||||
};
|
||||
|
||||
static struct xc_dom_arch xc_dom_arch_ia64be = {
|
||||
.guest_type = "xen-3.0-ia64be",
|
||||
.native_protocol = XEN_IO_PROTO_ABI_IA64,
|
||||
.page_shift = PAGE_SHIFT_IA64,
|
||||
.alloc_magic_pages = alloc_magic_pages,
|
||||
.start_info = start_info_ia64,
|
||||
.shared_info = shared_info_ia64,
|
||||
.vcpu = vcpu_ia64,
|
||||
};
|
||||
|
||||
static void __init register_arch_hooks(void)
|
||||
{
|
||||
xc_dom_register_arch_hooks(&xc_dom_arch);
|
||||
xc_dom_register_arch_hooks(&xc_dom_arch_ia64be);
|
||||
}
|
||||
|
||||
#include "xc_efi.h"
|
||||
|
||||
int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
{
|
||||
xen_pfn_t pfn;
|
||||
int rc;
|
||||
unsigned long start;
|
||||
unsigned long nbr;
|
||||
|
||||
/* setup initial p2m */
|
||||
if (dom->guest_type && strcmp(dom->guest_type,
|
||||
"hvm-3.0-ia64-sioemu") == 0) {
|
||||
start = FW_MEM_BASE >> PAGE_SHIFT_IA64;
|
||||
nbr = FW_MEM_SIZE >> PAGE_SHIFT_IA64;
|
||||
} else {
|
||||
start = 0;
|
||||
nbr = dom->total_pages;
|
||||
}
|
||||
|
||||
/* setup initial p2m */
|
||||
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr);
|
||||
for ( pfn = 0; pfn < nbr; pfn++ )
|
||||
dom->p2m_host[pfn] = start + pfn;
|
||||
|
||||
/* allocate guest memory */
|
||||
rc = xc_domain_populate_physmap_exact(dom->xch, dom->guest_domid,
|
||||
nbr, 0, 0,
|
||||
dom->p2m_host);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ia64_setup_memmap(struct xc_dom_image *dom)
|
||||
{
|
||||
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
unsigned long memmap_info_num_pages;
|
||||
unsigned long memmap_info_pfn;
|
||||
xen_ia64_memmap_info_t* memmap_info;
|
||||
unsigned int num_mds;
|
||||
efi_memory_desc_t *md;
|
||||
|
||||
char* start_info;
|
||||
struct xen_ia64_boot_param* bp;
|
||||
|
||||
/* setup memmap page */
|
||||
memmap_info_num_pages = 1;
|
||||
memmap_info_pfn = dom->start_info_pfn - 1;
|
||||
DOMPRINTF("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx",
|
||||
__FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
|
||||
memmap_info = xc_map_foreign_range(dom->xch, dom->guest_domid,
|
||||
page_size * memmap_info_num_pages,
|
||||
PROT_READ | PROT_WRITE,
|
||||
memmap_info_pfn);
|
||||
if (NULL == memmap_info)
|
||||
return -1;
|
||||
/* [0, total_pages) */
|
||||
memmap_info->efi_memdesc_size = sizeof(md[0]);
|
||||
memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
|
||||
num_mds = 0;
|
||||
md = (efi_memory_desc_t*)&memmap_info->memdesc;
|
||||
md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
|
||||
md[num_mds].pad = 0;
|
||||
md[num_mds].phys_addr = 0;
|
||||
md[num_mds].virt_addr = 0;
|
||||
md[num_mds].num_pages = dom->total_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
|
||||
md[num_mds].attribute = EFI_MEMORY_WB;
|
||||
num_mds++;
|
||||
memmap_info->efi_memmap_size = num_mds * sizeof(md[0]);
|
||||
munmap(memmap_info, page_size * memmap_info_num_pages);
|
||||
assert(num_mds <=
|
||||
(page_size * memmap_info_num_pages -
|
||||
offsetof(typeof(*memmap_info), memdesc))/sizeof(*md));
|
||||
|
||||
/*
|
||||
* kludge: we need to pass memmap_info page's pfn and other magic pages
|
||||
* somehow.
|
||||
* we use xen_ia64_boot_param::efi_memmap::{efi_memmap, efi_memmap_size}
|
||||
* for this purpose
|
||||
*/
|
||||
start_info = xc_map_foreign_range(dom->xch, dom->guest_domid,
|
||||
page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
dom->start_info_pfn);
|
||||
if (NULL == start_info)
|
||||
return -1;
|
||||
bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t));
|
||||
memset(bp, 0, sizeof(*bp));
|
||||
XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = memmap_info_num_pages;
|
||||
XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn;
|
||||
munmap(start_info, page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_setup_bootearly(struct xc_dom_image *dom)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
int rc;
|
||||
|
||||
DOMPRINTF("%s: setup firmware for %s", __FUNCTION__, dom->guest_type);
|
||||
|
||||
if (dom->guest_type && strcmp(dom->guest_type,
|
||||
"hvm-3.0-ia64-sioemu") == 0) {
|
||||
memset(&domctl, 0, sizeof(domctl));
|
||||
domctl.u.arch_setup.flags = XEN_DOMAINSETUP_sioemu_guest;
|
||||
domctl.u.arch_setup.bp = 0;
|
||||
domctl.u.arch_setup.maxmem = 0;
|
||||
domctl.cmd = XEN_DOMCTL_arch_setup;
|
||||
domctl.domain = dom->guest_domid;
|
||||
rc = xc_domctl(dom->xch, &domctl);
|
||||
DOMPRINTF("%s: hvm-3.0-ia64-sioemu: %d", __FUNCTION__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ia64_setup_memmap(dom);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memset(&domctl, 0, sizeof(domctl));
|
||||
domctl.cmd = XEN_DOMCTL_arch_setup;
|
||||
domctl.domain = dom->guest_domid;
|
||||
domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;
|
||||
rc = do_domctl(dom->xch, &domctl);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = xen_ia64_dom_fw_setup(dom, domctl.u.arch_setup.hypercall_imm,
|
||||
(dom->start_info_pfn << PAGE_SHIFT) +
|
||||
sizeof(start_info_t),
|
||||
dom->total_pages << PAGE_SHIFT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memset(&domctl, 0, sizeof(domctl));
|
||||
domctl.cmd = XEN_DOMCTL_arch_setup;
|
||||
domctl.domain = dom->guest_domid;
|
||||
domctl.u.arch_setup.flags = 0;
|
||||
|
||||
domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
|
||||
+ sizeof(start_info_t);
|
||||
domctl.u.arch_setup.maxmem = dom->total_pages << PAGE_SHIFT;
|
||||
domctl.u.arch_setup.vhpt_size_log2 = dom->vhpt_size_log2;
|
||||
rc = do_domctl(dom->xch, &domctl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int arch_setup_bootlate(struct xc_dom_image *dom)
|
||||
{
|
||||
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
shared_info_t *shared_info;
|
||||
|
||||
/* setup shared_info page */
|
||||
DOMPRINTF("%s: shared_info: mfn 0x%" PRIpfn "",
|
||||
__FUNCTION__, dom->shared_info_mfn);
|
||||
shared_info = xc_map_foreign_range(dom->xch, dom->guest_domid,
|
||||
page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
dom->shared_info_mfn);
|
||||
if ( shared_info == NULL )
|
||||
return -1;
|
||||
dom->arch_hooks->shared_info(dom, shared_info);
|
||||
munmap(shared_info, page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
+4
-16
@@ -109,14 +109,10 @@ static void *minios_privcmd_map_foreign_bulk(xc_interface *xch, xc_osdep_handle
|
||||
const xen_pfn_t *arr, int *err, unsigned int num)
|
||||
{
|
||||
unsigned long pt_prot = 0;
|
||||
#ifdef __ia64__
|
||||
/* TODO */
|
||||
#else
|
||||
if (prot & PROT_READ)
|
||||
pt_prot = L1_PROT_RO;
|
||||
if (prot & PROT_WRITE)
|
||||
pt_prot = L1_PROT;
|
||||
#endif
|
||||
return map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot);
|
||||
}
|
||||
|
||||
@@ -129,14 +125,11 @@ static void *minios_privcmd_map_foreign_batch(xc_interface *xch, xc_osdep_handl
|
||||
int i;
|
||||
unsigned long addr;
|
||||
|
||||
#ifdef __ia64__
|
||||
/* TODO */
|
||||
#else
|
||||
if (prot & PROT_READ)
|
||||
pt_prot = L1_PROT_RO;
|
||||
if (prot & PROT_WRITE)
|
||||
pt_prot = L1_PROT;
|
||||
#endif
|
||||
|
||||
addr = (unsigned long) map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (err[i])
|
||||
@@ -151,14 +144,12 @@ static void *minios_privcmd_map_foreign_range(xc_interface *xch, xc_osdep_handle
|
||||
unsigned long mfn)
|
||||
{
|
||||
unsigned long pt_prot = 0;
|
||||
#ifdef __ia64__
|
||||
/* TODO */
|
||||
#else
|
||||
|
||||
if (prot & PROT_READ)
|
||||
pt_prot = L1_PROT_RO;
|
||||
if (prot & PROT_WRITE)
|
||||
pt_prot = L1_PROT;
|
||||
#endif
|
||||
|
||||
assert(!(size % getpagesize()));
|
||||
return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, NULL, pt_prot);
|
||||
}
|
||||
@@ -172,14 +163,11 @@ static void *minios_privcmd_map_foreign_ranges(xc_interface *xch, xc_osdep_handl
|
||||
int i, j, n;
|
||||
unsigned long pt_prot = 0;
|
||||
void *ret;
|
||||
#ifdef __ia64__
|
||||
/* TODO */
|
||||
#else
|
||||
|
||||
if (prot & PROT_READ)
|
||||
pt_prot = L1_PROT_RO;
|
||||
if (prot & PROT_WRITE)
|
||||
pt_prot = L1_PROT;
|
||||
#endif
|
||||
|
||||
mfns = malloc((size / XC_PAGE_SIZE) * sizeof(*mfns));
|
||||
|
||||
|
||||
@@ -55,11 +55,7 @@
|
||||
#include <xen/arch-x86/xen-mca.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ia64__
|
||||
#define XC_PAGE_SHIFT 14
|
||||
#else
|
||||
#define XC_PAGE_SHIFT 12
|
||||
#endif
|
||||
#define XC_PAGE_SIZE (1UL << XC_PAGE_SHIFT)
|
||||
#define XC_PAGE_MASK (~(XC_PAGE_SIZE-1))
|
||||
|
||||
@@ -79,10 +75,6 @@
|
||||
#define xen_mb() asm volatile ( "mfence" : : : "memory")
|
||||
#define xen_rmb() xen_barrier()
|
||||
#define xen_wmb() xen_barrier()
|
||||
#elif defined(__ia64__)
|
||||
#define xen_mb() asm volatile ("mf" ::: "memory")
|
||||
#define xen_rmb() asm volatile ("mf" ::: "memory")
|
||||
#define xen_wmb() asm volatile ("mf" ::: "memory")
|
||||
#elif defined(__arm__)
|
||||
#define xen_mb() asm volatile ("dmb" : : : "memory")
|
||||
#define xen_rmb() asm volatile ("dmb" : : : "memory")
|
||||
@@ -1248,8 +1240,6 @@ unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
|
||||
int xc_get_pfn_list(xc_interface *xch, uint32_t domid, uint64_t *pfn_buf,
|
||||
unsigned long max_pfns);
|
||||
|
||||
unsigned long xc_ia64_fpsr_default(void);
|
||||
|
||||
int xc_copy_to_domain_page(xc_interface *xch, uint32_t domid,
|
||||
unsigned long dst_pfn, const char *src_page);
|
||||
|
||||
@@ -1659,15 +1649,6 @@ void xc_clear_last_error(xc_interface *xch);
|
||||
int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long value);
|
||||
int xc_get_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned long *value);
|
||||
|
||||
/* IA64 specific, nvram save */
|
||||
int xc_ia64_save_to_nvram(xc_interface *xch, uint32_t dom);
|
||||
|
||||
/* IA64 specific, nvram init */
|
||||
int xc_ia64_nvram_init(xc_interface *xch, char *dom_name, uint32_t dom);
|
||||
|
||||
/* IA64 specific, set guest OS type optimizations */
|
||||
int xc_ia64_set_os_type(xc_interface *xch, char *guest_os_type, uint32_t dom);
|
||||
|
||||
/* HVM guest pass-through */
|
||||
int xc_assign_device(xc_interface *xch,
|
||||
uint32_t domid,
|
||||
|
||||
@@ -1,637 +0,0 @@
|
||||
/******************************************************************************
|
||||
* arch-ia64/hypervisor-if.h
|
||||
*
|
||||
* Guest OS interface to IA64 Xen.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xen.h"
|
||||
|
||||
#ifndef __HYPERVISOR_IF_IA64_H__
|
||||
#define __HYPERVISOR_IF_IA64_H__
|
||||
|
||||
#if !defined(__GNUC__) || defined(__STRICT_ANSI__)
|
||||
#error "Anonymous structs/unions are a GNU extension."
|
||||
#endif
|
||||
|
||||
/* Structural guest handles introduced in 0x00030201. */
|
||||
#if __XEN_INTERFACE_VERSION__ >= 0x00030201
|
||||
#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
typedef struct { type *p; } __guest_handle_ ## name
|
||||
#else
|
||||
#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
typedef type * __guest_handle_ ## name
|
||||
#endif
|
||||
|
||||
#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
___DEFINE_XEN_GUEST_HANDLE(name, type); \
|
||||
___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
|
||||
|
||||
#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
|
||||
#define XEN_GUEST_HANDLE(name) __guest_handle_ ## name
|
||||
#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name)
|
||||
#define uint64_aligned_t uint64_t
|
||||
#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0)
|
||||
#ifdef __XEN_TOOLS__
|
||||
#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
|
||||
#endif
|
||||
#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
typedef unsigned long xen_pfn_t;
|
||||
#define PRI_xen_pfn "lx"
|
||||
#endif
|
||||
|
||||
/* Arch specific VIRQs definition */
|
||||
#define VIRQ_ITC VIRQ_ARCH_0 /* V. Virtual itc timer */
|
||||
#define VIRQ_MCA_CMC VIRQ_ARCH_1 /* MCA cmc interrupt */
|
||||
#define VIRQ_MCA_CPE VIRQ_ARCH_2 /* MCA cpe interrupt */
|
||||
|
||||
/* Maximum number of virtual CPUs in multi-processor guests. */
|
||||
/* WARNING: before changing this, check that shared_info fits on a page */
|
||||
#define XEN_LEGACY_MAX_VCPUS 64
|
||||
|
||||
/* IO ports location for PV. */
|
||||
#define IO_PORTS_PADDR 0x00000ffffc000000UL
|
||||
#define IO_PORTS_SIZE 0x0000000004000000UL
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef unsigned long xen_ulong_t;
|
||||
|
||||
#ifdef __XEN_TOOLS__
|
||||
#define XEN_PAGE_SIZE XC_PAGE_SIZE
|
||||
#else
|
||||
#define XEN_PAGE_SIZE PAGE_SIZE
|
||||
#endif
|
||||
|
||||
#define INVALID_MFN (~0UL)
|
||||
|
||||
struct pt_fpreg {
|
||||
union {
|
||||
unsigned long bits[2];
|
||||
long double __dummy; /* force 16-byte alignment */
|
||||
} u;
|
||||
};
|
||||
|
||||
union vac {
|
||||
unsigned long value;
|
||||
struct {
|
||||
int a_int:1;
|
||||
int a_from_int_cr:1;
|
||||
int a_to_int_cr:1;
|
||||
int a_from_psr:1;
|
||||
int a_from_cpuid:1;
|
||||
int a_cover:1;
|
||||
int a_bsw:1;
|
||||
long reserved:57;
|
||||
};
|
||||
};
|
||||
typedef union vac vac_t;
|
||||
|
||||
union vdc {
|
||||
unsigned long value;
|
||||
struct {
|
||||
int d_vmsw:1;
|
||||
int d_extint:1;
|
||||
int d_ibr_dbr:1;
|
||||
int d_pmc:1;
|
||||
int d_to_pmd:1;
|
||||
int d_itm:1;
|
||||
long reserved:58;
|
||||
};
|
||||
};
|
||||
typedef union vdc vdc_t;
|
||||
|
||||
struct mapped_regs {
|
||||
union vac vac;
|
||||
union vdc vdc;
|
||||
unsigned long virt_env_vaddr;
|
||||
unsigned long reserved1[29];
|
||||
unsigned long vhpi;
|
||||
unsigned long reserved2[95];
|
||||
union {
|
||||
unsigned long vgr[16];
|
||||
unsigned long bank1_regs[16]; // bank1 regs (r16-r31) when bank0 active
|
||||
};
|
||||
union {
|
||||
unsigned long vbgr[16];
|
||||
unsigned long bank0_regs[16]; // bank0 regs (r16-r31) when bank1 active
|
||||
};
|
||||
unsigned long vnat;
|
||||
unsigned long vbnat;
|
||||
unsigned long vcpuid[5];
|
||||
unsigned long reserved3[11];
|
||||
unsigned long vpsr;
|
||||
unsigned long vpr;
|
||||
unsigned long reserved4[76];
|
||||
union {
|
||||
unsigned long vcr[128];
|
||||
struct {
|
||||
unsigned long dcr; // CR0
|
||||
unsigned long itm;
|
||||
unsigned long iva;
|
||||
unsigned long rsv1[5];
|
||||
unsigned long pta; // CR8
|
||||
unsigned long rsv2[7];
|
||||
unsigned long ipsr; // CR16
|
||||
unsigned long isr;
|
||||
unsigned long rsv3;
|
||||
unsigned long iip;
|
||||
unsigned long ifa;
|
||||
unsigned long itir;
|
||||
unsigned long iipa;
|
||||
unsigned long ifs;
|
||||
unsigned long iim; // CR24
|
||||
unsigned long iha;
|
||||
unsigned long rsv4[38];
|
||||
unsigned long lid; // CR64
|
||||
unsigned long ivr;
|
||||
unsigned long tpr;
|
||||
unsigned long eoi;
|
||||
unsigned long irr[4];
|
||||
unsigned long itv; // CR72
|
||||
unsigned long pmv;
|
||||
unsigned long cmcv;
|
||||
unsigned long rsv5[5];
|
||||
unsigned long lrr0; // CR80
|
||||
unsigned long lrr1;
|
||||
unsigned long rsv6[46];
|
||||
};
|
||||
};
|
||||
union {
|
||||
unsigned long reserved5[128];
|
||||
struct {
|
||||
unsigned long precover_ifs;
|
||||
unsigned long unat; // not sure if this is needed until NaT arch is done
|
||||
int interrupt_collection_enabled; // virtual psr.ic
|
||||
/* virtual interrupt deliverable flag is evtchn_upcall_mask in
|
||||
* shared info area now. interrupt_mask_addr is the address
|
||||
* of evtchn_upcall_mask for current vcpu
|
||||
*/
|
||||
unsigned char *interrupt_mask_addr;
|
||||
int pending_interruption;
|
||||
unsigned char vpsr_pp;
|
||||
unsigned char vpsr_dfh;
|
||||
unsigned char hpsr_dfh;
|
||||
unsigned char hpsr_mfh;
|
||||
unsigned long reserved5_1[4];
|
||||
int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual
|
||||
int banknum; // 0 or 1, which virtual register bank is active
|
||||
unsigned long rrs[8]; // region registers
|
||||
unsigned long krs[8]; // kernel registers
|
||||
unsigned long tmp[16]; // temp registers (e.g. for hyperprivops)
|
||||
|
||||
/* itc paravirtualization
|
||||
* vAR.ITC = mAR.ITC + itc_offset
|
||||
* itc_last is one which was lastly passed to
|
||||
* the guest OS in order to prevent it from
|
||||
* going backwords.
|
||||
*/
|
||||
unsigned long itc_offset;
|
||||
unsigned long itc_last;
|
||||
};
|
||||
};
|
||||
};
|
||||
typedef struct mapped_regs mapped_regs_t;
|
||||
|
||||
struct vpd {
|
||||
struct mapped_regs vpd_low;
|
||||
unsigned long reserved6[3456];
|
||||
unsigned long vmm_avail[128];
|
||||
unsigned long reserved7[4096];
|
||||
};
|
||||
typedef struct vpd vpd_t;
|
||||
|
||||
struct arch_vcpu_info {
|
||||
};
|
||||
typedef struct arch_vcpu_info arch_vcpu_info_t;
|
||||
|
||||
/*
|
||||
* This structure is used for magic page in domain pseudo physical address
|
||||
* space and the result of XENMEM_machine_memory_map.
|
||||
* As the XENMEM_machine_memory_map result,
|
||||
* xen_memory_map::nr_entries indicates the size in bytes
|
||||
* including struct xen_ia64_memmap_info. Not the number of entries.
|
||||
*/
|
||||
struct xen_ia64_memmap_info {
|
||||
uint64_t efi_memmap_size; /* size of EFI memory map */
|
||||
uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
|
||||
uint32_t efi_memdesc_version; /* memory descriptor version */
|
||||
void *memdesc[0]; /* array of efi_memory_desc_t */
|
||||
};
|
||||
typedef struct xen_ia64_memmap_info xen_ia64_memmap_info_t;
|
||||
|
||||
struct arch_shared_info {
|
||||
/* PFN of the start_info page. */
|
||||
unsigned long start_info_pfn;
|
||||
|
||||
/* Interrupt vector for event channel. */
|
||||
int evtchn_vector;
|
||||
|
||||
/* PFN of memmap_info page */
|
||||
unsigned int memmap_info_num_pages;/* currently only = 1 case is
|
||||
supported. */
|
||||
unsigned long memmap_info_pfn;
|
||||
|
||||
uint64_t pad[31];
|
||||
};
|
||||
typedef struct arch_shared_info arch_shared_info_t;
|
||||
|
||||
typedef unsigned long xen_callback_t;
|
||||
|
||||
struct ia64_tr_entry {
|
||||
unsigned long pte;
|
||||
unsigned long itir;
|
||||
unsigned long vadr;
|
||||
unsigned long rid;
|
||||
};
|
||||
typedef struct ia64_tr_entry ia64_tr_entry_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(ia64_tr_entry_t);
|
||||
|
||||
struct vcpu_tr_regs {
|
||||
struct ia64_tr_entry itrs[12];
|
||||
struct ia64_tr_entry dtrs[12];
|
||||
};
|
||||
|
||||
union vcpu_ar_regs {
|
||||
unsigned long ar[128];
|
||||
struct {
|
||||
unsigned long kr[8];
|
||||
unsigned long rsv1[8];
|
||||
unsigned long rsc;
|
||||
unsigned long bsp;
|
||||
unsigned long bspstore;
|
||||
unsigned long rnat;
|
||||
unsigned long rsv2;
|
||||
unsigned long fcr;
|
||||
unsigned long rsv3[2];
|
||||
unsigned long eflag;
|
||||
unsigned long csd;
|
||||
unsigned long ssd;
|
||||
unsigned long cflg;
|
||||
unsigned long fsr;
|
||||
unsigned long fir;
|
||||
unsigned long fdr;
|
||||
unsigned long rsv4;
|
||||
unsigned long ccv; /* 32 */
|
||||
unsigned long rsv5[3];
|
||||
unsigned long unat;
|
||||
unsigned long rsv6[3];
|
||||
unsigned long fpsr;
|
||||
unsigned long rsv7[3];
|
||||
unsigned long itc;
|
||||
unsigned long rsv8[3];
|
||||
unsigned long ign1[16];
|
||||
unsigned long pfs; /* 64 */
|
||||
unsigned long lc;
|
||||
unsigned long ec;
|
||||
unsigned long rsv9[45];
|
||||
unsigned long ign2[16];
|
||||
};
|
||||
};
|
||||
|
||||
union vcpu_cr_regs {
|
||||
unsigned long cr[128];
|
||||
struct {
|
||||
unsigned long dcr; // CR0
|
||||
unsigned long itm;
|
||||
unsigned long iva;
|
||||
unsigned long rsv1[5];
|
||||
unsigned long pta; // CR8
|
||||
unsigned long rsv2[7];
|
||||
unsigned long ipsr; // CR16
|
||||
unsigned long isr;
|
||||
unsigned long rsv3;
|
||||
unsigned long iip;
|
||||
unsigned long ifa;
|
||||
unsigned long itir;
|
||||
unsigned long iipa;
|
||||
unsigned long ifs;
|
||||
unsigned long iim; // CR24
|
||||
unsigned long iha;
|
||||
unsigned long rsv4[38];
|
||||
unsigned long lid; // CR64
|
||||
unsigned long ivr;
|
||||
unsigned long tpr;
|
||||
unsigned long eoi;
|
||||
unsigned long irr[4];
|
||||
unsigned long itv; // CR72
|
||||
unsigned long pmv;
|
||||
unsigned long cmcv;
|
||||
unsigned long rsv5[5];
|
||||
unsigned long lrr0; // CR80
|
||||
unsigned long lrr1;
|
||||
unsigned long rsv6[46];
|
||||
};
|
||||
};
|
||||
|
||||
struct vcpu_guest_context_regs {
|
||||
unsigned long r[32];
|
||||
unsigned long b[8];
|
||||
unsigned long bank[16];
|
||||
unsigned long ip;
|
||||
unsigned long psr;
|
||||
unsigned long cfm;
|
||||
unsigned long pr;
|
||||
unsigned int nats; /* NaT bits for r1-r31. */
|
||||
unsigned int bnats; /* Nat bits for banked registers. */
|
||||
union vcpu_ar_regs ar;
|
||||
union vcpu_cr_regs cr;
|
||||
struct pt_fpreg f[128];
|
||||
unsigned long dbr[8];
|
||||
unsigned long ibr[8];
|
||||
unsigned long rr[8];
|
||||
unsigned long pkr[16];
|
||||
|
||||
/* FIXME: cpuid,pmd,pmc */
|
||||
|
||||
unsigned long xip;
|
||||
unsigned long xpsr;
|
||||
unsigned long xfs;
|
||||
unsigned long xr[4];
|
||||
|
||||
struct vcpu_tr_regs tr;
|
||||
|
||||
/* Physical registers in case of debug event. */
|
||||
unsigned long excp_iipa;
|
||||
unsigned long excp_ifa;
|
||||
unsigned long excp_isr;
|
||||
unsigned int excp_vector;
|
||||
|
||||
/*
|
||||
* The rbs is intended to be the image of the stacked registers still
|
||||
* in the cpu (not yet stored in memory). It is laid out as if it
|
||||
* were written in memory at a 512 (64*8) aligned address + offset.
|
||||
* rbs_voff is (offset / 8). rbs_nat contains NaT bits for the
|
||||
* remaining rbs registers. rbs_rnat contains NaT bits for in memory
|
||||
* rbs registers.
|
||||
* Note: loadrs is 2**14 bytes == 2**11 slots.
|
||||
*/
|
||||
unsigned int rbs_voff;
|
||||
unsigned long rbs[2048];
|
||||
unsigned long rbs_rnat;
|
||||
|
||||
/*
|
||||
* RSE.N_STACKED_PHYS via PAL_RSE_INFO
|
||||
* Strictly this isn't cpu context, but this value is necessary
|
||||
* for domain save/restore. So is here.
|
||||
*/
|
||||
unsigned long num_phys_stacked;
|
||||
};
|
||||
|
||||
struct vcpu_guest_context {
|
||||
#define VGCF_EXTRA_REGS (1UL << 1) /* Set extra regs. */
|
||||
#define VGCF_SET_CR_IRR (1UL << 2) /* Set cr_irr[0:3]. */
|
||||
#define VGCF_online (1UL << 3) /* make this vcpu online */
|
||||
#define VGCF_SET_AR_ITC (1UL << 4) /* set pv ar.itc. itc_offset, itc_last */
|
||||
unsigned long flags; /* VGCF_* flags */
|
||||
|
||||
struct vcpu_guest_context_regs regs;
|
||||
|
||||
unsigned long event_callback_ip;
|
||||
|
||||
/* xen doesn't share privregs pages with hvm domain so that this member
|
||||
* doesn't make sense for hvm domain.
|
||||
* ~0UL is already used for INVALID_P2M_ENTRY. */
|
||||
#define VGC_PRIVREGS_HVM (~(-2UL))
|
||||
unsigned long privregs_pfn;
|
||||
};
|
||||
typedef struct vcpu_guest_context vcpu_guest_context_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
|
||||
|
||||
/* dom0 vp op */
|
||||
#define __HYPERVISOR_ia64_dom0vp_op __HYPERVISOR_arch_0
|
||||
/* Map io space in machine address to dom0 physical address space.
|
||||
Currently physical assigned address equals to machine address. */
|
||||
#define IA64_DOM0VP_ioremap 0
|
||||
|
||||
/* Convert a pseudo physical page frame number to the corresponding
|
||||
machine page frame number. If no page is assigned, INVALID_MFN or
|
||||
GPFN_INV_MASK is returned depending on domain's non-vti/vti mode. */
|
||||
#define IA64_DOM0VP_phystomach 1
|
||||
|
||||
/* Convert a machine page frame number to the corresponding pseudo physical
|
||||
page frame number of the caller domain. */
|
||||
#define IA64_DOM0VP_machtophys 3
|
||||
|
||||
/* Reserved for future use. */
|
||||
#define IA64_DOM0VP_iounmap 4
|
||||
|
||||
/* Unmap and free pages contained in the specified pseudo physical region. */
|
||||
#define IA64_DOM0VP_zap_physmap 5
|
||||
|
||||
/* Assign machine page frame to dom0's pseudo physical address space. */
|
||||
#define IA64_DOM0VP_add_physmap 6
|
||||
|
||||
/* expose the p2m table into domain */
|
||||
#define IA64_DOM0VP_expose_p2m 7
|
||||
|
||||
/* xen perfmon */
|
||||
#define IA64_DOM0VP_perfmon 8
|
||||
|
||||
/* gmfn version of IA64_DOM0VP_add_physmap */
|
||||
#define IA64_DOM0VP_add_physmap_with_gmfn 9
|
||||
|
||||
/* get fpswa revision */
|
||||
#define IA64_DOM0VP_fpswa_revision 10
|
||||
|
||||
/* Add an I/O port space range */
|
||||
#define IA64_DOM0VP_add_io_space 11
|
||||
|
||||
/* expose the foreign domain's p2m table into privileged domain */
|
||||
#define IA64_DOM0VP_expose_foreign_p2m 12
|
||||
#define IA64_DOM0VP_EFP_ALLOC_PTE 0x1 /* allocate p2m table */
|
||||
|
||||
/* unexpose the foreign domain's p2m table into privileged domain */
|
||||
#define IA64_DOM0VP_unexpose_foreign_p2m 13
|
||||
|
||||
/* get memmap_info and memmap. It is possible to map the page directly
|
||||
by foreign page mapping, but there is a race between writer.
|
||||
This hypercall avoids such race. */
|
||||
#define IA64_DOM0VP_get_memmap 14
|
||||
|
||||
// flags for page assignement to pseudo physical address space
|
||||
#define _ASSIGN_readonly 0
|
||||
#define ASSIGN_readonly (1UL << _ASSIGN_readonly)
|
||||
#define ASSIGN_writable (0UL << _ASSIGN_readonly) // dummy flag
|
||||
/* Internal only: memory attribute must be WC/UC/UCE. */
|
||||
#define _ASSIGN_nocache 1
|
||||
#define ASSIGN_nocache (1UL << _ASSIGN_nocache)
|
||||
// tlb tracking
|
||||
#define _ASSIGN_tlb_track 2
|
||||
#define ASSIGN_tlb_track (1UL << _ASSIGN_tlb_track)
|
||||
/* Internal only: associated with PGC_allocated bit */
|
||||
#define _ASSIGN_pgc_allocated 3
|
||||
#define ASSIGN_pgc_allocated (1UL << _ASSIGN_pgc_allocated)
|
||||
/* Page is an IO page. */
|
||||
#define _ASSIGN_io 4
|
||||
#define ASSIGN_io (1UL << _ASSIGN_io)
|
||||
|
||||
/* This structure has the same layout of struct ia64_boot_param, defined in
|
||||
<asm/system.h>. It is redefined here to ease use. */
|
||||
struct xen_ia64_boot_param {
|
||||
unsigned long command_line; /* physical address of cmd line args */
|
||||
unsigned long efi_systab; /* physical address of EFI system table */
|
||||
unsigned long efi_memmap; /* physical address of EFI memory map */
|
||||
unsigned long efi_memmap_size; /* size of EFI memory map */
|
||||
unsigned long efi_memdesc_size; /* size of an EFI memory map descriptor */
|
||||
unsigned int efi_memdesc_version; /* memory descriptor version */
|
||||
struct {
|
||||
unsigned short num_cols; /* number of columns on console. */
|
||||
unsigned short num_rows; /* number of rows on console. */
|
||||
unsigned short orig_x; /* cursor's x position */
|
||||
unsigned short orig_y; /* cursor's y position */
|
||||
} console_info;
|
||||
unsigned long fpswa; /* physical address of the fpswa interface */
|
||||
unsigned long initrd_start;
|
||||
unsigned long initrd_size;
|
||||
unsigned long domain_start; /* va where the boot time domain begins */
|
||||
unsigned long domain_size; /* how big is the boot domain */
|
||||
};
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/* Size of the shared_info area (this is not related to page size). */
|
||||
#define XSI_SHIFT 14
|
||||
#define XSI_SIZE (1 << XSI_SHIFT)
|
||||
/* Log size of mapped_regs area (64 KB - only 4KB is used). */
|
||||
#define XMAPPEDREGS_SHIFT 12
|
||||
#define XMAPPEDREGS_SIZE (1 << XMAPPEDREGS_SHIFT)
|
||||
/* Offset of XASI (Xen arch shared info) wrt XSI_BASE. */
|
||||
#define XMAPPEDREGS_OFS XSI_SIZE
|
||||
|
||||
/* Hyperprivops. */
|
||||
#define HYPERPRIVOP_START 0x1
|
||||
#define HYPERPRIVOP_RFI (HYPERPRIVOP_START + 0x0)
|
||||
#define HYPERPRIVOP_RSM_DT (HYPERPRIVOP_START + 0x1)
|
||||
#define HYPERPRIVOP_SSM_DT (HYPERPRIVOP_START + 0x2)
|
||||
#define HYPERPRIVOP_COVER (HYPERPRIVOP_START + 0x3)
|
||||
#define HYPERPRIVOP_ITC_D (HYPERPRIVOP_START + 0x4)
|
||||
#define HYPERPRIVOP_ITC_I (HYPERPRIVOP_START + 0x5)
|
||||
#define HYPERPRIVOP_SSM_I (HYPERPRIVOP_START + 0x6)
|
||||
#define HYPERPRIVOP_GET_IVR (HYPERPRIVOP_START + 0x7)
|
||||
#define HYPERPRIVOP_GET_TPR (HYPERPRIVOP_START + 0x8)
|
||||
#define HYPERPRIVOP_SET_TPR (HYPERPRIVOP_START + 0x9)
|
||||
#define HYPERPRIVOP_EOI (HYPERPRIVOP_START + 0xa)
|
||||
#define HYPERPRIVOP_SET_ITM (HYPERPRIVOP_START + 0xb)
|
||||
#define HYPERPRIVOP_THASH (HYPERPRIVOP_START + 0xc)
|
||||
#define HYPERPRIVOP_PTC_GA (HYPERPRIVOP_START + 0xd)
|
||||
#define HYPERPRIVOP_ITR_D (HYPERPRIVOP_START + 0xe)
|
||||
#define HYPERPRIVOP_GET_RR (HYPERPRIVOP_START + 0xf)
|
||||
#define HYPERPRIVOP_SET_RR (HYPERPRIVOP_START + 0x10)
|
||||
#define HYPERPRIVOP_SET_KR (HYPERPRIVOP_START + 0x11)
|
||||
#define HYPERPRIVOP_FC (HYPERPRIVOP_START + 0x12)
|
||||
#define HYPERPRIVOP_GET_CPUID (HYPERPRIVOP_START + 0x13)
|
||||
#define HYPERPRIVOP_GET_PMD (HYPERPRIVOP_START + 0x14)
|
||||
#define HYPERPRIVOP_GET_EFLAG (HYPERPRIVOP_START + 0x15)
|
||||
#define HYPERPRIVOP_SET_EFLAG (HYPERPRIVOP_START + 0x16)
|
||||
#define HYPERPRIVOP_RSM_BE (HYPERPRIVOP_START + 0x17)
|
||||
#define HYPERPRIVOP_GET_PSR (HYPERPRIVOP_START + 0x18)
|
||||
#define HYPERPRIVOP_SET_RR0_TO_RR4 (HYPERPRIVOP_START + 0x19)
|
||||
#define HYPERPRIVOP_MAX (0x1a)
|
||||
|
||||
/* Fast and light hypercalls. */
|
||||
#define __HYPERVISOR_ia64_fast_eoi __HYPERVISOR_arch_1
|
||||
|
||||
/* Extra debug features. */
|
||||
#define __HYPERVISOR_ia64_debug_op __HYPERVISOR_arch_2
|
||||
|
||||
/* Xencomm macros. */
|
||||
#define XENCOMM_INLINE_MASK 0xf800000000000000UL
|
||||
#define XENCOMM_INLINE_FLAG 0x8000000000000000UL
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Optimization features.
|
||||
* The hypervisor may do some special optimizations for guests. This hypercall
|
||||
* can be used to switch on/of these special optimizations.
|
||||
*/
|
||||
#define __HYPERVISOR_opt_feature 0x700UL
|
||||
|
||||
#define XEN_IA64_OPTF_OFF 0x0
|
||||
#define XEN_IA64_OPTF_ON 0x1
|
||||
|
||||
/*
|
||||
* If this feature is switched on, the hypervisor inserts the
|
||||
* tlb entries without calling the guests traphandler.
|
||||
* This is useful in guests using region 7 for identity mapping
|
||||
* like the linux kernel does.
|
||||
*/
|
||||
#define XEN_IA64_OPTF_IDENT_MAP_REG7 1
|
||||
|
||||
/* Identity mapping of region 4 addresses in HVM. */
|
||||
#define XEN_IA64_OPTF_IDENT_MAP_REG4 2
|
||||
|
||||
/* Identity mapping of region 5 addresses in HVM. */
|
||||
#define XEN_IA64_OPTF_IDENT_MAP_REG5 3
|
||||
|
||||
#define XEN_IA64_OPTF_IDENT_MAP_NOT_SET (0)
|
||||
|
||||
struct xen_ia64_opt_feature {
|
||||
unsigned long cmd; /* Which feature */
|
||||
unsigned char on; /* Switch feature on/off */
|
||||
union {
|
||||
struct {
|
||||
/* The page protection bit mask of the pte.
|
||||
* This will be or'ed with the pte. */
|
||||
unsigned long pgprot;
|
||||
unsigned long key; /* A protection key for itir. */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* xen perfmon */
|
||||
#ifdef XEN
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef _ASM_IA64_PERFMON_H
|
||||
|
||||
#include <xen/list.h> // asm/perfmon.h requires struct list_head
|
||||
#include <asm/perfmon.h>
|
||||
// for PFM_xxx and pfarg_features_t, pfarg_context_t, pfarg_reg_t, pfarg_load_t
|
||||
|
||||
#endif /* _ASM_IA64_PERFMON_H */
|
||||
|
||||
DEFINE_XEN_GUEST_HANDLE(pfarg_features_t);
|
||||
DEFINE_XEN_GUEST_HANDLE(pfarg_context_t);
|
||||
DEFINE_XEN_GUEST_HANDLE(pfarg_reg_t);
|
||||
DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* XEN */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include "arch-ia64/hvm/memmap.h"
|
||||
#endif
|
||||
|
||||
#endif /* __HYPERVISOR_IF_IA64_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,99 +0,0 @@
|
||||
/******************************************************************************
|
||||
* debug_op.h
|
||||
*
|
||||
* Copyright (c) 2007 Tristan Gingold <tgingold@free.fr>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_IA64_DEBUG_OP_H__
|
||||
#define __XEN_PUBLIC_IA64_DEBUG_OP_H__
|
||||
|
||||
/* Set/Get extra conditions to break. */
|
||||
#define XEN_IA64_DEBUG_OP_SET_FLAGS 1
|
||||
#define XEN_IA64_DEBUG_OP_GET_FLAGS 2
|
||||
|
||||
/* Break on kernel single step. */
|
||||
#define XEN_IA64_DEBUG_ON_KERN_SSTEP (1 << 0)
|
||||
|
||||
/* Break on kernel debug (breakpoint or watch point). */
|
||||
#define XEN_IA64_DEBUG_ON_KERN_DEBUG (1 << 1)
|
||||
|
||||
/* Break on kernel taken branch. */
|
||||
#define XEN_IA64_DEBUG_ON_KERN_TBRANCH (1 << 2)
|
||||
|
||||
/* Break on interrupt injection. */
|
||||
#define XEN_IA64_DEBUG_ON_EXTINT (1 << 3)
|
||||
|
||||
/* Break on interrupt injection. */
|
||||
#define XEN_IA64_DEBUG_ON_EXCEPT (1 << 4)
|
||||
|
||||
/* Break on event injection. */
|
||||
#define XEN_IA64_DEBUG_ON_EVENT (1 << 5)
|
||||
|
||||
/* Break on privop/virtualized instruction (slow path only). */
|
||||
#define XEN_IA64_DEBUG_ON_PRIVOP (1 << 6)
|
||||
|
||||
/* Break on emulated PAL call (at entry). */
|
||||
#define XEN_IA64_DEBUG_ON_PAL (1 << 7)
|
||||
|
||||
/* Break on emulated SAL call (at entry). */
|
||||
#define XEN_IA64_DEBUG_ON_SAL (1 << 8)
|
||||
|
||||
/* Break on emulated EFI call (at entry). */
|
||||
#define XEN_IA64_DEBUG_ON_EFI (1 << 9)
|
||||
|
||||
/* Break on rfi emulation (slow path only, before exec). */
|
||||
#define XEN_IA64_DEBUG_ON_RFI (1 << 10)
|
||||
|
||||
/* Break on address translation switch. */
|
||||
#define XEN_IA64_DEBUG_ON_MMU (1 << 11)
|
||||
|
||||
/* Break on bad guest physical address. */
|
||||
#define XEN_IA64_DEBUG_ON_BAD_MPA (1 << 12)
|
||||
|
||||
/* Force psr.ss bit. */
|
||||
#define XEN_IA64_DEBUG_FORCE_SS (1 << 13)
|
||||
|
||||
/* Force psr.db bit. */
|
||||
#define XEN_IA64_DEBUG_FORCE_DB (1 << 14)
|
||||
|
||||
/* Break on ITR/PTR. */
|
||||
#define XEN_IA64_DEBUG_ON_TR (1 << 15)
|
||||
|
||||
/* Break on ITC/PTC.L/PTC.G/PTC.GA. */
|
||||
#define XEN_IA64_DEBUG_ON_TC (1 << 16)
|
||||
|
||||
/* Get translation cache. */
|
||||
#define XEN_IA64_DEBUG_OP_GET_TC 3
|
||||
|
||||
/* Translate virtual address to guest physical address. */
|
||||
#define XEN_IA64_DEBUG_OP_TRANSLATE 4
|
||||
|
||||
union xen_ia64_debug_op {
|
||||
uint64_t flags;
|
||||
struct xen_ia64_debug_vtlb {
|
||||
uint64_t nbr; /* IN/OUT */
|
||||
XEN_GUEST_HANDLE_64(ia64_tr_entry_t) tr; /* IN/OUT */
|
||||
} vtlb;
|
||||
};
|
||||
typedef union xen_ia64_debug_op xen_ia64_debug_op_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_ia64_debug_op_t);
|
||||
|
||||
#endif /* __XEN_PUBLIC_IA64_DEBUG_OP_H__ */
|
||||
@@ -1,91 +0,0 @@
|
||||
/******************************************************************************
|
||||
* memmap.h
|
||||
*
|
||||
* Copyright (c) 2008 Tristan Gingold <tgingold AT free fr>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
|
||||
#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
|
||||
|
||||
#define MEM_G (1UL << 30)
|
||||
#define MEM_M (1UL << 20)
|
||||
#define MEM_K (1UL << 10)
|
||||
|
||||
/* Guest physical address of IO ports space. */
|
||||
#define MMIO_START (3 * MEM_G)
|
||||
#define MMIO_SIZE (512 * MEM_M)
|
||||
|
||||
#define VGA_IO_START 0xA0000UL
|
||||
#define VGA_IO_SIZE 0x20000
|
||||
|
||||
#define LEGACY_IO_START (MMIO_START + MMIO_SIZE)
|
||||
#define LEGACY_IO_SIZE (64 * MEM_M)
|
||||
|
||||
#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
|
||||
#define IO_PAGE_SIZE XEN_PAGE_SIZE
|
||||
|
||||
#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
|
||||
#define STORE_PAGE_SIZE XEN_PAGE_SIZE
|
||||
|
||||
#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
|
||||
#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE
|
||||
|
||||
#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
|
||||
#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE
|
||||
|
||||
#define IO_SAPIC_START 0xfec00000UL
|
||||
#define IO_SAPIC_SIZE 0x100000
|
||||
|
||||
#define PIB_START 0xfee00000UL
|
||||
#define PIB_SIZE 0x200000
|
||||
|
||||
#define GFW_START (4 * MEM_G - 16 * MEM_M)
|
||||
#define GFW_SIZE (16 * MEM_M)
|
||||
|
||||
/* domVTI */
|
||||
#define GPFN_FRAME_BUFFER 0x1 /* VGA framebuffer */
|
||||
#define GPFN_LOW_MMIO 0x2 /* Low MMIO range */
|
||||
#define GPFN_PIB 0x3 /* PIB base */
|
||||
#define GPFN_IOSAPIC 0x4 /* IOSAPIC base */
|
||||
#define GPFN_LEGACY_IO 0x5 /* Legacy I/O base */
|
||||
#define GPFN_HIGH_MMIO 0x6 /* High MMIO range */
|
||||
|
||||
/* Nvram belongs to GFW memory space */
|
||||
#define NVRAM_SIZE (MEM_K * 64)
|
||||
#define NVRAM_START (GFW_START + 10 * MEM_M)
|
||||
|
||||
#define NVRAM_VALID_SIG 0x4650494e45584948 /* "HIXENIPF" */
|
||||
struct nvram_save_addr {
|
||||
unsigned long addr;
|
||||
unsigned long signature;
|
||||
};
|
||||
|
||||
#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,208 +0,0 @@
|
||||
/******************************************************************************
|
||||
* save_types.h
|
||||
*
|
||||
* Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_HVM_SAVE_IA64_H__
|
||||
#define __XEN_PUBLIC_HVM_SAVE_IA64_H__
|
||||
|
||||
#include "../../hvm/save.h"
|
||||
#include "../../arch-ia64.h"
|
||||
|
||||
/*
|
||||
* Save/restore header: general info about the save file.
|
||||
*/
|
||||
|
||||
/* x86 uses 0x54381286 */
|
||||
#define HVM_FILE_MAGIC 0x343641492f6e6558UL /* "Xen/IA64" */
|
||||
#define HVM_FILE_VERSION 0x0000000000000001UL
|
||||
|
||||
struct hvm_save_header {
|
||||
uint64_t magic; /* Must be HVM_FILE_MAGIC */
|
||||
uint64_t version; /* File format version */
|
||||
uint64_t changeset; /* Version of Xen that saved this file */
|
||||
uint64_t cpuid[5]; /* CPUID[0x01][%eax] on the saving machine */
|
||||
};
|
||||
|
||||
DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
|
||||
|
||||
/*
|
||||
* CPU
|
||||
*/
|
||||
struct hvm_hw_ia64_cpu {
|
||||
uint64_t ipsr;
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_ia64_cpu);
|
||||
|
||||
/*
|
||||
* CPU
|
||||
*/
|
||||
struct hvm_hw_ia64_vpd {
|
||||
struct vpd vpd;
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(VPD, 3, struct hvm_hw_ia64_vpd);
|
||||
|
||||
/*
|
||||
* device dependency
|
||||
* vacpi => viosapic => vlsapic
|
||||
*/
|
||||
/*
|
||||
* vlsapic
|
||||
*/
|
||||
struct hvm_hw_ia64_vlsapic {
|
||||
uint64_t insvc[4];
|
||||
uint64_t vhpi; // ??? should this be saved in vpd
|
||||
uint8_t xtp;
|
||||
uint8_t pal_init_pending;
|
||||
uint8_t pad[2];
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(VLSAPIC, 4, struct hvm_hw_ia64_vlsapic);
|
||||
/* set
|
||||
* unconditionaly set v->arch.irq_new_peding = 1
|
||||
* unconditionaly set v->arch.irq_new_condition = 0
|
||||
*/
|
||||
|
||||
/*
|
||||
* vtime
|
||||
*/
|
||||
/* itc, itm, itv are saved by arch vcpu context */
|
||||
struct hvm_hw_ia64_vtime {
|
||||
uint64_t itc;
|
||||
uint64_t itm;
|
||||
|
||||
uint64_t last_itc;
|
||||
uint64_t pending;
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(VTIME, 5, struct hvm_hw_ia64_vtime);
|
||||
/*
|
||||
* calculate v->vtm.vtm_offset
|
||||
* ??? Or should vtm_offset be set by leave_hypervisor_tail()?
|
||||
* start vtm_timer if necessary by vtm_set_itm().
|
||||
* ??? Or should vtm_timer be set by leave_hypervisor_tail()?
|
||||
*
|
||||
* ??? or should be done by schedule_tail()
|
||||
* => schedule_tail() should do.
|
||||
*/
|
||||
|
||||
/*
|
||||
* viosapic
|
||||
*/
|
||||
#define VIOSAPIC_NUM_PINS 48
|
||||
|
||||
/* To share VT-d code which uses vioapic_redir_entry.
|
||||
* Although on ia64 this is for vsapic, but we have to vioapic_redir_entry
|
||||
* instead of viosapic_redir_entry.
|
||||
*/
|
||||
union vioapic_redir_entry
|
||||
{
|
||||
uint64_t bits;
|
||||
struct {
|
||||
uint8_t vector;
|
||||
|
||||
uint8_t delivery_mode : 3;
|
||||
uint8_t reserve1 : 1;
|
||||
uint8_t delivery_status: 1;
|
||||
uint8_t polarity : 1;
|
||||
uint8_t reserve2 : 1;
|
||||
uint8_t trig_mode : 1;
|
||||
|
||||
uint8_t mask : 1;
|
||||
uint8_t reserve3 : 7;
|
||||
|
||||
uint8_t reserved[3];
|
||||
uint16_t dest_id;
|
||||
} fields;
|
||||
};
|
||||
|
||||
struct hvm_hw_ia64_viosapic {
|
||||
uint64_t irr;
|
||||
uint64_t isr;
|
||||
uint32_t ioregsel;
|
||||
uint32_t pad;
|
||||
uint64_t lowest_vcpu_id;
|
||||
uint64_t base_address;
|
||||
union vioapic_redir_entry redirtbl[VIOSAPIC_NUM_PINS];
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(VIOSAPIC, 6, struct hvm_hw_ia64_viosapic);
|
||||
|
||||
/*
|
||||
* vacpi
|
||||
* PM timer
|
||||
*/
|
||||
struct vacpi_regs {
|
||||
union {
|
||||
struct {
|
||||
uint32_t pm1a_sts:16;/* PM1a_EVT_BLK.PM1a_STS: status register */
|
||||
uint32_t pm1a_en:16; /* PM1a_EVT_BLK.PM1a_EN: enable register */
|
||||
};
|
||||
uint32_t evt_blk;
|
||||
};
|
||||
uint32_t tmr_val; /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
|
||||
};
|
||||
|
||||
struct hvm_hw_ia64_vacpi {
|
||||
struct vacpi_regs regs;
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(VACPI, 7, struct hvm_hw_ia64_vacpi);
|
||||
/* update last_gtime and setup timer of struct vacpi */
|
||||
|
||||
/*
|
||||
* opt_feature: identity mapping of region 4, 5 and 7.
|
||||
* With the c/s 16396:d2935f9c217f of xen-ia64-devel.hg,
|
||||
* opt_feature hypercall supports only region 4,5,7 identity mappings.
|
||||
* structure hvm_hw_ia64_identity_mappings only supports them.
|
||||
* The new structure, struct hvm_hw_ia64_identity_mappings, is created to
|
||||
* avoid to keep up with change of the xen/ia64 internal structure, struct
|
||||
* opt_feature.
|
||||
*
|
||||
* If it is enhanced in the future, new structure will be created.
|
||||
*/
|
||||
struct hvm_hw_ia64_identity_mapping {
|
||||
uint64_t on; /* on/off */
|
||||
uint64_t pgprot; /* The page protection bit mask of the pte. */
|
||||
uint64_t key; /* A protection key. */
|
||||
};
|
||||
|
||||
struct hvm_hw_ia64_identity_mappings {
|
||||
struct hvm_hw_ia64_identity_mapping im_reg4;/* Region 4 identity mapping */
|
||||
struct hvm_hw_ia64_identity_mapping im_reg5;/* Region 5 identity mapping */
|
||||
struct hvm_hw_ia64_identity_mapping im_reg7;/* Region 7 identity mapping */
|
||||
};
|
||||
DECLARE_HVM_SAVE_TYPE(OPT_FEATURE_IDENTITY_MAPPINGS, 8, struct hvm_hw_ia64_identity_mappings);
|
||||
|
||||
/*
|
||||
* Largest type-code in use
|
||||
*/
|
||||
#define HVM_SAVE_CODE_MAX 8
|
||||
|
||||
#endif /* __XEN_PUBLIC_HVM_SAVE_IA64_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,92 +0,0 @@
|
||||
/******************************************************************************
|
||||
* sioemu.h
|
||||
*
|
||||
* Copyright (c) 2008 Tristan Gingold <tgingold@free.fr>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_IA64_SIOEMU_H__
|
||||
#define __XEN_PUBLIC_IA64_SIOEMU_H__
|
||||
|
||||
/* SIOEMU specific hypercalls.
|
||||
The numbers are the minor part of FW_HYPERCALL_SIOEMU. */
|
||||
|
||||
/* Defines the callback entry point. r8=ip, r9=data.
|
||||
Must be called per-vcpu. */
|
||||
#define SIOEMU_HYPERCALL_SET_CALLBACK 0x01
|
||||
|
||||
/* Finish sioemu fw initialization and start firmware. r8=ip. */
|
||||
#define SIOEMU_HYPERCALL_START_FW 0x02
|
||||
|
||||
/* Add IO pages in physmap. */
|
||||
#define SIOEMU_HYPERCALL_ADD_IO_PHYSMAP 0x03
|
||||
|
||||
/* Get wallclock time. */
|
||||
#define SIOEMU_HYPERCALL_GET_TIME 0x04
|
||||
|
||||
/* Flush cache. */
|
||||
#define SIOEMU_HYPERCALL_FLUSH_CACHE 0x07
|
||||
|
||||
/* Get freq base. */
|
||||
#define SIOEMU_HYPERCALL_FREQ_BASE 0x08
|
||||
|
||||
/* Return from callback. */
|
||||
#define SIOEMU_HYPERCALL_CALLBACK_RETURN 0x09
|
||||
|
||||
/* Deliver an interrupt. */
|
||||
#define SIOEMU_HYPERCALL_DELIVER_INT 0x0a
|
||||
|
||||
/* SIOEMU callback reason. */
|
||||
|
||||
/* An event (from event channel) has to be delivered. */
|
||||
#define SIOEMU_CB_EVENT 0x00
|
||||
|
||||
/* Emulate an IO access. */
|
||||
#define SIOEMU_CB_IO_EMULATE 0x01
|
||||
|
||||
/* An IPI is sent to a dead vcpu. */
|
||||
#define SIOEMU_CB_WAKEUP_VCPU 0x02
|
||||
|
||||
/* A SAL hypercall is executed. */
|
||||
#define SIOEMU_CB_SAL_ASSIST 0x03
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
struct sioemu_callback_info {
|
||||
/* Saved registers. */
|
||||
unsigned long ip;
|
||||
unsigned long psr;
|
||||
unsigned long ifs;
|
||||
unsigned long nats;
|
||||
unsigned long r8;
|
||||
unsigned long r9;
|
||||
unsigned long r10;
|
||||
unsigned long r11;
|
||||
|
||||
/* Callback parameters. */
|
||||
unsigned long cause;
|
||||
unsigned long arg0;
|
||||
unsigned long arg1;
|
||||
unsigned long arg2;
|
||||
unsigned long arg3;
|
||||
unsigned long _pad2[2];
|
||||
unsigned long r2;
|
||||
};
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __XEN_PUBLIC_IA64_SIOEMU_H__ */
|
||||
@@ -36,7 +36,7 @@
|
||||
* @extra_args == Operation-specific extra arguments (NULL if none).
|
||||
*/
|
||||
|
||||
/* ia64, x86: Callback for event delivery. */
|
||||
/* x86: Callback for event delivery. */
|
||||
#define CALLBACKTYPE_event 0
|
||||
|
||||
/* x86: Failsafe callback when guest state cannot be restored by Xen. */
|
||||
|
||||
@@ -392,13 +392,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t);
|
||||
#define XEN_DOMAINSETUP_sioemu_guest (1UL<<_XEN_DOMAINSETUP_sioemu_guest)
|
||||
typedef struct xen_domctl_arch_setup {
|
||||
uint64_aligned_t flags; /* XEN_DOMAINSETUP_* */
|
||||
#ifdef __ia64__
|
||||
uint64_aligned_t bp; /* mpaddr of boot param area */
|
||||
uint64_aligned_t maxmem; /* Highest memory address for MDT. */
|
||||
uint64_aligned_t xsi_va; /* Xen shared_info area virtual address. */
|
||||
uint32_t hypercall_imm; /* Break imm for Xen hypercalls. */
|
||||
int8_t vhpt_size_log2; /* Log2 of VHPT size. */
|
||||
#endif
|
||||
} xen_domctl_arch_setup_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t);
|
||||
|
||||
@@ -577,21 +570,6 @@ struct xen_domctl_ext_vcpucontext {
|
||||
typedef struct xen_domctl_ext_vcpucontext xen_domctl_ext_vcpucontext_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_domctl_ext_vcpucontext_t);
|
||||
|
||||
/*
|
||||
* Set optimizaton features for a domain
|
||||
*/
|
||||
/* XEN_DOMCTL_set_opt_feature */
|
||||
struct xen_domctl_set_opt_feature {
|
||||
#if defined(__ia64__)
|
||||
struct xen_ia64_opt_feature optf;
|
||||
#else
|
||||
/* Make struct non-empty: do not depend on this field name! */
|
||||
uint64_t dummy;
|
||||
#endif
|
||||
};
|
||||
typedef struct xen_domctl_set_opt_feature xen_domctl_set_opt_feature_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_opt_feature_t);
|
||||
|
||||
/*
|
||||
* Set the target domain for a domain
|
||||
*/
|
||||
@@ -891,7 +869,7 @@ struct xen_domctl {
|
||||
#define XEN_DOMCTL_pin_mem_cacheattr 41
|
||||
#define XEN_DOMCTL_set_ext_vcpucontext 42
|
||||
#define XEN_DOMCTL_get_ext_vcpucontext 43
|
||||
#define XEN_DOMCTL_set_opt_feature 44
|
||||
#define XEN_DOMCTL_set_opt_feature 44 /* Obsolete IA64 only */
|
||||
#define XEN_DOMCTL_test_assign_device 45
|
||||
#define XEN_DOMCTL_set_target 46
|
||||
#define XEN_DOMCTL_deassign_device 47
|
||||
@@ -956,7 +934,6 @@ struct xen_domctl {
|
||||
struct xen_domctl_ioport_mapping ioport_mapping;
|
||||
struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
|
||||
struct xen_domctl_ext_vcpucontext ext_vcpucontext;
|
||||
struct xen_domctl_set_opt_feature set_opt_feature;
|
||||
struct xen_domctl_set_target set_target;
|
||||
struct xen_domctl_subscribe subscribe;
|
||||
struct xen_domctl_debug_op debug_op;
|
||||
|
||||
@@ -82,24 +82,6 @@ struct buffered_iopage {
|
||||
}; /* NB. Size of this structure must be no greater than one page. */
|
||||
typedef struct buffered_iopage buffered_iopage_t;
|
||||
|
||||
#if defined(__ia64__)
|
||||
struct pio_buffer {
|
||||
uint32_t page_offset;
|
||||
uint32_t pointer;
|
||||
uint32_t data_end;
|
||||
uint32_t buf_size;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
#define PIO_BUFFER_IDE_PRIMARY 0 /* I/O port = 0x1F0 */
|
||||
#define PIO_BUFFER_IDE_SECONDARY 1 /* I/O port = 0x170 */
|
||||
#define PIO_BUFFER_ENTRY_NUM 2
|
||||
struct buffered_piopage {
|
||||
struct pio_buffer pio[PIO_BUFFER_ENTRY_NUM];
|
||||
uint8_t buffer[1];
|
||||
};
|
||||
#endif /* defined(__ia64__) */
|
||||
|
||||
/*
|
||||
* ACPI Control/Event register locations. Location is controlled by a
|
||||
* version number in HVM_PARAM_ACPI_IOPORTS_LOCATION.
|
||||
|
||||
@@ -54,13 +54,7 @@
|
||||
#define HVM_PARAM_BUFIOREQ_PFN 6
|
||||
#define HVM_PARAM_BUFIOREQ_EVTCHN 26
|
||||
|
||||
#ifdef __ia64__
|
||||
|
||||
#define HVM_PARAM_NVRAM_FD 7
|
||||
#define HVM_PARAM_VHPT_SIZE 8
|
||||
#define HVM_PARAM_BUFPIOREQ_PFN 9
|
||||
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
/* Expose Viridian interfaces to this HVM guest? */
|
||||
#define HVM_PARAM_VIRIDIAN 9
|
||||
|
||||
@@ -102,8 +102,6 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm_save_end);
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include "../arch-x86/hvm/save.h"
|
||||
#elif defined(__ia64__)
|
||||
#include "../arch-ia64/hvm/save.h"
|
||||
#elif defined(__arm__)
|
||||
#include "../arch-arm/hvm/save.h"
|
||||
#else
|
||||
|
||||
Loaded 100 of 103 files, more files were not shown because too many files have changed in this diff.
Show more