mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[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>
This commit is contained in:
1 parent
05325dd821
commit
8a9e0cc712
34 files changed
+6965
No files matched your search
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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 = .;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MM_H__
|
||||
#define __ARCH_MM_H__
|
||||
|
||||
#include "page.h"
|
||||
|
||||
#define PFN_PHYS(x) (pfn_to_page(x))
|
||||
#define PHYS_PFN(x) (page_to_pfn(x))
|
||||
#define to_virt(x) __va(x)
|
||||
#define to_phys(x) __pa(x)
|
||||
|
||||
#define virt_to_mfn(x) virt_to_pfn(x)
|
||||
|
||||
#endif /* __ARCH_MM_H__ */
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* The file contains ia64 specific scheduler declarations.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SCHED_H__
|
||||
#define __ARCH_SCHED_H__
|
||||
|
||||
#include "os.h"
|
||||
|
||||
struct thread; /* Only declaration */
|
||||
|
||||
struct thread_regs
|
||||
{
|
||||
unsigned long unat_b; /* NaT before spilling */
|
||||
unsigned long sp;
|
||||
unsigned long rp;
|
||||
unsigned long pr;
|
||||
unsigned long bsp;
|
||||
unsigned long pfs;
|
||||
unsigned long rnat;
|
||||
unsigned long lc;
|
||||
|
||||
unsigned long unat_a; /* NaT after spilling. */
|
||||
unsigned long r4;
|
||||
unsigned long r5;
|
||||
unsigned long r6;
|
||||
unsigned long r7;
|
||||
|
||||
unsigned long b1;
|
||||
unsigned long b2;
|
||||
unsigned long b3;
|
||||
unsigned long b4;
|
||||
unsigned long b5;
|
||||
|
||||
ia64_fpreg_t f2;
|
||||
ia64_fpreg_t f3;
|
||||
ia64_fpreg_t f4;
|
||||
ia64_fpreg_t f5;
|
||||
ia64_fpreg_t f16;
|
||||
ia64_fpreg_t f17;
|
||||
ia64_fpreg_t f18;
|
||||
ia64_fpreg_t f19;
|
||||
ia64_fpreg_t f20;
|
||||
ia64_fpreg_t f21;
|
||||
ia64_fpreg_t f22;
|
||||
ia64_fpreg_t f23;
|
||||
ia64_fpreg_t f24;
|
||||
ia64_fpreg_t f25;
|
||||
ia64_fpreg_t f26;
|
||||
ia64_fpreg_t f27;
|
||||
ia64_fpreg_t f28;
|
||||
ia64_fpreg_t f29;
|
||||
ia64_fpreg_t f30;
|
||||
ia64_fpreg_t f31;
|
||||
};
|
||||
|
||||
typedef struct thread_regs thread_regs_t;
|
||||
|
||||
void arch_switch_threads(struct thread* prev, struct thread* next);
|
||||
|
||||
static inline struct thread* get_current(void)
|
||||
{
|
||||
struct thread *current;
|
||||
__asm ("mov %0=r13" : "=r" (current));
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __ARCH_SCHED_H__ */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
* The file contains ia64 special spinlock stuff.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _ARCH_SPINLOCK_H_
|
||||
#define _ARCH_SPINLOCK_H_
|
||||
|
||||
#include "atomic.h"
|
||||
|
||||
#define ARCH_SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
|
||||
|
||||
#define SPIN_LOCK_UNUSED 0
|
||||
#define SPIN_LOCK_USED 1
|
||||
|
||||
|
||||
static inline void
|
||||
_raw_spin_lock(spinlock_t* lck)
|
||||
{
|
||||
uint32_t ret;
|
||||
do {
|
||||
ret = ia64_cmpxchg_acq_32(&(lck->slock),
|
||||
SPIN_LOCK_UNUSED, SPIN_LOCK_USED);
|
||||
} while (ret == SPIN_LOCK_USED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_raw_spin_unlock(spinlock_t *lck)
|
||||
{
|
||||
asm volatile ("st4.rel.nta [%0] = r0\n\t" :: "r"(&(lck->slock))
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
_raw_spin_trylock(spinlock_t* lck)
|
||||
{
|
||||
uint32_t ret;
|
||||
ret = ia64_cmpxchg_acq_32(&(lck->slock), SPIN_LOCK_USED, SPIN_LOCK_USED);
|
||||
return (ret == SPIN_LOCK_USED);
|
||||
}
|
||||
|
||||
#endif /* _ARCH_SPINLOCK_H_ */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
|
||||
*/
|
||||
|
||||
#if !defined(_ASM_H_)
|
||||
#define _ASM_H_
|
||||
|
||||
#define ENTRY(_name_) \
|
||||
.global _name_; \
|
||||
.align 16; \
|
||||
.proc _name_; \
|
||||
_name_:; \
|
||||
|
||||
|
||||
#define END(_name_) \
|
||||
.endp _name_
|
||||
|
||||
#endif /* !defined(_ASM_H_) */
|
||||
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
* This code is mostly taken from FreeBSD machine/atomic.h
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (c) 1998 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_ATOMIC_H_
|
||||
#define _MACHINE_ATOMIC_H_
|
||||
|
||||
/*
|
||||
* Various simple arithmetic on memory which is atomic in the presence
|
||||
* of interrupts and SMP safe.
|
||||
*/
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
#include <types.h>
|
||||
|
||||
|
||||
/*
|
||||
* Everything is built out of cmpxchg.
|
||||
*/
|
||||
#define IA64_CMPXCHG(sz, sem, p, cmpval, newval, ret) \
|
||||
__asm __volatile ( \
|
||||
"mov ar.ccv=%2;;\n\t" \
|
||||
"cmpxchg" #sz "." #sem " %0=%4,%3,ar.ccv\n\t" \
|
||||
: "=r" (ret), "=m" (*p) \
|
||||
: "r" (cmpval), "r" (newval), "m" (*p) \
|
||||
: "memory")
|
||||
|
||||
|
||||
/*
|
||||
* Some common forms of cmpxch.
|
||||
*/
|
||||
|
||||
static __inline uint8_t
|
||||
ia64_cmpxchg_acq_8(volatile uint8_t* p, uint8_t cmpval, uint8_t newval)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
IA64_CMPXCHG(1, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
ia64_cmpxchg_acq_16(volatile uint16_t* p, uint16_t cmpval, uint16_t newval)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
IA64_CMPXCHG(2, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
ia64_cmpxchg_acq_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
IA64_CMPXCHG(4, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
ia64_cmpxchg_rel_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
IA64_CMPXCHG(4, rel, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
ia64_cmpxchg_acq_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
IA64_CMPXCHG(8, acq, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
ia64_cmpxchg_rel_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
IA64_CMPXCHG(8, rel, p, cmpval, newval, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#define ATOMIC_STORE_LOAD(type, width, size) \
|
||||
static __inline uint##width##_t \
|
||||
ia64_ld_acq_##width(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline uint##width##_t \
|
||||
atomic_load_acq_##width(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline uint##width##_t \
|
||||
atomic_load_acq_##type(volatile uint##width##_t* p) \
|
||||
{ \
|
||||
uint##width##_t v; \
|
||||
\
|
||||
__asm __volatile ("ld" size ".acq %0=%1" \
|
||||
: "=r" (v) \
|
||||
: "m" (*p) \
|
||||
: "memory"); \
|
||||
return (v); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_st_rel_##width(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_store_rel_##width(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_store_rel_##type(volatile uint##width##_t* p, uint##width##_t v)\
|
||||
{ \
|
||||
__asm __volatile ("st" size ".rel %0=%1" \
|
||||
: "=m" (*p) \
|
||||
: "r" (v) \
|
||||
: "memory"); \
|
||||
}
|
||||
|
||||
ATOMIC_STORE_LOAD(char, 8, "1")
|
||||
ATOMIC_STORE_LOAD(short, 16, "2")
|
||||
ATOMIC_STORE_LOAD(int, 32, "4")
|
||||
ATOMIC_STORE_LOAD(long, 64, "8")
|
||||
|
||||
#undef ATOMIC_STORE_LOAD
|
||||
|
||||
#define IA64_ATOMIC(sz, type, name, width, op) \
|
||||
\
|
||||
static __inline type \
|
||||
atomic_##name##_acq_##width(volatile type *p, type v) \
|
||||
{ \
|
||||
type old, ret; \
|
||||
do { \
|
||||
old = *p; \
|
||||
IA64_CMPXCHG(sz, acq, p, old, old op v, ret); \
|
||||
} while (ret != old); \
|
||||
return(ret); \
|
||||
} \
|
||||
\
|
||||
static __inline type \
|
||||
atomic_##name##_rel_##width(volatile type *p, type v) \
|
||||
{ \
|
||||
type old, ret; \
|
||||
do { \
|
||||
old = *p; \
|
||||
IA64_CMPXCHG(sz, rel, p, old, old op v, ret); \
|
||||
} while (ret != old); \
|
||||
return(ret); \
|
||||
}
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, set, 8, |)
|
||||
IA64_ATOMIC(2, uint16_t, set, 16, |)
|
||||
IA64_ATOMIC(4, uint32_t, set, 32, |)
|
||||
IA64_ATOMIC(8, uint64_t, set, 64, |)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, clear, 8, &~)
|
||||
IA64_ATOMIC(2, uint16_t, clear, 16, &~)
|
||||
IA64_ATOMIC(4, uint32_t, clear, 32, &~)
|
||||
IA64_ATOMIC(8, uint64_t, clear, 64, &~)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, add, 8, +)
|
||||
IA64_ATOMIC(2, uint16_t, add, 16, +)
|
||||
IA64_ATOMIC(4, uint32_t, add, 32, +)
|
||||
IA64_ATOMIC(8, uint64_t, add, 64, +)
|
||||
|
||||
IA64_ATOMIC(1, uint8_t, subtract, 8, -)
|
||||
IA64_ATOMIC(2, uint16_t, subtract, 16, -)
|
||||
IA64_ATOMIC(4, uint32_t, subtract, 32, -)
|
||||
IA64_ATOMIC(8, uint64_t, subtract, 64, -)
|
||||
|
||||
#undef IA64_ATOMIC
|
||||
#undef IA64_CMPXCHG
|
||||
|
||||
#define atomic_set_8 atomic_set_acq_8
|
||||
#define atomic_clear_8 atomic_clear_acq_8
|
||||
#define atomic_add_8 atomic_add_acq_8
|
||||
#define atomic_subtract_8 atomic_subtract_acq_8
|
||||
|
||||
#define atomic_set_16 atomic_set_acq_16
|
||||
#define atomic_clear_16 atomic_clear_acq_16
|
||||
#define atomic_add_16 atomic_add_acq_16
|
||||
#define atomic_subtract_16 atomic_subtract_acq_16
|
||||
|
||||
#define atomic_set_32 atomic_set_acq_32
|
||||
#define atomic_clear_32 atomic_clear_acq_32
|
||||
#define atomic_add_32 atomic_add_acq_32
|
||||
#define atomic_subtract_32 atomic_subtract_acq_32
|
||||
|
||||
#define atomic_set_64 atomic_set_acq_64
|
||||
#define atomic_clear_64 atomic_clear_acq_64
|
||||
#define atomic_add_64 atomic_add_acq_64
|
||||
#define atomic_subtract_64 atomic_subtract_acq_64
|
||||
|
||||
#define atomic_set_char atomic_set_8
|
||||
#define atomic_clear_char atomic_clear_8
|
||||
#define atomic_add_char atomic_add_8
|
||||
#define atomic_subtract_char atomic_subtract_8
|
||||
#define atomic_set_acq_char atomic_set_acq_8
|
||||
#define atomic_clear_acq_char atomic_clear_acq_8
|
||||
#define atomic_add_acq_char atomic_add_acq_8
|
||||
#define atomic_subtract_acq_char atomic_subtract_acq_8
|
||||
#define atomic_set_rel_char atomic_set_rel_8
|
||||
#define atomic_clear_rel_char atomic_clear_rel_8
|
||||
#define atomic_add_rel_char atomic_add_rel_8
|
||||
#define atomic_subtract_rel_char atomic_subtract_rel_8
|
||||
|
||||
#define atomic_set_short atomic_set_16
|
||||
#define atomic_clear_short atomic_clear_16
|
||||
#define atomic_add_short atomic_add_16
|
||||
#define atomic_subtract_short atomic_subtract_16
|
||||
#define atomic_set_acq_short atomic_set_acq_16
|
||||
#define atomic_clear_acq_short atomic_clear_acq_16
|
||||
#define atomic_add_acq_short atomic_add_acq_16
|
||||
#define atomic_subtract_acq_short atomic_subtract_acq_16
|
||||
#define atomic_set_rel_short atomic_set_rel_16
|
||||
#define atomic_clear_rel_short atomic_clear_rel_16
|
||||
#define atomic_add_rel_short atomic_add_rel_16
|
||||
#define atomic_subtract_rel_short atomic_subtract_rel_16
|
||||
|
||||
#define atomic_set_int atomic_set_32
|
||||
#define atomic_clear_int atomic_clear_32
|
||||
#define atomic_add_int atomic_add_32
|
||||
#define atomic_subtract_int atomic_subtract_32
|
||||
#define atomic_set_acq_int atomic_set_acq_32
|
||||
#define atomic_clear_acq_int atomic_clear_acq_32
|
||||
#define atomic_add_acq_int atomic_add_acq_32
|
||||
#define atomic_subtract_acq_int atomic_subtract_acq_32
|
||||
#define atomic_set_rel_int atomic_set_rel_32
|
||||
#define atomic_clear_rel_int atomic_clear_rel_32
|
||||
#define atomic_add_rel_int atomic_add_rel_32
|
||||
#define atomic_subtract_rel_int atomic_subtract_rel_32
|
||||
|
||||
#define atomic_set_long atomic_set_64
|
||||
#define atomic_clear_long atomic_clear_64
|
||||
#define atomic_add_long atomic_add_64
|
||||
#define atomic_subtract_long atomic_subtract_64
|
||||
#define atomic_set_acq_long atomic_set_acq_64
|
||||
#define atomic_clear_acq_long atomic_clear_acq_64
|
||||
#define atomic_add_acq_long atomic_add_acq_64
|
||||
#define atomic_subtract_acq_long atomic_subtract_acq_64
|
||||
#define atomic_set_rel_long atomic_set_rel_64
|
||||
#define atomic_clear_rel_long atomic_clear_rel_64
|
||||
#define atomic_add_rel_long atomic_add_rel_64
|
||||
#define atomic_subtract_rel_long atomic_subtract_rel_64
|
||||
|
||||
/*
|
||||
* Atomically compare the value stored at *p with cmpval and if the
|
||||
* two values are equal, update the value of *p with newval. Returns
|
||||
* zero if the compare failed, nonzero otherwise.
|
||||
*/
|
||||
static __inline int
|
||||
atomic_cmpset_acq_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_acq_32(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_32(volatile uint32_t* p, uint32_t cmpval, uint32_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_rel_32(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically compare the value stored at *p with cmpval and if the
|
||||
* two values are equal, update the value of *p with newval. Returns
|
||||
* zero if the compare failed, nonzero otherwise.
|
||||
*/
|
||||
static __inline int
|
||||
atomic_cmpset_acq_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_acq_64(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_64(volatile uint64_t* p, uint64_t cmpval, uint64_t newval)
|
||||
{
|
||||
return ia64_cmpxchg_rel_64(p, cmpval, newval) == cmpval;
|
||||
}
|
||||
|
||||
#define atomic_cmpset_32 atomic_cmpset_acq_32
|
||||
#define atomic_cmpset_64 atomic_cmpset_acq_64
|
||||
#define atomic_cmpset_int atomic_cmpset_32
|
||||
#define atomic_cmpset_long atomic_cmpset_64
|
||||
#define atomic_cmpset_acq_int atomic_cmpset_acq_32
|
||||
#define atomic_cmpset_rel_int atomic_cmpset_rel_32
|
||||
#define atomic_cmpset_acq_long atomic_cmpset_acq_64
|
||||
#define atomic_cmpset_rel_long atomic_cmpset_rel_64
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_acq_ptr(volatile void *dst, void *exp, void *src)
|
||||
{
|
||||
return atomic_cmpset_acq_long((volatile u_long *)dst,
|
||||
(u_long)exp, (u_long)src);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src)
|
||||
{
|
||||
return atomic_cmpset_rel_long((volatile u_long *)dst,
|
||||
(u_long)exp, (u_long)src);
|
||||
}
|
||||
|
||||
#define atomic_cmpset_ptr atomic_cmpset_acq_ptr
|
||||
|
||||
static __inline void *
|
||||
atomic_load_acq_ptr(volatile void *p)
|
||||
{
|
||||
return (void *)atomic_load_acq_long((volatile u_long *)p);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_store_rel_ptr(volatile void *p, void *v)
|
||||
{
|
||||
atomic_store_rel_long((volatile u_long *)p, (u_long)v);
|
||||
}
|
||||
|
||||
#define IA64_ATOMIC_PTR(NAME) \
|
||||
static __inline void \
|
||||
atomic_##NAME##_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_long((volatile u_long *)p, v); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_##NAME##_acq_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_acq_long((volatile u_long *)p, v);\
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
atomic_##NAME##_rel_ptr(volatile void *p, uintptr_t v) \
|
||||
{ \
|
||||
atomic_##NAME##_rel_long((volatile u_long *)p, v);\
|
||||
}
|
||||
|
||||
IA64_ATOMIC_PTR(set)
|
||||
IA64_ATOMIC_PTR(clear)
|
||||
IA64_ATOMIC_PTR(add)
|
||||
IA64_ATOMIC_PTR(subtract)
|
||||
|
||||
#undef IA64_ATOMIC_PTR
|
||||
|
||||
static __inline uint32_t
|
||||
atomic_readandclear_32(volatile uint32_t* p)
|
||||
{
|
||||
uint32_t val;
|
||||
do {
|
||||
val = *p;
|
||||
} while (!atomic_cmpset_32(p, val, 0));
|
||||
return val;
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
atomic_readandclear_64(volatile uint64_t* p)
|
||||
{
|
||||
uint64_t val;
|
||||
do {
|
||||
val = *p;
|
||||
} while (!atomic_cmpset_64(p, val, 0));
|
||||
return val;
|
||||
}
|
||||
|
||||
#define atomic_readandclear_int atomic_readandclear_32
|
||||
#define atomic_readandclear_long atomic_readandclear_64
|
||||
|
||||
|
||||
/* Some bit operations */
|
||||
|
||||
static inline void
|
||||
set_bit(int num, volatile void *addr)
|
||||
{
|
||||
uint32_t bit, b, old, new;
|
||||
volatile uint32_t *p;
|
||||
p = (volatile uint32_t *) addr + (num >> 5);
|
||||
b = 1 << (num & 31);
|
||||
bit = SWAP(b);
|
||||
do
|
||||
{
|
||||
old = *p;
|
||||
new = old | bit;
|
||||
} while(ia64_cmpxchg_acq_32(p, old, new) != old);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
clear_bit(int num, volatile void *addr)
|
||||
{
|
||||
uint32_t mask, m, old, new;
|
||||
volatile uint32_t *p;
|
||||
p = (volatile uint32_t *) addr + (num >> 5);
|
||||
m = ~(1 << (num & 31));
|
||||
mask = SWAP(m);
|
||||
do {
|
||||
old = *p;
|
||||
new = old & mask;
|
||||
} while (ia64_cmpxchg_acq_32(p, old, new) != old);
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
test_bit(int num, const volatile void *addr)
|
||||
{
|
||||
uint32_t val = SWAP(1);
|
||||
return val & (((const volatile uint32_t *) addr)[num >> 5] >> (num & 31));
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_set_bit - Set a bit and return its old value
|
||||
* num: Bit to set
|
||||
* addr: Address to count from
|
||||
*/
|
||||
static inline int
|
||||
test_and_set_bit (int num, volatile void *addr)
|
||||
{
|
||||
uint32_t bit, b, old, new;
|
||||
volatile uint32_t *m;
|
||||
|
||||
m = (volatile uint32_t *) addr + (num >> 5);
|
||||
b = 1 << (num & 31);
|
||||
bit = SWAP(b);
|
||||
do {
|
||||
old = *m;
|
||||
new = old | bit;
|
||||
} while (ia64_cmpxchg_acq_32(m, old, new) != old);
|
||||
return (old & bit) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* num: Bit to set
|
||||
* addr: Address to count from
|
||||
*/
|
||||
static
|
||||
inline int test_and_clear_bit(int num, volatile unsigned long * addr)
|
||||
{
|
||||
uint32_t bit, b, old, new;
|
||||
volatile uint32_t* a;
|
||||
|
||||
a = (volatile uint32_t *) addr + (num >> 5);
|
||||
b = ~(1 << (num & 31));
|
||||
bit = SWAP(b);
|
||||
do {
|
||||
old = *a;
|
||||
new = old & bit;
|
||||
} while (ia64_cmpxchg_acq_32(a, old, new) != old);
|
||||
return (old & ~bit) != 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#endif /* ! _MACHINE_ATOMIC_H_ */
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* This is a short summary of declarations and definitions from different
|
||||
* efi header files of Intels' EFI_Toolkit_1.10.14.62
|
||||
* used for the minimal implementation in mini-os.
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (C) 2001-2004, Intel Corporation.
|
||||
* THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO WARRANTIES WHATSOEVER,
|
||||
* INCLUDING ANY WARRANTY OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR
|
||||
* ANY PARTICULAR PURPOSE, OR ANY WARRANTY OTHERWISE ARISING OUT OF ANY
|
||||
* PROPOSAL, SPECIFICATION OR SAMPLE. Except for a limited copyright license
|
||||
* to copy this specification for internal use only, no license, express or
|
||||
* implied, by estoppel or otherwise, to any intellectual property rights is
|
||||
* granted herein. Intel disclaims all liability, including liability for
|
||||
* infringement of any proprietary rights, relating to implementation of
|
||||
* information in this specification. Intel does not warrant or represent
|
||||
* that such implementation(s) will not infringe such rights. Designers must
|
||||
* not rely on the absence or characteristics of any features or instructions
|
||||
* marked "reserved" or "undefined." Intel reserves these for future
|
||||
* definition and shall have no responsibility whatsoever for conflicts or
|
||||
* incompatibilities arising from future changes to them.
|
||||
* This document is an intermediate draft for comment only and is subject to
|
||||
* change without notice. Readers should not design products based on this
|
||||
* document.
|
||||
* Intel, the Intel logo, and Itanium are trademarks or registered trademarks
|
||||
* of Intel Corporation or its subsidiaries in the United States and other
|
||||
* countries.
|
||||
* Other names and brands may be claimed as the property of others.
|
||||
*/
|
||||
|
||||
#ifndef _EFI_H_
|
||||
#define _EFI_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
#define EFIWARN(a) (a)
|
||||
#define EFI_ERROR(a) (((int64_t) a) < 0)
|
||||
|
||||
|
||||
#define EFI_SUCCESS 0
|
||||
#define EFI_LOAD_ERROR EFIERR(1)
|
||||
#define EFI_INVALID_PARAMETER EFIERR(2)
|
||||
#define EFI_UNSUPPORTED EFIERR(3)
|
||||
#define EFI_BAD_BUFFER_SIZE EFIERR(4)
|
||||
#define EFI_BUFFER_TOO_SMALL EFIERR(5)
|
||||
#define EFI_NOT_READY EFIERR(6)
|
||||
#define EFI_DEVICE_ERROR EFIERR(7)
|
||||
#define EFI_WRITE_PROTECTED EFIERR(8)
|
||||
#define EFI_OUT_OF_RESOURCES EFIERR(9)
|
||||
#define EFI_VOLUME_CORRUPTED EFIERR(10)
|
||||
#define EFI_VOLUME_FULL EFIERR(11)
|
||||
#define EFI_NO_MEDIA EFIERR(12)
|
||||
#define EFI_MEDIA_CHANGED EFIERR(13)
|
||||
#define EFI_NOT_FOUND EFIERR(14)
|
||||
#define EFI_ACCESS_DENIED EFIERR(15)
|
||||
#define EFI_NO_RESPONSE EFIERR(16)
|
||||
#define EFI_NO_MAPPING EFIERR(17)
|
||||
#define EFI_TIMEOUT EFIERR(18)
|
||||
#define EFI_NOT_STARTED EFIERR(19)
|
||||
#define EFI_ALREADY_STARTED EFIERR(20)
|
||||
#define EFI_ABORTED EFIERR(21)
|
||||
#define EFI_ICMP_ERROR EFIERR(22)
|
||||
#define EFI_TFTP_ERROR EFIERR(23)
|
||||
#define EFI_PROTOCOL_ERROR EFIERR(24)
|
||||
|
||||
#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1)
|
||||
#define EFI_WARN_DELETE_FAILURE EFIWARN(2)
|
||||
#define EFI_WARN_WRITE_FAILURE EFIWARN(3)
|
||||
#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4)
|
||||
|
||||
|
||||
typedef uint64_t efi_status_t;
|
||||
typedef void* efi_handle_t;
|
||||
typedef void* efi_event_t;
|
||||
typedef uint16_t efi_char16_t;
|
||||
|
||||
|
||||
/*
|
||||
* Standard EFI table header
|
||||
*/
|
||||
|
||||
struct efi_table_header
|
||||
{
|
||||
uint64_t Signature;
|
||||
// Revision of EFI table specification,
|
||||
// upper 16 bit - major revision number
|
||||
// lower 16 bit - minor revision number
|
||||
uint32_t Revision;
|
||||
uint32_t HeaderSize;
|
||||
uint32_t CRC32;
|
||||
uint32_t Reserved;
|
||||
};
|
||||
typedef struct efi_table_header efi_table_header_t;
|
||||
|
||||
/*
|
||||
* EFI Time
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Year; /* 1998 - 20XX */
|
||||
uint8_t Month; /* 1 - 12 */
|
||||
uint8_t Day; /* 1 - 31 */
|
||||
uint8_t Hour; /* 0 - 23 */
|
||||
uint8_t Minute; /* 0 - 59 */
|
||||
uint8_t Second; /* 0 - 59 */
|
||||
uint8_t Pad1;
|
||||
uint32_t Nanosecond; /* 0 - 999,999,999 */
|
||||
int16_t TimeZone; /* -1440 to 1440 or 2047 */
|
||||
uint8_t Daylight;
|
||||
uint8_t Pad2;
|
||||
} efi_time_t;
|
||||
|
||||
/* Bit definitions for efi_time_t.Daylight */
|
||||
#define EFI_TIME_ADJUST_DAYLIGHT 0x01
|
||||
#define EFI_TIME_IN_DAYLIGHT 0x02
|
||||
|
||||
/* Value definition for efi_time_t.TimeZone */
|
||||
#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Resolution; /* 1e-6 parts per million */
|
||||
uint32_t Accuracy; /* hertz */
|
||||
uint8_t SetsToZero; /* Set clears sub-second time */
|
||||
} efi_time_capabilities_t;
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_get_time_t) (efi_time_t*, efi_time_capabilities_t*);
|
||||
typedef efi_status_t (*efi_set_time_t) (efi_time_t*);
|
||||
typedef efi_status_t (*efi_get_wakeup_time_t) (uint8_t*, uint8_t*, efi_time_t*);
|
||||
typedef efi_status_t (*efi_set_wakeup_time_t) (uint8_t, efi_time_t*);
|
||||
|
||||
/*
|
||||
* Memory
|
||||
* Preseve the attr on any range supplied.
|
||||
* ConventialMemory must have WB,SR,SW when supplied.
|
||||
* When allocating from ConventialMemory always make it WB,SR,SW
|
||||
* When returning to ConventialMemory always make it WB,SR,SW
|
||||
* When getting the memory map, or on RT for runtime types
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
EfiReservedMemoryType, /* 0 */
|
||||
EfiLoaderCode,
|
||||
EfiLoaderData,
|
||||
EfiBootServicesCode,
|
||||
EfiBootServicesData,
|
||||
EfiRuntimeServicesCode,
|
||||
EfiRuntimeServicesData, /* 6 */
|
||||
EfiConventionalMemory, /* 7 */
|
||||
EfiUnusableMemory,
|
||||
EfiACPIReclaimMemory, /* 9 */
|
||||
EfiACPIMemoryNVS, /* 10, a */
|
||||
EfiMemoryMappedIO,
|
||||
EfiMemoryMappedIOPortSpace, /* 12, c */
|
||||
EfiPalCode, /* 13, d */
|
||||
EfiMaxMemoryType /* 14, e */
|
||||
} efi_memory_type_t;
|
||||
|
||||
/* possible caching types for the memory range */
|
||||
#define EFI_MEMORY_UC 0x0000000000000001
|
||||
#define EFI_MEMORY_WC 0x0000000000000002
|
||||
#define EFI_MEMORY_WT 0x0000000000000004
|
||||
#define EFI_MEMORY_WB 0x0000000000000008
|
||||
#define EFI_MEMORY_UCE 0x0000000000000010
|
||||
/* physical memory protection on range */
|
||||
#define EFI_MEMORY_WP 0x0000000000001000
|
||||
#define EFI_MEMORY_RP 0x0000000000002000
|
||||
#define EFI_MEMORY_XP 0x0000000000004000
|
||||
/* range requires a runtime mapping */
|
||||
#define EFI_MEMORY_RUNTIME 0x8000000000000000
|
||||
|
||||
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
|
||||
|
||||
typedef uint64_t efi_phys_addr_t;
|
||||
typedef uint64_t efi_virt_addr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Type; /* 32 bit padding */
|
||||
efi_phys_addr_t PhysicalStart;
|
||||
efi_virt_addr_t VirtualStart;
|
||||
uint64_t NumberOfPages;
|
||||
uint64_t Attribute;
|
||||
} efi_memory_descriptor_t;
|
||||
|
||||
#define NextMemoryDescriptor(Ptr,Size) ((efi_memory_descriptor_t*) (((uint8_t*) Ptr) + Size))
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_set_virtual_address_map_t)
|
||||
(
|
||||
uint64_t MemoryMapSize,
|
||||
uint64_t DescriptorSize,
|
||||
uint32_t DescriptorVersion,
|
||||
efi_memory_descriptor_t* VirtualMap
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_convert_pointer_t)
|
||||
(
|
||||
uint64_t DebugDisposition,
|
||||
void** Address
|
||||
);
|
||||
|
||||
/*
|
||||
* A GUID
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Data1;
|
||||
uint16_t Data2;
|
||||
uint16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
} efi_guid_t;
|
||||
|
||||
/*
|
||||
* EFI Configuration Table and GUID definitions
|
||||
*/
|
||||
|
||||
#define MPS_TABLE_GUID \
|
||||
{ 0xeb9d2d2f, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define ACPI_TABLE_GUID \
|
||||
{ 0xeb9d2d30, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define ACPI_20_TABLE_GUID \
|
||||
{ 0x8868e871, 0xe4f1, 0x11d3, \
|
||||
{ 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
|
||||
|
||||
#define SMBIOS_TABLE_GUID \
|
||||
{ 0xeb9d2d31, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
#define SAL_SYSTEM_TABLE_GUID \
|
||||
{ 0xeb9d2d32, 0x2d88, 0x11d3, \
|
||||
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
|
||||
|
||||
/* DIG64 Headless Console & Debug Port Table. */
|
||||
#define HCDP_TABLE_GUID \
|
||||
{0xf951938d, 0x620b, 0x42ef, \
|
||||
{0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } }
|
||||
|
||||
|
||||
typedef struct efi_configuration_table
|
||||
{
|
||||
efi_guid_t VendorGuid;
|
||||
void* VendorTable;
|
||||
} efi_configuration_table_t;
|
||||
|
||||
|
||||
/*
|
||||
* EFI platform variables
|
||||
*/
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
{ 0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, \
|
||||
0xE0, 0x98, 0x03, 0x2B, 0x8C }
|
||||
|
||||
/* Variable attributes */
|
||||
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
|
||||
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
|
||||
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
|
||||
|
||||
/* Variable size limitation */
|
||||
#define EFI_MAXIMUM_VARIABLE_SIZE 1024
|
||||
|
||||
typedef efi_status_t (*efi_get_variable_t)
|
||||
(
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t *VendorGuid,
|
||||
uint32_t* Attributes,
|
||||
uint64_t* DataSize,
|
||||
void* Data
|
||||
);
|
||||
|
||||
typedef
|
||||
efi_status_t (*efi_get_next_variable_name_t)
|
||||
(
|
||||
uint64_t* VariableNameSize,
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t* VendorGuid
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_set_variable_t)
|
||||
(
|
||||
efi_char16_t* VariableName,
|
||||
efi_guid_t* VendorGuid,
|
||||
uint32_t Attributes,
|
||||
uint64_t DataSize,
|
||||
void* Data
|
||||
);
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EfiResetCold,
|
||||
EfiResetWarm,
|
||||
EfiResetShutdown
|
||||
} efi_reset_type_t;
|
||||
|
||||
|
||||
typedef efi_status_t (*efi_reset_system_t)
|
||||
(
|
||||
efi_reset_type_t ResetType,
|
||||
efi_status_t ResetStatus,
|
||||
uint64_t DataSize,
|
||||
efi_char16_t* ResetData
|
||||
);
|
||||
|
||||
typedef efi_status_t (*efi_get_next_high_mono_count_t) (uint32_t* HighCount);
|
||||
|
||||
|
||||
/*
|
||||
* EFI Runtime Serivces Table
|
||||
*/
|
||||
|
||||
#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552
|
||||
#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) \
|
||||
| (EFI_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
efi_table_header_t Hdr;
|
||||
/* Time services */
|
||||
efi_get_time_t GetTime;
|
||||
efi_set_time_t SetTime;
|
||||
efi_get_wakeup_time_t GetWakeupTime;
|
||||
efi_set_wakeup_time_t SetWakeupTime;
|
||||
/* Virtual memory services */
|
||||
efi_set_virtual_address_map_t SetVirtualAddressMap;
|
||||
efi_convert_pointer_t ConvertPointer;
|
||||
/* Variable serviers */
|
||||
efi_get_variable_t GetVariable;
|
||||
efi_get_next_variable_name_t GetNextVariableName;
|
||||
efi_set_variable_t SetVariable;
|
||||
/* Misc */
|
||||
efi_get_next_high_mono_count_t GetNextHighMonotonicCount;
|
||||
efi_reset_system_t ResetSystem;
|
||||
|
||||
} efi_runtime_services_t;
|
||||
|
||||
|
||||
#define EFI_SPECIFICATION_MAJOR_REVISION 1
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
|
||||
#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) \
|
||||
| (EFI_SPECIFICATION_MINOR_REVISION))
|
||||
|
||||
struct efi_system_table
|
||||
{
|
||||
efi_table_header_t Hdr;
|
||||
|
||||
uint64_t FirmwareVendor; // phys addr of CHAR16
|
||||
uint32_t FirmwareRevision; // Firmware vendor specific
|
||||
|
||||
efi_handle_t ConsoleInHandle;
|
||||
uint64_t ConIn;
|
||||
|
||||
efi_handle_t ConsoleOutHandle;
|
||||
uint64_t ConOut;
|
||||
|
||||
efi_handle_t StandardErrorHandle;
|
||||
uint64_t StdErr;
|
||||
|
||||
uint64_t RuntimeServices; // phys addr
|
||||
uint64_t BootServices; // phys addr
|
||||
|
||||
uint64_t NumberOfTableEntries; // Number of entries in Config
|
||||
uint64_t ConfigurationTable; // phys addr of ConfigTable
|
||||
};
|
||||
|
||||
typedef struct efi_system_table efi_system_table_t;
|
||||
|
||||
|
||||
#define EFI_PAGE_SIZE 4096
|
||||
#define EFI_PAGE_MASK 0xFFF
|
||||
#define EFI_PAGE_SHIFT 12
|
||||
|
||||
#define EFI_SIZE_TO_PAGES(a) \
|
||||
( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) )
|
||||
|
||||
|
||||
void init_efi(void);
|
||||
int efi_get_time(efi_time_t* tmP);
|
||||
efi_status_t ia64_call_efi_physical(void *, ...);
|
||||
|
||||
|
||||
#endif /* _EFI_H_ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(_ENDIAN_H_)
|
||||
#define _ENDIAN_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
#if defined(BIG_ENDIAN)
|
||||
|
||||
static __inline uint64_t
|
||||
__bswap64(uint64_t __x)
|
||||
{
|
||||
uint64_t __r;
|
||||
asm __volatile("mux1 %0=%1,@rev" : "=r" (__r) : "r"(__x));
|
||||
return __r;
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
__bswap32(uint32_t __x)
|
||||
{
|
||||
return (__bswap64(__x) >> 32);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
__bswap16(uint16_t __x)
|
||||
{
|
||||
return (__bswap64(__x) >> 48);
|
||||
}
|
||||
|
||||
#define doswap(x,sz) ( \
|
||||
((sz)==1)? (uint8_t)(x): \
|
||||
((sz)==2)? __bswap16(x): \
|
||||
((sz)==4)? __bswap32(x): \
|
||||
((sz)==8)? __bswap64(x): \
|
||||
~0l )
|
||||
|
||||
#define SWAP(x) doswap((x), sizeof((x)))
|
||||
|
||||
|
||||
#else /* defined(BIG_ENDIAN) */
|
||||
|
||||
#define SWAP(x) (x)
|
||||
|
||||
#endif /* defined(BIG_ENDIAN) */
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
|
||||
#endif /* !defined(_ENDIAN_H_) */
|
||||
@@ -0,0 +1,226 @@
|
||||
/******************************************************************************
|
||||
* hypercall.h
|
||||
*
|
||||
* Mini-OS-specific hypervisor handling for ia64.
|
||||
*
|
||||
* Copyright (c) 2002-2004, K A Fraser
|
||||
* Changes: Dietmar Hahn <dietmar.hahn@fujiti-siemens.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation; or, when distributed
|
||||
* separately from the Linux kernel or incorporated into other
|
||||
* software packages, subject to the following license:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this source file (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __HYPERCALL_H__
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include "lib.h" /* memcpy() */
|
||||
#include "errno.h" /* ENOSYS() */
|
||||
#include <xen/event_channel.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/version.h>
|
||||
|
||||
#ifndef _HYPERVISOR_H_
|
||||
# error "please don't include this file directly"
|
||||
#endif
|
||||
|
||||
// See linux/compiler.h
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4,
|
||||
unsigned long a5, unsigned long cmd);
|
||||
/*
|
||||
* Assembler stubs for hyper-calls.
|
||||
*/
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall(0, 0, 0, 0, 0, \
|
||||
__HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall1(type, name, a1) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
0, 0, 0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall2(type, name, a1, a2) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
0, 0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall3(type, name, a1, a2, a3) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
0, 0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall4(type, name, a1, a2, a3, a4) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
(unsigned long)a4, \
|
||||
0, __HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
|
||||
({ \
|
||||
long __res; \
|
||||
__res = __hypercall((unsigned long)a1, \
|
||||
(unsigned long)a2, \
|
||||
(unsigned long)a3, \
|
||||
(unsigned long)a4, \
|
||||
(unsigned long)a5, \
|
||||
__HYPERVISOR_##name); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
|
||||
extern unsigned long xencomm_vaddr_to_paddr(unsigned long vaddr);
|
||||
struct xencomm_handle;
|
||||
|
||||
/* Inline version. To be used only on linear space (kernel space). */
|
||||
static inline struct xencomm_handle *
|
||||
xencomm_create_inline(void *buffer)
|
||||
{
|
||||
unsigned long paddr;
|
||||
|
||||
paddr = xencomm_vaddr_to_paddr((unsigned long)buffer);
|
||||
return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG);
|
||||
}
|
||||
|
||||
static inline int
|
||||
xencomm_arch_event_channel_op(int cmd, void *arg)
|
||||
{
|
||||
int rc;
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
rc = _hypercall2(int, event_channel_op, cmd, newArg);
|
||||
if (unlikely(rc == -ENOSYS)) {
|
||||
struct evtchn_op op;
|
||||
|
||||
op.cmd = cmd;
|
||||
memcpy(&op.u, arg, sizeof(op.u));
|
||||
rc = _hypercall1(int, event_channel_op_compat, &op);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#define HYPERVISOR_event_channel_op xencomm_arch_event_channel_op
|
||||
|
||||
static inline int
|
||||
xencomm_arch_xen_version(int cmd, struct xencomm_handle *arg)
|
||||
{
|
||||
return _hypercall2(int, xen_version, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
xencomm_arch_xen_feature(int cmd, struct xencomm_handle *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, xen_version, cmd, newArg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_xen_version(int cmd, void *arg)
|
||||
{
|
||||
switch(cmd) {
|
||||
case XENVER_version:
|
||||
return xencomm_arch_xen_version(cmd, 0);
|
||||
case XENVER_get_features:
|
||||
return xencomm_arch_xen_feature(cmd, arg);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
xencomm_arch_console_io(int cmd, int count, char *str)
|
||||
{
|
||||
struct xencomm_handle *newStr;
|
||||
|
||||
newStr = xencomm_create_inline(str);
|
||||
return _hypercall3(int, console_io, cmd, count, newStr);
|
||||
}
|
||||
|
||||
|
||||
#define HYPERVISOR_console_io xencomm_arch_console_io
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op_compat(int cmd, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_compat, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
xencomm_arch_sched_op(int cmd, void *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, sched_op, cmd, newArg);
|
||||
}
|
||||
|
||||
#define HYPERVISOR_sched_op xencomm_arch_sched_op
|
||||
|
||||
static inline int
|
||||
xencomm_arch_callback_op(int cmd, void *arg)
|
||||
{
|
||||
struct xencomm_handle *newArg;
|
||||
|
||||
newArg = xencomm_create_inline(arg);
|
||||
return _hypercall2(int, callback_op, cmd, newArg);
|
||||
}
|
||||
#define HYPERVISOR_callback_op xencomm_arch_callback_op
|
||||
|
||||
static inline int
|
||||
xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
|
||||
struct xencomm_handle *uop,
|
||||
unsigned int count)
|
||||
{
|
||||
return _hypercall3(int, grant_table_op, cmd, uop, count);
|
||||
}
|
||||
|
||||
int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
@@ -0,0 +1,776 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* This code is mostly taken from FreeBSD.
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright (c) 2000 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IA64_CPU_H_
|
||||
#define _IA64_CPU_H_
|
||||
|
||||
#include "ia64_fpu.h"
|
||||
|
||||
/*
|
||||
* Definition of Region Register bits (RR)
|
||||
*
|
||||
* RR bit field positions
|
||||
*/
|
||||
#define IA64_RR_VE 0
|
||||
#define IA64_RR_MBZ0 1
|
||||
#define IA64_RR_PS 2
|
||||
#define IA64_RR_PS_LEN 6
|
||||
#define IA64_RR_RID 8
|
||||
#define IA64_RR_RID_LEN 24
|
||||
#define IA64_RR_MBZ1 32
|
||||
|
||||
#define IA64_RR_IDX_POS 61
|
||||
|
||||
#define IA64_RR_VAL(size,rid) (((size) << IA64_RR_PS) | ((rid) << IA64_RR_RID))
|
||||
|
||||
/*
|
||||
* Define Protection Key Register (PKR)
|
||||
*
|
||||
* PKR bit field positions
|
||||
*/
|
||||
#define IA64_PKR_V 0
|
||||
#define IA64_PKR_WD 1
|
||||
#define IA64_PKR_RD 2
|
||||
#define IA64_PKR_XD 3
|
||||
#define IA64_PKR_MBZ0 4
|
||||
#define IA64_PKR_KEY 8
|
||||
#define IA64_PKR_KEY_LEN 24
|
||||
#define IA64_PKR_MBZ1 32
|
||||
|
||||
#define IA64_PKR_VALID (1 << IA64_PKR_V)
|
||||
|
||||
|
||||
/*
|
||||
* ITIR bit field positions
|
||||
*/
|
||||
|
||||
#define IA64_ITIR_MBZ0 0
|
||||
#define IA64_ITIR_PS 2
|
||||
#define IA64_ITIR_PS_LEN 6
|
||||
#define IA64_ITIR_KEY 8
|
||||
#define IA64_ITIR_KEY_LEN 24
|
||||
#define IA64_ITIR_MBZ1 32
|
||||
#define IA64_ITIR_MBZ1_LEN 16
|
||||
#define IA64_ITIR_PPN 48
|
||||
#define IA64_ITIR_PPN_LEN 15
|
||||
#define IA64_ITIR_MBZ2 63
|
||||
|
||||
/*
|
||||
* Definition of PSR and IPSR bits.
|
||||
*/
|
||||
#define IA64_PSR_BE 0x0000000000000002
|
||||
#define IA64_PSR_UP 0x0000000000000004
|
||||
#define IA64_PSR_AC 0x0000000000000008
|
||||
#define IA64_PSR_MFL 0x0000000000000010
|
||||
#define IA64_PSR_MFH_BIT 5
|
||||
#define IA64_PSR_MFH (1 << IA64_PSR_MFH_BIT)
|
||||
#define IA64_PSR_UMASK (IA64_PSR_BE | IA64_PSR_UP | \
|
||||
IA64_PSR_AC | IA64_PSR_MFL | \
|
||||
IA64_PSR_MFH)
|
||||
#define IA64_PSR_IC_BIT 13
|
||||
#define IA64_PSR_IC (1<<IA64_PSR_IC_BIT) /*0x0000000000002000*/
|
||||
#define IA64_PSR_I_BIT 14
|
||||
#define IA64_PSR_I (1<<IA64_PSR_I_BIT) /*0x0000000000004000*/
|
||||
#define IA64_PSR_PK 0x0000000000008000
|
||||
#define IA64_PSR_DT 0x0000000000020000
|
||||
#define IA64_PSR_DFL 0x0000000000040000
|
||||
#define IA64_PSR_DFH 0x0000000000080000
|
||||
#define IA64_PSR_SP 0x0000000000100000
|
||||
#define IA64_PSR_PP 0x0000000000200000
|
||||
#define IA64_PSR_DI 0x0000000000400000
|
||||
#define IA64_PSR_SI 0x0000000000800000
|
||||
#define IA64_PSR_DB 0x0000000001000000
|
||||
#define IA64_PSR_LP 0x0000000002000000
|
||||
#define IA64_PSR_TB 0x0000000004000000
|
||||
#define IA64_PSR_RT 0x0000000008000000
|
||||
#define IA64_PSR_CPL 0x0000000300000000
|
||||
#define IA64_PSR_CPL_KERN 0x0000000000000000
|
||||
#define IA64_PSR_CPL_1 0x0000000100000000
|
||||
#define IA64_PSR_CPL_2 0x0000000200000000
|
||||
#define IA64_PSR_CPL_USER 0x0000000300000000
|
||||
#define IA64_PSR_IS 0x0000000400000000
|
||||
#define IA64_PSR_MC 0x0000000800000000
|
||||
#define IA64_PSR_IT 0x0000001000000000
|
||||
#define IA64_PSR_ID 0x0000002000000000
|
||||
#define IA64_PSR_DA 0x0000004000000000
|
||||
#define IA64_PSR_DD 0x0000008000000000
|
||||
#define IA64_PSR_SS 0x0000010000000000
|
||||
#define IA64_PSR_RI 0x0000060000000000
|
||||
#define IA64_PSR_RI_0 0x0000000000000000
|
||||
#define IA64_PSR_RI_1 0x0000020000000000
|
||||
#define IA64_PSR_RI_2 0x0000040000000000
|
||||
#define IA64_PSR_RI_SHIFT 41
|
||||
#define IA64_PSR_ED 0x0000080000000000
|
||||
#define IA64_PSR_BN 0x0000100000000000
|
||||
#define IA64_PSR_IA 0x0000200000000000
|
||||
|
||||
|
||||
/* Endianess of mini-os. */
|
||||
#if defined(BIG_ENDIAN)
|
||||
#define MOS_IA64_PSR_BE IA64_PSR_BE
|
||||
#else
|
||||
#define MOS_IA64_PSR_BE 0
|
||||
#endif
|
||||
|
||||
#define STARTUP_PSR (IA64_PSR_IT | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_2 | IA64_PSR_AC)
|
||||
|
||||
#define MOS_SYS_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_2 | IA64_PSR_AC)
|
||||
|
||||
#define MOS_USR_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \
|
||||
IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \
|
||||
IA64_PSR_BN | IA64_PSR_CPL_USER | IA64_PSR_AC)
|
||||
|
||||
/*
|
||||
* Definition of ISR bits.
|
||||
*/
|
||||
#define IA64_ISR_CODE 0x000000000000ffff
|
||||
#define IA64_ISR_VECTOR 0x0000000000ff0000
|
||||
#define IA64_ISR_X 0x0000000100000000
|
||||
#define IA64_ISR_W 0x0000000200000000
|
||||
#define IA64_ISR_R 0x0000000400000000
|
||||
#define IA64_ISR_NA 0x0000000800000000
|
||||
#define IA64_ISR_SP 0x0000001000000000
|
||||
#define IA64_ISR_RS 0x0000002000000000
|
||||
#define IA64_ISR_IR 0x0000004000000000
|
||||
#define IA64_ISR_NI 0x0000008000000000
|
||||
#define IA64_ISR_SO 0x0000010000000000
|
||||
#define IA64_ISR_EI 0x0000060000000000
|
||||
#define IA64_ISR_EI_0 0x0000000000000000
|
||||
#define IA64_ISR_EI_1 0x0000020000000000
|
||||
#define IA64_ISR_EI_2 0x0000040000000000
|
||||
#define IA64_ISR_ED 0x0000080000000000
|
||||
|
||||
/*
|
||||
* DCR bit positions
|
||||
*/
|
||||
#define IA64_DCR_PP 0
|
||||
#define IA64_DCR_BE 1
|
||||
#define IA64_DCR_LC 2
|
||||
#define IA64_DCR_MBZ0 4
|
||||
#define IA64_DCR_MBZ0_V 0xf
|
||||
#define IA64_DCR_DM 8
|
||||
#define IA64_DCR_DP 9
|
||||
#define IA64_DCR_DK 10
|
||||
#define IA64_DCR_DX 11
|
||||
#define IA64_DCR_DR 12
|
||||
#define IA64_DCR_DA 13
|
||||
#define IA64_DCR_DD 14
|
||||
#define IA64_DCR_DEFER_ALL 0x7f00
|
||||
#define IA64_DCR_MBZ1 2
|
||||
#define IA64_DCR_MBZ1_V 0xffffffffffffULL
|
||||
|
||||
|
||||
/* Endianess of DCR register. */
|
||||
#if defined(BIG_ENDIAN)
|
||||
#define MOS_IA64_DCR_BE (1 << IA64_DCR_BE)
|
||||
#else
|
||||
#define MOS_IA64_DCR_BE (0 << IA64_DCR_BE)
|
||||
#endif
|
||||
|
||||
#define IA64_DCR_DEFAULT (MOS_IA64_DCR_BE)
|
||||
|
||||
/*
|
||||
* Vector numbers for various ia64 interrupts.
|
||||
*/
|
||||
#define IA64_VEC_VHPT 0
|
||||
#define IA64_VEC_ITLB 1
|
||||
#define IA64_VEC_DTLB 2
|
||||
#define IA64_VEC_ALT_ITLB 3
|
||||
#define IA64_VEC_ALT_DTLB 4
|
||||
#define IA64_VEC_NESTED_DTLB 5
|
||||
#define IA64_VEC_IKEY_MISS 6
|
||||
#define IA64_VEC_DKEY_MISS 7
|
||||
#define IA64_VEC_DIRTY_BIT 8
|
||||
#define IA64_VEC_INST_ACCESS 9
|
||||
#define IA64_VEC_DATA_ACCESS 10
|
||||
#define IA64_VEC_BREAK 11
|
||||
#define IA64_VEC_EXT_INTR 12
|
||||
#define IA64_VEC_PAGE_NOT_PRESENT 20
|
||||
#define IA64_VEC_KEY_PERMISSION 21
|
||||
#define IA64_VEC_INST_ACCESS_RIGHTS 22
|
||||
#define IA64_VEC_DATA_ACCESS_RIGHTS 23
|
||||
#define IA64_VEC_GENERAL_EXCEPTION 24
|
||||
#define IA64_VEC_DISABLED_FP 25
|
||||
#define IA64_VEC_NAT_CONSUMPTION 26
|
||||
#define IA64_VEC_SPECULATION 27
|
||||
#define IA64_VEC_DEBUG 29
|
||||
#define IA64_VEC_UNALIGNED_REFERENCE 30
|
||||
#define IA64_VEC_UNSUPP_DATA_REFERENCE 31
|
||||
#define IA64_VEC_FLOATING_POINT_FAULT 32
|
||||
#define IA64_VEC_FLOATING_POINT_TRAP 33
|
||||
#define IA64_VEC_LOWER_PRIVILEGE_TRANSFER 34
|
||||
#define IA64_VEC_TAKEN_BRANCH_TRAP 35
|
||||
#define IA64_VEC_SINGLE_STEP_TRAP 36
|
||||
#define IA64_VEC_IA32_EXCEPTION 45
|
||||
#define IA64_VEC_IA32_INTERCEPT 46
|
||||
#define IA64_VEC_IA32_INTERRUPT 47
|
||||
|
||||
/*
|
||||
* Define hardware RSE Configuration Register
|
||||
*
|
||||
* RS Configuration (RSC) bit field positions
|
||||
*/
|
||||
|
||||
#define IA64_RSC_MODE 0
|
||||
#define IA64_RSC_PL 2
|
||||
#define IA64_RSC_BE 4
|
||||
#define IA64_RSC_MBZ0 5
|
||||
#define IA64_RSC_MBZ0_V 0x3ff
|
||||
#define IA64_RSC_LOADRS 16
|
||||
#define IA64_RSC_LOADRS_LEN 14
|
||||
#define IA64_RSC_MBZ1 30
|
||||
#define IA64_RSC_MBZ1_V 0x3ffffffffULL
|
||||
|
||||
/*
|
||||
* RSC modes
|
||||
*/
|
||||
#define IA64_RSC_MODE_LY (0x0) /* Lazy */
|
||||
#define IA64_RSC_MODE_SI (0x1) /* Store intensive */
|
||||
#define IA64_RSC_MODE_LI (0x2) /* Load intensive */
|
||||
#define IA64_RSC_MODE_EA (0x3) /* Eager */
|
||||
|
||||
/* RSE endian mode. */
|
||||
#if defined(BIG_ENDIAN)
|
||||
#define MOS_IA64_RSC_BE 1 /* Big endian rse. */
|
||||
#else
|
||||
#define MOS_IA64_RSC_BE 0 /* Little endian rse. */
|
||||
#endif
|
||||
|
||||
#define IA64_RSE_EAGER ((IA64_RSC_MODE_EA<<IA64_RSC_MODE) | \
|
||||
(MOS_IA64_RSC_BE << IA64_RSC_BE) )
|
||||
|
||||
#define IA64_RSE_LAZY ((IA64_RSC_MODE_LY<<IA64_RSC_MODE) | \
|
||||
(MOS_IA64_RSC_BE << IA64_RSC_BE) )
|
||||
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* ia64 function descriptor and global pointer */
|
||||
struct ia64_fdesc
|
||||
{
|
||||
uint64_t func;
|
||||
uint64_t gp;
|
||||
};
|
||||
typedef struct ia64_fdesc ia64_fdesc_t;
|
||||
|
||||
#define FDESC_FUNC(fn) (((struct ia64_fdesc *) fn)->func)
|
||||
#define FDESC_GP(fn) (((struct ia64_fdesc *) fn)->gp)
|
||||
|
||||
|
||||
/*
|
||||
* Various special ia64 instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory Fence.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_mf(void)
|
||||
{
|
||||
__asm __volatile("mf" ::: "memory");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_mf_a(void)
|
||||
{
|
||||
__asm __volatile("mf.a");
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush Cache.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_fc(uint64_t va)
|
||||
{
|
||||
__asm __volatile("fc %0" :: "r"(va));
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync instruction stream.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_sync_i(void)
|
||||
{
|
||||
__asm __volatile("sync.i");
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate address in VHPT for va.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_thash(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("thash %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate VHPT tag for va.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_ttag(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("ttag %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert virtual address to physical.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_tpa(uint64_t va)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("tpa %0=%1" : "=r" (result) : "r" (va));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.e instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_e(uint64_t v)
|
||||
{
|
||||
__asm __volatile("ptc.e %0;; srlz.d;;" :: "r"(v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.g instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_g(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.g %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.ga instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_ga(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.ga %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptc.l instruction.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_ptc_l(uint64_t va, uint64_t size)
|
||||
{
|
||||
__asm __volatile("ptc.l %0,%1;; srlz.d;;" :: "r"(va), "r"(size<<2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the value of psr.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_psr(void)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("mov %0=psr;;" : "=r" (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_set_psr(uint64_t v)
|
||||
{
|
||||
__asm __volatile("mov psr.l=%0" :: "r" (v));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ia64_srlz_d(void)
|
||||
{
|
||||
__asm __volatile("srlz.d;;");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
disable_intr(void)
|
||||
{
|
||||
__asm __volatile ("rsm psr.ic|psr.i");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
enable_intr(void)
|
||||
{
|
||||
__asm __volatile ("ssm psr.ic|psr.i");
|
||||
}
|
||||
|
||||
/*
|
||||
* Define accessors for application registers.
|
||||
*/
|
||||
|
||||
#define IA64_AR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile(";;mov %0=ar." #name ";;" : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov ar." #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_AR(k0)
|
||||
IA64_AR(k1)
|
||||
IA64_AR(k2)
|
||||
IA64_AR(k3)
|
||||
IA64_AR(k4)
|
||||
IA64_AR(k5)
|
||||
IA64_AR(k6)
|
||||
IA64_AR(k7)
|
||||
|
||||
IA64_AR(rsc)
|
||||
IA64_AR(bsp)
|
||||
IA64_AR(bspstore)
|
||||
IA64_AR(rnat)
|
||||
|
||||
IA64_AR(fcr)
|
||||
|
||||
IA64_AR(eflag)
|
||||
IA64_AR(csd)
|
||||
IA64_AR(ssd)
|
||||
IA64_AR(cflg)
|
||||
IA64_AR(fsr)
|
||||
IA64_AR(fir)
|
||||
IA64_AR(fdr)
|
||||
|
||||
IA64_AR(ccv)
|
||||
|
||||
IA64_AR(unat)
|
||||
|
||||
IA64_AR(fpsr)
|
||||
|
||||
IA64_AR(itc)
|
||||
|
||||
IA64_AR(pfs)
|
||||
IA64_AR(lc)
|
||||
IA64_AR(ec)
|
||||
|
||||
/*
|
||||
* Define accessors for control registers.
|
||||
*/
|
||||
|
||||
#define IA64_CR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile("mov %0=cr." #name : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov cr." #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_CR(dcr)
|
||||
IA64_CR(itm)
|
||||
IA64_CR(iva)
|
||||
|
||||
IA64_CR(pta)
|
||||
|
||||
IA64_CR(ipsr)
|
||||
IA64_CR(isr)
|
||||
|
||||
IA64_CR(iip)
|
||||
IA64_CR(ifa)
|
||||
IA64_CR(itir)
|
||||
IA64_CR(iipa)
|
||||
IA64_CR(ifs)
|
||||
IA64_CR(iim)
|
||||
IA64_CR(iha)
|
||||
|
||||
IA64_CR(lid)
|
||||
IA64_CR(ivr)
|
||||
IA64_CR(tpr)
|
||||
IA64_CR(eoi)
|
||||
IA64_CR(irr0)
|
||||
IA64_CR(irr1)
|
||||
IA64_CR(irr2)
|
||||
IA64_CR(irr3)
|
||||
IA64_CR(itv)
|
||||
IA64_CR(pmv)
|
||||
IA64_CR(cmcv)
|
||||
|
||||
IA64_CR(lrr0)
|
||||
IA64_CR(lrr1)
|
||||
|
||||
#define IA64_GR(name) \
|
||||
\
|
||||
static __inline uint64_t \
|
||||
ia64_get_##name(void) \
|
||||
{ \
|
||||
uint64_t result; \
|
||||
__asm __volatile("mov %0=" #name : "=r" (result)); \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
ia64_set_##name(uint64_t v) \
|
||||
{ \
|
||||
__asm __volatile("mov " #name "=%0" :: "r" (v)); \
|
||||
}
|
||||
|
||||
IA64_GR(sp)
|
||||
IA64_GR(b0)
|
||||
IA64_GR(r13) // tp
|
||||
|
||||
|
||||
/*
|
||||
* Write a region register.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_set_rr(uint64_t rrbase, uint64_t v)
|
||||
{
|
||||
__asm __volatile("mov rr[%0]=%1;; srlz.d;;"
|
||||
:: "r"(rrbase), "r"(v) : "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a region register.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_rr(uint64_t rrbase)
|
||||
{
|
||||
uint64_t v;
|
||||
__asm __volatile("mov %1=rr[%0];;"
|
||||
: "=r" (v) : "r"(rrbase) : "memory");
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a CPUID register.
|
||||
*/
|
||||
static __inline uint64_t
|
||||
ia64_get_cpuid(int i)
|
||||
{
|
||||
uint64_t result;
|
||||
__asm __volatile("mov %0=cpuid[%1]"
|
||||
: "=r" (result) : "r"(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct trap_frame
|
||||
{
|
||||
uint64_t rsc;
|
||||
uint64_t ndirty; /* number of dirty regs */
|
||||
uint64_t ssd;
|
||||
uint64_t iip; /* interrupted ip */
|
||||
uint64_t ipsr; /* interrupted psr */
|
||||
uint64_t ifs; /* interruption func status register */
|
||||
|
||||
uint16_t trap_num; /* Trap num, index in trap_vec */
|
||||
uint64_t cfm; /* current frame marker */
|
||||
uint64_t pfs; /* previous function state ar64 */
|
||||
uint64_t bsp; /* backing store pointer ar17 */
|
||||
uint64_t rnat; /* rse nat collection ar19 */
|
||||
uint64_t csd; /* comp and store data reg ar25 */
|
||||
uint64_t ccv; /* comp and xchange val reg ar32 */
|
||||
uint64_t unat; /* */
|
||||
uint64_t fpsr; /* floating point state reg ar40 */
|
||||
uint64_t pr; /* predicate regs 0-63 */
|
||||
|
||||
uint64_t gp; /* the gp pointer */
|
||||
uint64_t sp; /* stack pointer */
|
||||
uint64_t tp; /* thread pointer */
|
||||
|
||||
uint64_t r2; /* global reg 2 */
|
||||
uint64_t r3;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
uint64_t r16;
|
||||
uint64_t r17;
|
||||
uint64_t r18;
|
||||
uint64_t r19;
|
||||
uint64_t r20;
|
||||
uint64_t r21;
|
||||
uint64_t r22;
|
||||
uint64_t r23;
|
||||
uint64_t r24;
|
||||
uint64_t r25;
|
||||
uint64_t r26;
|
||||
uint64_t r27;
|
||||
uint64_t r28;
|
||||
uint64_t r29;
|
||||
uint64_t r30;
|
||||
uint64_t r31;
|
||||
|
||||
uint64_t b0;
|
||||
uint64_t b6;
|
||||
uint64_t b7;
|
||||
|
||||
ia64_fpreg_t f6; /* floating point register 6 */
|
||||
ia64_fpreg_t f7;
|
||||
ia64_fpreg_t f8;
|
||||
ia64_fpreg_t f9;
|
||||
ia64_fpreg_t f10;
|
||||
ia64_fpreg_t f11;
|
||||
|
||||
uint64_t ifa; /* interruption faulting address */
|
||||
uint64_t isr; /* interruption status register */
|
||||
uint64_t iim; /* interruption immediate register */
|
||||
};
|
||||
|
||||
typedef struct trap_frame trap_frame_t;
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Page access parameters. */
|
||||
#define PTE_P_SHIFT 0
|
||||
#define PTE_P 1
|
||||
|
||||
#define PTE_MA_SHIFT 2
|
||||
#define PTE_MA_WB 0
|
||||
|
||||
#define PTE_A_SHIFT 5
|
||||
#define PTE_A 1
|
||||
#define PTE_D_SHIFT 6
|
||||
#define PTE_D 1
|
||||
|
||||
#define PTE_AR_SHIFT 9
|
||||
#define PTE_AR_R 0
|
||||
#define PTE_AR_RX 1
|
||||
#define PTE_AR_RW 2
|
||||
#define PTE_AR_RWX 3
|
||||
#define PTE_AR_R_RW 4
|
||||
#define PTE_AR_RX_RWX 5
|
||||
#define PTE_AR_RWX_RW 6
|
||||
/* privilege level */
|
||||
#define PTE_PL_SHIFT 7
|
||||
#define PTE_PL_KERN 0 /* used for kernel */
|
||||
/* page size */
|
||||
#define PTE_PS_4K 12
|
||||
#define PTE_PS_8K 13
|
||||
#define PTE_PS_16K 14
|
||||
#define PTE_PS_64K 16
|
||||
#define PTE_PS_256K 18
|
||||
#define PTE_PS_1M 20
|
||||
#define PTE_PS_4M 22
|
||||
#define PTE_PS_16M 24
|
||||
#define PTE_PS_64M 26
|
||||
#define PTE_PS_256M 28
|
||||
|
||||
|
||||
/* Some offsets for ia64_pte_t. */
|
||||
#define PTE_OFF_P 0
|
||||
#define PTE_OFF_MA 3
|
||||
#define PTE_OFF_A 5
|
||||
#define PTE_OFF_D 6
|
||||
#define PTE_OFF_PL 7
|
||||
#define PTE_OFF_AR 9
|
||||
#define PTE_OFF_PPN 12
|
||||
#define PTE_OFF_ED 52
|
||||
|
||||
#if !defined(_ASM) && !defined(__ASSEMBLY__)
|
||||
/*
|
||||
* A short-format VHPT entry. Also matches the TLB insertion format.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(BIG_ENDIAN)
|
||||
uint64_t pte_ig :11; /* bits 53..63 */
|
||||
uint64_t pte_ed :1; /* bits 52..52 */
|
||||
uint64_t pte_rv2:2; /* bits 50..51 */
|
||||
uint64_t pte_ppn:38; /* bits 12..49 */
|
||||
uint64_t pte_ar :3; /* bits 9..11 */
|
||||
uint64_t pte_pl :2; /* bits 7..8 */
|
||||
uint64_t pte_d :1; /* bits 6..6 */
|
||||
uint64_t pte_a :1; /* bits 5..5 */
|
||||
uint64_t pte_ma :3; /* bits 2..4 */
|
||||
uint64_t pte_rv1:1; /* bits 1..1 */
|
||||
uint64_t pte_p :1; /* bits 0..0 */
|
||||
#else
|
||||
uint64_t pte_p :1; /* bits 0..0 */
|
||||
uint64_t pte_rv1:1; /* bits 1..1 */
|
||||
uint64_t pte_ma :3; /* bits 2..4 */
|
||||
uint64_t pte_a :1; /* bits 5..5 */
|
||||
uint64_t pte_d :1; /* bits 6..6 */
|
||||
uint64_t pte_pl :2; /* bits 7..8 */
|
||||
uint64_t pte_ar :3; /* bits 9..11 */
|
||||
uint64_t pte_ppn:38; /* bits 12..49 */
|
||||
uint64_t pte_rv2:2; /* bits 50..51 */
|
||||
uint64_t pte_ed :1; /* bits 52..52 */
|
||||
uint64_t pte_ig :11; /* bits 53..63 */
|
||||
#endif
|
||||
} ia64_pte_t;
|
||||
|
||||
|
||||
/*
|
||||
* A long-format VHPT entry.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t pte_p :1; /* bits 0..0 */
|
||||
uint64_t pte_rv1 :1; /* bits 1..1 */
|
||||
uint64_t pte_ma :3; /* bits 2..4 */
|
||||
uint64_t pte_a :1; /* bits 5..5 */
|
||||
uint64_t pte_d :1; /* bits 6..6 */
|
||||
uint64_t pte_pl :2; /* bits 7..8 */
|
||||
uint64_t pte_ar :3; /* bits 9..11 */
|
||||
uint64_t pte_ppn :38; /* bits 12..49 */
|
||||
uint64_t pte_rv2 :2; /* bits 50..51 */
|
||||
uint64_t pte_ed :1; /* bits 52..52 */
|
||||
uint64_t pte_ig :11; /* bits 53..63 */
|
||||
uint64_t pte_rv3 :2; /* bits 0..1 */
|
||||
uint64_t pte_ps :6; /* bits 2..7 */
|
||||
uint64_t pte_key :24; /* bits 8..31 */
|
||||
uint64_t pte_rv4 :32; /* bits 32..63 */
|
||||
uint64_t pte_tag; /* includes ti */
|
||||
uint64_t pte_chain; /* pa of collision chain */
|
||||
} ia64_lpte_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _IA64_CPU_H_ */
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* This code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IA64_FPU_H_
|
||||
#define _IA64_FPU_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
* Floating point status register bits.
|
||||
*/
|
||||
#define IA64_FPSR_TRAP_VD UL_CONST(0x0000000000000001)
|
||||
#define IA64_FPSR_TRAP_DD UL_CONST(0x0000000000000002)
|
||||
#define IA64_FPSR_TRAP_ZD UL_CONST(0x0000000000000004)
|
||||
#define IA64_FPSR_TRAP_OD UL_CONST(0x0000000000000008)
|
||||
#define IA64_FPSR_TRAP_UD UL_CONST(0x0000000000000010)
|
||||
#define IA64_FPSR_TRAP_ID UL_CONST(0x0000000000000020)
|
||||
#define IA64_FPSR_SF(i,v) ((v) << ((i)*13+6))
|
||||
|
||||
#define IA64_SF_FTZ UL_CONST(0x0001)
|
||||
#define IA64_SF_WRE UL_CONST(0x0002)
|
||||
#define IA64_SF_PC UL_CONST(0x000c)
|
||||
#define IA64_SF_PC_0 UL_CONST(0x0000)
|
||||
#define IA64_SF_PC_1 UL_CONST(0x0004)
|
||||
#define IA64_SF_PC_2 UL_CONST(0x0008)
|
||||
#define IA64_SF_PC_3 UL_CONST(0x000c)
|
||||
#define IA64_SF_RC UL_CONST(0x0030)
|
||||
#define IA64_SF_RC_NEAREST UL_CONST(0x0000)
|
||||
#define IA64_SF_RC_NEGINF UL_CONST(0x0010)
|
||||
#define IA64_SF_RC_POSINF UL_CONST(0x0020)
|
||||
#define IA64_SF_RC_TRUNC UL_CONST(0x0030)
|
||||
#define IA64_SF_TD UL_CONST(0x0040)
|
||||
#define IA64_SF_V UL_CONST(0x0080)
|
||||
#define IA64_SF_D UL_CONST(0x0100)
|
||||
#define IA64_SF_Z UL_CONST(0x0200)
|
||||
#define IA64_SF_O UL_CONST(0x0400)
|
||||
#define IA64_SF_U UL_CONST(0x0800)
|
||||
#define IA64_SF_I UL_CONST(0x1000)
|
||||
|
||||
#define IA64_SF_DEFAULT (IA64_SF_PC_3 | IA64_SF_RC_NEAREST)
|
||||
|
||||
#define IA64_FPSR_DEFAULT (IA64_FPSR_TRAP_VD \
|
||||
| IA64_FPSR_TRAP_DD \
|
||||
| IA64_FPSR_TRAP_ZD \
|
||||
| IA64_FPSR_TRAP_OD \
|
||||
| IA64_FPSR_TRAP_UD \
|
||||
| IA64_FPSR_TRAP_ID \
|
||||
| IA64_FPSR_SF(0, IA64_SF_DEFAULT) \
|
||||
| IA64_FPSR_SF(1, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD \
|
||||
| IA64_SF_WRE)) \
|
||||
| IA64_FPSR_SF(2, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD)) \
|
||||
| IA64_FPSR_SF(3, (IA64_SF_DEFAULT \
|
||||
| IA64_SF_TD)))
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This is from sys/cdefs.h in FreeBSD */
|
||||
#define __aligned(x) __attribute__((__aligned__(x)))
|
||||
|
||||
/* A single Floating Point register. */
|
||||
struct ia64_fpreg
|
||||
{
|
||||
uint8_t fpr_bits[16];
|
||||
} __aligned(16);
|
||||
|
||||
typedef struct ia64_fpreg ia64_fpreg_t;
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _IA64_FPU_H_ */
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (C) 2007 - Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__OS_H__)
|
||||
#define __OS_H__
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
#include "types.h"
|
||||
#include "endian.h"
|
||||
#include "ia64_cpu.h"
|
||||
#include "atomic.h"
|
||||
#include "efi.h"
|
||||
#include "sal.h"
|
||||
#include "pal.h"
|
||||
#include "hypervisor.h"
|
||||
|
||||
|
||||
typedef uint64_t paddr_t; /* Physical address. */
|
||||
typedef uint64_t caddr_t; /* rr7/kernel memory address. */
|
||||
|
||||
#include "page.h"
|
||||
#include "mm.h"
|
||||
|
||||
|
||||
void do_exit(void);
|
||||
void arch_init(start_info_t *si); /* in common.c */
|
||||
void arch_print_info(void); /* in common.c */
|
||||
|
||||
|
||||
/* Size of xen_ia64_boot_param.command_line */
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
|
||||
struct xen_ia64_boot_param* ia64_boot_paramP;
|
||||
extern struct xen_ia64_boot_param ia64BootParamG;
|
||||
extern char boot_cmd_line[];
|
||||
extern efi_system_table_t* efiSysTableP;
|
||||
extern int bootverbose;
|
||||
|
||||
extern void ia64_probe_sapics(void);
|
||||
|
||||
|
||||
|
||||
/* Contains the needed stuff from efi. */
|
||||
struct efi
|
||||
{
|
||||
|
||||
efi_system_table_t* efiSysTableP;
|
||||
efi_set_virtual_address_map_t setVirtAddrMapF;
|
||||
efi_get_time_t getTimeF;
|
||||
efi_reset_system_t resetSystemF;
|
||||
|
||||
};
|
||||
|
||||
struct machine_fw
|
||||
{
|
||||
struct efi efi;
|
||||
|
||||
uint64_t ia64_port_base; /* physical address */
|
||||
uint64_t ia64_pal_base; /* virtual rr7 address */
|
||||
|
||||
sal_system_table_t* ia64_sal_tableP;
|
||||
sal_entry_t* ia64_sal_entryP; /* SAL_PROC entrypoint */
|
||||
|
||||
uint64_t ia64_efi_acpi_table; /* physical address */
|
||||
uint64_t ia64_efi_acpi20_table; /* physical address */
|
||||
|
||||
uint64_t mach_mem_start; /* phys start addr of machine memory */
|
||||
uint64_t mach_mem_size; /* size of machine memory */
|
||||
|
||||
uint64_t kernstart; /* virt address of kern text start */
|
||||
uint64_t kernend;
|
||||
uint64_t kernpstart; /* phys address of kern text start */
|
||||
uint64_t kernpend;
|
||||
};
|
||||
|
||||
extern struct machine_fw machineFwG;
|
||||
|
||||
#define ia64_sal_entry machineFwG.ia64_sal_entryP
|
||||
|
||||
#define smp_processor_id() 0
|
||||
|
||||
static inline uint64_t
|
||||
xchg8(uint64_t* ptr, uint64_t x) \
|
||||
{
|
||||
uint64_t oldVal;
|
||||
asm volatile ("xchg8 %0=[%1],%2" : "=r" (oldVal)
|
||||
: "r" (ptr), "r" (x) : "memory");
|
||||
return oldVal;
|
||||
}
|
||||
#define xchg xchg8
|
||||
|
||||
// Counts the number of 1-bits in x.
|
||||
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
# define get_popcnt(x) __builtin_popcountl(x)
|
||||
#else
|
||||
# define get_popcnt(x) \
|
||||
({ \
|
||||
uint64_t num; \
|
||||
asm ("popcnt %0=%1" : "=r" (num) : "r" (x)); \
|
||||
num; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __ffs - find first bit in word.
|
||||
* @x: The word to search
|
||||
*
|
||||
* Undefined if no bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static inline unsigned long
|
||||
__ffs (unsigned long x)
|
||||
{
|
||||
unsigned long result;
|
||||
|
||||
result = get_popcnt((x-1) & ~x);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
synch_clear_bit(int num, volatile void *addr)
|
||||
{
|
||||
clear_bit(num, addr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
synch_set_bit(int num, volatile void *addr)
|
||||
{
|
||||
set_bit(num, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
synch_test_bit(int nr, const volatile void *addr)
|
||||
{
|
||||
return test_bit(nr, addr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
synch_test_and_set_bit(int num, volatile void * addr)
|
||||
{
|
||||
return test_and_set_bit(num, addr);
|
||||
}
|
||||
|
||||
|
||||
#define synch_cmpxchg(ptr, old, new) \
|
||||
((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
|
||||
(unsigned long)(old), \
|
||||
(unsigned long)(new), \
|
||||
sizeof(*(ptr))))
|
||||
|
||||
static inline unsigned long
|
||||
__synch_cmpxchg(volatile void *ptr, uint64_t old, uint64_t new, int size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return ia64_cmpxchg_acq_8(ptr, old, new);
|
||||
case 2:
|
||||
return ia64_cmpxchg_acq_16(ptr, old, new);
|
||||
case 4:
|
||||
return ia64_cmpxchg_acq_32(ptr, old, new);
|
||||
case 8:
|
||||
return ia64_cmpxchg_acq_64(ptr, old, new);
|
||||
}
|
||||
return ia64_cmpxchg_acq_64(ptr, old, new);
|
||||
}
|
||||
|
||||
/*
|
||||
* Force a proper event-channel callback from Xen after clearing the
|
||||
* callback mask. We do this in a very simple manner, by making a call
|
||||
* down into Xen. The pending flag will be checked by Xen on return.
|
||||
*/
|
||||
static inline void
|
||||
force_evtchn_callback(void)
|
||||
{
|
||||
(void)HYPERVISOR_xen_version(0, NULL);
|
||||
}
|
||||
|
||||
extern shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_shutdown(unsigned int reason)
|
||||
{
|
||||
struct sched_shutdown sched_shutdown = {
|
||||
.reason = reason
|
||||
};
|
||||
|
||||
int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
|
||||
|
||||
if (rc == -ENOSYS)
|
||||
rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This code is from the originally os.h and should be put in a
|
||||
* common header file!
|
||||
*/
|
||||
|
||||
/*
|
||||
* The use of 'barrier' in the following reflects their use as local-lock
|
||||
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
|
||||
* critical operations are executed. All critical operations must complete
|
||||
* /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
|
||||
* includes these barriers, for example.
|
||||
*/
|
||||
|
||||
#define __cli() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = SWAP(1); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define __sti() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = 0; \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if (unlikely(SWAP(_vcpu->evtchn_upcall_pending))) \
|
||||
force_evtchn_callback(); \
|
||||
} while (0)
|
||||
|
||||
#define __save_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = SWAP(_vcpu->evtchn_upcall_mask); \
|
||||
} while (0)
|
||||
|
||||
#define __restore_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(SWAP(_vcpu->evtchn_upcall_pending)) ) \
|
||||
force_evtchn_callback(); \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define safe_halt() ((void)0)
|
||||
|
||||
#define __save_and_cli(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = SWAP(_vcpu->evtchn_upcall_mask); \
|
||||
_vcpu->evtchn_upcall_mask = SWAP(1); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_save(x) __save_and_cli(x)
|
||||
#define local_irq_restore(x) __restore_flags(x)
|
||||
#define local_save_flags(x) __save_flags(x)
|
||||
#define local_irq_disable() __cli()
|
||||
#define local_irq_enable() __sti()
|
||||
|
||||
#define irqs_disabled() \
|
||||
SWAP(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].evtchn_upcall_mask)
|
||||
|
||||
/* This is a barrier for the compiler only, NOT the processor! */
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#define mb() ia64_mf()
|
||||
#define rmb() mb()
|
||||
#define wmb() mb()
|
||||
|
||||
|
||||
#define BUG() \
|
||||
{ printk("mini-os BUG at %s:%d!\n", __FILE__, __LINE__); do_exit(); }
|
||||
|
||||
#define PRINT_BV(_fmt, _params...) \
|
||||
if (bootverbose) \
|
||||
printk(_fmt , ## _params)
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#if defined(__ASSEMBLY__)
|
||||
|
||||
#define UL_CONST(x) x
|
||||
#define UL_TYPE(x) x
|
||||
|
||||
#else /* defined(__ASSEMBLY__) */
|
||||
|
||||
#define UL_CONST(x) x##UL
|
||||
#define UL_TYPE(x) ((uint64_t)x)
|
||||
|
||||
#endif /* defined(__ASSEMBLY__) */
|
||||
|
||||
#endif /* !defined(__OS_H__) */
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* Common stuff for memory and page handling.
|
||||
* Parts are taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(_PAGE_H_)
|
||||
#define _PAGE_H_
|
||||
|
||||
#include "os.h"
|
||||
#include "ia64_cpu.h"
|
||||
|
||||
#define PTE_KERNEL_ATTR ((PTE_P<<PTE_P_SHIFT) |\
|
||||
(PTE_MA_WB<<PTE_MA_SHIFT) |\
|
||||
(PTE_D<<PTE_D_SHIFT) |\
|
||||
(PTE_A<<PTE_A_SHIFT) |\
|
||||
(PTE_PL_KERN<<PTE_PL_SHIFT) |\
|
||||
(PTE_AR_RWX<<PTE_AR_SHIFT))
|
||||
|
||||
|
||||
/* The kernel tr page size for text and data. */
|
||||
#define KERNEL_TR_PAGE_SIZE PTE_PS_1M
|
||||
/* The efi-pal page size for text and data. */
|
||||
#define PAL_TR_PAGE_SIZE PTE_PS_1M
|
||||
|
||||
/* Commonly 16K pages are used. */
|
||||
#define PAGE_SHIFT 14 /* 16K pages */
|
||||
#define PAGE_SIZE (1<<(PAGE_SHIFT))
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#define KSTACK_PAGES 4 /* 4 pages for the kernel stack + bsp */
|
||||
|
||||
#define IA64_TR_KERNEL 0 /* itr0, dtr0: maps kernel image (code) */
|
||||
#define IA64_TR_PAL 1 /* itr1: maps pal code */
|
||||
|
||||
/*
|
||||
* Manipulating region bits of an address.
|
||||
*/
|
||||
#define IA64_RR_BASE(n) ((UL_TYPE(n)) << 61)
|
||||
#define IA64_RR_MASK(x) ((UL_TYPE(x)) & ((1L << 61) - 1))
|
||||
#define IA64_RR_EXTR(x) ((x) >> 61)
|
||||
|
||||
#define IA64_PHYS_TO_RR5(x) ((x) | IA64_RR_BASE(5))
|
||||
#define IA64_PHYS_TO_RR7(x) ((x) | IA64_RR_BASE(7))
|
||||
|
||||
#define __pa(x) IA64_RR_MASK(x)
|
||||
#define __va(x) IA64_PHYS_TO_RR7(x)
|
||||
|
||||
#define roundup_page(x) ((((unsigned long)(x)) + PAGE_SIZE -1) & PAGE_MASK)
|
||||
#define trunc_page(x) ((unsigned long)(x) & PAGE_MASK)
|
||||
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
/* Contains the parts of the physically memory. */
|
||||
extern paddr_t phys_avail[];
|
||||
|
||||
#define page_to_pfn(page) ((uint64_t)(page) >> PAGE_SHIFT)
|
||||
#define pfn_to_page(pfn) ((uint64_t)pfn << PAGE_SHIFT)
|
||||
/* Get phyiscal address of page of virtual address. */
|
||||
#define virt_to_page(addr) ((uint64_t)__pa(addr) & PAGE_MASK)
|
||||
#define virt_to_pfn(addr) (page_to_pfn(virt_to_page(addr)))
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
||||
/* For both see minios-ia64.lds. */
|
||||
/* This is where the kernel virtually starts. */
|
||||
#define KERNEL_START IA64_PHYS_TO_RR5(0x100000000)
|
||||
/* !!!!!
|
||||
* For physical start of kernel
|
||||
* Currently used in arch/ia64/fw.S.
|
||||
* !!!!!
|
||||
*/
|
||||
#define KERNEL_PHYS_START_SHIFT 20
|
||||
|
||||
/* A region 5 address to physical address */
|
||||
#define KERN_VIRT_2_PHYS(x) (((x) - KERNEL_START) + \
|
||||
(1 << KERNEL_PHYS_START_SHIFT))
|
||||
|
||||
// This is xen specific !
|
||||
#define PAGE_SHIFT_XEN_16K 14 // For 16KB page size
|
||||
#define mfn_to_virt(mfn) ((void*)__va((mfn) << PAGE_SHIFT_XEN_16K))
|
||||
|
||||
#endif /* !defined(_PAGE_H_) */
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* The code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PAL_H_
|
||||
#define _PAL_H_
|
||||
|
||||
/*
|
||||
* Architected static calling convention procedures.
|
||||
*/
|
||||
#define PAL_CACHE_FLUSH 1
|
||||
#define PAL_CACHE_INFO 2
|
||||
#define PAL_CACHE_INIT 3
|
||||
#define PAL_CACHE_SUMMARY 4
|
||||
#define PAL_MEM_ATTRIB 5
|
||||
#define PAL_PTCE_INFO 6
|
||||
#define PAL_VM_INFO 7
|
||||
#define PAL_VM_SUMMARY 8
|
||||
#define PAL_BUS_GET_FEATURES 9
|
||||
#define PAL_BUS_SET_FEATURES 10
|
||||
#define PAL_DEBUG_INFO 11
|
||||
#define PAL_FIXED_ADDR 12
|
||||
#define PAL_FREQ_BASE 13
|
||||
#define PAL_FREQ_RATIOS 14
|
||||
#define PAL_PERF_MON_INFO 15
|
||||
#define PAL_PLATFORM_ADDR 16
|
||||
#define PAL_PROC_GET_FEATURE 17
|
||||
#define PAL_PROC_SET_FEATURE 18
|
||||
#define PAL_RSE_INFO 19
|
||||
#define PAL_VERSION 20
|
||||
#define PAL_MC_CLEAR_LOG 21
|
||||
#define PAL_MC_DRAIN 22
|
||||
#define PAL_MC_DYNAMIC_STATE 24
|
||||
#define PAL_MC_ERROR_INFO 25
|
||||
#define PAL_MC_EXPECTED 23
|
||||
#define PAL_MC_REGISTER_MEM 27
|
||||
#define PAL_MC_RESUME 26
|
||||
#define PAL_HALT 28
|
||||
#define PAL_HALT_LIGHT 29
|
||||
#define PAL_COPY_INFO 30
|
||||
#define PAL_CACHE_LINE_INIT 31
|
||||
#define PAL_PMI_ENTRYPOINT 32
|
||||
#define PAL_ENTER_IA_32_ENV 33
|
||||
#define PAL_VM_PAGE_SIZE 34
|
||||
#define PAL_MEM_FOR_TEST 37
|
||||
#define PAL_CACHE_PROT_INFO 38
|
||||
#define PAL_REGISTER_INFO 39
|
||||
#define PAL_SHUTDOWN 40
|
||||
#define PAL_PREFETCH_VISIBILITY 41
|
||||
|
||||
|
||||
struct ia64_pal_result
|
||||
{
|
||||
int64_t pal_status;
|
||||
uint64_t pal_result[3];
|
||||
};
|
||||
|
||||
extern struct ia64_pal_result
|
||||
ia64_call_pal_static(uint64_t proc, uint64_t arg1,
|
||||
uint64_t arg2, uint64_t arg3);
|
||||
|
||||
#endif /* _PAL_H_ */
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Hewlett-Packard Co
|
||||
* Dan Magenheimer <dan.magenheimer@hp.com>
|
||||
*
|
||||
* Paravirtualizations of privileged operations for Xen/ia64
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PRIVOP_H_
|
||||
#define _PRIVOP_H_
|
||||
|
||||
#include <xen/arch-ia64.h>
|
||||
|
||||
#define IA64_PARAVIRTUALIZED
|
||||
|
||||
/* At 1 MB, before per-cpu space but still addressable using addl instead
|
||||
of movl. */
|
||||
#define XSI_BASE 0xfffffffffff00000
|
||||
|
||||
/* Address of mapped regs. */
|
||||
#define XMAPPEDREGS_BASE (XSI_BASE + XSI_SIZE)
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define XEN_HYPER_RFI break HYPERPRIVOP_RFI
|
||||
#define XEN_HYPER_RSM_PSR_DT break HYPERPRIVOP_RSM_DT
|
||||
#define XEN_HYPER_SSM_PSR_DT break HYPERPRIVOP_SSM_DT
|
||||
#define XEN_HYPER_COVER break HYPERPRIVOP_COVER
|
||||
#define XEN_HYPER_ITC_D break HYPERPRIVOP_ITC_D
|
||||
#define XEN_HYPER_ITC_I break HYPERPRIVOP_ITC_I
|
||||
#define XEN_HYPER_SSM_I break HYPERPRIVOP_SSM_I
|
||||
#define XEN_HYPER_GET_IVR break HYPERPRIVOP_GET_IVR
|
||||
#define XEN_HYPER_GET_TPR break HYPERPRIVOP_GET_TPR
|
||||
#define XEN_HYPER_SET_TPR break HYPERPRIVOP_SET_TPR
|
||||
#define XEN_HYPER_EOI break HYPERPRIVOP_EOI
|
||||
#define XEN_HYPER_SET_ITM break HYPERPRIVOP_SET_ITM
|
||||
#define XEN_HYPER_THASH break HYPERPRIVOP_THASH
|
||||
#define XEN_HYPER_PTC_GA break HYPERPRIVOP_PTC_GA
|
||||
#define XEN_HYPER_ITR_D break HYPERPRIVOP_ITR_D
|
||||
#define XEN_HYPER_GET_RR break HYPERPRIVOP_GET_RR
|
||||
#define XEN_HYPER_SET_RR break HYPERPRIVOP_SET_RR
|
||||
#define XEN_HYPER_SET_KR break HYPERPRIVOP_SET_KR
|
||||
#define XEN_HYPER_FC break HYPERPRIVOP_FC
|
||||
#define XEN_HYPER_GET_CPUID break HYPERPRIVOP_GET_CPUID
|
||||
#define XEN_HYPER_GET_PMD break HYPERPRIVOP_GET_PMD
|
||||
#define XEN_HYPER_GET_EFLAG break HYPERPRIVOP_GET_EFLAG
|
||||
#define XEN_HYPER_SET_EFLAG break HYPERPRIVOP_SET_EFLAG
|
||||
#define XEN_HYPER_RSM_BE break HYPERPRIVOP_RSM_BE
|
||||
#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR
|
||||
|
||||
#define XSI_IFS (XSI_BASE + XSI_IFS_OFS)
|
||||
#define XSI_PRECOVER_IFS (XSI_BASE + XSI_PRECOVER_IFS_OFS)
|
||||
#define XSI_INCOMPL_REGFR (XSI_BASE + XSI_INCOMPL_REGFR_OFS)
|
||||
#define XSI_IFA (XSI_BASE + XSI_IFA_OFS)
|
||||
#define XSI_ISR (XSI_BASE + XSI_ISR_OFS)
|
||||
#define XSI_IIM (XSI_BASE + XSI_IIM_OFS)
|
||||
#define XSI_ITIR (XSI_BASE + XSI_ITIR_OFS)
|
||||
#define XSI_PSR_I_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS)
|
||||
#define XSI_PSR_IC (XSI_BASE + XSI_PSR_IC_OFS)
|
||||
#define XSI_IPSR (XSI_BASE + XSI_IPSR_OFS)
|
||||
#define XSI_IIP (XSI_BASE + XSI_IIP_OFS)
|
||||
#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS)
|
||||
#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS)
|
||||
#define XSI_IHA (XSI_BASE + XSI_IHA_OFS)
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define XEN_HYPER_SSM_I asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
|
||||
#define XEN_HYPER_GET_IVR asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
|
||||
|
||||
/************************************************/
|
||||
/* Instructions paravirtualized for performance */
|
||||
/************************************************/
|
||||
|
||||
/* Xen uses memory-mapped virtual privileged registers for access to many
|
||||
* performance-sensitive privileged registers. Some, like the processor
|
||||
* status register (psr), are broken up into multiple memory locations.
|
||||
* Others, like "pend", are abstractions based on privileged registers.
|
||||
* "Pend" is guaranteed to be set if reading cr.ivr would return a
|
||||
* (non-spurious) interrupt. */
|
||||
#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
|
||||
#define XSI_PSR_I \
|
||||
(*XEN_MAPPEDREGS->interrupt_mask_addr)
|
||||
#define xen_get_virtual_psr_i() \
|
||||
(!XSI_PSR_I)
|
||||
#define xen_set_virtual_psr_i(_val) \
|
||||
({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
|
||||
#define xen_get_virtual_psr_ic() \
|
||||
( XEN_MAPPEDREGS->interrupt_collection_enabled )
|
||||
#define xen_set_virtual_psr_ic(_val) \
|
||||
({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
|
||||
#define xen_get_virtual_pend() (XEN_MAPPEDREGS->pending_interruption)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _PRIVOP_H_ */
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
* The code is mostly taken from FreeBSD.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The SAL System Table starts with a header which is described in
|
||||
* sal_system_table_t.
|
||||
* Table header will be followed by a variable number of variable length
|
||||
* entries. The first byte of each entry will identify the entry type and
|
||||
* the entries shall be in ascending order by the entry type. Each entry
|
||||
* type will have a known fixed length. The total length of this table
|
||||
* depends upon the configuration of the system. Operating system software
|
||||
* must step through each entry until it reaches the ENTRY_COUNT. The entries
|
||||
* are sorted on entry type in ascending order.
|
||||
* Unless otherwise stated, there is one entry per entry type.
|
||||
*/
|
||||
|
||||
#ifndef _SAL_H_
|
||||
#define _SAL_H_
|
||||
|
||||
typedef uint64_t u_int64_t;
|
||||
typedef uint32_t u_int32_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
typedef uint8_t u_int8_t;
|
||||
|
||||
struct sal_system_table {
|
||||
char sal_signature[4];
|
||||
#define SAL_SIGNATURE "SST_"
|
||||
uint32_t sal_length;
|
||||
uint8_t sal_rev[2]; /* Byte 8 - Minor, Byte 0 - Major */
|
||||
uint16_t sal_entry_count; // num entries in var part
|
||||
uint8_t sal_checksum;
|
||||
uint8_t sal_reserved1[7];
|
||||
uint8_t sal_a_version[2]; // like sal_rev
|
||||
uint8_t sal_b_version[2]; // like sal_rev
|
||||
char sal_oem_id[32]; // Ascii - manufacturer of HW
|
||||
char sal_product_id[32]; // ascii - identification
|
||||
uint8_t sal_reserved2[8];
|
||||
};
|
||||
|
||||
typedef struct sal_system_table sal_system_table_t;
|
||||
|
||||
#define SAL_DESC_ENTRYPOINT 0
|
||||
#define SAL_DESC_ENTRYPOINT_LENGTH 48
|
||||
#define SAL_DESC_MEMORY 1
|
||||
#define SAL_DESC_MEMORY_LENGTH 32
|
||||
#define SAL_DESC_PLATFORM 2
|
||||
#define SAL_DESC_PLATFORM_LENGT 16
|
||||
#define SAL_DESC_TR_REG 3
|
||||
#define SAL_DESC_TR_REG_LENGTH 32
|
||||
#define SAL_DESC_PURGE_TR_CACHE 4
|
||||
#define SAL_DESC_PURGE_TR_CACHE_LENGTH 16
|
||||
#define SAL_DESC_AP_WAKEUP 5
|
||||
#define SAL_DESC_AP_WAKEUP_LENGTH 16
|
||||
|
||||
|
||||
struct sal_entrypoint_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 0 */
|
||||
uint8_t sale_reserved1[7];
|
||||
uint64_t sale_pal_proc; /* PAL_PROC entry point */
|
||||
uint64_t sale_sal_proc; /* SAL_PROC entry point */
|
||||
uint64_t sale_sal_gp; /* gp for SAL_PROC, PAL_PROC */
|
||||
uint8_t sale_reserved2[16];
|
||||
};
|
||||
|
||||
struct sal_memory_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 1 */
|
||||
uint8_t sale_need_virtual;
|
||||
uint8_t sale_current_attribute;
|
||||
uint8_t sale_access_rights;
|
||||
uint8_t sale_supported_attributes;
|
||||
uint8_t sale_reserved1;
|
||||
uint8_t sale_memory_type[2];
|
||||
uint64_t sale_physical_address;
|
||||
uint32_t sale_length;
|
||||
uint8_t sale_reserved2[12];
|
||||
};
|
||||
|
||||
struct sal_platform_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 2 */
|
||||
uint8_t sale_features;
|
||||
uint8_t sale_reserved[14];
|
||||
};
|
||||
|
||||
struct sal_tr_descriptor
|
||||
{
|
||||
u_int8_t sale_type; /* == 3 */
|
||||
u_int8_t sale_register_type;
|
||||
u_int8_t sale_register_number;
|
||||
u_int8_t sale_reserved1[5];
|
||||
u_int64_t sale_virtual_address;
|
||||
u_int64_t sale_page_size;
|
||||
u_int8_t sale_reserved2[8];
|
||||
};
|
||||
|
||||
struct sal_ptc_cache_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 4 */
|
||||
uint8_t sale_reserved[3];
|
||||
uint32_t sale_domains;
|
||||
uint64_t sale_address;
|
||||
};
|
||||
|
||||
struct sal_ap_wakeup_descriptor
|
||||
{
|
||||
uint8_t sale_type; /* == 5 */
|
||||
uint8_t sale_mechanism;
|
||||
uint8_t sale_reserved[6];
|
||||
uint64_t sale_vector;
|
||||
};
|
||||
|
||||
/*
|
||||
* SAL Procedure numbers.
|
||||
*/
|
||||
|
||||
#define SAL_SET_VECTORS 0x01000000
|
||||
#define SAL_GET_STATE_INFO 0x01000001
|
||||
#define SAL_GET_STATE_INFO_SIZE 0x01000002
|
||||
#define SAL_CLEAR_STATE_INFO 0x01000003
|
||||
#define SAL_MC_RENDEZ 0x01000004
|
||||
#define SAL_MC_SET_PARAMS 0x01000005
|
||||
#define SAL_REGISTER_PHYSICAL_ADDR 0x01000006
|
||||
#define SAL_CACHE_FLUSH 0x01000008
|
||||
#define SAL_CACHE_INIT 0x01000009
|
||||
#define SAL_PCI_CONFIG_READ 0x01000010
|
||||
#define SAL_PCI_CONFIG_WRITE 0x01000011
|
||||
#define SAL_FREQ_BASE 0x01000012
|
||||
#define SAL_UPDATE_PAL 0x01000020
|
||||
|
||||
/* SAL_SET_VECTORS event handler types */
|
||||
#define SAL_OS_MCA 0
|
||||
#define SAL_OS_INIT 1
|
||||
#define SAL_OS_BOOT_RENDEZ 2
|
||||
|
||||
/* SAL_GET_STATE_INFO, SAL_GET_STATE_INFO_SIZE types */
|
||||
#define SAL_INFO_MCA 0
|
||||
#define SAL_INFO_INIT 1
|
||||
#define SAL_INFO_CMC 2
|
||||
#define SAL_INFO_CPE 3
|
||||
#define SAL_INFO_TYPES 4 /* number of types we know about */
|
||||
|
||||
struct ia64_sal_result
|
||||
{
|
||||
int64_t sal_status;
|
||||
uint64_t sal_result[3];
|
||||
};
|
||||
typedef struct ia64_sal_result ia64_sal_result_t;
|
||||
|
||||
typedef ia64_sal_result_t sal_entry_t
|
||||
( uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t, uint64_t, uint64_t
|
||||
);
|
||||
|
||||
extern ia64_sal_result_t ia64_sal_call(uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
|
||||
extern void ia64_sal_init(sal_system_table_t *saltab);
|
||||
|
||||
#endif /* _SAL_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
|
||||
*
|
||||
****************************************************************************
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(_TRAPS_H_)
|
||||
#define _TRAPS_H_
|
||||
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
/* See ia64_cpu.h */
|
||||
struct trap_frame;
|
||||
|
||||
#define pt_regs trap_frame
|
||||
|
||||
/*
|
||||
* A dummy function, which is currently not supported.
|
||||
*/
|
||||
inline static void trap_init(void)
|
||||
{
|
||||
//printk("trap_init() until now not needed!\n");
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#include "ia64_cpu.h"
|
||||
|
||||
#endif /* !defined(_TRAPS_H_) */
|
||||
|
||||