aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/arch
diff options
context:
space:
mode:
authorawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>2007-02-15 13:13:36 -0700
committerawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>2007-02-15 13:13:36 -0700
commit8a9e0cc712a69a1a0e8cd718cf88b53bd2896ffa (patch)
tree02ed46464ffe812a9ca07e30aaec90c2021b37be /extras/mini-os/arch
parent05325dd82113019dbf483c8c968909e7c13111aa (diff)
downloadxen-8a9e0cc712a69a1a0e8cd718cf88b53bd2896ffa.tar.gz
xen-8a9e0cc712a69a1a0e8cd718cf88b53bd2896ffa.tar.bz2
xen-8a9e0cc712a69a1a0e8cd718cf88b53bd2896ffa.zip
[IA64][MINIOS] Port of mini-os to ia64
ia64 specific parts of mini-os. Minimal config: # Kernel image file. kernel = "mini-os.gz" # Initial memory allocation (in megabytes) for the new domain. memory = 64 # A name for your domain. name = "Mini-OS" Signed-off-by: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
Diffstat (limited to 'extras/mini-os/arch')
-rw-r--r--extras/mini-os/arch/ia64/Makefile56
-rw-r--r--extras/mini-os/arch/ia64/__divdi3.S141
-rw-r--r--extras/mini-os/arch/ia64/__udivdi3.S142
-rw-r--r--extras/mini-os/arch/ia64/__umoddi3.S154
-rw-r--r--extras/mini-os/arch/ia64/arch.mk5
-rw-r--r--extras/mini-os/arch/ia64/common.c236
-rw-r--r--extras/mini-os/arch/ia64/debug.c179
-rw-r--r--extras/mini-os/arch/ia64/efi.c237
-rw-r--r--extras/mini-os/arch/ia64/fw.S519
-rw-r--r--extras/mini-os/arch/ia64/gen_off.c177
-rw-r--r--extras/mini-os/arch/ia64/ia64.S224
-rw-r--r--extras/mini-os/arch/ia64/ivt.S865
-rw-r--r--extras/mini-os/arch/ia64/minios-ia64.lds54
-rw-r--r--extras/mini-os/arch/ia64/mm.c132
-rw-r--r--extras/mini-os/arch/ia64/sal.c103
-rw-r--r--extras/mini-os/arch/ia64/sched.c74
-rw-r--r--extras/mini-os/arch/ia64/time.c280
-rw-r--r--extras/mini-os/arch/ia64/xencomm.c256
18 files changed, 3834 insertions, 0 deletions
diff --git a/extras/mini-os/arch/ia64/Makefile b/extras/mini-os/arch/ia64/Makefile
new file mode 100644
index 0000000000..58f52caff1
--- /dev/null
+++ b/extras/mini-os/arch/ia64/Makefile
@@ -0,0 +1,56 @@
+#
+# Special makefile for ia64.
+#
+
+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 += __divdi3.o
+
+GEN_OFF_SRC := gen_off.c
+GEN_OFF_BIN := gen_off
+GEN_OFF_H := $(ARCH_SPEC_INC)/offsets.h
+
+all: $(ARCH_LIB)
+
+$(GEN_OFF_BIN): $(GEN_OFF_SRC)
+ $(CC) -o $@ $(CPPFLAGS) $<
+
+$(GEN_OFF_H): $(GEN_OFF_BIN)
+ ./$(GEN_OFF_BIN) > $(GEN_OFF_H)
+
+$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+ $(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
+
+clean:
+ rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+ rm -f $(GEN_OFF_BIN)
+ rm -f $(GEN_OFF_H)
diff --git a/extras/mini-os/arch/ia64/__divdi3.S b/extras/mini-os/arch/ia64/__divdi3.S
new file mode 100644
index 0000000000..514163ca8f
--- /dev/null
+++ b/extras/mini-os/arch/ia64/__divdi3.S
@@ -0,0 +1,141 @@
+.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
diff --git a/extras/mini-os/arch/ia64/__udivdi3.S b/extras/mini-os/arch/ia64/__udivdi3.S
new file mode 100644
index 0000000000..6a1c367718
--- /dev/null
+++ b/extras/mini-os/arch/ia64/__udivdi3.S
@@ -0,0 +1,142 @@
+.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
diff --git a/extras/mini-os/arch/ia64/__umoddi3.S b/extras/mini-os/arch/ia64/__umoddi3.S
new file mode 100644
index 0000000000..790317f655
--- /dev/null
+++ b/extras/mini-os/arch/ia64/__umoddi3.S
@@ -0,0 +1,154 @@
+.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
diff --git a/extras/mini-os/arch/ia64/arch.mk b/extras/mini-os/arch/ia64/arch.mk
new file mode 100644
index 0000000000..167e3a1f50
--- /dev/null
+++ b/extras/mini-os/arch/ia64/arch.mk
@@ -0,0 +1,5 @@
+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
diff --git a/extras/mini-os/arch/ia64/common.c b/extras/mini-os/arch/ia64/common.c
new file mode 100644
index 0000000000..ee496338a2
--- /dev/null
+++ b/extras/mini-os/arch/ia64/common.c
@@ -0,0 +1,236 @@
+/*
+ * 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 "os.h"
+#include "types.h"
+#include "lib.h"
+#include "page.h"
+#include "xen/xen.h"
+#include "privop.h"
+#include "xen/callback.h"
+#include "ia64_cpu.h"
+#include "hypervisor.h"
+#include "events.h"
+#include "console.h"
+#include "time.h"
+#include "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;
+
+
+struct xen_ia64_boot_param ia64BootParamG;
+char boot_cmd_line[COMMAND_LINE_SIZE+1];
+
+
+void
+ia64_write_itr_i(ia64_pte_t* pteP, u32 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, 0);
+ xen_set_virtual_psr_ic(1);
+}
+
+extern char hypervisor_callback;
+
+static void
+registerCallback(void)
+{
+ struct callback_register event =
+ {
+ .type = SWAP(CALLBACKTYPE_event),
+ .address = SWAP((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 = SWAP(xen_start_info->nr_pages);
+ start_info.shared_info = SWAP(xen_start_info->shared_info);
+ start_info.flags = SWAP(xen_start_info->flags);
+ start_info.store_mfn = SWAP(xen_start_info->store_mfn);
+ start_info.store_evtchn = SWAP(xen_start_info->store_evtchn);
+ start_info.console.domU.mfn = SWAP(xen_start_info->console.domU.mfn);
+ start_info.console.domU.evtchn =
+ SWAP(xen_start_info->console.domU.evtchn);
+ start_info.pt_base = SWAP(xen_start_info->pt_base);
+ start_info.nr_pt_frames = SWAP(xen_start_info->nr_pt_frames);
+ start_info.mfn_list = SWAP(xen_start_info->mfn_list);
+ start_info.mod_start = SWAP(xen_start_info->mod_start);
+ start_info.mod_len = SWAP(xen_start_info->mod_len);
+}
+
+static void
+init_boot_params(void)
+{
+ /* ia64_boot_paramP is initialised in ia64.S! */
+ ia64BootParamG.command_line = SWAP(ia64_boot_paramP->command_line);
+ ia64BootParamG.efi_systab = SWAP(ia64_boot_paramP->efi_systab);
+ ia64BootParamG.efi_memmap = SWAP(ia64_boot_paramP->efi_memmap);
+ ia64BootParamG.efi_memmap_size =
+ SWAP(ia64_boot_paramP->efi_memmap_size);
+ ia64BootParamG.efi_memdesc_size =
+ SWAP(ia64_boot_paramP->efi_memdesc_size);
+ ia64BootParamG.efi_memdesc_version =
+ SWAP(ia64_boot_paramP->efi_memdesc_version);
+ ia64BootParamG.console_info.num_cols =
+ SWAP(ia64_boot_paramP->console_info.num_cols);
+ ia64BootParamG.console_info.num_rows =
+ SWAP(ia64_boot_paramP->console_info.num_rows);
+ ia64BootParamG.console_info.orig_x =
+ SWAP(ia64_boot_paramP->console_info.orig_x);
+ ia64BootParamG.console_info.orig_y =
+ SWAP(ia64_boot_paramP->console_info.orig_y);
+ ia64BootParamG.fpswa = SWAP(ia64_boot_paramP->fpswa);
+ ia64BootParamG.initrd_start = SWAP(ia64_boot_paramP->initrd_start);
+ ia64BootParamG.initrd_size = SWAP(ia64_boot_paramP->initrd_size);
+ ia64BootParamG.domain_start = SWAP(ia64_boot_paramP->domain_start);
+ ia64BootParamG.domain_size = SWAP(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;
+}
+
+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();
+ initialized = 1;
+}
+
+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);
+ 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);
+ printk("xen_guest_cmdline : %s\n", boot_cmd_line);
+}
diff --git a/extras/mini-os/arch/ia64/debug.c b/extras/mini-os/arch/ia64/debug.c
new file mode 100644
index 0000000000..d95252b4c3
--- /dev/null
+++ b/extras/mini-os/arch/ia64/debug.c
@@ -0,0 +1,179 @@
+/*
+ ****************************************************************************
+ * 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 "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
+{
+#if !defined(BIG_ENDIAN)
+ 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 */
+#else /* !BIG_ENDIAN */
+ uint64_t v :1; /* The v bit */
+ uint64_t res :25; /* reserved */
+ uint64_t rrb_pr :6;
+ uint64_t rrb_fr :7;
+ uint64_t rrb_gr :7;
+ uint64_t sor :4;
+ uint64_t sol :7; /* 7-13 size of locals (in + loc) */
+ uint64_t sof :7; /* 0-6 size of frame */
+#endif /* BIG_ENDIAN */
+} 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);
+}
diff --git a/extras/mini-os/arch/ia64/efi.c b/extras/mini-os/arch/ia64/efi.c
new file mode 100644
index 0000000000..498eac42ad
--- /dev/null
+++ b/extras/mini-os/arch/ia64/efi.c
@@ -0,0 +1,237 @@
+/*
+ * 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 "os.h"
+#include "efi.h"
+#include "page.h"
+#include "lib.h"
+#include "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;
+ }
+
+#if defined(BIG_ENDIAN)
+ tmP->Year = SWAP(tmP->Year);
+ tmP->TimeZone = SWAP(tmP->TimeZone);
+ tmP->Nanosecond = SWAP(tmP->Nanosecond);
+#endif
+
+ 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)
+{
+#if defined(BIG_ENDIAN)
+ if(SWAP(a_le->Data1) != b->Data1)
+ return 1;
+ if(SWAP(a_le->Data2) != b->Data2)
+ return 1;
+ if(SWAP(a_le->Data3) != b->Data3)
+ return 1;
+ return memcmp(a_le->Data4, b->Data4, sizeof(uint8_t)*8);
+#else
+ return memcmp(a_le, b, sizeof(efi_guid_t));
+#endif
+}
+
+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(SWAP(efiSysTableP->FirmwareVendor));
+ if (fwP) {
+ for (i = 0; i < (int)sizeof(fwVendor) - 1 && *fwP; ++i)
+ fwVendor[i] = SWAP(*fwP++);
+ fwVendor[i] = '\0';
+ }
+ PRINT_BV(" EFI-FirmwareVendor : %s\n", fwVendor);
+ PRINT_BV(" EFI-FirmwareRevision : %d\n",
+ SWAP(efiSysTableP->FirmwareRevision));
+ PRINT_BV(" EFI-SystemTable-Revision : %d.%d\n",
+ SWAP(efiSysTableP->Hdr.Revision)>>16,
+ SWAP(efiSysTableP->Hdr.Revision)&0xffff);
+ rsP = (efi_runtime_services_t*)
+ __va(SWAP(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, SWAP(mdP->Type), SWAP(mdP->Attribute));
+ PRINT_BV(" PhysStart: 0x%lx NumPages: 0x%lx\n",
+ SWAP(mdP->PhysicalStart), SWAP(mdP->NumberOfPages));
+ switch (SWAP(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",
+ SWAP(mdP->PhysicalStart),
+ SWAP(mdP->PhysicalStart)+
+ SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE);
+ if (numConvMem) {
+ printk(" Currently only one efi "
+ "memory chunk supported !!!\n");
+ break;
+ }
+ machineFwG.mach_mem_start =
+ SWAP(mdP->PhysicalStart);
+ machineFwG.mach_mem_size =
+ SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE;
+ numConvMem++;
+ break;
+ case EfiMemoryMappedIOPortSpace:
+ PRINT_BV(" -> EfiMemMappedIOPortSpace\n");
+ break;
+ case EfiPalCode:
+ machineFwG.ia64_pal_base =
+ __va(SWAP(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 (SWAP(mdP->Attribute) & EFI_MEMORY_RUNTIME) {
+ if (SWAP(mdP->Attribute) & EFI_MEMORY_WB)
+ mdP->VirtualStart =
+ SWAP(__va(mdP->PhysicalStart));
+ else {
+ if (SWAP(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(SWAP((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(SWAP((uint64_t)rsP->GetTime));
+ /* Getting efi function pointer for resetSystem. */
+ machineFwG.efi.resetSystemF =
+ (efi_reset_system_t)__va(SWAP((uint64_t)rsP->ResetSystem));
+
+ /* Scanning the Configuration table of the EfiSystemTable. */
+ PRINT_BV("NumberOfConfigTableEntries: %ld\n",
+ SWAP(efiSysTableP->NumberOfTableEntries));
+
+ confP = (efi_configuration_table_t*)
+ __va(SWAP(efiSysTableP->ConfigurationTable));
+ for (i = 0; i < SWAP(efiSysTableP->NumberOfTableEntries); i++) {
+ if (!efi_guid_cmp(&confP[i].VendorGuid, &sal)) {
+ machineFwG.ia64_sal_tableP = (sal_system_table_t*)
+ __va(SWAP((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(SWAP((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(SWAP((uint64_t) confP[i].VendorTable));
+ PRINT_BV(" Found Acpi20Table at: 0x%lx\n",
+ (uint64_t) machineFwG.ia64_efi_acpi20_table);
+ continue;
+ }
+ }
+}
diff --git a/extras/mini-os/arch/ia64/fw.S b/extras/mini-os/arch/ia64/fw.S
new file mode 100644
index 0000000000..db89dfa934
--- /dev/null
+++ b/extras/mini-os/arch/ia64/fw.S
@@ -0,0 +1,519 @@
+/*
+ * 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 "asm.h"
+#include "page.h"
+#include "ia64_cpu.h"
+#include "ia64_fpu.h"
+#include "offsets.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
+#if defined(BIG_ENDIAN)
+ mux1 r14=r14,@rev // swap because mini-os is in BE
+ mov ar.rsc=3
+ ;;
+#endif
+ mov out0=in1
+ mov out1=in2
+ mov out2=in3
+ mov out3=in4
+ mov out4=in5
+ mov b6=r14
+ ;;
+#if defined(BIG_ENDIAN)
+ mux1 gp=gp,@rev // swap because mini-os is in BE
+ rum IA64_PSR_BE
+ ;;
+#endif
+
+ br.call.sptk.many rp=b6 // call EFI procedure
+
+#if defined(BIG_ENDIAN)
+ ;;
+ sum IA64_PSR_BE
+ mov ar.rsc=IA64_RSE_EAGER
+#endif
+ 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
+ ;;
+#if defined(BIG_ENDIAN)
+ rum IA64_PSR_BE // set psr.be==0
+ ;;
+#endif
+ br.cond.sptk b6 // call into firmware
+ ;;
+#if defined(BIG_ENDIAN)
+ sum IA64_PSR_BE // set psr.be==1
+ ;;
+#endif
+ 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
+ ;;
+#if defined(BIG_ENDIAN)
+ mux1 r14=r14,@rev // swap if mini-os is in BE
+ mux1 gp=gp,@rev // swap if mini-os is in BE
+#endif
+ ;;
+ mov b6=r14
+
+#if defined(BIG_ENDIAN)
+ rum IA64_PSR_BE
+ ;;
+#endif
+
+ br.call.sptk.many rp=b6 // call EFI procedure
+
+#if defined(BIG_ENDIAN)
+ sum IA64_PSR_BE
+ ;;
+#endif
+
+ 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)
diff --git a/extras/mini-os/arch/ia64/gen_off.c b/extras/mini-os/arch/ia64/gen_off.c
new file mode 100644
index 0000000000..b5d2f15c1e
--- /dev/null
+++ b/extras/mini-os/arch/ia64/gen_off.c
@@ -0,0 +1,177 @@
+/*
+ * 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 <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include "types.h"
+#include "sched.h"
+#include "xen/xen.h"
+#include "xen/arch-ia64.h"
+
+#define SZ(st,e) sizeof(((st *)0)->e)
+#define OFF(st,e,d,o) print_define(fp, #d, offsetof(st, e) + o, SZ(st, e))
+#define TFOFF(e,d) OFF(trap_frame_t, e, d, 0)
+#define SIZE(st,d) fprintf(fp, "#define %-30s\t0x%016lx\n", #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)
+
+void
+print_define(FILE *fp, char *name, uint64_t val, int size)
+{
+ char ld_name[64];
+ char st_name[64];
+ char sz_name[64];
+
+ strcpy(ld_name, name);
+ strcat(ld_name, "_ld");
+ strcpy(st_name, name);
+ strcat(st_name, "_st");
+ strcpy(sz_name, name);
+ strcat(sz_name, "_sz");
+ fprintf(fp, "#define %-30s\t0x%016lx\n", name, val);
+ fprintf(fp, "#define %-30s\t%u\n", sz_name, size);
+ switch (size) {
+ case 1:
+ fprintf(fp, "#define %-30s\tld1\n", ld_name);
+ fprintf(fp, "#define %-30s\tst1\n", st_name);
+ break;
+ case 2:
+ fprintf(fp, "#define %-30s\tld2\n", ld_name);
+ fprintf(fp, "#define %-30s\tst2\n", st_name);
+ break;
+ case 4:
+ fprintf(fp, "#define %-30s\tld4\n", ld_name);
+ fprintf(fp, "#define %-30s\tst4\n", st_name);
+ break;
+ case 8:
+ fprintf(fp, "#define %-30s\tld8\n", ld_name);
+ fprintf(fp, "#define %-30s\tst8\n", st_name);
+ break;
+ default: ;
+ }
+ return;
+}
+
+
+int
+main(int argc, char ** argv)
+{
+ FILE *fp;
+
+ fp = stdout;
+
+ 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);
+}
diff --git a/extras/mini-os/arch/ia64/ia64.S b/extras/mini-os/arch/ia64/ia64.S
new file mode 100644
index 0000000000..63721b4c36
--- /dev/null
+++ b/extras/mini-os/arch/ia64/ia64.S
@@ -0,0 +1,224 @@
+/*
+ * 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 "asm.h"
+#include "page.h"
+#include "ia64_cpu.h"
+#include "ia64_fpu.h"
+#include "privop.h"
+#include "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
+ ;;
+
+ /*
+ * Now pin mappings into the TLB for kernel text and data
+ */
+ mov r18=KERNEL_TR_PAGE_SIZE<<2
+ 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
+ ;;
+#if defined(BIG_ENDIAN)
+ mux1 r14=r14,@rev // swap because mini-os is in BE
+#endif
+ ;;
+ 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
+ ;;
+
+ 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)
diff --git a/extras/mini-os/arch/ia64/ivt.S b/extras/mini-os/arch/ia64/ivt.S
new file mode 100644
index 0000000000..86f8bb4060
--- /dev/null
+++ b/extras/mini-os/arch/ia64/ivt.S
@@ -0,0 +1,865 @@
+/*
+ * 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 "asm.h"
+#include "page.h"
+#include "ia64_cpu.h"
+#include "privop.h"
+#include "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
+#if defined(BIG_ENDIAN)
+ mux1 r21=r21,@rev // swap because mini-os is in BE
+ mux1 r22=r22,@rev // swap because mini-os is in BE
+ ;;
+#endif
+ 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;;
+#if defined(BIG_ENDIAN)
+ mux1 r31=r31,@rev // swap because mini-os is in BE
+ ;;
+#endif
+ 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;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r16=r16,@rev; mux1 r17=r17,@rev;;
+#endif
+ ld8 r18=[r30],16; ld8 r19=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r18=r18,@rev; mux1 r19=r19,@rev;;
+#endif
+ ld8 r20=[r30],16; ld8 r21=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r20=r20,@rev; mux1 r21=r21,@rev;;
+#endif
+ ld8 r22=[r30],16; ld8 r23=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r22=r22,@rev; mux1 r23=r23,@rev;;
+#endif
+ ld8 r24=[r30],16; ld8 r25=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r24=r24,@rev; mux1 r25=r25,@rev;;
+#endif
+ ld8 r26=[r30],16; ld8 r27=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r26=r26,@rev; mux1 r27=r27,@rev;;
+#endif
+ ld8 r28=[r30],16; ld8 r29=[r31],16;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r28=r28,@rev; mux1 r29=r29,@rev;;
+#endif
+ ld8 r30=[r30]; ld8 r31=[r31];;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r30=r30,@rev; mux1 r31=r31,@rev;;
+#endif
+
+ 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];
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r21=r21,@rev
+ ;;
+#endif
+ 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
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ ;;
+ mux1 r21=r21,@rev
+ mux1 r22=r22,@rev
+ ;;
+#endif
+ 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 r19=(MOS_IA64_RSC_BE << IA64_RSC_BE)
+ ;;
+ or r21=(MOS_IA64_RSC_BE << IA64_RSC_BE),r21
+ ;;
+ 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
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r22=r22,@rev
+ ;;
+#endif
+ 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;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r31=r31,@rev
+ ;;
+#endif
+ 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
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r16=r16,@rev; mux1 r17=r17,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r16,16
+ .mem.offset 8,0; st8.spill [r3]=r17,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r18=r18,@rev; mux1 r19=r19,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r18,16
+ .mem.offset 8,0; st8.spill [r3]=r19,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r20=r20,@rev; mux1 r21=r21,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r20,16
+ .mem.offset 8,0; st8.spill [r3]=r21,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r22=r22,@rev; mux1 r23=r23,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r22,16
+ .mem.offset 8,0; st8.spill [r3]=r23,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r24=r24,@rev; mux1 r25=r25,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r24,16
+ .mem.offset 8,0; st8.spill [r3]=r25,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r26=r26,@rev; mux1 r27=r27,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r26,16
+ .mem.offset 8,0; st8.spill [r3]=r27,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r28=r28,@rev; mux1 r29=r29,@rev;;
+#endif
+ .mem.offset 0,0; st8.spill [r2]=r28,16
+ .mem.offset 8,0; st8.spill [r3]=r29,16
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r30=r30,@rev; mux1 r31=r31,@rev;;
+#endif
+ .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
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 loc3=loc3,@rev; mux1 loc4=loc4,@rev;;
+#endif
+ st8 [loc5]=loc3,TF_IIM-TF_IFA // store cr.ifa
+ st8 [loc6]=loc4 // store cr.isr
+ ;;
+ ld8 loc3=[loc1] // load XEN.iim
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 loc3=loc3,@rev;;
+#endif
+ st8 [loc5]=loc3 // store cr.iim
+ ;;
+ mov ar.pfs=loc0
+ ;;
+ br.ret.sptk.few rp
+END(save_special_regs)
+
+
+ENTRY(hypervisor_callback)
+ // Calculate the stack address for storing.
+ // Use the kernel stack here because it's mapped wired!
+ // -> no nested tlb faults!
+ movl r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE
+
+ //add r18=-TF_SIZE,sp
+ add r30=0xabab,r0
+ ;;
+{ .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_trap_error
+ ;;
+ mov out0=r18 // the trap frame
+ movl r22=XSI_PSR_IC
+ mov r23=1;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r23=r23,@rev;;
+#endif
+ 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 r16=16,sp // load EF-pointer again
+ ;;
+ //mov r18=sp
+ movl r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE
+ ;;
+
+ // 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
+ ;;
+
+ //bsw.1
+ movl r30=XSI_BANKNUM
+ mov r31=1;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r31=r31,@rev;;
+#endif
+ 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
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r25=r25,@rev; mux1 r23=r23,@rev;;
+#endif
+ 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
+ ;;
+#if defined(BIG_ENDIAN) // swap because mini-os is in BE
+ mux1 r25=r25,@rev;;
+ mux1 r25=r25,@rev; mux1 r23=r23,@rev;;
+#endif
+ 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
+ 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)|(0<<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)
+
+
+IVT_ERR(Data_Nested_TLB, 5, 0x1400)
+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)
diff --git a/extras/mini-os/arch/ia64/minios-ia64.lds b/extras/mini-os/arch/ia64/minios-ia64.lds
new file mode 100644
index 0000000000..70435de11e
--- /dev/null
+++ b/extras/mini-os/arch/ia64/minios-ia64.lds
@@ -0,0 +1,54 @@
+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) }
+
+ .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) }
+
+ _end = .;
+
+}
diff --git a/extras/mini-os/arch/ia64/mm.c b/extras/mini-os/arch/ia64/mm.c
new file mode 100644
index 0000000000..ad5acccc7e
--- /dev/null
+++ b/extras/mini-os/arch/ia64/mm.c
@@ -0,0 +1,132 @@
+/*
+ * 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 "os.h"
+#include "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;
+
+/* 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;
+}
+
+/* Helper function used in gnttab.c. */
+void*
+map_frames(unsigned long* frames, unsigned long n)
+{
+ n = n;
+ return (void*) __va(frames[0] << PAGE_SHIFT);
+}
+
diff --git a/extras/mini-os/arch/ia64/sal.c b/extras/mini-os/arch/ia64/sal.c
new file mode 100644
index 0000000000..d087053287
--- /dev/null
+++ b/extras/mini-os/arch/ia64/sal.c
@@ -0,0 +1,103 @@
+/*
+ * 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 "os.h"
+#include "lib.h"
+#include "console.h"
+#include "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 < SWAP(saltab->sal_entry_count); i++) {
+ switch (SWAP(*p)) {
+ case SAL_DESC_ENTRYPOINT: // 0
+ {
+ struct sal_entrypoint_descriptor *dp;
+
+ dp = (struct sal_entrypoint_descriptor*)p;
+ ia64_pal_entry =
+ IA64_PHYS_TO_RR7(SWAP(dp->sale_pal_proc));
+ PRINT_BV(" PAL Proc at 0x%lx\n", ia64_pal_entry);
+ sal_fdesc.func =
+ IA64_PHYS_TO_RR7(SWAP(dp->sale_sal_proc));
+ sal_fdesc.gp = IA64_PHYS_TO_RR7(SWAP(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];
+ }
+}
+
diff --git a/extras/mini-os/arch/ia64/sched.c b/extras/mini-os/arch/ia64/sched.c
new file mode 100644
index 0000000000..64052b6fc5
--- /dev/null
+++ b/extras/mini-os/arch/ia64/sched.c
@@ -0,0 +1,74 @@
+/*
+ * 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 "types.h"
+#include "sched.h"
+#include "lib.h"
+#include "xmalloc.h"
+#include "mm.h"
+
+/* The function is implemented in fw.S */
+extern void thread_starter(void);
+
+struct thread*
+arch_create_thread(char *name, void (*function)(void *), void *data)
+{
+ struct thread* _thread;
+
+ _thread = (struct thread*)_xmalloc(sizeof(struct thread), 16);
+ /* Allocate 2 pages for stack, stack will be 2pages aligned */
+ _thread->stack = (char *)alloc_pages(1);
+ _thread->name = name;
+ memset((void*)&(_thread->regs), 0, sizeof(_thread->regs));
+ _thread->regs.sp = ((uint64_t)_thread->stack) + 2 * PAGE_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__);
+}
diff --git a/extras/mini-os/arch/ia64/time.c b/extras/mini-os/arch/ia64/time.c
new file mode 100644
index 0000000000..2d943e8c7a
--- /dev/null
+++ b/extras/mini-os/arch/ia64/time.c
@@ -0,0 +1,280 @@
+/*
+ * Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
+ * Description: simple ia64 specific time handling
+ * mktime() is taken from Linux (see copyright below)
+ * Parts are taken from FreeBSD.
+ *
+ ****************************************************************************
+ * For the copy of the mktime() from linux.
+ * 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
+ *
+ ****************************************************************************
+ *
+ * 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 "os.h"
+#include "console.h"
+#include "time.h"
+#include "efi.h"
+#include "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;
+
+
+/*
+ * mktime() is take from Linux. See copyright above.
+ * 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.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * 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 year0, const unsigned int mon0,
+ const unsigned int day, const unsigned int hour,
+ const unsigned int min, const unsigned int sec)
+{
+ unsigned int mon = mon0, year = year0;
+
+ /* 1..12 -> 11,12,1..10 */
+ if (0 >= (int) (mon -= 2)) {
+ mon += 12; /* Puts Feb last since it has leap day */
+ year -= 1;
+ }
+
+ return (
+ (
+ ((unsigned long)
+ (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+ year*365 - 719499
+ ) * 24 + hour /* now have hours */
+ ) * 60 + min /* now have minutes */
+ ) * 60 + sec; /* finally seconds */
+}
+
+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.ts_nsec += new;
+ if (os_time.ts_nsec > 1000000000) { /* On overflow. */
+ os_time.ts_sec++;
+ os_time.ts_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()
+ */
+u64
+monotonic_clock(void)
+{
+ uint64_t delta;
+
+ delta = ia64_get_itc() - itc_at_boot;
+ delta = ns_from_cycles(delta);
+ return delta;
+}
+
+void
+gettimeofday(struct timeval *tv)
+{
+ calculate_time();
+ tv->tv_sec = os_time.ts_sec; /* seconds */
+ tv->tv_usec = NSEC_TO_USEC(os_time.ts_nsec); /* microseconds */
+};
+
+/*
+ * 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_call(SAL_FREQ_BASE, 0, 0, 0, 0, 0, 0, 0);
+#if defined(BIG_ENDIAN)
+//#warning calculate_frequencies TODO
+ /*
+ * I have to do an own function with switching psr.be!
+ * Currently it's running because it's a break into the hypervisor
+ * behind the call.!
+ */
+#endif
+ 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;
+ int err = 0;
+
+ printk("Initialising time\n");
+ calculate_frequencies();
+
+ itm_val = (itc_frequency + HZ/2) / HZ;
+ printk(" itm_val: %ld\n", itm_val);
+
+ os_time.ts_sec = 0;
+ os_time.ts_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.ts_sec = mktime(SWAP(tm.Year), SWAP(tm.Month),
+ SWAP(tm.Day), SWAP(tm.Hour),
+ SWAP(tm.Minute), SWAP(tm.Second));
+ os_time.ts_nsec = tm.Nanosecond;
+ } else
+ printk("efi_get_time() failed\n");
+
+ err = bind_virq(VIRQ_ITC, timer_interrupt, NULL);
+ if (err != 0) {
+ printk("XEN timer request chn bind failed %i\n", err);
+ return;
+ }
+ 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();
+}
diff --git a/extras/mini-os/arch/ia64/xencomm.c b/extras/mini-os/arch/ia64/xencomm.c
new file mode 100644
index 0000000000..587576a0b4
--- /dev/null
+++ b/extras/mini-os/arch/ia64/xencomm.c
@@ -0,0 +1,256 @@
+/*
+ * 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 <os.h>
+#include <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)
+
+
+/* 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;
+}
+
+#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++] = SWAP(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++] = SWAP(XENCOMM_INVALID);
+ desc->magic = SWAP(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,
+ 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 *)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;
+}
+
+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);
+}
+