# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 50aea0ec406bd03dad9da31255857e4a41f7efcc
# Parent e01441c9a607d3364dc092f186e0d925a3d4d8d4
# Parent 74db626d2fcfde3e61f1f43934eddd034d64a4a9
Merge with xenppc-unstable-merge.hg.
---
linux-2.6-xen-sparse/arch/ia64/dig/setup.c | 2
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 2
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c | 27
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 6
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 60 -
linux-2.6-xen-sparse/include/asm-ia64/agp.h | 12
linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h | 20
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h | 165 ---
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 38
linux-2.6-xen-sparse/include/asm-ia64/io.h | 6
linux-2.6-xen-sparse/include/asm-ia64/machvec.h | 2
linux-2.6-xen-sparse/include/asm-ia64/maddr.h | 88 +
linux-2.6-xen-sparse/include/asm-ia64/page.h | 69 -
linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h | 4
tools/debugger/gdb/gdbbuild | 4
tools/examples/xmexample.vti | 32
tools/libxc/ia64/xc_ia64_hvm_build.c | 13
tools/libxc/ia64/xc_ia64_linux_save.c | 2
tools/libxc/ia64/xc_ia64_stubs.c | 16
xen/arch/ia64/asm-offsets.c | 1
xen/arch/ia64/linux-xen/efi.c | 22
xen/arch/ia64/linux-xen/iosapic.c | 2
xen/arch/ia64/linux-xen/irq_ia64.c | 10
xen/arch/ia64/linux-xen/mca.c | 1
xen/arch/ia64/linux-xen/process-linux-xen.c | 5
xen/arch/ia64/linux-xen/smp.c | 4
xen/arch/ia64/linux-xen/unwind.c | 3
xen/arch/ia64/vmx/Makefile | 2
xen/arch/ia64/vmx/mmio.c | 17
xen/arch/ia64/vmx/vmmu.c | 1
xen/arch/ia64/vmx/vmx_hypercall.c | 12
xen/arch/ia64/vmx/vmx_init.c | 47
xen/arch/ia64/vmx/vmx_phy_mode.c | 3
xen/arch/ia64/vmx/vmx_process.c | 8
xen/arch/ia64/vmx/vmx_support.c | 136 +-
xen/arch/ia64/vmx/vtlb.c | 101 -
xen/arch/ia64/xen/acpi.c | 3
xen/arch/ia64/xen/dom0_ops.c | 5
xen/arch/ia64/xen/dom_fw.c | 967 ++++++++---------
xen/arch/ia64/xen/domain.c | 49
xen/arch/ia64/xen/faults.c | 7
xen/arch/ia64/xen/flushd.S | 11
xen/arch/ia64/xen/fw_emul.c | 165 ++-
xen/arch/ia64/xen/hypercall.c | 130 +-
xen/arch/ia64/xen/hyperprivop.S | 81 -
xen/arch/ia64/xen/irq.c | 4
xen/arch/ia64/xen/ivt.S | 1035 ++++++++++---------
xen/arch/ia64/xen/mm.c | 7
xen/arch/ia64/xen/pcdp.c | 1
xen/arch/ia64/xen/privop.c | 4
xen/arch/ia64/xen/privop_stat.c | 113 +-
xen/arch/ia64/xen/vcpu.c | 31
xen/arch/ia64/xen/vhpt.c | 18
xen/arch/ia64/xen/xen.lds.S | 8
xen/arch/ia64/xen/xenasm.S | 22
xen/arch/ia64/xen/xensetup.c | 12
xen/arch/ia64/xen/xentime.c | 4
xen/arch/x86/physdev.c | 5
xen/include/asm-ia64/config.h | 6
xen/include/asm-ia64/dom_fw.h | 56 -
xen/include/asm-ia64/domain.h | 14
xen/include/asm-ia64/grant_table.h | 2
xen/include/asm-ia64/linux-xen/asm/processor.h | 8
xen/include/asm-ia64/linux-xen/linux/efi.h | 4
xen/include/asm-ia64/multicall.h | 8
xen/include/asm-ia64/perfc.h | 12
xen/include/asm-ia64/perfc_defn.h | 17
xen/include/asm-ia64/privop_stat.h | 43
xen/include/asm-ia64/uaccess.h | 18
xen/include/asm-ia64/vcpu.h | 17
xen/include/asm-ia64/vhpt.h | 2
xen/include/asm-ia64/vmx.h | 8
xen/include/asm-ia64/vmx_vcpu.h | 7
xen/include/asm-ia64/vmx_vpd.h | 10
xen/include/public/domctl.h | 7
xen/include/public/xen.h | 1
76 files changed, 2182 insertions(+), 1683 deletions(-)
diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/arch/ia64/dig/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/dig/setup.c Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/dig/setup.c Wed Aug 30 22:36:18
2006 +0100
@@ -69,7 +69,7 @@ dig_setup (char **cmdline_p)
screen_info.orig_video_isVGA = 1; /* XXX fake */
screen_info.orig_video_ega_bx = 3; /* XXX fake */
#ifdef CONFIG_XEN
- if (!is_running_on_xen())
+ if (!is_running_on_xen() || !is_initial_xendomain())
return;
if (xen_start_info->console.dom0.info_size >=
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Wed Aug 30 22:36:18
2006 +0100
@@ -560,7 +560,9 @@ setup_arch (char **cmdline_p)
platform_setup(cmdline_p);
paging_init();
+#ifdef CONFIG_XEN
contiguous_bitmap_init(max_pfn);
+#endif
}
/*
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Wed Aug 30 22:36:18
2006 +0100
@@ -371,6 +371,8 @@ int
int
HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
{
+ __u64 va1, va2, pa1, pa2;
+
if (cmd == GNTTABOP_map_grant_ref) {
unsigned int i;
for (i = 0; i < count; i++) {
@@ -378,8 +380,29 @@ HYPERVISOR_grant_table_op(unsigned int c
(struct gnttab_map_grant_ref*)uop + i);
}
}
-
- return ____HYPERVISOR_grant_table_op(cmd, uop, count);
+ va1 = (__u64)uop & PAGE_MASK;
+ pa1 = pa2 = 0;
+ if ((REGION_NUMBER(va1) == 5) &&
+ ((va1 - KERNEL_START) >= KERNEL_TR_PAGE_SIZE)) {
+ pa1 = ia64_tpa(va1);
+ if (cmd <= GNTTABOP_transfer) {
+ static uint32_t uop_size[GNTTABOP_transfer + 1] = {
+ sizeof(struct gnttab_map_grant_ref),
+ sizeof(struct gnttab_unmap_grant_ref),
+ sizeof(struct gnttab_setup_table),
+ sizeof(struct gnttab_dump_table),
+ sizeof(struct gnttab_transfer),
+ };
+ va2 = (__u64)uop + (uop_size[cmd] * count) - 1;
+ va2 &= PAGE_MASK;
+ if (va1 != va2) {
+ /* maximum size of uop is 2pages */
+ BUG_ON(va2 > va1 + PAGE_SIZE);
+ pa2 = ia64_tpa(va2);
+ }
+ }
+ }
+ return ____HYPERVISOR_grant_table_op(cmd, uop, count, pa1, pa2);
}
EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Wed Aug 30
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Wed Aug 30
22:36:18 2006 +0100
@@ -846,7 +846,7 @@ void __init setup_arch(char **cmdline_p)
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Make sure we have a large enough P->M table. */
- phys_to_machine_mapping = alloc_bootmem(
+ phys_to_machine_mapping = alloc_bootmem_pages(
end_pfn * sizeof(unsigned long));
memset(phys_to_machine_mapping, ~0,
end_pfn * sizeof(unsigned long));
@@ -863,7 +863,7 @@ void __init setup_arch(char **cmdline_p)
* list of frames that make up the p2m table. Used by
* save/restore.
*/
- pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
+ pfn_to_mfn_frame_list_list =
alloc_bootmem_pages(PAGE_SIZE);
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list
=
virt_to_mfn(pfn_to_mfn_frame_list_list);
@@ -873,7 +873,7 @@ void __init setup_arch(char **cmdline_p)
k++;
BUG_ON(k>=fpp);
pfn_to_mfn_frame_list[k] =
- alloc_bootmem(PAGE_SIZE);
+ alloc_bootmem_pages(PAGE_SIZE);
pfn_to_mfn_frame_list_list[k] =
virt_to_mfn(pfn_to_mfn_frame_list[k]);
j=0;
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 30
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 30
22:36:18 2006 +0100
@@ -193,6 +193,7 @@ static void netfront_closing(struct xenb
static void end_access(int, void *);
static void netif_disconnect_backend(struct netfront_info *);
+static int open_netdev(struct netfront_info *);
static void close_netdev(struct netfront_info *);
static void netif_free(struct netfront_info *);
@@ -263,15 +264,22 @@ static int __devinit netfront_probe(stru
dev->dev.driver_data = info;
err = talk_to_backend(dev, info);
- if (err) {
- xennet_sysfs_delif(info->netdev);
- unregister_netdev(netdev);
- free_netdev(netdev);
- dev->dev.driver_data = NULL;
- return err;
- }
+ if (err)
+ goto fail_backend;
+
+ err = open_netdev(info);
+ if (err)
+ goto fail_open;
return 0;
+
+ fail_open:
+ xennet_sysfs_delif(info->netdev);
+ unregister_netdev(netdev);
+ fail_backend:
+ free_netdev(netdev);
+ dev->dev.driver_data = NULL;
+ return err;
}
@@ -1887,27 +1895,9 @@ create_netdev(int handle, int copying_re
SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &dev->dev);
- err = register_netdev(netdev);
- if (err) {
- printk(KERN_WARNING "%s> register_netdev err=%d\n",
- __FUNCTION__, err);
- goto exit_free_rx;
- }
-
- err = xennet_sysfs_addif(netdev);
- if (err) {
- /* This can be non-fatal: it only means no tuning parameters */
- printk(KERN_WARNING "%s> add sysfs failed err=%d\n",
- __FUNCTION__, err);
- }
-
np->netdev = netdev;
-
return netdev;
-
- exit_free_rx:
- gnttab_free_grant_references(np->gref_rx_head);
exit_free_tx:
gnttab_free_grant_references(np->gref_tx_head);
exit:
@@ -1966,6 +1956,26 @@ static int __devexit netfront_remove(str
return 0;
}
+
+static int open_netdev(struct netfront_info *info)
+{
+ int err;
+
+ err = register_netdev(info->netdev);
+ if (err) {
+ printk(KERN_WARNING "%s: register_netdev err=%d\n",
+ __FUNCTION__, err);
+ return err;
+ }
+
+ err = xennet_sysfs_addif(info->netdev);
+ if (err) {
+ /* This can be non-fatal: it only means no tuning parameters */
+ printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
+ __FUNCTION__, err);
+ }
+ return 0;
+}
static void close_netdev(struct netfront_info *info)
{
diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/include/asm-ia64/agp.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/agp.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/agp.h Wed Aug 30 22:36:18
2006 +0100
@@ -19,10 +19,21 @@
#define flush_agp_cache() mb()
/* Convert a physical address to an address suitable for the GART. */
+#ifndef CONFIG_XEN
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+#else
#define phys_to_gart(x) phys_to_machine_for_dma(x)
#define gart_to_phys(x) machine_to_phys_for_dma(x)
+#endif
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#ifndef CONFIG_XEN
+#define alloc_gatt_pages(order) \
+ ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order) \
+ free_pages((unsigned long)(table), (order))
+#else
#include <asm/hypervisor.h>
static inline char*
alloc_gatt_pages(unsigned int order)
@@ -46,5 +57,6 @@ free_gatt_pages(void* table, unsigned in
xen_destroy_contiguous_region((unsigned long)table, order);
free_pages((unsigned long)table, order);
}
+#endif /* CONFIG_XEN */
#endif /* _ASM_IA64_AGP_H */
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h Wed Aug 30
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h Wed Aug 30
22:36:18 2006 +0100
@@ -7,11 +7,28 @@
*/
#include <linux/config.h>
#include <asm/machvec.h>
+#ifdef CONFIG_XEN
/* Needed for arch/i386/kernel/swiotlb.c and arch/i386/kernel/pci-dma-xen.c */
#include <asm/hypervisor.h>
/* Needed for arch/i386/kernel/swiotlb.c */
#include <asm-i386/mach-xen/asm/swiotlb.h>
+#endif
+#ifndef CONFIG_XEN
+#define dma_alloc_coherent platform_dma_alloc_coherent
+#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent
mem. is cheap */
+#define dma_free_coherent platform_dma_free_coherent
+#define dma_free_noncoherent platform_dma_free_coherent
+#define dma_map_single platform_dma_map_single
+#define dma_map_sg platform_dma_map_sg
+#define dma_unmap_single platform_dma_unmap_single
+#define dma_unmap_sg platform_dma_unmap_sg
+#define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu
+#define dma_sync_sg_for_cpu platform_dma_sync_sg_for_cpu
+#define dma_sync_single_for_device platform_dma_sync_single_for_device
+#define dma_sync_sg_for_device platform_dma_sync_sg_for_device
+#define dma_mapping_error platform_dma_mapping_error
+#else
int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
enum dma_data_direction direction);
void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -50,6 +67,7 @@ dma_sync_sg_for_device(struct device *de
swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
flush_write_buffers();
}
+#endif
#define dma_map_page(dev, pg, off, size, dir) \
dma_map_single(dev, page_address(pg) + (off), (size), (dir))
@@ -91,6 +109,7 @@ dma_cache_sync (void *vaddr, size_t size
#define dma_is_consistent(dma_handle) (1) /* all we do is coherent
memory... */
+#ifdef CONFIG_XEN
/* arch/i386/kernel/swiotlb.o requires */
void contiguous_bitmap_init(unsigned long end_pfn);
@@ -111,5 +130,6 @@ range_straddles_page_boundary(void *p, s
return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
!test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
}
+#endif
#endif /* _ASM_IA64_DMA_MAPPING_H */
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Aug 30 22:36:18
2006 +0100
@@ -51,7 +51,7 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name) \
+ : "J" (__HYPERVISOR_##name) \
: "r2","r8", \
"memory" ); \
(type)__res; \
@@ -66,8 +66,8 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "r" ((unsigned long)(a1)) \
+ : "J" (__HYPERVISOR_##name), \
+ "rI" ((unsigned long)(a1)) \
: "r14","r2","r8", \
"memory" ); \
(type)__res; \
@@ -83,9 +83,9 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)) \
+ : "J" (__HYPERVISOR_##name), \
+ "rI" ((unsigned long)(a1)), \
+ "rI" ((unsigned long)(a2)) \
: "r14","r15","r2","r8", \
"memory" ); \
(type)__res; \
@@ -102,10 +102,10 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)), \
- "r" ((unsigned long)(a3)) \
+ : "J" (__HYPERVISOR_##name), \
+ "rI" ((unsigned long)(a1)), \
+ "rI" ((unsigned long)(a2)), \
+ "rI" ((unsigned long)(a3)) \
: "r14","r15","r16","r2","r8", \
"memory" ); \
(type)__res; \
@@ -123,11 +123,11 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)), \
- "r" ((unsigned long)(a3)), \
- "r" ((unsigned long)(a4)) \
+ : "J" (__HYPERVISOR_##name), \
+ "rI" ((unsigned long)(a1)), \
+ "rI" ((unsigned long)(a2)), \
+ "rI" ((unsigned long)(a3)), \
+ "rI" ((unsigned long)(a4)) \
: "r14","r15","r16","r2","r8", \
"r17","memory" ); \
(type)__res; \
@@ -146,12 +146,12 @@
"break 0x1000 ;;\n" \
"mov %0=r8 ;;\n" \
: "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)), \
- "r" ((unsigned long)(a3)), \
- "r" ((unsigned long)(a4)), \
- "r" ((unsigned long)(a5)) \
+ : "J" (__HYPERVISOR_##name), \
+ "rI" ((unsigned long)(a1)), \
+ "rI" ((unsigned long)(a2)), \
+ "rI" ((unsigned long)(a3)), \
+ "rI" ((unsigned long)(a4)), \
+ "rI" ((unsigned long)(a5)) \
: "r14","r15","r16","r2","r8", \
"r17","r18","memory" ); \
(type)__res; \
@@ -275,9 +275,10 @@ HYPERVISOR_physdev_op(
//XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
static inline int
____HYPERVISOR_grant_table_op(
- unsigned int cmd, void *uop, unsigned int count)
-{
- return _hypercall3(int, grant_table_op, cmd, uop, count);
+ unsigned int cmd, void *uop, unsigned int count,
+ unsigned long pa1, unsigned long pa2)
+{
+ return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
}
int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
@@ -290,6 +291,13 @@ HYPERVISOR_vcpu_op(
}
extern int HYPERVISOR_suspend(unsigned long srec);
+
+static inline unsigned long
+HYPERVISOR_hvm_op(
+ int cmd, void *arg)
+{
+ return _hypercall2(unsigned long, hvm_op, cmd, arg);
+}
static inline int
HYPERVISOR_callback_op(
@@ -307,99 +315,15 @@ static inline void exit_idle(void) {}
})
#include <linux/err.h>
+#ifdef CONFIG_XEN
#include <asm/xen/privop.h>
-
-#define _hypercall_imm1(type, name, imm, a1) \
-({ \
- long __res; \
- __asm__ __volatile__ (";;\n" \
- "mov r14=%2\n" \
- "mov r15=%3\n" \
- "mov r2=%1\n" \
- "break 0x1000 ;;\n" \
- "mov %0=r8 ;;\n" \
- : "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "i" (imm), \
- "r" ((unsigned long)(a1)) \
- : "r14","r15","r2","r8", \
- "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall_imm2(type, name, imm, a1, a2) \
-({ \
- long __res; \
- __asm__ __volatile__ (";;\n" \
- "mov r14=%2\n" \
- "mov r15=%3\n" \
- "mov r16=%4\n" \
- "mov r2=%1\n" \
- "break 0x1000 ;;\n" \
- "mov %0=r8 ;;\n" \
- : "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "i" (imm), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)) \
- : "r14","r15","r16","r2","r8", \
- "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall_imm3(type, name, imm, a1, a2, a3) \
-({ \
- long __res; \
- __asm__ __volatile__ (";;\n" \
- "mov r14=%2\n" \
- "mov r15=%3\n" \
- "mov r16=%4\n" \
- "mov r17=%5\n" \
- "mov r2=%1\n" \
- "break 0x1000 ;;\n" \
- "mov %0=r8 ;;\n" \
- : "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "i" (imm), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)), \
- "r" ((unsigned long)(a3)) \
- : "r14","r15","r16","r17", \
- "r2","r8", \
- "memory" ); \
- (type)__res; \
-})
-
-#define _hypercall_imm4(type, name, imm, a1, a2, a3, a4) \
-({ \
- long __res; \
- __asm__ __volatile__ (";;\n" \
- "mov r14=%2\n" \
- "mov r15=%3\n" \
- "mov r16=%4\n" \
- "mov r17=%5\n" \
- "mov r18=%6\n" \
- "mov r2=%1\n" \
- "break 0x1000 ;;\n" \
- "mov %0=r8 ;;\n" \
- : "=r" (__res) \
- : "i" (__HYPERVISOR_##name), \
- "i" (imm), \
- "r" ((unsigned long)(a1)), \
- "r" ((unsigned long)(a2)), \
- "r" ((unsigned long)(a3)), \
- "r" ((unsigned long)(a4)) \
- : "r14","r15","r16","r17","r18", \
- "r2","r8", \
- "memory" ); \
- (type)__res; \
-})
+#endif /* CONFIG_XEN */
static inline unsigned long
__HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
{
- return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
- IA64_DOM0VP_ioremap, ioaddr, size);
+ return _hypercall3(unsigned long, ia64_dom0vp_op,
+ IA64_DOM0VP_ioremap, ioaddr, size);
}
static inline unsigned long
@@ -421,8 +345,8 @@ static inline unsigned long
static inline unsigned long
__HYPERVISOR_phystomach(unsigned long gpfn)
{
- return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
- IA64_DOM0VP_phystomach, gpfn);
+ return _hypercall2(unsigned long, ia64_dom0vp_op,
+ IA64_DOM0VP_phystomach, gpfn);
}
static inline unsigned long
@@ -438,8 +362,8 @@ static inline unsigned long
static inline unsigned long
__HYPERVISOR_machtophys(unsigned long mfn)
{
- return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
- IA64_DOM0VP_machtophys, mfn);
+ return _hypercall2(unsigned long, ia64_dom0vp_op,
+ IA64_DOM0VP_machtophys, mfn);
}
static inline unsigned long
@@ -455,8 +379,8 @@ static inline unsigned long
static inline unsigned long
__HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
{
- return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
- IA64_DOM0VP_zap_physmap, gpfn, extent_order);
+ return _hypercall3(unsigned long, ia64_dom0vp_op,
+ IA64_DOM0VP_zap_physmap, gpfn, extent_order);
}
static inline unsigned long
@@ -473,9 +397,8 @@ __HYPERVISOR_add_physmap(unsigned long g
__HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
unsigned long flags, domid_t domid)
{
- return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
- IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
- domid);
+ return _hypercall5(unsigned long, ia64_dom0vp_op,
+ IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
}
static inline unsigned long
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Wed Aug 30
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h Wed Aug 30
22:36:18 2006 +0100
@@ -33,7 +33,7 @@
#ifndef __HYPERVISOR_H__
#define __HYPERVISOR_H__
-#ifndef CONFIG_XEN
+#if !defined(CONFIG_XEN) && !defined(CONFIG_VMX_GUEST)
#define is_running_on_xen() (0)
#define HYPERVISOR_ioremap(offset, size) (offset)
#else
@@ -41,7 +41,7 @@ extern int running_on_xen;
#define is_running_on_xen() (running_on_xen)
#endif
-#ifdef CONFIG_XEN
+#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST)
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -59,10 +59,9 @@ extern shared_info_t *HYPERVISOR_shared_
extern shared_info_t *HYPERVISOR_shared_info;
extern start_info_t *xen_start_info;
-#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
-
void force_evtchn_callback(void);
+#ifndef CONFIG_VMX_GUEST
/* Turn jiffies into Xen system time. XXX Implement me. */
#define jiffies_to_st(j) 0
@@ -145,10 +144,14 @@ int privcmd_mmap(struct file * file, str
#define scrub_pages(_p,_n) ((void)0)
#endif
#define pte_mfn(_x) pte_pfn(_x)
-#define __pte_ma(_x) ((pte_t) {(_x)})
#define phys_to_machine_mapping_valid(_x) (1)
-#define pfn_pte_ma(_x,_y) __pte_ma(0)
-
+
+#endif /* !CONFIG_VMX_GUEST */
+
+#define __pte_ma(_x) ((pte_t) {(_x)}) /* unmodified use */
+#define pfn_pte_ma(_x,_y) __pte_ma(0) /* unmodified use */
+
+#ifndef CONFIG_VMX_GUEST
int __xen_create_contiguous_region(unsigned long vstart, unsigned int order,
unsigned int address_bits);
static inline int
xen_create_contiguous_region(unsigned long vstart,
@@ -170,6 +173,8 @@ xen_destroy_contiguous_region(unsigned l
__xen_destroy_contiguous_region(vstart, order);
}
+#endif /* !CONFIG_VMX_GUEST */
+
// for netfront.c, netback.c
#define MULTI_UVMFLAGS_INDEX 0 //XXX any value
@@ -180,12 +185,29 @@ MULTI_update_va_mapping(
{
mcl->op = __HYPERVISOR_update_va_mapping;
mcl->result = 0;
+}
+
+static inline void
+MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
+ void *uop, unsigned int count)
+{
+ mcl->op = __HYPERVISOR_grant_table_op;
+ mcl->args[0] = cmd;
+ mcl->args[1] = (unsigned long)uop;
+ mcl->args[2] = count;
}
// for debug
asmlinkage int xprintk(const char *fmt, ...);
#define xprintd(fmt, ...) xprintk("%s:%d " fmt, __func__, __LINE__, \
##__VA_ARGS__)
-#endif /* CONFIG_XEN */
+
+#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */
+
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
+#else
+#define is_initial_xendomain() 0
+#endif
#endif /* __HYPERVISOR_H__ */
diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/include/asm-ia64/io.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/io.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/io.h Wed Aug 30 22:36:18
2006 +0100
@@ -97,6 +97,11 @@ extern int valid_mmap_phys_addr_range (u
* The following two macros are deprecated and scheduled for removal.
* Please use the PCI-DMA interface defined in <asm/pci.h> instead.
*/
+#ifndef CONFIG_XEN
+#define bus_to_virt phys_to_virt
+#define virt_to_bus virt_to_phys
+#define page_to_bus page_to_phys
+#else
#define bus_to_virt(bus) \
phys_to_virt(machine_to_phys_for_dma(bus))
#define virt_to_bus(virt) \
@@ -124,6 +129,7 @@ extern int valid_mmap_phys_addr_range (u
(((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \
((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
bvec_to_pseudophys((vec2))))
+#endif /* CONFIG_XEN */
# endif /* KERNEL */
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/machvec.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/machvec.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec.h Wed Aug 30 22:36:18
2006 +0100
@@ -247,6 +247,7 @@ extern void machvec_init (const char *na
# error Unknown configuration. Update asm-ia64/machvec.h.
# endif /* CONFIG_IA64_GENERIC */
+#ifdef CONFIG_XEN
# define platform_dma_map_sg dma_map_sg
# define platform_dma_unmap_sg dma_unmap_sg
# define platform_dma_mapping_error dma_mapping_error
@@ -259,6 +260,7 @@ extern void machvec_init (const char *na
dma_sync_single_for_cpu
# define platform_dma_sync_single_for_device \
dma_sync_single_for_device
+#endif
/*
* Declare default routines which aren't declared anywhere else:
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/page.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/page.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h Wed Aug 30 22:36:18
2006 +0100
@@ -117,6 +117,9 @@ extern unsigned long max_low_pfn;
# define pfn_to_page(pfn) (vmem_map + (pfn))
#endif
+#ifndef CONFIG_XEN
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#endif
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
@@ -221,12 +224,9 @@ get_order (unsigned long size)
#ifndef __ASSEMBLY__
#ifdef CONFIG_XEN
-#define INVALID_P2M_ENTRY (~0UL)
-
#include <linux/kernel.h>
#include <asm/hypervisor.h>
#include <xen/features.h> // to compile netback, netfront
-typedef unsigned long maddr_t; // to compile netback, netfront
/*
* XXX hack!
@@ -265,68 +265,7 @@ extern struct address_space xen_ia64_for
})
#define HAVE_ARCH_FREE_PAGE
-/* XXX xen page size != page size */
-
-static inline unsigned long
-pfn_to_mfn_for_dma(unsigned long pfn)
-{
- unsigned long mfn;
- mfn = HYPERVISOR_phystomach(pfn);
- BUG_ON(mfn == 0); // XXX
- BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
- BUG_ON(mfn == INVALID_MFN);
- return mfn;
-}
-
-static inline unsigned long
-phys_to_machine_for_dma(unsigned long phys)
-{
- unsigned long machine =
- pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
- machine |= (phys & ~PAGE_MASK);
- return machine;
-}
-
-static inline unsigned long
-mfn_to_pfn_for_dma(unsigned long mfn)
-{
- unsigned long pfn;
- pfn = HYPERVISOR_machtophys(mfn);
- BUG_ON(pfn == 0);
- //BUG_ON(pfn == INVALID_M2P_ENTRY);
- return pfn;
-}
-
-static inline unsigned long
-machine_to_phys_for_dma(unsigned long machine)
-{
- unsigned long phys =
- mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
- phys |= (machine & ~PAGE_MASK);
- return phys;
-}
-
-#define set_phys_to_machine(pfn, mfn) do { } while (0)
-#define xen_machphys_update(mfn, pfn) do { } while (0)
-
-/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
-#define FOREIGN_FRAME(m) (INVALID_P2M_ENTRY)
-
-#define mfn_to_pfn(mfn) (mfn)
-#define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
-#define pfn_to_mfn(pfn) (pfn)
-#define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
-#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
-
-static inline unsigned long
-mfn_to_local_pfn(unsigned long mfn)
-{
- extern unsigned long max_mapnr;
- unsigned long pfn = mfn_to_pfn_for_dma(mfn);
- if (!pfn_valid(pfn))
- return INVALID_P2M_ENTRY;
- return pfn;
-}
+#include <asm/maddr.h>
#endif /* CONFIG_XEN */
#endif /* __ASSEMBLY__ */
diff -r e01441c9a607 -r 50aea0ec406b
linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h Wed Aug 30 14:09:31
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h Wed Aug 30 22:36:18
2006 +0100
@@ -126,7 +126,11 @@ static inline void
static inline void
pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
{
+#ifndef CONFIG_XEN
+ pmd_val(*pmd_entry) = page_to_phys(pte);
+#else
pmd_val(*pmd_entry) = page_to_pseudophys(pte);
+#endif
}
static inline void
diff -r e01441c9a607 -r 50aea0ec406b tools/debugger/gdb/gdbbuild
--- a/tools/debugger/gdb/gdbbuild Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/debugger/gdb/gdbbuild Wed Aug 30 22:36:18 2006 +0100
@@ -18,7 +18,7 @@ if [ "$MAKE" ]; then
if [ "$MAKE" ]; then
$MAKE
elif which gmake ; then
- gmake -j4
+ gmake -j4 CFLAGS=-D__XEN_TOOLS__
else
- make -j4
+ make -j4 CFLAGS=-D__XEN_TOOLS__
fi
diff -r e01441c9a607 -r 50aea0ec406b tools/examples/xmexample.vti
--- a/tools/examples/xmexample.vti Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/examples/xmexample.vti Wed Aug 30 22:36:18 2006 +0100
@@ -37,11 +37,9 @@ name = "ExampleVTIDomain"
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
-#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
# type=ioemu specify the NIC is an ioemu device not netfront
vif = [ 'type=ioemu, bridge=xenbr0' ]
-# for multiple NICs in device model, 3 in this example
-#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
@@ -51,7 +49,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ]
# and MODE is r for read-only, w for read-write.
#disk = [ 'phy:hda1,hda1,r' ]
-disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ]
+disk = [ 'file:/var/images/xenia64.img,hda,w', ',hdc:cdrom,r' ]
#----------------------------------------------------------------------------
# Set according to whether you want the domain restarted when it exits.
@@ -65,13 +63,6 @@ disk = [ 'file:/var/images/xenia64.img,i
# New stuff
device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
-
-# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
-
-#-----------------------------------------------------------------------------
-# Disk image for
-#cdrom=
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c) or CD-ROM (d)
@@ -91,8 +82,17 @@ vnc=0
vnc=0
#----------------------------------------------------------------------------
-# enable spawning vncviewer(only valid when vnc=1), default = 1
-vncviewer=0
+# set VNC display number, default = domid
+#vncdisplay=1
+
+#----------------------------------------------------------------------------
+# try to find an unused port for the VNC server, default = 1
+#vncunused=1
+
+#----------------------------------------------------------------------------
+# enable spawning vncviewer for domain's console
+# (only valid when vnc=1), default = 0
+#vncconsole=0
#----------------------------------------------------------------------------
# no graphics, use serial port
@@ -108,14 +108,12 @@ serial='pty'
serial='pty'
#-----------------------------------------------------------------------------
-# enable audio support
-#enable-audio=1
-
+# enable sound card support, [sb16|es1370|all|..,..], default none
+#soundhw='sb16'
#-----------------------------------------------------------------------------
# set the real time clock to local time [default=0 i.e. set to utc]
#localtime=1
-
#-----------------------------------------------------------------------------
# start in full screen
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Wed Aug 30 22:36:18 2006 +0100
@@ -553,7 +553,6 @@ setup_guest(int xc_handle, uint32_t dom,
{
unsigned long page_array[2];
shared_iopage_t *sp;
- int i;
unsigned long dom_memsize = (memsize << 20);
DECLARE_DOMCTL;
@@ -604,18 +603,6 @@ setup_guest(int xc_handle, uint32_t dom,
goto error_out;
memset(sp, 0, PAGE_SIZE);
-
- for (i = 0; i < vcpus; i++) {
- uint32_t vp_eport;
-
- vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
- if (vp_eport < 0) {
- DPRINTF("Couldn't get unbound port from VMX guest.\n");
- goto error_out;
- }
- sp->vcpu_iodata[i].vp_eport = vp_eport;
- }
-
munmap(sp, PAGE_SIZE);
return 0;
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_linux_save.c
--- a/tools/libxc/ia64/xc_ia64_linux_save.c Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c Wed Aug 30 22:36:18 2006 +0100
@@ -79,7 +79,7 @@ static int xc_ia64_shadow_control(int xc
}
return xc_shadow_control(xc_handle, domid, sop,
- dirty_bitmap, pages, stats);
+ dirty_bitmap, pages, NULL, 0, stats);
}
static inline ssize_t
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_stubs.c
--- a/tools/libxc/ia64/xc_ia64_stubs.c Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_stubs.c Wed Aug 30 22:36:18 2006 +0100
@@ -36,7 +36,6 @@ xc_ia64_get_pfn_list(int xc_handle, uint
struct xen_domctl domctl;
int num_pfns,ret;
unsigned int __start_page, __nr_pages;
- unsigned long max_pfns;
xen_pfn_t *__pfn_buf;
__start_page = start_page;
@@ -44,27 +43,22 @@ xc_ia64_get_pfn_list(int xc_handle, uint
__pfn_buf = pfn_buf;
while (__nr_pages) {
- max_pfns = ((unsigned long)__start_page << 32) | __nr_pages;
domctl.cmd = XEN_DOMCTL_getmemlist;
- domctl.domain = (domid_t)domid;
- domctl.u.getmemlist.max_pfns = max_pfns;
+ domctl.domain = (domid_t)domid;
+ domctl.u.getmemlist.max_pfns = __nr_pages;
+ domctl.u.getmemlist.start_pfn =__start_page;
domctl.u.getmemlist.num_pfns = 0;
set_xen_guest_handle(domctl.u.getmemlist.buffer, __pfn_buf);
- if ((max_pfns != -1UL)
- && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
+ if (mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
PERROR("Could not lock pfn list buffer");
return -1;
}
ret = do_domctl(xc_handle, &domctl);
- if (max_pfns != -1UL)
- (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
+ (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
- if (max_pfns == -1UL)
- return 0;
-
num_pfns = domctl.u.getmemlist.num_pfns;
__start_page += num_pfns;
__nr_pages -= num_pfns;
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/asm-offsets.c Wed Aug 30 22:36:18 2006 +0100
@@ -31,7 +31,6 @@ void foo(void)
DEFINE(IA64_SWITCH_STACK_SIZE, sizeof (struct switch_stack));
DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
- DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info));
DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t));
BLANK();
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/efi.c
--- a/xen/arch/ia64/linux-xen/efi.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/efi.c Wed Aug 30 22:36:18 2006 +0100
@@ -291,28 +291,6 @@ efi_memmap_walk_uc (efi_freemem_callback
{
walk(callback, arg, EFI_MEMORY_UC);
}
-
-#ifdef XEN
-void
-efi_memmap_walk_type(u32 type, efi_walk_type_callback_t callback, void *arg)
-{
- void *efi_map_start, *efi_map_end, *p;
- efi_memory_desc_t *md;
- u64 efi_desc_size;
-
- efi_map_start = __va(ia64_boot_param->efi_memmap);
- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
- efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
- for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
- md = p;
- if (md->type == type) {
- if ((*callback)(md, arg) < 0)
- return;
- }
- }
-}
-#endif
/*
* Look for the PAL_CODE region reported by EFI and maps it using an
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/iosapic.c
--- a/xen/arch/ia64/linux-xen/iosapic.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/iosapic.c Wed Aug 30 22:36:18 2006 +0100
@@ -77,6 +77,8 @@
#include <linux/list.h>
#ifndef XEN
#include <linux/pci.h>
+#else
+#include <xen/errno.h>
#endif
#include <linux/smp.h>
#include <linux/smp_lock.h>
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c Wed Aug 30 22:36:18 2006 +0100
@@ -40,6 +40,10 @@
#include <asm/pgtable.h>
#include <asm/system.h>
+#ifdef XEN
+#include <xen/perfc.h>
+#endif
+
#ifdef CONFIG_PERFMON
# include <asm/perfmon.h>
#endif
@@ -108,6 +112,9 @@ ia64_handle_irq (ia64_vector vector, str
{
unsigned long saved_tpr;
+#ifdef XEN
+ perfc_incrc(irqs);
+#endif
#if IRQ_DEBUG
#ifdef XEN
xen_debug_irq(vector, regs);
@@ -290,8 +297,5 @@ ia64_send_ipi (int cpu, int vector, int
ipi_data = (delivery_mode << 8) | (vector & 0xff);
ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
-#ifdef XEN
- //printf ("send_ipi to %d (%x)\n", cpu, phys_cpu_id);
-#endif
writeq(ipi_data, ipi_addr);
}
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/mca.c Wed Aug 30 22:36:18 2006 +0100
@@ -79,6 +79,7 @@
#ifdef XEN
#include <xen/symbols.h>
+#include <xen/mm.h>
#endif
#if defined(IA64_MCA_DEBUG_INFO)
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/process-linux-xen.c
--- a/xen/arch/ia64/linux-xen/process-linux-xen.c Wed Aug 30 14:09:31
2006 -0500
+++ b/xen/arch/ia64/linux-xen/process-linux-xen.c Wed Aug 30 22:36:18
2006 +0100
@@ -10,6 +10,7 @@
#include <xen/lib.h>
#include <xen/symbols.h>
#include <xen/smp.h>
+#include <xen/sched.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
@@ -166,6 +167,7 @@ show_regs (struct pt_regs *regs)
printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26,
regs->r27, regs->r28);
printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29,
regs->r30, regs->r31);
+#ifndef XEN
if (user_mode(regs)) {
/* print the stacked registers */
unsigned long val, *bsp, ndirty;
@@ -180,6 +182,7 @@ show_regs (struct pt_regs *regs)
((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
}
} else
+#endif
show_stack(NULL, NULL);
}
@@ -807,6 +810,7 @@ get_wchan (struct task_struct *p)
} while (count++ < 16);
return 0;
}
+#endif // !XEN
void
cpu_halt (void)
@@ -831,6 +835,7 @@ cpu_halt (void)
ia64_pal_halt(min_power_state);
}
+#ifndef XEN
void
machine_restart (char *restart_cmd)
{
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/smp.c Wed Aug 30 22:36:18 2006 +0100
@@ -48,6 +48,7 @@
#include <asm/unistd.h>
#include <asm/mca.h>
#ifdef XEN
+#include <xen/errno.h>
#include <asm/vhpt.h>
#include <asm/hw_irq.h>
#endif
@@ -146,6 +147,9 @@ handle_IPI (int irq, void *dev_id, struc
unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
unsigned long ops;
+#ifdef XEN
+ perfc_incrc(ipis);
+#endif
mb(); /* Order interrupt and bit testing. */
while ((ops = xchg(pending_ipis, 0)) != 0) {
mb(); /* Order bit clearing and data access. */
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/unwind.c
--- a/xen/arch/ia64/linux-xen/unwind.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/unwind.c Wed Aug 30 22:36:18 2006 +0100
@@ -33,6 +33,7 @@
#include <xen/sched.h>
#include <xen/xmalloc.h>
#include <xen/spinlock.h>
+#include <xen/errno.h>
// work around
#ifdef CONFIG_SMP
@@ -2315,6 +2316,7 @@ unw_init (void)
__start_unwind, __end_unwind);
}
+#ifndef XEN
/*
* DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
*
@@ -2353,3 +2355,4 @@ sys_getunwind (void __user *buf, size_t
return -EFAULT;
return unw.gate_table_size;
}
+#endif
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/Makefile Wed Aug 30 22:36:18 2006 +0100
@@ -1,5 +1,5 @@ obj-y += hvm_vioapic.o
obj-y += hvm_vioapic.o
-obj-y += mm.o
+#obj-y += mm.o
obj-y += mmio.o
obj-y += pal_emul.o
obj-y += vlsapic.o
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/mmio.c Wed Aug 30 22:36:18 2006 +0100
@@ -22,6 +22,7 @@
*/
#include <linux/sched.h>
+#include <xen/mm.h>
#include <asm/tlb.h>
#include <asm/vmx_mm_def.h>
#include <asm/gcc_intrin.h>
@@ -30,7 +31,6 @@
#include <asm/bundle.h>
#include <asm/types.h>
#include <public/hvm/ioreq.h>
-#include <asm/mm.h>
#include <asm/vmx.h>
#include <public/event_channel.h>
#include <public/xen.h>
@@ -155,10 +155,9 @@ static void low_mmio_access(VCPU *vcpu,
p->type = 1;
p->df = 0;
- set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
- p->state = STATE_IOREQ_READY;
- evtchn_send(iopacket_port(v));
- vmx_wait_io();
+ p->io_count++;
+
+ vmx_send_assist_req(v);
if(dir==IOREQ_READ){ //read
*val=p->u.data;
}
@@ -187,11 +186,9 @@ static void legacy_io_access(VCPU *vcpu,
p->type = 0;
p->df = 0;
- set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
- p->state = STATE_IOREQ_READY;
- evtchn_send(iopacket_port(v));
-
- vmx_wait_io();
+ p->io_count++;
+
+ vmx_send_assist_req(v);
if(dir==IOREQ_READ){ //read
*val=p->u.data;
}
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmmu.c Wed Aug 30 22:36:18 2006 +0100
@@ -33,6 +33,7 @@
#include <asm/kregs.h>
#include <asm/vcpu.h>
#include <xen/irq.h>
+#include <xen/errno.h>
/*
* Get the machine page frame number in 16KB unit
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Wed Aug 30 22:36:18 2006 +0100
@@ -59,21 +59,23 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
}
else if (IS_PRIV(current->domain)) {
d = find_domain_by_id(a.domid);
- if (!d)
+ if (d == NULL)
return -ESRCH;
}
else
return -EPERM;
if (op == HVMOP_set_param) {
+ d->arch.hvm_domain.params[a.index] = a.value;
rc = 0;
- d->arch.hvm_domain.params[a.index] = a.value;
}
- else
- rc = d->arch.hvm_domain.params[a.index];
+ else {
+ a.value = d->arch.hvm_domain.params[a.index];
+ rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
+ }
put_domain(d);
- return rc;
+ break;
}
default:
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_init.c Wed Aug 30 22:36:18 2006 +0100
@@ -206,7 +206,7 @@ vmx_create_vp(struct vcpu *v)
u64 ret;
vpd_t *vpd = (vpd_t *)v->arch.privregs;
u64 ivt_base;
- extern char vmx_ia64_ivt;
+ extern char vmx_ia64_ivt;
/* ia64_ivt is function pointer, so need this tranlation */
ivt_base = (u64) &vmx_ia64_ivt;
printk("ivt_base: 0x%lx\n", ivt_base);
@@ -265,6 +265,29 @@ vmx_load_state(struct vcpu *v)
* anchored in vcpu */
}
+static void vmx_create_event_channels(struct vcpu *v)
+{
+ vcpu_iodata_t *p;
+ struct vcpu *o;
+
+ if (v->vcpu_id == 0) {
+ /* Ugly: create event channels for every vcpu when vcpu 0
+ starts, so that they're available for ioemu to bind to. */
+ for_each_vcpu(v->domain, o) {
+ p = get_vio(v->domain, o->vcpu_id);
+ o->arch.arch_vmx.xen_port = p->vp_eport =
+ alloc_unbound_xen_event_channel(o, 0);
+ DPRINTK("Allocated port %d for hvm.\n",
+ o->arch.arch_vmx.xen_port);
+ }
+ }
+}
+
+static void vmx_release_assist_channel(struct vcpu *v)
+{
+ free_xen_event_channel(v, v->arch.arch_vmx.xen_port);
+}
+
/*
* Initialize VMX envirenment for guest. Only the 1st vp/vcpu
* is registered here.
@@ -286,6 +309,8 @@ vmx_final_setup_guest(struct vcpu *v)
#ifndef HASH_VHPT
init_domain_tlb(v);
#endif
+ vmx_create_event_channels(v);
+
/* v->arch.schedule_tail = arch_vmx_do_launch; */
vmx_create_vp(v);
@@ -301,6 +326,15 @@ vmx_final_setup_guest(struct vcpu *v)
set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags);
/* Set up guest 's indicator for VTi domain*/
set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
+}
+
+void
+vmx_relinquish_guest_resources(struct domain *d)
+{
+ struct vcpu *v;
+
+ for_each_vcpu(d, v)
+ vmx_release_assist_channel(v);
}
void
@@ -411,6 +445,9 @@ void vmx_setup_platform(struct domain *d
memset(&d->shared_info->evtchn_mask[0], 0xff,
sizeof(d->shared_info->evtchn_mask));
+ /* initiate spinlock for pass virq */
+ spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
+
/* Initialize the virtual interrupt lines */
vmx_virq_line_init(d);
@@ -420,13 +457,5 @@ void vmx_setup_platform(struct domain *d
void vmx_do_launch(struct vcpu *v)
{
- if (evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0) {
- printk("VMX domain bind port %d to vcpu %d failed!\n",
- iopacket_port(v), v->vcpu_id);
- domain_crash_synchronous();
- }
-
- clear_bit(iopacket_port(v), &v->domain->shared_info->evtchn_mask[0]);
-
vmx_load_all_rr(v);
}
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Wed Aug 30 22:36:18 2006 +0100
@@ -195,7 +195,8 @@ vmx_load_all_rr(VCPU *vcpu)
(void *)vcpu->domain->shared_info,
(void *)vcpu->arch.privregs,
(void *)vcpu->arch.vhpt.hash, pal_vaddr );
- ia64_set_pta(vcpu->arch.arch_vmx.mpta);
+ ia64_set_pta(VMX(vcpu, mpta));
+ ia64_set_dcr(VMX(vcpu, mdcr));
ia64_srlz_d();
ia64_set_psr(psr);
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_process.c Wed Aug 30 22:36:18 2006 +0100
@@ -186,6 +186,7 @@ void leave_hypervisor_tail(struct pt_reg
{
struct domain *d = current->domain;
struct vcpu *v = current;
+ int callback_irq;
// FIXME: Will this work properly if doing an RFI???
if (!is_idle_domain(d) ) { // always comes from guest
// struct pt_regs *user_regs = vcpu_regs(current);
@@ -212,6 +213,13 @@ void leave_hypervisor_tail(struct pt_reg
// VCPU(v, irr[0]) |= 1UL << 0x10;
// v->arch.irq_new_pending = 1;
// }
+
+ callback_irq = d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+ if (callback_irq != 0 && local_events_need_delivery()) {
+ /*inject para-device call back irq*/
+ v->vcpu_info->evtchn_upcall_mask = 1;
+ vmx_vcpu_pend_interrupt(v, callback_irq);
+ }
if ( v->arch.irq_new_pending ) {
v->arch.irq_new_pending = 0;
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_support.c Wed Aug 30 22:36:18 2006 +0100
@@ -1,4 +1,3 @@
-
/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
/*
* vmx_support.c: vmx specific support interface.
@@ -22,45 +21,11 @@
#include <xen/config.h>
#include <xen/sched.h>
#include <xen/hypercall.h>
+#include <xen/event.h>
#include <public/sched.h>
#include <public/hvm/ioreq.h>
#include <asm/vmx.h>
#include <asm/vmx_vcpu.h>
-
-/*
- * I/O emulation should be atomic from domain point of view. However,
- * when emulation code is waiting for I/O completion by blocking,
- * other events like DM interrupt, VBD, etc. may come and unblock
- * current exection flow. So we have to prepare for re-block if unblocked
- * by non I/O completion event. After io emulation is done, re-enable
- * pending indicaion if other ports are pending
- */
-void vmx_wait_io(void)
-{
- struct vcpu *v = current;
- struct domain *d = v->domain;
- int port = iopacket_port(v);
-
- for (;;) {
- if (test_and_clear_bit(0, &v->vcpu_info->evtchn_upcall_pending) &&
- test_and_clear_bit(port / BITS_PER_LONG,
- &v->vcpu_info->evtchn_pending_sel) &&
- test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]))
- vmx_io_assist(v);
-
- if (!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
- break;
-
- do_sched_op_compat(SCHEDOP_block, 0);
- }
-
- /* re-enable indication if other pending events */
- if (d->shared_info->evtchn_pending[port / BITS_PER_LONG])
- set_bit(port / BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-
- if (v->vcpu_info->evtchn_pending_sel)
- set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
-}
/*
* Only place to call vmx_io_assist is mmio/legacy_io emulation.
@@ -83,17 +48,15 @@ void vmx_io_assist(struct vcpu *v)
p = &vio->vp_ioreq;
- if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
- if (p->state != STATE_IORESP_READY) {
- /* Can't block here, for the same reason as other places to
- * use vmx_wait_io. Simple return is safe since vmx_wait_io will
- * try to block again
- */
- return;
- } else
- p->state = STATE_INVALID;
-
- clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
+ if (p->state == STATE_IORESP_READY) {
+ p->state = STATE_INVALID;
+ }
+ else {
+ /* Can't block here, for the same reason as other places to
+ * use vmx_wait_io. Simple return is safe since vmx_wait_io will
+ * try to block again
+ */
+ return;
}
}
@@ -108,35 +71,62 @@ void vmx_io_assist(struct vcpu *v)
*/
void vmx_intr_assist(struct vcpu *v)
{
- vcpu_iodata_t *vio;
- struct domain *d = v->domain;
- extern void vmx_vcpu_pend_batch_interrupt(VCPU *vcpu,
- unsigned long *pend_irr);
- int port = iopacket_port(v);
-
- if (test_bit(port, &d->shared_info->evtchn_pending[0]) ||
- test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
- vmx_wait_io();
-
- /* I/O emulation is atomic, so it's impossible to see execution flow
- * out of vmx_wait_io, when guest is still waiting for response.
- */
- if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
- panic_domain(vcpu_regs(v),"!!!Bad resume to guest before I/O emulation
is done.\n");
-
- /* Even without event pending, we still need to sync pending bits
- * between DM and vlsapic. The reason is that interrupt delivery
- * shares same event channel as I/O emulation, with corresponding
- * indicator possibly cleared when vmx_wait_io().
- */
- vio = get_vio(v->domain, v->vcpu_id);
- if (!vio)
- panic_domain(vcpu_regs(v),"Corruption: bad shared page: %lx\n",
(unsigned long)vio);
-
#ifdef V_IOSAPIC_READY
/* Confirm virtual interrupt line signals, and set pending bits in vpd */
- if(v->vcpu_id==0)
+ if (spin_trylock(&v->domain->arch.arch_vmx.virq_assist_lock)) {
vmx_virq_line_assist(v);
+ spin_unlock(&v->domain->arch.arch_vmx.virq_assist_lock);
+ }
#endif
return;
}
+
+void vmx_send_assist_req(struct vcpu *v)
+{
+ ioreq_t *p;
+
+ p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+ if (unlikely(p->state != STATE_INVALID)) {
+ /* This indicates a bug in the device model. Crash the
+ domain. */
+ printk("Device model set bad IO state %d.\n", p->state);
+ domain_crash(v->domain);
+ return;
+ }
+ wmb();
+ p->state = STATE_IOREQ_READY;
+ notify_via_xen_event_channel(v->arch.arch_vmx.xen_port);
+
+ /*
+ * Waiting for MMIO completion
+ * like the wait_on_xen_event_channel() macro like...
+ * but, we can't call do_softirq() at this point..
+ */
+ for (;;) {
+ if (p->state != STATE_IOREQ_READY &&
+ p->state != STATE_IOREQ_INPROCESS)
+ break;
+
+ set_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
+ mb(); /* set blocked status /then/ re-evaluate condition */
+ if (p->state != STATE_IOREQ_READY &&
+ p->state != STATE_IOREQ_INPROCESS)
+ {
+ clear_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
+ break;
+ }
+
+ /* I want to call __enter_scheduler() only */
+ do_sched_op_compat(SCHEDOP_yield, 0);
+ mb();
+ }
+
+ /* the code under this line is completer phase... */
+ vmx_io_assist(v);
+}
+
+/* Wake up a vcpu whihc is waiting for interrupts to come in */
+void vmx_prod_vcpu(struct vcpu *v)
+{
+ vcpu_unblock(v);
+}
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vtlb.c Wed Aug 30 22:36:18 2006 +0100
@@ -23,7 +23,7 @@
#include <linux/sched.h>
#include <asm/tlb.h>
-#include <asm/mm.h>
+#include <xen/mm.h>
#include <asm/vmx_mm_def.h>
#include <asm/gcc_intrin.h>
#include <linux/interrupt.h>
@@ -148,13 +148,17 @@ static void vmx_vhpt_insert(thash_cb_t *
rr.rrval = ia64_get_rr(ifa);
head = (thash_data_t *)ia64_thash(ifa);
tag = ia64_ttag(ifa);
- if( INVALID_VHPT(head) ) {
- len = head->len;
- head->page_flags = pte;
- head->len = len;
- head->itir = rr.ps << 2;
- head->etag = tag;
- return;
+ cch = head;
+ while (cch) {
+ if (INVALID_VHPT(cch)) {
+ len = cch->len;
+ cch->page_flags = pte;
+ cch->len = len;
+ cch->itir = rr.ps << 2;
+ cch->etag = tag;
+ return;
+ }
+ cch = cch->next;
}
if(head->len>=MAX_CCN_DEPTH){
@@ -214,12 +218,22 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
{
u64 ret;
thash_data_t * data;
+ PTA vpta;
+
data = vhpt_lookup(iha);
if (data == NULL) {
data = vtlb_lookup(current, iha, DSIDE_TLB);
if (data != NULL)
thash_vhpt_insert(current, data->page_flags, data->itir ,iha);
}
+
+ /* VHPT long format is not read. */
+ vmx_vcpu_get_pta(current, &vpta.val);
+ if (vpta.vf == 1) {
+ *pte = 0;
+ return 0;
+ }
+
asm volatile ("rsm psr.ic|psr.i;;"
"srlz.d;;"
"ld8.s r9=[%1];;"
@@ -231,11 +245,10 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
"ssm psr.ic;;"
"srlz.d;;"
"ssm psr.i;;"
- : "=r"(ret) : "r"(iha), "r"(pte):"memory");
+ : "=r"(ret) : "r"(iha), "r"(pte):"memory");
return ret;
}
-
/*
* purge software guest tlb
*/
@@ -243,28 +256,29 @@ void vtlb_purge(VCPU *v, u64 va, u64 ps)
void vtlb_purge(VCPU *v, u64 va, u64 ps)
{
thash_data_t *cur;
- u64 start, end, curadr, size, psbits, tag, def_size;
+ u64 start, curadr, size, psbits, tag, rr_ps, num;
ia64_rr vrr;
thash_cb_t *hcb = &v->arch.vtlb;
+
vcpu_get_rr(v, va, &vrr.rrval);
psbits = VMX(v, psbits[(va >> 61)]);
- size = PSIZE(ps);
- start = va & (-size);
- end = start + size;
+ start = va & ~((1UL << ps) - 1);
while (psbits) {
curadr = start;
- ps = __ffs(psbits);
- psbits &= ~(1UL << ps);
- def_size = PSIZE(ps);
- vrr.ps = ps;
- while (curadr < end) {
+ rr_ps = __ffs(psbits);
+ psbits &= ~(1UL << rr_ps);
+ num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps));
+ size = PSIZE(rr_ps);
+ vrr.ps = rr_ps;
+ while (num) {
cur = vsa_thash(hcb->pta, curadr, vrr.rrval, &tag);
while (cur) {
- if (cur->etag == tag && cur->ps == ps)
+ if (cur->etag == tag && cur->ps == rr_ps)
cur->etag = 1UL << 63;
cur = cur->next;
}
- curadr += def_size;
+ curadr += size;
+ num--;
}
}
}
@@ -277,14 +291,14 @@ static void vhpt_purge(VCPU *v, u64 va,
{
//thash_cb_t *hcb = &v->arch.vhpt;
thash_data_t *cur;
- u64 start, end, size, tag;
+ u64 start, size, tag, num;
ia64_rr rr;
- size = PSIZE(ps);
- start = va & (-size);
- end = start + size;
- rr.rrval = ia64_get_rr(va);
- size = PSIZE(rr.ps);
- while(start < end){
+
+ start = va & ~((1UL << ps) - 1);
+ rr.rrval = ia64_get_rr(va);
+ size = PSIZE(rr.ps);
+ num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps));
+ while (num) {
cur = (thash_data_t *)ia64_thash(start);
tag = ia64_ttag(start);
while (cur) {
@@ -293,6 +307,7 @@ static void vhpt_purge(VCPU *v, u64 va,
cur = cur->next;
}
start += size;
+ num--;
}
machine_tlb_purge(va, ps);
}
@@ -347,24 +362,20 @@ void vtlb_insert(VCPU *v, u64 pte, u64 i
u64 tag, len;
thash_cb_t *hcb = &v->arch.vtlb;
vcpu_get_rr(v, va, &vrr.rrval);
-#ifdef VTLB_DEBUG
- if (vrr.ps != itir_ps(itir)) {
-// machine_tlb_insert(hcb->vcpu, entry);
- panic_domain(NULL, "not preferred ps with va: 0x%lx vrr.ps=%d
ps=%ld\n",
- va, vrr.ps, itir_ps(itir));
- return;
- }
-#endif
vrr.ps = itir_ps(itir);
VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps);
hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
- if( INVALID_TLB(hash_table) ) {
- len = hash_table->len;
- hash_table->page_flags = pte;
- hash_table->len = len;
- hash_table->itir=itir;
- hash_table->etag=tag;
- return;
+ cch = hash_table;
+ while (cch) {
+ if (INVALID_TLB(cch)) {
+ len = cch->len;
+ cch->page_flags = pte;
+ cch->len = len;
+ cch->itir=itir;
+ cch->etag=tag;
+ return;
+ }
+ cch = cch->next;
}
if (hash_table->len>=MAX_CCN_DEPTH){
thash_recycle_cch(hcb, hash_table);
@@ -458,10 +469,6 @@ void thash_purge_and_insert(VCPU *v, u64
ps = itir_ps(itir);
vcpu_get_rr(current, ifa, &vrr.rrval);
mrr.rrval = ia64_get_rr(ifa);
-// if (vrr.ps != itir_ps(itir)) {
-// printf("not preferred ps with va: 0x%lx vrr.ps=%d ps=%ld\n",
-// ifa, vrr.ps, itir_ps(itir));
-// }
if(VMX_DOMAIN(v)){
/* Ensure WB attribute if pte is related to a normal mem page,
* which is required by vga acceleration since qemu maps shared
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/acpi.c
--- a/xen/arch/ia64/xen/acpi.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/acpi.c Wed Aug 30 22:36:18 2006 +0100
@@ -51,6 +51,9 @@
#include <asm/numa.h>
#include <asm/sal.h>
#include <asm/hw_irq.h>
+#ifdef XEN
+#include <xen/errno.h>
+#endif
#define BAD_MADT_ENTRY(entry, end) ( \
(!entry) || (unsigned long)entry + sizeof(*entry) > end || \
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/dom0_ops.c Wed Aug 30 22:36:18 2006 +0100
@@ -21,6 +21,7 @@
#include <asm/vmx.h>
#include <asm/dom_fw.h>
#include <xen/iocap.h>
+#include <xen/errno.h>
void build_physmap_table(struct domain *d);
@@ -39,8 +40,8 @@ long arch_do_domctl(xen_domctl_t *op, XE
{
unsigned long i;
struct domain *d = find_domain_by_id(op->domain);
- unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
- unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
+ unsigned long start_page = op->u.getmemlist.start_pfn;
+ unsigned long nr_pages = op->u.getmemlist.max_pfns;
unsigned long mfn;
if ( d == NULL ) {
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/dom_fw.c Wed Aug 30 22:36:18 2006 +0100
@@ -21,28 +21,23 @@
#include <asm/fpswa.h>
#include <xen/version.h>
#include <xen/acpi.h>
+#include <xen/errno.h>
#include <asm/dom_fw.h>
#include <asm/bundle.h>
-static void dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char
*fw_mem, int fw_mem_size, unsigned long maxmem);
-
-extern struct domain *dom0;
+#define ONE_MB (1UL << 20)
extern unsigned long running_on_sim;
-/* Note: two domains cannot be created simulteanously! */
-static unsigned long dom_fw_base_mpa = -1;
-static unsigned long imva_fw_base = -1;
-
#define FW_VENDOR
"X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-#define MAKE_MD(typ, attr, start, end, abs) \
+#define MAKE_MD(typ, attr, start, end)
\
do { \
- md = efi_memmap + i++; \
+ md = tables->efi_memmap + i++; \
md->type = typ; \
md->pad = 0; \
- md->phys_addr = abs ? start : start_mpaddr + start; \
+ md->phys_addr = start; \
md->virt_addr = 0; \
md->num_pages = (end - start) >> EFI_PAGE_SHIFT; \
md->attribute = attr; \
@@ -51,44 +46,31 @@ static unsigned long imva_fw_base = -1;
#define EFI_HYPERCALL_PATCH(tgt, call) \
do { \
dom_efi_hypercall_patch(d, FW_HYPERCALL_##call##_PADDR, \
- FW_HYPERCALL_##call); \
- tgt = dom_pa((unsigned long) pfn); \
- *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr; \
- *pfn++ = 0; \
+ FW_HYPERCALL_##call, hypercalls_imva); \
+ /* Descriptor address. */ \
+ tables->efi_runtime.tgt = \
+ FW_FIELD_MPA(func_ptrs) + 8 * pfn; \
+ /* Descriptor. */ \
+ tables->func_ptrs[pfn++] = FW_HYPERCALL_##call##_PADDR; \
+ tables->func_ptrs[pfn++] = 0; \
} while (0)
-
-// return domain (meta)physical address for a given imva
-// this function is a call-back from dom_fw_init
-static unsigned long
-dom_pa(unsigned long imva)
-{
- if (dom_fw_base_mpa == -1 || imva_fw_base == -1) {
- printf("dom_pa: uninitialized! (spinning...)\n");
- while(1);
- }
- if (imva - imva_fw_base > PAGE_SIZE) {
- printf("dom_pa: bad offset! imva=0x%lx, imva_fw_base=0x%lx
(spinning...)\n",
- imva, imva_fw_base);
- while(1);
- }
- return dom_fw_base_mpa + (imva - imva_fw_base);
-}
// allocate a page for fw
// build_physmap_table() which is called by new_thread()
// does for domU.
-#define ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, mpaddr) \
- do { \
- if ((d) == dom0) { \
- assign_new_domain0_page((d), (mpaddr)); \
- } \
- } while (0)
+static inline void
+assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
+{
+ if (d == dom0)
+ assign_new_domain0_page(d, mpaddr);
+}
/**************************************************************************
Hypercall bundle creation
**************************************************************************/
-static void build_hypercall_bundle(UINT64 *imva, UINT64 brkimm, UINT64 hypnum,
UINT64 ret)
+static void
+build_hypercall_bundle(u64 *imva, u64 brkimm, u64 hypnum, u64 ret)
{
INST64_A5 slot0;
INST64_I19 slot1;
@@ -104,8 +86,8 @@ static void build_hypercall_bundle(UINT6
slot1.inst = 0;
slot1.qp = 0; slot1.x6 = 0; slot1.x3 = 0; slot1.major = 0x0;
slot1.imm20 = brkimm; slot1.i = brkimm >> 20;
- // if ret slot2: br.ret.sptk.many rp
- // else slot2: br.cond.sptk.many rp
+ // if ret slot2: br.ret.sptk.many rp
+ // else slot2: br.cond.sptk.many rp
slot2.inst = 0; slot2.qp = 0; slot2.p = 1; slot2.b2 = 0;
slot2.wh = 0; slot2.d = 0; slot2.major = 0x0;
if (ret) {
@@ -125,7 +107,8 @@ static void build_hypercall_bundle(UINT6
ia64_fc(imva + 1);
}
-static void build_pal_hypercall_bundles(UINT64 *imva, UINT64 brkimm, UINT64
hypnum)
+static void
+build_pal_hypercall_bundles(u64 *imva, u64 brkimm, u64 hypnum)
{
extern unsigned long pal_call_stub[];
IA64_BUNDLE bundle;
@@ -162,76 +145,68 @@ static void build_pal_hypercall_bundles(
}
// builds a hypercall bundle at domain physical address
-static void dom_fpswa_hypercall_patch(struct domain *d)
+static void
+dom_fpswa_hypercall_patch(struct domain *d, unsigned long imva)
{
unsigned long *entry_imva, *patch_imva;
- unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
- unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
-
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
- entry_imva = domain_mpa_to_imva(d, entry_paddr);
- patch_imva = domain_mpa_to_imva(d, patch_paddr);
-
+ const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
+ const unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
+
+ entry_imva = (unsigned long *)(imva + entry_paddr -
+ FW_HYPERCALL_BASE_PADDR);
+ patch_imva = (unsigned long *)(imva + patch_paddr -
+ FW_HYPERCALL_BASE_PADDR);
+
+ /* Descriptor. */
*entry_imva++ = patch_paddr;
*entry_imva = 0;
- build_hypercall_bundle(patch_imva, d->arch.breakimm,
FW_HYPERCALL_FPSWA, 1);
+
+ build_hypercall_bundle(patch_imva, d->arch.breakimm,
+ FW_HYPERCALL_FPSWA, 1);
}
// builds a hypercall bundle at domain physical address
-static void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr,
unsigned long hypercall)
-{
- unsigned long *imva;
-
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
- imva = domain_mpa_to_imva(d, paddr);
- build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
+static void
+dom_efi_hypercall_patch(struct domain *d, unsigned long paddr,
+ unsigned long hypercall, unsigned long imva)
+{
+ build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
+ d->arch.breakimm, hypercall, 1);
}
// builds a hypercall bundle at domain physical address
-static void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr,
unsigned long hypercall,unsigned long ret)
-{
- unsigned long *imva;
-
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
- imva = domain_mpa_to_imva(d, paddr);
- build_hypercall_bundle(imva, d->arch.breakimm, hypercall, ret);
-}
-
-static void dom_fw_pal_hypercall_patch(struct domain *d, unsigned long paddr)
-{
- unsigned long *imva;
-
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
- imva = domain_mpa_to_imva(d, paddr);
- build_pal_hypercall_bundles(imva, d->arch.breakimm,
FW_HYPERCALL_PAL_CALL);
-}
-
-
-void dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem)
-{
- struct ia64_boot_param *bp;
-
- dom_fw_base_mpa = 0;
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, dom_fw_base_mpa);
- imva_fw_base = (unsigned long) domain_mpa_to_imva(d, dom_fw_base_mpa);
- ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, bp_mpa);
- bp = domain_mpa_to_imva(d, bp_mpa);
- dom_fw_init(d, bp, (char *) imva_fw_base, PAGE_SIZE, maxmem);
-}
-
-
-/* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
-
-#define NFUNCPTRS 20
+static void
+dom_fw_hypercall_patch(struct domain *d, unsigned long paddr,
+ unsigned long hypercall,unsigned long ret,
+ unsigned long imva)
+{
+ build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
+ d->arch.breakimm, hypercall, ret);
+}
+
+static void
+dom_fw_pal_hypercall_patch(struct domain *d, unsigned long paddr,
+ unsigned long imva)
+{
+ build_pal_hypercall_bundles((u64*)(imva + paddr -
+ FW_HYPERCALL_BASE_PADDR),
+ d->arch.breakimm, FW_HYPERCALL_PAL_CALL);
+}
static inline void
print_md(efi_memory_desc_t *md)
{
- printk("domain mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx)
(%luMB)\n",
- md->type, md->attribute, md->phys_addr,
- md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
- md->num_pages >> (20 - EFI_PAGE_SHIFT));
+ u64 size;
+
+ printk("dom mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) ",
+ md->type, md->attribute, md->phys_addr,
+ md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
+
+ size = md->num_pages << EFI_PAGE_SHIFT;
+ if (size > ONE_MB)
+ printf ("(%luMB)\n", size >> 20);
+ else
+ printf ("(%luKB)\n", size >> 10);
}
static u32 lsapic_nbr;
@@ -316,6 +291,8 @@ struct fake_acpi_tables {
u8 pm1a_cnt_blk[1];
u8 pm_tmr_blk[4];
};
+#define ACPI_TABLE_MPA(field) \
+ FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);
/* Create enough of an ACPI structure to make the guest OS ACPI happy. */
static void
@@ -345,8 +322,8 @@ dom_fw_fake_acpi(struct domain *d, struc
xsdt->asl_compiler_revision = (xen_major_version() << 16) |
xen_minor_version();
- xsdt->table_offset_entry[0] = dom_pa((unsigned long) fadt);
- tables->madt_ptr = dom_pa((unsigned long) madt);
+ xsdt->table_offset_entry[0] = ACPI_TABLE_MPA(fadt);
+ tables->madt_ptr = ACPI_TABLE_MPA(madt);
xsdt->checksum = generate_acpi_checksum(xsdt, xsdt->length);
@@ -364,8 +341,8 @@ dom_fw_fake_acpi(struct domain *d, struc
facs->version = 1;
facs->length = sizeof(struct facs_descriptor_rev2);
- fadt->xfirmware_ctrl = dom_pa((unsigned long) facs);
- fadt->Xdsdt = dom_pa((unsigned long) dsdt);
+ fadt->xfirmware_ctrl = ACPI_TABLE_MPA(facs);
+ fadt->Xdsdt = ACPI_TABLE_MPA(dsdt);
/*
* All of the below FADT entries are filled it to prevent warnings
@@ -375,15 +352,15 @@ dom_fw_fake_acpi(struct domain *d, struc
fadt->pm1_evt_len = 4;
fadt->xpm1a_evt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
fadt->xpm1a_evt_blk.register_bit_width = 8;
- fadt->xpm1a_evt_blk.address = dom_pa((unsigned long)
&tables->pm1a_evt_blk);
+ fadt->xpm1a_evt_blk.address = ACPI_TABLE_MPA(pm1a_evt_blk);
fadt->pm1_cnt_len = 1;
fadt->xpm1a_cnt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
fadt->xpm1a_cnt_blk.register_bit_width = 8;
- fadt->xpm1a_cnt_blk.address = dom_pa((unsigned long)
&tables->pm1a_cnt_blk);
+ fadt->xpm1a_cnt_blk.address = ACPI_TABLE_MPA(pm1a_cnt_blk);
fadt->pm_tm_len = 4;
fadt->xpm_tmr_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
fadt->xpm_tmr_blk.register_bit_width = 8;
- fadt->xpm_tmr_blk.address = dom_pa((unsigned long) &tables->pm_tmr_blk);
+ fadt->xpm_tmr_blk.address = ACPI_TABLE_MPA(pm_tmr_blk);
fadt->checksum = generate_acpi_checksum(fadt, fadt->length);
@@ -392,7 +369,7 @@ dom_fw_fake_acpi(struct domain *d, struc
strcpy(rsdp->oem_id, "XEN");
rsdp->revision = 2; /* ACPI 2.0 includes XSDT */
rsdp->length = sizeof(struct acpi20_table_rsdp);
- rsdp->xsdt_address = dom_pa((unsigned long) xsdt);
+ rsdp->xsdt_address = ACPI_TABLE_MPA(xsdt);
rsdp->checksum = generate_acpi_checksum(rsdp,
ACPI_RSDP_CHECKSUM_LENGTH);
@@ -467,115 +444,6 @@ dom_fw_fake_acpi(struct domain *d, struc
return;
}
-#define NUM_EFI_SYS_TABLES 6
-#define NUM_MEM_DESCS 64 //large enough
-
-struct dom0_passthrough_arg {
- struct domain* d;
- int flags;
- efi_memory_desc_t *md;
- int* i;
-};
-
-static int
-dom_fw_dom0_passthrough(efi_memory_desc_t *md, void *arg__)
-{
- struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
- unsigned long paddr;
- struct domain* d = arg->d;
- u64 start = md->phys_addr;
- u64 size = md->num_pages << EFI_PAGE_SHIFT;
-
- if (md->type == EFI_MEMORY_MAPPED_IO ||
- md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
-
- //XXX some machine has large mmio area whose size is about several TB.
- // It requires impractical memory to map such a huge region
- // to a domain.
- // For now we don't map it, but later we must fix this.
- if (md->type == EFI_MEMORY_MAPPED_IO && (size > 0x100000000UL))
- return 0;
-
- paddr = assign_domain_mmio_page(d, start, size);
- } else
- paddr = assign_domain_mach_page(d, start, size, arg->flags);
-
- BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
- md->type != EFI_RUNTIME_SERVICES_DATA &&
- md->type != EFI_ACPI_RECLAIM_MEMORY &&
- md->type != EFI_ACPI_MEMORY_NVS &&
- md->type != EFI_RESERVED_TYPE &&
- md->type != EFI_MEMORY_MAPPED_IO &&
- md->type != EFI_MEMORY_MAPPED_IO_PORT_SPACE);
-
- arg->md->type = md->type;
- arg->md->pad = 0;
- arg->md->phys_addr = paddr;
- arg->md->virt_addr = 0;
- arg->md->num_pages = md->num_pages;
- arg->md->attribute = md->attribute;
-
- (*arg->i)++;
- arg->md++;
- return 0;
-}
-
-/*
- * Create dom0 MDT entries for conventional memory below 1MB. Without
- * this Linux will assume VGA is present because 0xA0000 will always
- * be either a hole in the MDT or an I/O region via the passthrough.
- */
-static int
-dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
-{
- struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
- u64 end = min(HYPERCALL_START,
- md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
-
- BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
-
- /* avoid hypercall area */
- if (md->phys_addr >= HYPERCALL_START)
- return 0;
-
- /* avoid firmware base area */
- if (md->phys_addr < dom_pa(imva_fw_base))
- end = min(end, dom_pa(imva_fw_base));
- else if (md->phys_addr < dom_pa(imva_fw_base + PAGE_SIZE)) {
- if (end < dom_pa(imva_fw_base + PAGE_SIZE))
- return 0;
- md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
- }
-
- arg->md->type = md->type;
- arg->md->pad = 0;
- arg->md->phys_addr = md->phys_addr;
- arg->md->virt_addr = 0;
- arg->md->num_pages = (end - md->phys_addr) >> EFI_PAGE_SHIFT;
- arg->md->attribute = md->attribute;
-
- (*arg->i)++;
- arg->md++;
-
- /* if firmware area spliced the md, add the upper part here */
- if (end == dom_pa(imva_fw_base)) {
- end = min(HYPERCALL_START,
- md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
- if (end > dom_pa(imva_fw_base + PAGE_SIZE)) {
- arg->md->type = md->type;
- arg->md->pad = 0;
- arg->md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
- arg->md->virt_addr = 0;
- arg->md->num_pages = (end - arg->md->phys_addr) >> EFI_PAGE_SHIFT;
- arg->md->attribute = md->attribute;
-
- (*arg->i)++;
- arg->md++;
- }
- }
- return 0;
-}
-
static int
efi_mdt_cmp(const void *a, const void *b)
{
@@ -595,279 +463,403 @@ efi_mdt_cmp(const void *a, const void *b
return 0;
}
+#define NFUNCPTRS 16
+#define NUM_EFI_SYS_TABLES 6
+#define NUM_MEM_DESCS 64 //large enough
+
+struct fw_tables {
+ efi_system_table_t efi_systab;
+ efi_runtime_services_t efi_runtime;
+ efi_config_table_t efi_tables[NUM_EFI_SYS_TABLES];
+
+ struct ia64_sal_systab sal_systab;
+ struct ia64_sal_desc_entry_point sal_ed;
+ struct ia64_sal_desc_ap_wakeup sal_wakeup;
+ /* End of SAL descriptors. Do not forget to update checkum bound. */
+
+ fpswa_interface_t fpswa_inf;
+ efi_memory_desc_t efi_memmap[NUM_MEM_DESCS];
+ unsigned long func_ptrs[2*NFUNCPTRS];
+ struct xen_sal_data sal_data;
+ unsigned char fw_vendor[sizeof(FW_VENDOR)];
+};
+#define FW_FIELD_MPA(field) \
+ FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
+
+/* Complete the dom0 memmap. */
+static int
+complete_dom0_memmap(struct domain *d,
+ struct fw_tables *tables,
+ unsigned long maxmem,
+ int num_mds)
+{
+ efi_memory_desc_t *md;
+ u64 addr;
+ int j;
+ void *efi_map_start, *efi_map_end, *p;
+ u64 efi_desc_size;
+ int i;
+
+ /* Walk through all MDT entries.
+ Copy all interesting entries. */
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+ const efi_memory_desc_t *md = p;
+ efi_memory_desc_t *dom_md = &tables->efi_memmap[num_mds];
+ u64 start = md->phys_addr;
+ u64 size = md->num_pages << EFI_PAGE_SHIFT;
+ u64 end = start + size;
+
+ switch (md->type) {
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_ACPI_RECLAIM_MEMORY:
+ case EFI_ACPI_MEMORY_NVS:
+ case EFI_RESERVED_TYPE:
+ /* Map into dom0 - All these are writable. */
+ assign_domain_mach_page(d, start, size,
+ ASSIGN_writable);
+ /* Fall-through. */
+ case EFI_MEMORY_MAPPED_IO:
+ /* Will be mapped with ioremap. */
+ /* Copy descriptor. */
+ *dom_md = *md;
+ dom_md->virt_addr = 0;
+ num_mds++;
+ break;
+
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ /* Map into dom0. */
+ assign_domain_mmio_page(d, start, size);
+ /* Copy descriptor. */
+ *dom_md = *md;
+ dom_md->virt_addr = 0;
+ num_mds++;
+ break;
+
+ case EFI_CONVENTIONAL_MEMORY:
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ /* Create dom0 MDT entries for conventional memory
+ below 1MB. Without this Linux will assume VGA is
+ present because 0xA0000 will always be either a hole
+ in the MDT or an I/O region via the passthrough. */
+
+ end = min(ONE_MB, end);
+
+ /* Avoid firmware and hypercall area.
+ We know they are 0-based. */
+ if (end < FW_END_PADDR || start >= ONE_MB)
+ break;
+ if (start < FW_END_PADDR)
+ start = FW_END_PADDR;
+
+ dom_md->type = EFI_CONVENTIONAL_MEMORY;
+ dom_md->phys_addr = start;
+ dom_md->virt_addr = 0;
+ dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
+ dom_md->attribute = md->attribute;
+ num_mds++;
+ break;
+
+ case EFI_UNUSABLE_MEMORY:
+ case EFI_PAL_CODE:
+ /* Discard. */
+ break;
+
+ default:
+ /* Print a warning but continue. */
+ printf("complete_dom0_memmap: warning: "
+ "unhandled MDT entry type %u\n", md->type);
+ }
+ }
+ BUG_ON(num_mds > NUM_MEM_DESCS);
+
+ sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
+ efi_mdt_cmp, NULL);
+
+ /* find gaps and fill them with conventional memory */
+ i = num_mds;
+ for (j = 0; j < num_mds; j++) {
+ unsigned long end;
+ unsigned long next_start;
+
+ md = &tables->efi_memmap[j];
+ end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+ if (j + 1 < num_mds) {
+ efi_memory_desc_t* next_md;
+ next_md = &tables->efi_memmap[j + 1];
+ next_start = next_md->phys_addr;
+
+ /* Have just been sorted. */
+ BUG_ON(end > next_start);
+
+ /* No room for memory! */
+ if (end == next_start)
+ continue;
+
+ if (next_start > maxmem)
+ next_start = maxmem;
+ }
+ else
+ next_start = maxmem;
+
+ /* Avoid "legacy" low memory addresses
+ and the HYPERCALL area. */
+ if (end < ONE_MB)
+ end = ONE_MB;
+
+ // clip the range and align to PAGE_SIZE
+ next_start = next_start & PAGE_MASK;
+ end = PAGE_ALIGN(end);
+
+ /* No room for memory. */
+ if (end >= next_start)
+ continue;
+
+ MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+ end, next_start);
+
+ if (next_start >= maxmem)
+ break;
+ }
+ num_mds = i;
+ BUG_ON(num_mds > NUM_MEM_DESCS);
+ sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
+ efi_mdt_cmp, NULL);
+
+ // dom0 doesn't need build_physmap_table()
+ // see arch_set_info_guest()
+ // instead we allocate pages manually.
+ for (i = 0; i < num_mds; i++) {
+ md = &tables->efi_memmap[i];
+ if (md->phys_addr > maxmem)
+ break;
+
+ if (md->type == EFI_LOADER_DATA ||
+ md->type == EFI_PAL_CODE ||
+ md->type == EFI_CONVENTIONAL_MEMORY) {
+ unsigned long start = md->phys_addr & PAGE_MASK;
+ unsigned long end = md->phys_addr +
+ (md->num_pages << EFI_PAGE_SHIFT);
+
+ if (end == start) {
+ /* md->num_pages = 0 is allowed. */
+ continue;
+ }
+ if (end > (max_page << PAGE_SHIFT))
+ end = (max_page << PAGE_SHIFT);
+
+ for (addr = start; addr < end; addr += PAGE_SIZE)
+ assign_new_domain0_page(d, addr);
+ }
+ }
+ // Map low-memory holes & unmapped MMIO for legacy drivers
+ for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
+ if (domain_page_mapped(d, addr))
+ continue;
+
+ if (efi_mmio(addr, PAGE_SIZE))
+ assign_domain_mmio_page(d, addr, PAGE_SIZE);
+ }
+ return num_mds;
+}
+
static void
-dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int
fw_mem_size, unsigned long maxmem)
-{
- efi_system_table_t *efi_systab;
- efi_runtime_services_t *efi_runtime;
- efi_config_table_t *efi_tables;
- struct ia64_sal_systab *sal_systab;
- struct ia64_sal_desc_entry_point *sal_ed;
- struct ia64_sal_desc_ap_wakeup *sal_wakeup;
- fpswa_interface_t *fpswa_inf;
- efi_memory_desc_t *efi_memmap, *md;
- struct xen_sal_data *sal_data;
- unsigned long *pfn;
- unsigned char checksum = 0;
- char *cp, *fw_vendor;
- int num_mds, j, i = 0;
- const unsigned long start_mpaddr = 0;
-
-/* FIXME: should check size but for now we have a whole MB to play with.
- And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
- if (fw_mem_size < sizeof(fw_mem_proto)) {
- printf("sys_fw_init: insufficient space for fw_mem\n");
- return 0;
- }
-*/
- memset(fw_mem, 0, fw_mem_size);
-
- cp = fw_mem;
- efi_systab = (void *) cp; cp += sizeof(*efi_systab);
- efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
- efi_tables = (void *) cp; cp += NUM_EFI_SYS_TABLES *
sizeof(*efi_tables);
- sal_systab = (void *) cp; cp += sizeof(*sal_systab);
- sal_ed = (void *) cp; cp += sizeof(*sal_ed);
- sal_wakeup = (void *) cp; cp += sizeof(*sal_wakeup);
- fpswa_inf = (void *) cp; cp += sizeof(*fpswa_inf);
- efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
- pfn = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
- sal_data = (void *) cp; cp += sizeof(*sal_data);
+dom_fw_init(struct domain *d,
+ struct ia64_boot_param *bp,
+ struct fw_tables *tables,
+ unsigned long hypercalls_imva,
+ unsigned long maxmem)
+{
+ efi_memory_desc_t *md;
+ unsigned long pfn;
+ unsigned char checksum;
+ char *cp;
+ int num_mds, i;
+
+ memset(tables, 0, sizeof(struct fw_tables));
/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
- d->arch.efi_runtime = efi_runtime;
- d->arch.fpswa_inf = fpswa_inf;
- d->arch.sal_data = sal_data;
-
- memset(efi_systab, 0, sizeof(efi_systab));
- efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
- efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
- efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
- fw_vendor = cp;
- cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to
64-bit boundary
-
- memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
- efi_systab->fw_vendor = dom_pa((unsigned long) fw_vendor);
- efi_systab->fw_revision = 1;
- efi_systab->runtime = (void *) dom_pa((unsigned long) efi_runtime);
- efi_systab->nr_tables = NUM_EFI_SYS_TABLES;
- efi_systab->tables = dom_pa((unsigned long) efi_tables);
-
- efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
- efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
- efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-
- EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
- EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
- EFI_HYPERCALL_PATCH(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
- EFI_HYPERCALL_PATCH(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
-
EFI_HYPERCALL_PATCH(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
- EFI_HYPERCALL_PATCH(efi_runtime->get_variable,EFI_GET_VARIABLE);
-
EFI_HYPERCALL_PATCH(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
- EFI_HYPERCALL_PATCH(efi_runtime->set_variable,EFI_SET_VARIABLE);
-
EFI_HYPERCALL_PATCH(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
- EFI_HYPERCALL_PATCH(efi_runtime->reset_system,EFI_RESET_SYSTEM);
-
- efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
- efi_tables[0].table = dom_pa((unsigned long) sal_systab);
+ d->arch.efi_runtime = &tables->efi_runtime;
+ d->arch.fpswa_inf = &tables->fpswa_inf;
+ d->arch.sal_data = &tables->sal_data;
+
+ /* EFI systab. */
+ tables->efi_systab.hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ tables->efi_systab.hdr.revision = EFI_SYSTEM_TABLE_REVISION;
+ tables->efi_systab.hdr.headersize = sizeof(tables->efi_systab.hdr);
+
+ memcpy(tables->fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
+ tables->efi_systab.fw_vendor = FW_FIELD_MPA(fw_vendor);
+ tables->efi_systab.fw_revision = 1;
+ tables->efi_systab.runtime = (void *)FW_FIELD_MPA(efi_runtime);
+ tables->efi_systab.nr_tables = NUM_EFI_SYS_TABLES;
+ tables->efi_systab.tables = FW_FIELD_MPA(efi_tables);
+
+ /* EFI runtime. */
+ tables->efi_runtime.hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
+ tables->efi_runtime.hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
+ tables->efi_runtime.hdr.headersize = sizeof(tables->efi_runtime.hdr);
+
+ pfn = 0;
+ EFI_HYPERCALL_PATCH(get_time,EFI_GET_TIME);
+ EFI_HYPERCALL_PATCH(set_time,EFI_SET_TIME);
+ EFI_HYPERCALL_PATCH(get_wakeup_time,EFI_GET_WAKEUP_TIME);
+ EFI_HYPERCALL_PATCH(set_wakeup_time,EFI_SET_WAKEUP_TIME);
+ EFI_HYPERCALL_PATCH(set_virtual_address_map,
+ EFI_SET_VIRTUAL_ADDRESS_MAP);
+ EFI_HYPERCALL_PATCH(get_variable,EFI_GET_VARIABLE);
+ EFI_HYPERCALL_PATCH(get_next_variable,EFI_GET_NEXT_VARIABLE);
+ EFI_HYPERCALL_PATCH(set_variable,EFI_SET_VARIABLE);
+ EFI_HYPERCALL_PATCH(get_next_high_mono_count,
+ EFI_GET_NEXT_HIGH_MONO_COUNT);
+ EFI_HYPERCALL_PATCH(reset_system,EFI_RESET_SYSTEM);
+
+ /* System tables. */
+ tables->efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
+ tables->efi_tables[0].table = FW_FIELD_MPA(sal_systab);
for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
- efi_tables[i].guid = NULL_GUID;
- efi_tables[i].table = 0;
- }
+ tables->efi_tables[i].guid = NULL_GUID;
+ tables->efi_tables[i].table = 0;
+ }
+ i = 1;
if (d == dom0) {
+ /* Write messages to the console. */
+ touch_acpi_table();
+
printf("Domain0 EFI passthrough:");
- i = 1;
if (efi.mps) {
- efi_tables[i].guid = MPS_TABLE_GUID;
- efi_tables[i].table = __pa(efi.mps);
- printf(" MPS=0x%lx",efi_tables[i].table);
+ tables->efi_tables[i].guid = MPS_TABLE_GUID;
+ tables->efi_tables[i].table = __pa(efi.mps);
+ printf(" MPS=0x%lx",tables->efi_tables[i].table);
i++;
}
- touch_acpi_table();
-
if (efi.acpi20) {
- efi_tables[i].guid = ACPI_20_TABLE_GUID;
- efi_tables[i].table = __pa(efi.acpi20);
- printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
+ tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
+ tables->efi_tables[i].table = __pa(efi.acpi20);
+ printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
i++;
}
if (efi.acpi) {
- efi_tables[i].guid = ACPI_TABLE_GUID;
- efi_tables[i].table = __pa(efi.acpi);
- printf(" ACPI=0x%lx",efi_tables[i].table);
+ tables->efi_tables[i].guid = ACPI_TABLE_GUID;
+ tables->efi_tables[i].table = __pa(efi.acpi);
+ printf(" ACPI=0x%lx",tables->efi_tables[i].table);
i++;
}
if (efi.smbios) {
- efi_tables[i].guid = SMBIOS_TABLE_GUID;
- efi_tables[i].table = __pa(efi.smbios);
- printf(" SMBIOS=0x%lx",efi_tables[i].table);
+ tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;
+ tables->efi_tables[i].table = __pa(efi.smbios);
+ printf(" SMBIOS=0x%lx",tables->efi_tables[i].table);
i++;
}
if (efi.hcdp) {
- efi_tables[i].guid = HCDP_TABLE_GUID;
- efi_tables[i].table = __pa(efi.hcdp);
- printf(" HCDP=0x%lx",efi_tables[i].table);
+ tables->efi_tables[i].guid = HCDP_TABLE_GUID;
+ tables->efi_tables[i].table = __pa(efi.hcdp);
+ printf(" HCDP=0x%lx",tables->efi_tables[i].table);
i++;
}
printf("\n");
} else {
printf("DomainU EFI build up:");
- i = 1;
-
- if ((unsigned long)fw_mem + fw_mem_size - (unsigned long)cp >=
- sizeof(struct fake_acpi_tables)) {
- struct fake_acpi_tables *acpi_tables;
-
- acpi_tables = (void *)cp;
- cp += sizeof(struct fake_acpi_tables);
- dom_fw_fake_acpi(d, acpi_tables);
-
- efi_tables[i].guid = ACPI_20_TABLE_GUID;
- efi_tables[i].table = dom_pa((unsigned long)
acpi_tables);
- printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
- i++;
- }
+
+ tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
+ tables->efi_tables[i].table = FW_ACPI_BASE_PADDR;
+ printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
+ i++;
printf("\n");
}
/* fill in the SAL system table: */
- memcpy(sal_systab->signature, "SST_", 4);
- sal_systab->size = sizeof(*sal_systab);
- sal_systab->sal_rev_minor = 1;
- sal_systab->sal_rev_major = 0;
- sal_systab->entry_count = 2;
-
- strcpy((char *)sal_systab->oem_id, "Xen/ia64");
- strcpy((char *)sal_systab->product_id, "Xen/ia64");
-
- /* fill in an entry point: */
- sal_ed->type = SAL_DESC_ENTRY_POINT;
- sal_ed->pal_proc = FW_HYPERCALL_PAL_CALL_PADDR + start_mpaddr;
- dom_fw_pal_hypercall_patch (d, sal_ed->pal_proc);
- sal_ed->sal_proc = FW_HYPERCALL_SAL_CALL_PADDR + start_mpaddr;
- dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
- sal_ed->gp = 0; // will be ignored
+ memcpy(tables->sal_systab.signature, "SST_", 4);
+ tables->sal_systab.size = sizeof(tables->sal_systab);
+ tables->sal_systab.sal_rev_minor = 1;
+ tables->sal_systab.sal_rev_major = 0;
+ tables->sal_systab.entry_count = 2;
+
+ strcpy((char *)tables->sal_systab.oem_id, "Xen/ia64");
+ strcpy((char *)tables->sal_systab.product_id, "Xen/ia64");
+
+ /* PAL entry point: */
+ tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
+ tables->sal_ed.pal_proc = FW_HYPERCALL_PAL_CALL_PADDR;
+ dom_fw_pal_hypercall_patch(d, tables->sal_ed.pal_proc,
+ hypercalls_imva);
+ /* SAL entry point. */
+ tables->sal_ed.sal_proc = FW_HYPERCALL_SAL_CALL_PADDR;
+ dom_fw_hypercall_patch(d, tables->sal_ed.sal_proc,
+ FW_HYPERCALL_SAL_CALL, 1, hypercalls_imva);
+ tables->sal_ed.gp = 0; /* will be ignored */
/* Fill an AP wakeup descriptor. */
- sal_wakeup->type = SAL_DESC_AP_WAKEUP;
- sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
- sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC;
+ tables->sal_wakeup.type = SAL_DESC_AP_WAKEUP;
+ tables->sal_wakeup.mechanism = IA64_SAL_AP_EXTERNAL_INT;
+ tables->sal_wakeup.vector = XEN_SAL_BOOT_RENDEZ_VEC;
/* Compute checksum. */
- for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
+ checksum = 0;
+ for (cp = (char *)&tables->sal_systab;
+ cp < (char *)&tables->fpswa_inf;
+ ++cp)
checksum += *cp;
- sal_systab->checksum = -checksum;
+ tables->sal_systab.checksum = -checksum;
/* SAL return point. */
- d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr;
- dom_fw_hypercall_patch (d, d->arch.sal_return_addr,
- FW_HYPERCALL_SAL_RETURN, 0);
+ dom_fw_hypercall_patch(d, FW_HYPERCALL_SAL_RETURN_PADDR,
+ FW_HYPERCALL_SAL_RETURN, 0, hypercalls_imva);
/* Fill in the FPSWA interface: */
- fpswa_inf->revision = fpswa_interface->revision;
- dom_fpswa_hypercall_patch(d);
- fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR +
start_mpaddr;
+ tables->fpswa_inf.revision = fpswa_interface->revision;
+ dom_fpswa_hypercall_patch(d, hypercalls_imva);
+ tables->fpswa_inf.fpswa = (void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
i = 0; /* Used by MAKE_MD */
- /* Create dom0/domu md entry for fw_mem area */
- MAKE_MD(EFI_ACPI_RECLAIM_MEMORY, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
- dom_pa((unsigned long)fw_mem),
- dom_pa((unsigned long)fw_mem + fw_mem_size), 1);
-
- if (d == dom0) {
- /* hypercall patches live here, masquerade as reserved PAL
memory */
-
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
0);
-
- /* pass through the I/O port space */
- if (!running_on_sim) {
- struct dom0_passthrough_arg arg;
- arg.md = &efi_memmap[i];
- arg.i = &i;
- arg.d = d;
- arg.flags = ASSIGN_writable;
- //XXX Is this needed?
- efi_memmap_walk_type(EFI_RUNTIME_SERVICES_CODE,
- dom_fw_dom0_passthrough, &arg);
- // for ACPI table.
- arg.flags = ASSIGN_readonly;
- efi_memmap_walk_type(EFI_RUNTIME_SERVICES_DATA,
- dom_fw_dom0_passthrough, &arg);
- arg.flags = ASSIGN_writable;
- efi_memmap_walk_type(EFI_ACPI_RECLAIM_MEMORY,
- dom_fw_dom0_passthrough, &arg);
- efi_memmap_walk_type(EFI_ACPI_MEMORY_NVS,
- dom_fw_dom0_passthrough, &arg);
- efi_memmap_walk_type(EFI_RESERVED_TYPE,
- dom_fw_dom0_passthrough, &arg);
- efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO,
- dom_fw_dom0_passthrough, &arg);
- efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO_PORT_SPACE,
- dom_fw_dom0_passthrough, &arg);
- efi_memmap_walk_type(EFI_CONVENTIONAL_MEMORY,
- dom_fw_dom0_lowmem, &arg);
- }
- else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
- } else {
- /* hypercall patches live here, masquerade as reserved
- PAL memory */
- MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
- HYPERCALL_START, HYPERCALL_END, 1);
+ /* hypercall patches live here, masquerade as reserved PAL memory */
+ MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,
+ FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
+
+ /* Create dom0/domu md entry for fw and cpi tables area. */
+ MAKE_MD(EFI_ACPI_MEMORY_NVS, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+ FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR);
+ MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+ FW_TABLES_BASE_PADDR, FW_TABLES_END_PADDR);
+
+ if (d != dom0 || running_on_sim) {
+ /* DomU (or hp-ski).
+ Create a continuous memory area. */
+ /* Memory. */
+ MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+ FW_END_PADDR, maxmem);
+
/* Create an entry for IO ports. */
MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
- IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE, 1);
- MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
- }
-
- // simple
- // MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
- // HYPERCALL_END, maxmem, 0);
- // is not good. Check overlap.
- sort(efi_memmap, i, sizeof(efi_memory_desc_t),
- efi_mdt_cmp, NULL);
-
- // find gap and fill it with conventional memory
- num_mds = i;
- for (j = 0; j < num_mds; j++) {
- unsigned long end;
- unsigned long next_start;
-
- md = &efi_memmap[j];
- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-
- next_start = maxmem;
- if (j + 1 < num_mds) {
- efi_memory_desc_t* next_md = &efi_memmap[j + 1];
- next_start = next_md->phys_addr;
- BUG_ON(end > next_start);
- if (end == next_md->phys_addr)
- continue;
- }
-
- // clip the range and align to PAGE_SIZE
- // Avoid "legacy" low memory addresses and the
- // HYPERCALL patch area.
- if (end < HYPERCALL_END)
- end = HYPERCALL_END;
- if (next_start > maxmem)
- next_start = maxmem;
- end = PAGE_ALIGN(end);
- next_start = next_start & PAGE_MASK;
- if (end >= next_start)
- continue;
-
- MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
- end, next_start, 0);
- if (next_start >= maxmem)
- |