aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'target-ia64')
-rw-r--r--target-ia64/cpu.h86
-rw-r--r--target-ia64/exec.h61
-rw-r--r--target-ia64/fake-exec.c59
-rw-r--r--target-ia64/firmware.c715
-rw-r--r--target-ia64/firmware.h62
-rw-r--r--target-ia64/helper.c5
-rw-r--r--target-ia64/machine.c35
-rw-r--r--target-ia64/op.c22
-rw-r--r--target-ia64/op_helper.c104
-rw-r--r--target-ia64/translate.c39
10 files changed, 1188 insertions, 0 deletions
diff --git a/target-ia64/cpu.h b/target-ia64/cpu.h
new file mode 100644
index 000000000..e002d5617
--- /dev/null
+++ b/target-ia64/cpu.h
@@ -0,0 +1,86 @@
+/*
+ * IA64 virtual CPU header
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Copyright (c) 2007 Intel Corporation
+ * Zhang xiantao <xiantao.zhang@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef CPU_IA64_H
+#define CPU_IA64_H
+#include "config.h"
+#include "ia64intrin.h"
+
+#include<string.h>
+
+#define TARGET_LONG_BITS 64
+
+#define TARGET_PAGE_BITS 16
+
+#define ELF_MACHINE EM_IA_64
+
+#define NB_MMU_MODES 2
+#define CPU_PAL_HALT 1
+#define HF_HALTED_MASK (1 << CPU_PAL_HALT)
+
+#include "cpu-defs.h"
+
+#include "softfloat.h"
+
+#define CPUState struct CPUIA64State
+
+typedef struct CPUIA64State {
+ CPU_COMMON;
+ uint32_t hflags;
+ int mp_state;
+} CPUIA64State;
+
+#define cpu_gen_code cpu_ia64_gen_code
+#define cpu_init cpu_ia64_init
+#define cpu_signal_handler cpu_ia64_signal_handler
+
+extern struct CPUIA64State *env;
+int cpu_get_pic_interrupt(CPUIA64State *s);
+int cpu_exec(CPUState *env1);
+CPUState *cpu_ia64_init(const char * cpu_model);
+
+static inline int cpu_mmu_index (CPUState *env)
+{
+ return 0;
+}
+
+#define CPU_PC_FROM_TB(env, tb) do{}while(0)
+
+#include "cpu-all.h"
+
+/*
+ * These ones really should go to the appropriate tcg header file, if/when
+ * tcg support is added for ia64.
+ */
+void flush_icache_range(unsigned long start, unsigned long stop);
+void tcg_dump_info(FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = 0;
+ *cs_base = 0;
+ *flags = 0;
+}
+
+#endif
diff --git a/target-ia64/exec.h b/target-ia64/exec.h
new file mode 100644
index 000000000..060d9c35b
--- /dev/null
+++ b/target-ia64/exec.h
@@ -0,0 +1,61 @@
+/*
+ * IA64 execution defines
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2007 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __IA64_H__
+#define __IA64_H__
+
+//#include "dyngen-exec.h"
+#include "config.h"
+
+#include "dyngen-exec.h"
+
+#include "cpu.h"
+#include "exec-all.h"
+
+#define tcg_qemu_tb_exec(tb_ptr) 0
+
+register struct CPUIA64State *env asm(AREG0);
+
+static inline void env_to_regs(void)
+{
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+void do_interrupt (CPUState *env);
+
+void cpu_lock(void);
+void cpu_unlock(void);
+
+static inline int cpu_halted(CPUState *env) {
+ /* handle exit of HALTED state */
+ if (!(env->hflags & HF_HALTED_MASK))
+ return 0;
+ return EXCP_HALTED;
+}
+
+static inline int cpu_has_work(CPUState *env)
+{
+ return (env->interrupt_request & (CPU_INTERRUPT_HARD));
+}
+
+#endif
diff --git a/target-ia64/fake-exec.c b/target-ia64/fake-exec.c
new file mode 100644
index 000000000..c11cc3221
--- /dev/null
+++ b/target-ia64/fake-exec.c
@@ -0,0 +1,59 @@
+/*
+ * fake-exec.c for ia64.
+ *
+ * This is a file for stub functions so that compilation is possible
+ * when TCG CPU emulation is disabled during compilation.
+ *
+ * Copyright 2007 IBM Corporation.
+ * Added by & Authors:
+ * Jerone Young <jyoung5@us.ibm.com>
+ *
+ * Copyright 2008 Intel Corporation.
+ * Added by Xiantao Zhang <xiantao.zhang@intel.com>
+ *
+ * This work is licensed under the GNU GPL licence version 2 or later.
+ *
+ */
+#include <stdio.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+
+int code_copy_enabled = 0;
+
+void cpu_gen_init(void)
+{
+}
+
+unsigned long code_gen_max_block_size(void)
+{
+ return 32;
+}
+
+int cpu_ia64_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
+{
+ return 0;
+}
+
+void tcg_dump_info(FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+ return;
+}
+
+void flush_icache_range(unsigned long start, unsigned long stop)
+{
+ while (start < stop) {
+ asm volatile ("fc %0" :: "r"(start));
+ start += 32;
+ }
+ asm volatile (";;sync.i;;srlz.i;;");
+}
+
+int cpu_restore_state(TranslationBlock *tb,
+ CPUState *env, unsigned long searched_pc,
+ void *puc)
+
+{
+ return 0;
+}
diff --git a/target-ia64/firmware.c b/target-ia64/firmware.c
new file mode 100644
index 000000000..79f846421
--- /dev/null
+++ b/target-ia64/firmware.c
@@ -0,0 +1,715 @@
+/*
+ * firmware.c : Firmware build logic for ia64 platform.
+ *
+ * Ported from Xen 3.0 Source.
+ * Copyright (c) 2007, Intel Corporation.
+ * Zhang Xiantao <xiantao.zhang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <zlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "cpu.h"
+
+#include "firmware.h"
+
+#include "qemu-common.h"
+
+typedef struct {
+ unsigned long signature;
+ unsigned int type;
+ unsigned int length;
+} HOB_GENERIC_HEADER;
+
+/*
+ * INFO HOB is the first data data in one HOB list
+ * it contains the control information of the HOB list
+ */
+typedef struct {
+ HOB_GENERIC_HEADER header;
+ unsigned long length; // current length of hob
+ unsigned long cur_pos; // current poisiton of hob
+ unsigned long buf_size; // size of hob buffer
+} HOB_INFO;
+
+typedef struct{
+ unsigned long start;
+ unsigned long size;
+} hob_mem_t;
+
+typedef enum {
+ HOB_TYPE_INFO=0,
+ HOB_TYPE_TERMINAL,
+ HOB_TYPE_MEM,
+ HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
+ HOB_TYPE_PAL_CACHE_SUMMARY,
+ HOB_TYPE_PAL_MEM_ATTRIB,
+ HOB_TYPE_PAL_CACHE_INFO,
+ HOB_TYPE_PAL_CACHE_PROT_INFO,
+ HOB_TYPE_PAL_DEBUG_INFO,
+ HOB_TYPE_PAL_FIXED_ADDR,
+ HOB_TYPE_PAL_FREQ_BASE,
+ HOB_TYPE_PAL_FREQ_RATIOS,
+ HOB_TYPE_PAL_HALT_INFO,
+ HOB_TYPE_PAL_PERF_MON_INFO,
+ HOB_TYPE_PAL_PROC_GET_FEATURES,
+ HOB_TYPE_PAL_PTCE_INFO,
+ HOB_TYPE_PAL_REGISTER_INFO,
+ HOB_TYPE_PAL_RSE_INFO,
+ HOB_TYPE_PAL_TEST_INFO,
+ HOB_TYPE_PAL_VM_SUMMARY,
+ HOB_TYPE_PAL_VM_INFO,
+ HOB_TYPE_PAL_VM_PAGE_SIZE,
+ HOB_TYPE_NR_VCPU,
+ HOB_TYPE_NR_NVRAM,
+ HOB_TYPE_MAX
+} hob_type_t;
+
+static int hob_init(void *buffer ,unsigned long buf_size);
+static int add_pal_hob(void* hob_buf);
+static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size);
+static int add_vcpus_hob(void* hob_buf, unsigned long nr_vcpu);
+static int add_nvram_hob(void *hob_buf, unsigned long nvram_addr);
+static int build_hob(void *hob_buf, unsigned long hob_buf_size,
+ unsigned long dom_mem_size, unsigned long vcpus,
+ unsigned long nvram_addr);
+static int load_hob(void *hob_buf, unsigned long dom_mem_size);
+
+int
+kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+ unsigned long nvram_addr)
+{
+ char *hob_buf;
+
+ hob_buf = malloc(GFW_HOB_SIZE);
+ if (hob_buf == NULL) {
+ Hob_Output("Hob: Could not allocate hob");
+ return -1;
+ }
+
+ if (build_hob(hob_buf, GFW_HOB_SIZE, memsize, vcpus, nvram_addr) < 0) {
+ free(hob_buf);
+ Hob_Output("Could not build hob");
+ return -1;
+ }
+
+ if (load_hob(hob_buf, memsize) < 0) {
+ free(hob_buf);
+ Hob_Output("Could not load hob");
+ return -1;
+ }
+ free(hob_buf);
+
+ return 0;
+}
+
+static int
+hob_init(void *buffer, unsigned long buf_size)
+{
+ HOB_INFO *phit;
+ HOB_GENERIC_HEADER *terminal;
+
+ if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size) {
+ // buffer too small
+ return -1;
+ }
+
+ phit = (HOB_INFO*)buffer;
+ phit->header.signature = HOB_SIGNATURE;
+ phit->header.type = HOB_TYPE_INFO;
+ phit->header.length = sizeof(HOB_INFO);
+ phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER);
+ phit->cur_pos = 0;
+ phit->buf_size = buf_size;
+
+ terminal = (HOB_GENERIC_HEADER*)(buffer + sizeof(HOB_INFO));
+ terminal->signature = HOB_SIGNATURE;
+ terminal->type = HOB_TYPE_TERMINAL;
+ terminal->length = sizeof(HOB_GENERIC_HEADER);
+
+ return 0;
+}
+
+/*
+ * Add a new HOB to the HOB List.
+ *
+ * hob_start - start address of hob buffer
+ * type - type of the hob to be added
+ * data - data of the hob to be added
+ * data_size - size of the data
+ */
+static int
+hob_add(void* hob_start, int type, void* data, int data_size)
+{
+ HOB_INFO *phit;
+ HOB_GENERIC_HEADER *newhob, *tail;
+
+ phit = (HOB_INFO*)hob_start;
+
+ if (phit->length + data_size > phit->buf_size) {
+ // no space for new hob
+ return -1;
+ }
+
+ //append new HOB
+ newhob = (HOB_GENERIC_HEADER*)(hob_start + phit->length -
+ sizeof(HOB_GENERIC_HEADER));
+ newhob->signature = HOB_SIGNATURE;
+ newhob->type = type;
+ newhob->length = data_size + sizeof(HOB_GENERIC_HEADER);
+ memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size);
+
+ // append terminal HOB
+ tail = (HOB_GENERIC_HEADER*)(hob_start + phit->length + data_size);
+ tail->signature = HOB_SIGNATURE;
+ tail->type = HOB_TYPE_TERMINAL;
+ tail->length = sizeof(HOB_GENERIC_HEADER);
+
+ // adjust HOB list length
+ phit->length += sizeof(HOB_GENERIC_HEADER) + data_size;
+
+ return 0;
+}
+
+static int
+get_hob_size(void* hob_buf)
+{
+ HOB_INFO *phit = (HOB_INFO*)hob_buf;
+
+ if (phit->header.signature != HOB_SIGNATURE) {
+ Hob_Output("xc_get_hob_size:Incorrect signature");
+ return -1;
+ }
+ return phit->length;
+}
+
+static int
+add_max_hob_entry(void* hob_buf)
+{
+ long max_hob = 0;
+ return hob_add(hob_buf, HOB_TYPE_MAX, &max_hob, sizeof(long));
+}
+
+static int
+build_hob(void* hob_buf, unsigned long hob_buf_size,
+ unsigned long dom_mem_size, unsigned long vcpus,
+ unsigned long nvram_addr)
+{
+ //Init HOB List
+ if (hob_init(hob_buf, hob_buf_size) < 0) {
+ Hob_Output("buffer too small");
+ goto err_out;
+ }
+
+ if (add_mem_hob(hob_buf,dom_mem_size) < 0) {
+ Hob_Output("Add memory hob failed, buffer too small");
+ goto err_out;
+ }
+
+ if (add_vcpus_hob(hob_buf, vcpus) < 0) {
+ Hob_Output("Add NR_VCPU hob failed, buffer too small");
+ goto err_out;
+ }
+
+ if (add_pal_hob(hob_buf) < 0) {
+ Hob_Output("Add PAL hob failed, buffer too small");
+ goto err_out;
+ }
+
+ if (add_nvram_hob(hob_buf, nvram_addr) < 0) {
+ Hob_Output("Add nvram hob failed, buffer too small");
+ goto err_out;
+ }
+
+ if (add_max_hob_entry(hob_buf) < 0) {
+ Hob_Output("Add max hob entry failed, buffer too small");
+ goto err_out;
+ }
+ return 0;
+
+err_out:
+ return -1;
+}
+static int
+load_hob(void *hob_buf, unsigned long dom_mem_size)
+{
+ int hob_size;
+
+ hob_size = get_hob_size(hob_buf);
+ if (hob_size < 0) {
+ Hob_Output("Invalid hob data");
+ return -1;
+ }
+
+ if (hob_size > GFW_HOB_SIZE) {
+ Hob_Output("No enough memory for hob data");
+ return -1;
+ }
+
+ cpu_physical_memory_write(GFW_HOB_START, hob_buf, hob_size);
+
+ return 0;
+}
+
+static int
+add_mem_hob(void* hob_buf, unsigned long dom_mem_size)
+{
+ hob_mem_t memhob;
+
+ // less than 3G
+ memhob.start = 0;
+ memhob.size = MIN(dom_mem_size, 0xC0000000);
+
+ if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
+ return -1;
+
+ if (dom_mem_size > 0xC0000000) {
+ // 4G ~ 4G+remain
+ memhob.start = 0x100000000; //4G
+ memhob.size = dom_mem_size - 0xC0000000;
+ if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+add_vcpus_hob(void* hob_buf, unsigned long vcpus)
+{
+ return hob_add(hob_buf, HOB_TYPE_NR_VCPU, &vcpus, sizeof(vcpus));
+}
+
+static int
+add_nvram_hob(void *hob_buf, unsigned long nvram_addr)
+{
+ return hob_add(hob_buf, HOB_TYPE_NR_NVRAM,
+ &nvram_addr, sizeof(nvram_addr));
+}
+
+static const unsigned char config_pal_bus_get_features_data[24] = {
+ 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_cache_summary[16] = {
+ 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_mem_attrib[8] = {
+ 241, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_cache_info[152] = {
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12,
+ 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1,
+ 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0,
+ 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
+ 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255,
+ 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9,
+ 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0
+};
+
+static const unsigned char config_pal_cache_prot_info[200] = {
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
+ 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0,
+ 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255,
+ 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160,
+ 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static const unsigned char config_pal_debug_info[16] = {
+ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_fixed_addr[8] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_freq_base[8] = {
+ 109, 219, 182, 13, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_freq_ratios[24] = {
+ 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4,
+ 0, 0, 0, 7, 0, 0, 0
+};
+
+static const unsigned char config_pal_halt_info[64] = {
+ 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_perf_mon_info[136] = {
+ 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_proc_get_features[104] = {
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
+ 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
+ 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_ptce_info[24] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_register_info[64] = {
+ 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3,
+ 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4,
+ 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255
+};
+
+static const unsigned char config_pal_rse_info[16] = {
+ 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_test_info[48] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_vm_summary[16] = {
+ 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_vm_info[104] = {
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85,
+ 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0,
+ 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0
+};
+
+static const unsigned char config_pal_vm_page_size[16] = {
+ 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0
+};
+
+typedef struct{
+ hob_type_t type;
+ void* data;
+ unsigned long size;
+} hob_batch_t;
+
+static const hob_batch_t hob_batch[]={
+ { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA,
+ &config_pal_bus_get_features_data,
+ sizeof(config_pal_bus_get_features_data)
+ },
+ { HOB_TYPE_PAL_CACHE_SUMMARY,
+ &config_pal_cache_summary,
+ sizeof(config_pal_cache_summary)
+ },
+ { HOB_TYPE_PAL_MEM_ATTRIB,
+ &config_pal_mem_attrib,
+ sizeof(config_pal_mem_attrib)
+ },
+ { HOB_TYPE_PAL_CACHE_INFO,
+ &config_pal_cache_info,
+ sizeof(config_pal_cache_info)
+ },
+ { HOB_TYPE_PAL_CACHE_PROT_INFO,
+ &config_pal_cache_prot_info,
+ sizeof(config_pal_cache_prot_info)
+ },
+ { HOB_TYPE_PAL_DEBUG_INFO,
+ &config_pal_debug_info,
+ sizeof(config_pal_debug_info)
+ },
+ { HOB_TYPE_PAL_FIXED_ADDR,
+ &config_pal_fixed_addr,
+ sizeof(config_pal_fixed_addr)
+ },
+ { HOB_TYPE_PAL_FREQ_BASE,
+ &config_pal_freq_base,
+ sizeof(config_pal_freq_base)
+ },
+ { HOB_TYPE_PAL_FREQ_RATIOS,
+ &config_pal_freq_ratios,
+ sizeof(config_pal_freq_ratios)
+ },
+ { HOB_TYPE_PAL_HALT_INFO,
+ &config_pal_halt_info,
+ sizeof(config_pal_halt_info)
+ },
+ { HOB_TYPE_PAL_PERF_MON_INFO,
+ &config_pal_perf_mon_info,
+ sizeof(config_pal_perf_mon_info)
+ },
+ { HOB_TYPE_PAL_PROC_GET_FEATURES,
+ &config_pal_proc_get_features,
+ sizeof(config_pal_proc_get_features)
+ },
+ { HOB_TYPE_PAL_PTCE_INFO,
+ &config_pal_ptce_info,
+ sizeof(config_pal_ptce_info)
+ },
+ { HOB_TYPE_PAL_REGISTER_INFO,
+ &config_pal_register_info,
+ sizeof(config_pal_register_info)
+ },
+ { HOB_TYPE_PAL_RSE_INFO,
+ &config_pal_rse_info,
+ sizeof(config_pal_rse_info)
+ },
+ { HOB_TYPE_PAL_TEST_INFO,
+ &config_pal_test_info,
+ sizeof(config_pal_test_info)
+ },
+ { HOB_TYPE_PAL_VM_SUMMARY,
+ &config_pal_vm_summary,
+ sizeof(config_pal_vm_summary)
+ },
+ { HOB_TYPE_PAL_VM_INFO,
+ &config_pal_vm_info,
+ sizeof(config_pal_vm_info)
+ },
+ { HOB_TYPE_PAL_VM_PAGE_SIZE,
+ &config_pal_vm_page_size,
+ sizeof(config_pal_vm_page_size)
+ },
+};
+
+static int
+add_pal_hob(void* hob_buf)
+{
+ int i;
+ for (i = 0; i < sizeof(hob_batch)/sizeof(hob_batch_t); i++) {
+ if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data,
+ hob_batch[i].size) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+uint8_t *read_image(const char *filename, unsigned long *size)
+{
+ int kernel_fd = -1;
+ gzFile kernel_gfd = NULL;
+ uint8_t *image = NULL, *tmp;
+ unsigned int bytes;
+
+ if ((filename == NULL) || (size == NULL))
+ return NULL;
+
+ kernel_fd = open(filename, O_RDONLY);
+ if (kernel_fd < 0) {
+ Hob_Output("Could not open kernel image\n");
+ goto out_1;
+ }
+
+ if ((kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL) {
+ Hob_Output("Could not allocate decompression state for state file\n");
+ goto out_1;
+ }
+
+ *size = 0;
+
+#define CHUNK 1*1024*1024
+ while(1)
+ {
+ if ((tmp = realloc(image, *size + CHUNK)) == NULL) {
+ Hob_Output("Could not allocate memory for kernel image");
+ free(image);
+ image = NULL;
+ goto out;
+ }
+ image = tmp;
+
+ bytes = gzread(kernel_gfd, image + *size, CHUNK);
+ switch (bytes) {
+ case -1:
+ Hob_Output("Error reading kernel image");
+ free(image);
+ image = NULL;
+ goto out;
+ case 0: /* EOF */
+ goto out;
+ default:
+ *size += bytes;
+ break;
+ }
+ }
+#undef CHUNK
+
+out:
+ if (*size == 0) {
+ Hob_Output("Could not read kernel image");
+ free(image);
+ image = NULL;
+ } else if (image) {
+ /* Shrink allocation to fit image. */
+ tmp = realloc(image, *size);
+ if (tmp)
+ image = tmp;
+ }
+
+ if (kernel_gfd != NULL)
+ gzclose(kernel_gfd);
+ else if (kernel_fd >= 0)
+ close(kernel_fd);
+ return image;
+
+out_1:
+ return NULL;
+}
+
+int kvm_ia64_nvram_init(unsigned long type)
+{
+ unsigned long nvram_fd;
+ char nvram_path[PATH_MAX];
+ unsigned long i;
+
+ if (nvram) {
+ if (strlen(nvram) > PATH_MAX) {
+ goto out;
+ }
+ if (type == READ_FROM_NVRAM) {
+ if (access(nvram, R_OK | W_OK | X_OK) == -1)
+ goto out;
+ nvram_fd = open(nvram, O_RDONLY);
+ return nvram_fd;
+ }
+ else { /* write from gfw to nvram file */
+ i = access(nvram, R_OK | W_OK | X_OK);
+ if ((i == -1) && (errno != ENOENT))
+ goto out;
+ nvram_fd = open(nvram, O_CREAT|O_RDWR, 0777);
+ return nvram_fd;
+ }
+ }
+ else {
+ strcpy(nvram_path, "nvram.dat");
+ if (type == READ_FROM_NVRAM) {
+ if (access(nvram_path, R_OK | W_OK | X_OK) == -1)
+ goto out;
+ nvram_fd = open(nvram_path, O_RDONLY);
+ return nvram_fd;
+ }
+ else { /* write from gfw to nvram file */
+ i = access(nvram_path, R_OK | W_OK | X_OK);
+ if ((i == -1) && (errno != ENOENT))
+ goto out;
+ nvram_fd = open(nvram_path, O_CREAT|O_RDWR, 0777);
+ return nvram_fd;
+ }
+ }
+out:
+ return -1;
+}
+
+int
+kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd)
+{
+ struct stat file_stat;
+ uint8_t *nvram_buf;
+ int r = 0;
+
+ nvram_buf = malloc(NVRAM_SIZE);
+
+ if ((fstat(nvram_fd, &file_stat) < 0) ||
+ (NVRAM_SIZE != file_stat.st_size) ||
+ (read(nvram_fd, nvram_buf, NVRAM_SIZE) != NVRAM_SIZE)) {
+ r = -1;
+ goto out;
+ }
+
+ cpu_physical_memory_write(NVRAM_START, nvram_buf, NVRAM_SIZE);
+
+ out:
+ free(nvram_buf);
+ return r;
+}
+
+int
+kvm_ia64_copy_from_GFW_to_nvram()
+{
+ struct nvram_save_addr nvram_addr_buf;
+ uint8_t *nvram_buf;
+ unsigned long nvram_fd;
+ unsigned long type = WRITE_TO_NVRAM;
+ int ret = -1;
+
+ nvram_buf = malloc(NVRAM_SIZE);
+ if (!nvram_buf)
+ goto out_free;
+
+ cpu_physical_memory_read(NVRAM_START, (uint8_t *)&nvram_addr_buf,
+ sizeof(struct nvram_save_addr));
+ if (nvram_addr_buf.signature != NVRAM_VALID_SIG) {
+ goto out_free;
+ }
+
+ cpu_physical_memory_read(nvram_addr_buf.addr, nvram_buf, NVRAM_SIZE);
+
+ nvram_fd = kvm_ia64_nvram_init(type);
+ if (nvram_fd == -1)
+ goto out;
+
+ lseek(nvram_fd, 0, SEEK_SET);
+ if (write(nvram_fd, nvram_buf, NVRAM_SIZE) != NVRAM_SIZE)
+ goto out;
+
+ ret = 0;
+ out:
+ close(nvram_fd);
+ out_free:
+ free(nvram_buf);
+ return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/target-ia64/firmware.h b/target-ia64/firmware.h
new file mode 100644
index 000000000..a47db671d
--- /dev/null
+++ b/target-ia64/firmware.h
@@ -0,0 +1,62 @@
+/*
+ * firmwar.h: Firmware build logic head file
+ *
+ * Copyright (c) 2007, Intel Corporation.
+ * Zhang Xiantao <xiantao.zhang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __FIRM_WARE_H
+#define __FIRM_WARE_
+#include "cpu.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <zlib.h>
+
+#define GFW_SIZE (16UL<<20)
+#define GFW_START ((4UL<<30) - GFW_SIZE)
+
+#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64"
+#define GFW_HOB_START ((4UL<<30) - (14UL<<20)) // 4G - 14M
+#define GFW_HOB_SIZE (1UL<<20) // 1M
+#define HOB_OFFSET (GFW_HOB_START-GFW_START)
+
+#define Hob_Output(s) fprintf(stderr, s)
+
+#define NVRAM_START (GFW_START + NVRAM_OFFSET)
+#define NVRAM_OFFSET (10 * (1UL << 20))
+#define NVRAM_SIZE (64 * (1UL << 10))
+#define NVRAM_VALID_SIG 0x4650494e45584948 /* "HIXENIPF" */
+#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)
+#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))
+#define READ_FROM_NVRAM 0
+#define WRITE_TO_NVRAM 1
+
+struct nvram_save_addr {
+ unsigned long addr;
+ unsigned long signature;
+};
+
+extern const char *nvram;
+extern int kvm_ia64_build_hob(unsigned long memsize, unsigned long vcpus,
+ unsigned long nvram_addr);
+extern uint8_t *read_image(const char *filename, unsigned long *size);
+
+extern int kvm_ia64_copy_from_GFW_to_nvram(void);
+extern int kvm_ia64_nvram_init(unsigned long type);
+extern int kvm_ia64_copy_from_nvram_to_GFW(unsigned long nvram_fd);
+#endif //__FIRM_WARE_
diff --git a/target-ia64/helper.c b/target-ia64/helper.c
new file mode 100644
index 000000000..4a94dcafb
--- /dev/null
+++ b/target-ia64/helper.c
@@ -0,0 +1,5 @@
+
+/*
+ * IA64 emulation helpers for qemu. (Leave it as blank now.)
+ *
+ */
diff --git a/target-ia64/machine.c b/target-ia64/machine.c
new file mode 100644
index 000000000..dd205c576
--- /dev/null
+++ b/target-ia64/machine.c
@@ -0,0 +1,35 @@
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+#include "exec-all.h"
+#include "qemu-kvm.h"
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+ CPUState *env = opaque;
+
+ if (kvm_enabled()) {
+ kvm_save_registers(env);
+ kvm_save_mpstate(env);
+ }
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+ CPUState *env = opaque;
+
+ if (kvm_enabled()) {
+ kvm_load_registers(env);
+ kvm_load_mpstate(env);
+ }
+ return 0;
+}
+
+extern QEMUMachine ipf_machine;
+
+static void ipf_machine_init(void)
+{
+ qemu_register_machine(&ipf_machine);
+}
+
+machine_init(ipf_machine_init);
diff --git a/target-ia64/op.c b/target-ia64/op.c
new file mode 100644
index 000000000..f7301c641
--- /dev/null
+++ b/target-ia64/op.c
@@ -0,0 +1,22 @@
+/*
+ * IA64 micro operations
+ *
+ * Leave it blank for future implementation
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
diff --git a/target-ia64/op_helper.c b/target-ia64/op_helper.c
new file mode 100644
index 000000000..d51525ac4
--- /dev/null
+++ b/target-ia64/op_helper.c
@@ -0,0 +1,104 @@
+/*
+ * op_helper.c: IA64 emulation cpu micro-operations helpers for qemu.
+ *
+ * Copyright (c) 2007 Intel Corporation
+ * Zhang Xiantao <xiantao.zhang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+
+#include "qemu-kvm.h"
+#include "qemu-common.h"
+
+void cpu_ia64_set_model(CPUIA64State *env, uint32_t id);
+void cpu_ia64_close(CPUIA64State *env);
+void switch_mode(CPUState *env, int mode);
+void do_interrupt(CPUIA64State *env);
+int cpu_ia64_handle_mmu_fault (CPUState *env, target_ulong address,
+ int access_type, int is_user, int is_softmmu);
+CPUState *cpu_ia64_init(const char *cpu_model)
+{
+ CPUState *env;
+ env = qemu_mallocz(sizeof(CPUState));
+ if (!env)
+ return NULL;
+ cpu_exec_init(env);
+ cpu_reset(env);
+ if (kvm_enabled()) {
+ kvm_qemu_init_env(env);
+ kvm_init_vcpu(env);
+ }
+ return env;
+}
+
+void cpu_reset(CPUIA64State *env)
+{
+}
+
+static inline void set_feature(CPUIA64State *env, int feature)
+{
+}
+
+void cpu_ia64_set_model(CPUIA64State *env, uint32_t id)
+{
+}
+
+void cpu_ia64_close(CPUIA64State *env)
+{
+ free(env);
+}
+
+extern int semihosting_enabled;
+
+void switch_mode(CPUState *env, int mode)
+{
+}
+
+/* Handle a CPU exception. */
+void do_interrupt(CPUIA64State *env)
+{
+ if (kvm_enabled()) {
+ printf("%s: unexpect\n", __FUNCTION__);
+ exit(-1);
+ }
+}
+
+int cpu_ia64_handle_mmu_fault (CPUState *env, target_ulong address,
+ int access_type, int is_user, int is_softmmu)
+{
+ return 1;
+}
+
+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+ return -1;
+}
+
+void cpu_dump_state(CPUState *env, FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ int flags)
+{
+ return;
+}
+
+void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+{
+ return;
+}
diff --git a/target-ia64/translate.c b/target-ia64/translate.c
new file mode 100644
index 000000000..86f48f50c
--- /dev/null
+++ b/target-ia64/translate.c
@@ -0,0 +1,39 @@
+/*
+ * translation.c : IA64 translation code.
+ * Just put it as blank now, and implement it later.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+static uint16_t *gen_opc_ptr;
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "disas.h"
+#include "gen-op.h"
+
+int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+{
+ return 0;
+}
+int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+{
+ return 0;
+}