mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[POWERPC] merge with xen-unstable.hg
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
This commit is contained in:
1 parent
8a1ca3b97e
commit
ff3dfde07d
30 files changed
+468
-247
No files matched your search
@@ -1 +1,4 @@
|
||||
GUEST_SRCS-y += powerpc64/xc_linux_build.c
|
||||
GUEST_SRCS-y += powerpc64/ft_build.c
|
||||
|
||||
CTRL_SRCS-y += powerpc64/xc_memory.c
|
||||
@@ -27,14 +27,16 @@
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/memory.h>
|
||||
#include <xc_private.h>
|
||||
#include <xg_private.h>
|
||||
#include <xenctrl.h>
|
||||
|
||||
/* XXX 64M hack */
|
||||
#define MEMSIZE (64UL << 20)
|
||||
#include "ft_build.h"
|
||||
|
||||
#define INITRD_ADDR (24UL << 20)
|
||||
#define DEVTREE_ADDR (16UL << 20)
|
||||
|
||||
#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
|
||||
|
||||
@@ -91,8 +93,8 @@ static int init_boot_vcpu(
|
||||
int xc_handle,
|
||||
int domid,
|
||||
struct domain_setup_info *dsi,
|
||||
unsigned long dtb,
|
||||
unsigned long kaddr)
|
||||
unsigned long devtree_addr,
|
||||
unsigned long kern_addr)
|
||||
{
|
||||
vcpu_guest_context_t ctxt;
|
||||
int rc;
|
||||
@@ -101,15 +103,15 @@ static int init_boot_vcpu(
|
||||
ctxt.user_regs.pc = dsi->v_kernentry;
|
||||
ctxt.user_regs.msr = 0;
|
||||
ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
|
||||
ctxt.user_regs.gprs[3] = dtb;
|
||||
ctxt.user_regs.gprs[4] = kaddr;
|
||||
ctxt.user_regs.gprs[3] = devtree_addr;
|
||||
ctxt.user_regs.gprs[4] = kern_addr;
|
||||
ctxt.user_regs.gprs[5] = 0;
|
||||
/* There is a buggy kernel that does not zero the "local_paca", so
|
||||
* we must make sure this register is 0 */
|
||||
ctxt.user_regs.gprs[13] = 0;
|
||||
|
||||
DPRINTF("xc_vcpu_setvcpucontext:\n"
|
||||
" pc 0x%"PRIx64", msr 0x016%"PRIx64"\n"
|
||||
" pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
|
||||
" r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
|
||||
" %016"PRIx64"\n",
|
||||
ctxt.user_regs.pc, ctxt.user_regs.msr,
|
||||
@@ -156,30 +158,69 @@ static int install_image(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* XXX be more flexible about placement in memory */
|
||||
static int load_dtb(
|
||||
static int load_devtree(
|
||||
int xc_handle,
|
||||
int domid,
|
||||
const char *dtb_path,
|
||||
unsigned long dtb_addr,
|
||||
struct domain_setup_info *dsi,
|
||||
xen_pfn_t *page_array)
|
||||
xen_pfn_t *page_array,
|
||||
void *devtree,
|
||||
unsigned long devtree_addr,
|
||||
unsigned long initrd_base,
|
||||
unsigned long initrd_len,
|
||||
start_info_t *si,
|
||||
unsigned long si_addr)
|
||||
{
|
||||
uint8_t *img;
|
||||
unsigned long dtb_size;
|
||||
uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
|
||||
struct boot_param_header *header;
|
||||
uint64_t *prop;
|
||||
unsigned int devtree_size;
|
||||
unsigned int proplen;
|
||||
int rc = 0;
|
||||
|
||||
img = load_file(dtb_path, &dtb_size);
|
||||
if (img == NULL) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
header = devtree;
|
||||
devtree_size = header->totalsize;
|
||||
|
||||
DPRINTF("adding initrd props\n");
|
||||
|
||||
/* initrd-start */
|
||||
prop = ft_get_prop(devtree, "/chosen/linux,initrd-start", &proplen);
|
||||
if (prop == NULL) {
|
||||
DPRINTF("couldn't find linux,initrd-start\n");
|
||||
return -1;
|
||||
}
|
||||
if (proplen != sizeof(*prop)) {
|
||||
DPRINTF("couldn't set linux,initrd-start (size %d)\n", proplen);
|
||||
return -1;
|
||||
}
|
||||
*prop = initrd_base;
|
||||
|
||||
DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size);
|
||||
rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size);
|
||||
/* initrd-end */
|
||||
prop = ft_get_prop(devtree, "/chosen/linux,initrd-end", &proplen);
|
||||
if (prop == NULL) {
|
||||
DPRINTF("couldn't find linux,initrd-end\n");
|
||||
return -1;
|
||||
}
|
||||
if (proplen != sizeof(*prop)) {
|
||||
DPRINTF("couldn't set linux,initrd-end (size %d)\n", proplen);
|
||||
return -1;
|
||||
}
|
||||
*prop = initrd_base + initrd_len;
|
||||
|
||||
/* start-info (XXX being removed soon) */
|
||||
prop = ft_get_prop(devtree, "/xen/start-info", &proplen);
|
||||
if (prop == NULL) {
|
||||
DPRINTF("couldn't find /xen/start-info\n");
|
||||
return -1;
|
||||
}
|
||||
if (proplen != sizeof(start_info)) {
|
||||
DPRINTF("couldn't set /xen/start-info (size %d)\n", proplen);
|
||||
return -1;
|
||||
}
|
||||
memcpy(prop, start_info, proplen);
|
||||
|
||||
DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
|
||||
rc = install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
|
||||
devtree_size);
|
||||
|
||||
out:
|
||||
free(img);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -294,17 +335,16 @@ out:
|
||||
}
|
||||
|
||||
static unsigned long create_start_info(start_info_t *si,
|
||||
unsigned int console_evtchn, unsigned int store_evtchn)
|
||||
unsigned int console_evtchn, unsigned int store_evtchn,
|
||||
unsigned long nr_pages)
|
||||
{
|
||||
unsigned long eomem;
|
||||
unsigned long si_addr;
|
||||
|
||||
memset(si, 0, sizeof(*si));
|
||||
snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
|
||||
|
||||
eomem = MEMSIZE;
|
||||
si->nr_pages = eomem >> PAGE_SHIFT;
|
||||
si->shared_info = eomem - (PAGE_SIZE * 1);
|
||||
si->nr_pages = nr_pages;
|
||||
si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
|
||||
si->store_mfn = si->nr_pages - 2;
|
||||
si->store_evtchn = store_evtchn;
|
||||
si->console.domU.mfn = si->nr_pages - 3;
|
||||
@@ -314,24 +354,24 @@ static unsigned long create_start_info(start_info_t *si,
|
||||
return si_addr;
|
||||
}
|
||||
|
||||
static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
|
||||
static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
|
||||
unsigned long *nr_pages)
|
||||
{
|
||||
int nr_pages;
|
||||
int rc;
|
||||
|
||||
DPRINTF("xc_get_tot_pages\n");
|
||||
nr_pages = xc_get_tot_pages(xc_handle, domid);
|
||||
DPRINTF(" 0x%x\n", nr_pages);
|
||||
*nr_pages = xc_get_tot_pages(xc_handle, domid);
|
||||
DPRINTF(" 0x%lx\n", *nr_pages);
|
||||
|
||||
*page_array = malloc(nr_pages * sizeof(xen_pfn_t));
|
||||
*page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
|
||||
if (*page_array == NULL) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF("xc_get_pfn_list\n");
|
||||
rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages);
|
||||
if (rc != nr_pages) {
|
||||
rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
|
||||
if (rc != *nr_pages) {
|
||||
perror("Could not get the page frame list");
|
||||
return -1;
|
||||
}
|
||||
@@ -339,6 +379,11 @@ static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_page_array(xen_pfn_t *page_array)
|
||||
{
|
||||
free(page_array);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int xc_linux_build(int xc_handle,
|
||||
@@ -351,57 +396,70 @@ int xc_linux_build(int xc_handle,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
unsigned long *console_mfn,
|
||||
void *devtree)
|
||||
{
|
||||
start_info_t si;
|
||||
struct domain_setup_info dsi;
|
||||
xen_pfn_t *page_array = NULL;
|
||||
unsigned long nr_pages;
|
||||
unsigned long devtree_addr = 0;
|
||||
unsigned long kern_addr;
|
||||
unsigned long dtb_addr;
|
||||
unsigned long si_addr;
|
||||
unsigned long initrd_base = 0;
|
||||
unsigned long initrd_len = 0;
|
||||
start_info_t si;
|
||||
unsigned long si_addr;
|
||||
int rc = 0;
|
||||
|
||||
if (get_page_array(xc_handle, domid, &page_array)) {
|
||||
DPRINTF("%s\n", __func__);
|
||||
|
||||
if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DPRINTF("loading image '%s'\n", image_name);
|
||||
if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
kern_addr = 0;
|
||||
|
||||
if (initrd_name && initrd_name[0] != '\0' &&
|
||||
load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base,
|
||||
&initrd_len)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
/* XXX install initrd addr/len into device tree */
|
||||
|
||||
dtb_addr = (16 << 20);
|
||||
if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) {
|
||||
dtb_addr = 0;
|
||||
if (initrd_name && initrd_name[0] != '\0') {
|
||||
DPRINTF("loading initrd '%s'\n", initrd_name);
|
||||
if (load_initrd(xc_handle, domid, page_array, initrd_name,
|
||||
&initrd_base, &initrd_len)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
si_addr = create_start_info(&si, console_evtchn, store_evtchn);
|
||||
/* start_info stuff: about to be removed */
|
||||
si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
|
||||
*console_mfn = page_array[si.console.domU.mfn];
|
||||
*store_mfn = page_array[si.store_mfn];
|
||||
|
||||
if (install_image(xc_handle, domid, page_array, &si, si_addr,
|
||||
sizeof(start_info_t))) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) {
|
||||
if (devtree) {
|
||||
DPRINTF("loading flattened device tree\n");
|
||||
devtree_addr = DEVTREE_ADDR;
|
||||
if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
|
||||
initrd_base, initrd_len, &si, si_addr)) {
|
||||
DPRINTF("couldn't load flattened device tree.\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
free_page_array(page_array);
|
||||
return rc;
|
||||
}
|
||||
@@ -19,10 +19,10 @@
|
||||
*/
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <asm/misc.h>
|
||||
#include <xen/lib.h>
|
||||
|
||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
||||
void __cmpxchg_called_with_bad_pointer(void)
|
||||
{
|
||||
trap();
|
||||
BUG();
|
||||
}
|
||||
@@ -191,3 +191,20 @@ void show_backtrace(ulong sp, ulong lr, ulong pc)
|
||||
backtrace(sp, lr, pc);
|
||||
console_end_sync();
|
||||
}
|
||||
|
||||
void __warn(char *file, int line)
|
||||
{
|
||||
ulong sp;
|
||||
ulong lr;
|
||||
|
||||
console_start_sync();
|
||||
printk("WARN at %s:%d\n", file, line);
|
||||
|
||||
sp = (ulong)__builtin_frame_address(0);
|
||||
lr = (ulong)__builtin_return_address(0);
|
||||
|
||||
backtrace(sp, lr, lr);
|
||||
console_end_sync();
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -31,6 +31,7 @@
|
||||
#include <asm/io.h>
|
||||
#include "exceptions.h"
|
||||
#include "of-devtree.h"
|
||||
#include "oftree.h"
|
||||
|
||||
/* Secondary processors use this for handshaking with main processor. */
|
||||
volatile unsigned int __spin_ack;
|
||||
@@ -38,7 +39,6 @@ volatile unsigned int __spin_ack;
|
||||
static ulong of_vec;
|
||||
static ulong of_msr;
|
||||
static int of_out;
|
||||
static ofdn_t boot_cpu;
|
||||
static char bootargs[256];
|
||||
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
@@ -669,7 +669,7 @@ static int boot_of_fixup_chosen(void *mem)
|
||||
dn = ofd_node_find(mem, ofpath);
|
||||
if (dn <= 0) of_panic("no node for: %s\n", ofpath);
|
||||
|
||||
boot_cpu = dn;
|
||||
ofd_boot_cpu = dn;
|
||||
val = dn;
|
||||
|
||||
dn = ofd_node_find(mem, "/chosen");
|
||||
@@ -681,7 +681,7 @@ static int boot_of_fixup_chosen(void *mem)
|
||||
} else {
|
||||
of_printf("*** can't find path to booting cpu, "
|
||||
"SMP is disabled\n");
|
||||
boot_cpu = -1;
|
||||
ofd_boot_cpu = -1;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@@ -773,7 +773,7 @@ static void __init boot_of_fix_maple(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int __init boot_of_serial(void *oftree)
|
||||
static int __init boot_of_serial(void *oft)
|
||||
{
|
||||
int n;
|
||||
int p;
|
||||
@@ -805,7 +805,7 @@ static int __init boot_of_serial(void *oftree)
|
||||
continue;
|
||||
|
||||
of_printf("pruning `%s' from devtree\n", buf);
|
||||
rc = ofd_prune_path(oftree, buf);
|
||||
rc = ofd_prune_path(oft, buf);
|
||||
if (rc < 0)
|
||||
of_panic("prune of `%s' failed\n", buf);
|
||||
}
|
||||
@@ -858,8 +858,8 @@ static int __init boot_of_serial(void *oftree)
|
||||
static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
|
||||
{
|
||||
static module_t mods[3];
|
||||
void *oftree;
|
||||
ulong oftree_sz = 48 * PAGE_SIZE;
|
||||
void *oft;
|
||||
ulong oft_sz = 48 * PAGE_SIZE;
|
||||
ulong mod0_start;
|
||||
ulong mod0_size;
|
||||
static const char sepr[] = " -- ";
|
||||
@@ -922,28 +922,28 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
|
||||
}
|
||||
|
||||
/* snapshot the tree */
|
||||
oftree = (void*)find_space(oftree_sz, PAGE_SIZE, mbi);
|
||||
if (oftree == 0)
|
||||
oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
|
||||
if (oft == 0)
|
||||
of_panic("Could not allocate OFD tree\n");
|
||||
|
||||
of_printf("creating oftree\n");
|
||||
of_printf("creating oft\n");
|
||||
of_test("package-to-path");
|
||||
oftree = ofd_create(oftree, oftree_sz);
|
||||
pkg_save(oftree);
|
||||
oft = ofd_create(oft, oft_sz);
|
||||
pkg_save(oft);
|
||||
|
||||
if (ofd_size(oftree) > oftree_sz)
|
||||
if (ofd_size(oft) > oft_sz)
|
||||
of_panic("Could not fit all of native devtree\n");
|
||||
|
||||
boot_of_fixup_refs(oftree);
|
||||
boot_of_fixup_chosen(oftree);
|
||||
boot_of_fixup_refs(oft);
|
||||
boot_of_fixup_chosen(oft);
|
||||
|
||||
if (ofd_size(oftree) > oftree_sz)
|
||||
if (ofd_size(oft) > oft_sz)
|
||||
of_panic("Could not fit all devtree fixups\n");
|
||||
|
||||
ofd_walk(oftree, OFD_ROOT, /* add_hype_props */ NULL, 2);
|
||||
ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
|
||||
|
||||
mods[1].mod_start = (ulong)oftree;
|
||||
mods[1].mod_end = mods[1].mod_start + oftree_sz;
|
||||
mods[1].mod_start = (ulong)oft;
|
||||
mods[1].mod_end = mods[1].mod_start + oft_sz;
|
||||
of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
|
||||
mods[1].mod_start, mods[1].mod_end);
|
||||
|
||||
@@ -952,7 +952,7 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
|
||||
mbi->mods_count = 2;
|
||||
mbi->mods_addr = (u32)mods;
|
||||
|
||||
boot_of_serial(oftree);
|
||||
boot_of_serial(oft);
|
||||
}
|
||||
|
||||
static int __init boot_of_cpus(void)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <public/xen.h>
|
||||
#include <public/domctl.h>
|
||||
#include <public/sysctl.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *);
|
||||
void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c)
|
||||
@@ -92,6 +93,22 @@ long arch_do_domctl(struct xen_domctl *domctl,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XEN_DOMCTL_real_mode_area:
|
||||
{
|
||||
struct domain *d;
|
||||
unsigned int log = domctl->u.real_mode_area.log;
|
||||
|
||||
d = find_domain_by_id(domctl->domain);
|
||||
if (d == NULL)
|
||||
return -ESRCH;
|
||||
|
||||
if (!cpu_rma_valid(log))
|
||||
return -EINVAL;
|
||||
|
||||
ret = allocate_rma(d, log - PAGE_SHIFT);
|
||||
put_domain(d);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
|
||||
@@ -75,11 +75,6 @@ unsigned long hypercall_create_continuation(unsigned int op,
|
||||
|
||||
int arch_domain_create(struct domain *d)
|
||||
{
|
||||
unsigned long rma_base;
|
||||
unsigned long rma_sz;
|
||||
uint rma_order_pages;
|
||||
int rc;
|
||||
|
||||
if (d->domain_id == IDLE_DOMAIN_ID) {
|
||||
d->shared_info = (void *)alloc_xenheap_page();
|
||||
clear_page(d->shared_info);
|
||||
@@ -87,20 +82,6 @@ int arch_domain_create(struct domain *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate the real mode area */
|
||||
rma_order_pages = cpu_default_rma_order_pages();
|
||||
d->max_pages = 1UL << rma_order_pages;
|
||||
d->tot_pages = 0;
|
||||
|
||||
rc = allocate_rma(d, rma_order_pages);
|
||||
if (rc)
|
||||
return rc;
|
||||
rma_base = page_to_maddr(d->arch.rma_page);
|
||||
rma_sz = rma_size(rma_order_pages);
|
||||
|
||||
d->shared_info = (shared_info_t *)
|
||||
(rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base);
|
||||
|
||||
d->arch.large_page_sizes = cpu_large_page_orders(
|
||||
d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order));
|
||||
|
||||
@@ -264,7 +245,8 @@ void sync_vcpu_execstate(struct vcpu *v)
|
||||
|
||||
void domain_relinquish_resources(struct domain *d)
|
||||
{
|
||||
free_domheap_pages(d->arch.rma_page, d->arch.rma_order);
|
||||
if (d->arch.rma_page)
|
||||
free_domheap_pages(d->arch.rma_page, d->arch.rma_order);
|
||||
free_extents(d);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#define parseelfimage parseelfimage_32
|
||||
#define loadelfimage loadelfimage_32
|
||||
#define xen_elfnote_string xen_elfnote_string32
|
||||
#define xen_elfnote_numeric xen_elfnote_numeric32
|
||||
#define ELFSIZE 32
|
||||
#include "../../common/elf.c"
|
||||
|
||||
@@ -112,9 +112,8 @@ static void do_ni_papr_hypercall(struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vcpu *v = get_current();
|
||||
|
||||
printk("unsupported hcall 0x%lx was called by dom0x%x\n",
|
||||
printk("unsupported PAPR hcall 0x%lx was called by dom0x%x\n",
|
||||
regs->gprs[3], v->domain->domain_id);
|
||||
debugger_trap_immediate();
|
||||
|
||||
regs->gprs[3] = H_Parameter;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ int iommu_put(u32 buid, ulong ioba, union tce tce)
|
||||
|
||||
pfn = tce.tce_bits.tce_rpn;
|
||||
mfn = pfn2mfn(d, pfn, &mtype);
|
||||
if (mfn > 0) {
|
||||
if (mfn != INVALID_MFN) {
|
||||
#ifdef DEBUG
|
||||
printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
|
||||
ioba, pfn, mfn);
|
||||
|
||||
+29
-12
@@ -301,27 +301,41 @@ uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages)
|
||||
|
||||
return total_nrpages;
|
||||
}
|
||||
|
||||
int allocate_rma(struct domain *d, unsigned int order_pages)
|
||||
{
|
||||
ulong rma_base;
|
||||
ulong rma_sz = rma_size(order_pages);
|
||||
|
||||
d->arch.rma_page = alloc_domheap_pages(d, order_pages, 0);
|
||||
int allocate_rma(struct domain *d, unsigned int order)
|
||||
{
|
||||
struct vcpu *v;
|
||||
ulong rma_base;
|
||||
ulong rma_sz;
|
||||
|
||||
if (d->arch.rma_page)
|
||||
free_domheap_pages(d->arch.rma_page, d->arch.rma_order);
|
||||
|
||||
d->arch.rma_page = alloc_domheap_pages(d, order, 0);
|
||||
if (d->arch.rma_page == NULL) {
|
||||
DPRINTK("Could not allocate order_pages=%d RMA for domain %u\n",
|
||||
order_pages, d->domain_id);
|
||||
DPRINTK("Could not allocate order=%d RMA for domain %u\n",
|
||||
order, d->domain_id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
d->arch.rma_order = order_pages;
|
||||
d->arch.rma_order = order;
|
||||
|
||||
rma_base = page_to_maddr(d->arch.rma_page);
|
||||
rma_sz = rma_size(d->arch.rma_order);
|
||||
BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */
|
||||
|
||||
/* XXX */
|
||||
/* XXX shouldn't be needed */
|
||||
printk("clearing RMA: 0x%lx[0x%lx]\n", rma_base, rma_sz);
|
||||
memset((void *)rma_base, 0, rma_sz);
|
||||
|
||||
d->shared_info = (shared_info_t *)
|
||||
(rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base);
|
||||
|
||||
/* if there are already running vcpus, adjust v->vcpu_info */
|
||||
/* XXX untested */
|
||||
for_each_vcpu(d, v) {
|
||||
v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -331,6 +345,10 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type)
|
||||
ulong rma_size_mfn = 1UL << d->arch.rma_order;
|
||||
struct page_extents *pe;
|
||||
|
||||
if (type)
|
||||
*type = PFN_TYPE_NONE;
|
||||
|
||||
/* quick tests first */
|
||||
if (pfn < rma_size_mfn) {
|
||||
if (type)
|
||||
*type = PFN_TYPE_RMA;
|
||||
@@ -344,7 +362,6 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type)
|
||||
return pfn;
|
||||
}
|
||||
|
||||
/* quick tests first */
|
||||
list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
|
||||
uint end_pfn = pe->pfn + (1 << pe->order);
|
||||
|
||||
@@ -364,7 +381,7 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type)
|
||||
}
|
||||
|
||||
BUG();
|
||||
return 0;
|
||||
return INVALID_MFN;
|
||||
}
|
||||
|
||||
void guest_physmap_add_page(
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#undef RTAS
|
||||
|
||||
ofdn_t ofd_boot_cpu;
|
||||
|
||||
#ifdef PAPR_VTERM
|
||||
static ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d)
|
||||
{
|
||||
@@ -172,24 +174,21 @@ static ofdn_t ofd_cpus_props(void *m, struct domain *d)
|
||||
#endif
|
||||
|
||||
c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu));
|
||||
if (ofd_boot_cpu == -1)
|
||||
ofd_boot_cpu = c;
|
||||
while (c > 0) {
|
||||
ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
|
||||
ofd_prop_add(m, c, "ibm,pft-size",
|
||||
ibm_pft_size, sizeof (ibm_pft_size));
|
||||
/* Since we are not MP yet we prune all but the booting cpu */
|
||||
if (c == ofd_boot_cpu) {
|
||||
ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
|
||||
ofd_prop_add(m, c, "ibm,pft-size",
|
||||
ibm_pft_size, sizeof (ibm_pft_size));
|
||||
|
||||
/* FIXME: Check the the "l2-cache" property who's
|
||||
* contents is an orphaned phandle? */
|
||||
c = ofd_node_find_next(m, c);
|
||||
|
||||
/* Since we are not MP yet we can prune the rest of the CPUs */
|
||||
while (c > 0) {
|
||||
ofdn_t nc;
|
||||
|
||||
nc = ofd_node_find_next(m, c);
|
||||
/* FIXME: Check the the "l2-cache" property who's
|
||||
* contents is an orphaned phandle? */
|
||||
} else
|
||||
ofd_node_prune(m, c);
|
||||
|
||||
c = nc;
|
||||
}
|
||||
c = ofd_node_find_next(m, c);
|
||||
}
|
||||
|
||||
return n;
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
#ifndef _OFTREE_H
|
||||
#define _OFTREE_H
|
||||
#include <xen/multiboot.h>
|
||||
#include "of-devtree.h"
|
||||
|
||||
extern ulong oftree;
|
||||
extern ulong oftree_len;
|
||||
extern ulong oftree_end;
|
||||
extern ofdn_t ofd_boot_cpu;
|
||||
|
||||
extern int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si);
|
||||
extern void ofd_memory_props(void *m, struct domain *d);
|
||||
|
||||
@@ -164,6 +164,10 @@ static void h_enter(struct cpu_user_regs *regs)
|
||||
lpn = pte.bits.rpn & lpn;
|
||||
|
||||
rpn = pfn2mfn(d, lpn, &mtype);
|
||||
if (rpn == INVALID_MFN) {
|
||||
regs->gprs[3] = H_Parameter;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mtype == PFN_TYPE_IO) {
|
||||
/* only a privilaged dom can access outside IO space */
|
||||
|
||||
@@ -32,21 +32,19 @@
|
||||
|
||||
#undef SERIALIZE
|
||||
|
||||
extern volatile struct processor_area * volatile global_cpu_table[];
|
||||
|
||||
struct rma_settings {
|
||||
int order;
|
||||
int rmlr0;
|
||||
int rmlr12;
|
||||
int rmlr_0;
|
||||
int rmlr_1_2;
|
||||
};
|
||||
|
||||
static struct rma_settings rma_orders[] = {
|
||||
{ .order = 26, .rmlr0 = 0, .rmlr12 = 3, }, /* 64 MB */
|
||||
{ .order = 27, .rmlr0 = 1, .rmlr12 = 3, }, /* 128 MB */
|
||||
{ .order = 28, .rmlr0 = 1, .rmlr12 = 0, }, /* 256 MB */
|
||||
{ .order = 30, .rmlr0 = 0, .rmlr12 = 2, }, /* 1 GB */
|
||||
{ .order = 34, .rmlr0 = 0, .rmlr12 = 1, }, /* 16 GB */
|
||||
{ .order = 38, .rmlr0 = 0, .rmlr12 = 0, }, /* 256 GB */
|
||||
{ .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /* 64 MB */
|
||||
{ .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */
|
||||
{ .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */
|
||||
{ .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /* 1 GB */
|
||||
{ .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /* 16 GB */
|
||||
{ .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */
|
||||
};
|
||||
|
||||
static uint log_large_page_sizes[] = {
|
||||
@@ -68,6 +66,11 @@ unsigned int cpu_default_rma_order_pages(void)
|
||||
return rma_orders[0].order - PAGE_SHIFT;
|
||||
}
|
||||
|
||||
int cpu_rma_valid(unsigned int log)
|
||||
{
|
||||
return cpu_find_rma(log) != NULL;
|
||||
}
|
||||
|
||||
unsigned int cpu_large_page_orders(uint *sizes, uint max)
|
||||
{
|
||||
uint i = 0;
|
||||
@@ -85,12 +88,36 @@ unsigned int cpu_extent_order(void)
|
||||
return log_large_page_sizes[0] - PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static u64 cpu0_hids[6];
|
||||
static u64 cpu0_hior;
|
||||
|
||||
void cpu_initialize(int cpuid)
|
||||
{
|
||||
ulong r1, r2;
|
||||
union hid0 hid0;
|
||||
union hid1 hid1;
|
||||
union hid4 hid4;
|
||||
union hid5 hid5;
|
||||
|
||||
__asm__ __volatile__ ("mr %0, 1" : "=r" (r1));
|
||||
__asm__ __volatile__ ("mr %0, 2" : "=r" (r2));
|
||||
|
||||
if (cpuid == 0) {
|
||||
/* we can assume that these are sane to start with. We
|
||||
* _do_not_ store the results in case we want to mess with them
|
||||
* on a per-cpu basis later. */
|
||||
cpu0_hids[0] = mfhid0();
|
||||
cpu0_hids[1] = mfhid1();
|
||||
cpu0_hids[4] = mfhid4();
|
||||
cpu0_hids[5] = mfhid5();
|
||||
cpu0_hior = 0;
|
||||
}
|
||||
|
||||
hid0.word = cpu0_hids[0];
|
||||
hid1.word = cpu0_hids[1];
|
||||
hid4.word = cpu0_hids[4];
|
||||
hid5.word = cpu0_hids[5];
|
||||
|
||||
/* This is SMP safe because the compiler must use r13 for it. */
|
||||
parea = global_cpu_table[cpuid];
|
||||
ASSERT(parea != NULL);
|
||||
@@ -103,25 +130,21 @@ void cpu_initialize(int cpuid)
|
||||
mtdec(timebase_freq);
|
||||
mthdec(timebase_freq);
|
||||
|
||||
union hid0 hid0;
|
||||
hid0.bits.nap = 1; /* NAP */
|
||||
hid0.bits.dpm = 1; /* Dynamic Power Management */
|
||||
hid0.bits.nhr = 0; /* ! Not Hard Reset */
|
||||
hid0.bits.hdice_en = 1; /* enable HDEC */
|
||||
hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */
|
||||
/* onlu debug Xen should do this */
|
||||
hid0.bits.en_attn = 1; /* Enable attn instruction */
|
||||
|
||||
hid0.word = mfhid0();
|
||||
hid0.bits.nap = 1;
|
||||
hid0.bits.dpm = 1;
|
||||
hid0.bits.nhr = 1;
|
||||
hid0.bits.hdice = 1; /* enable HDEC */
|
||||
hid0.bits.eb_therm = 1;
|
||||
hid0.bits.en_attn = 1;
|
||||
#ifdef SERIALIZE
|
||||
ulong s = 0;
|
||||
|
||||
s |= 1UL << (63-0); /* one_ppc */
|
||||
s |= 1UL << (63-2); /* isync_sc */
|
||||
s |= 1UL << (63-16); /* inorder */
|
||||
hid0.bits.one_ppc = 1;
|
||||
hid0.bits.isync_sc = 1;
|
||||
hid0.bits.inorder = 1;
|
||||
/* may not want these */
|
||||
s |= 1UL << (63-1); /* do_single */
|
||||
s |= 1UL << (63-3); /* ser-gp */
|
||||
hid0.word |= s;
|
||||
hid0.bits.do_single = 1;
|
||||
hid0.bits.ser-gp = 1;
|
||||
#endif
|
||||
|
||||
printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n",
|
||||
@@ -129,32 +152,42 @@ void cpu_initialize(int cpuid)
|
||||
|
||||
mthid0(hid0.word);
|
||||
|
||||
union hid1 hid1;
|
||||
hid1.bits.bht_pm = 7; /* branch history table prediction mode */
|
||||
hid1.bits.en_ls = 1; /* enable link stack */
|
||||
|
||||
hid1.word = mfhid1();
|
||||
hid1.bits.bht_pm = 7;
|
||||
hid1.bits.en_ls = 1;
|
||||
hid1.bits.en_cc = 1; /* enable count cache */
|
||||
hid1.bits.en_ic = 1; /* enable inst cache */
|
||||
|
||||
hid1.bits.en_cc = 1;
|
||||
hid1.bits.en_ic = 1;
|
||||
hid1.bits.pf_mode = 2; /* prefetch mode */
|
||||
|
||||
hid1.bits.pf_mode = 2;
|
||||
hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */
|
||||
hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */
|
||||
hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */
|
||||
hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */
|
||||
|
||||
hid1.bits.en_if_cach = 1;
|
||||
hid1.bits.en_ic_rec = 1;
|
||||
hid1.bits.en_id_rec = 1;
|
||||
hid1.bits.en_er_rec = 1;
|
||||
|
||||
hid1.bits.en_sp_itw = 1;
|
||||
hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */
|
||||
mthid1(hid1.word);
|
||||
|
||||
union hid5 hid5;
|
||||
/* no changes to hid4 but we want to make sure that secondaries
|
||||
* are sane */
|
||||
hid4.bits.lg_pg_dis = 0; /* make sure we enable large pages */
|
||||
mthid4(hid4.word);
|
||||
|
||||
hid5.word = mfhid5();
|
||||
hid5.bits.DCBZ_size = 0;
|
||||
hid5.bits.DCBZ32_ill = 0;
|
||||
hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */
|
||||
hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */
|
||||
mthid5(hid5.word);
|
||||
|
||||
#ifdef DUMP_HIDS
|
||||
printk("hid0 0x%016lx\n"
|
||||
"hid1 0x%016lx\n"
|
||||
"hid4 0x%016lx\n"
|
||||
"hid5 0x%016lx\n",
|
||||
mfhid0(), mfhid1(), mfhid4(), mfhid5());
|
||||
#endif
|
||||
|
||||
mthior(cpu0_hior);
|
||||
|
||||
/* for good luck */
|
||||
__asm__ __volatile__("isync; slbia; isync" : : : "memory");
|
||||
}
|
||||
|
||||
@@ -166,18 +199,18 @@ void cpu_init_vcpu(struct vcpu *v)
|
||||
|
||||
hid4.word = mfhid4();
|
||||
|
||||
hid4.bits.lpes0 = 0; /* exceptions set MSR_HV=1 */
|
||||
hid4.bits.lpes1 = 1; /* RMA applies */
|
||||
hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */
|
||||
hid4.bits.lpes_1 = 1; /* RMA applies */
|
||||
|
||||
hid4.bits.rmor = page_to_maddr(d->arch.rma_page) >> 26;
|
||||
hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26;
|
||||
|
||||
hid4.bits.lpid01 = d->domain_id & 3;
|
||||
hid4.bits.lpid25 = (d->domain_id >> 2) & 0xf;
|
||||
hid4.bits.lpid_0_1 = d->domain_id & 3;
|
||||
hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf;
|
||||
|
||||
rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT);
|
||||
ASSERT(rma_settings != NULL);
|
||||
hid4.bits.rmlr0 = rma_settings->rmlr0;
|
||||
hid4.bits.rmlr12 = rma_settings->rmlr12;
|
||||
hid4.bits.rmlr_0 = rma_settings->rmlr_0;
|
||||
hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2;
|
||||
|
||||
v->arch.cpu.hid4.word = hid4.word;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ cpumask_t cpu_present_map;
|
||||
cpumask_t cpu_possible_map;
|
||||
|
||||
/* XXX get this from ISA node in device tree */
|
||||
void *vgabase;
|
||||
ulong isa_io_base;
|
||||
struct ns16550_defaults ns16550;
|
||||
|
||||
@@ -255,7 +256,6 @@ static int kick_secondary_cpus(int maxcpus)
|
||||
break;
|
||||
init_parea(cpuid);
|
||||
cpu_set(cpuid, cpu_online_map);
|
||||
cpu_set(cpuid, cpu_possible_map);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -339,7 +339,7 @@ static void __init __start_xen(multiboot_info_t *mbi)
|
||||
#endif
|
||||
|
||||
/* Deal with secondary processors. */
|
||||
if (opt_nosmp) {
|
||||
if (opt_nosmp || ofd_boot_cpu == -1) {
|
||||
printk("nosmp: leaving secondary processors spinning forever\n");
|
||||
} else {
|
||||
printk("spinning up at most %d total processors ...\n", max_cpus);
|
||||
@@ -350,8 +350,13 @@ static void __init __start_xen(multiboot_info_t *mbi)
|
||||
|
||||
/* Create initial domain 0. */
|
||||
dom0 = domain_create(0);
|
||||
if ((dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL))
|
||||
if (dom0 == NULL)
|
||||
panic("Error creating domain 0\n");
|
||||
dom0->max_pages = ~0U;
|
||||
if (0 > allocate_rma(dom0, cpu_default_rma_order_pages()))
|
||||
panic("Error allocating domain 0 RMA\n");
|
||||
if (NULL == alloc_vcpu(dom0, 0, 0))
|
||||
panic("Error creating domain 0 vcpu 0\n");
|
||||
|
||||
set_bit(_DOMF_privileged, &dom0->domain_flags);
|
||||
/* post-create hooks sets security label */
|
||||
|
||||
@@ -78,7 +78,6 @@ unsigned int shadow_set_allocation(struct domain *d,
|
||||
unsigned int megabytes,
|
||||
int *preempted)
|
||||
{
|
||||
unsigned int rc;
|
||||
uint pages;
|
||||
uint p;
|
||||
uint order;
|
||||
@@ -91,7 +90,7 @@ unsigned int shadow_set_allocation(struct domain *d,
|
||||
if (megabytes == 0) {
|
||||
/* old management tools */
|
||||
megabytes = 1; /* 1/64th of 64M */
|
||||
printk("%s: Fix management tools to set and get shadow/htab values\n"
|
||||
printk("%s: WARNING!!: Update your managment tools\n"
|
||||
" using %d MiB htab\n",
|
||||
__func__, megabytes);
|
||||
}
|
||||
@@ -112,7 +111,7 @@ unsigned int shadow_set_allocation(struct domain *d,
|
||||
for (p = 0; p < (1 << order); p++)
|
||||
clear_page((void *)(addr + (p << PAGE_SHIFT)));
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shadow_domctl(struct domain *d,
|
||||
|
||||
@@ -47,14 +47,24 @@ static unsigned long paddr_to_maddr(unsigned long paddr)
|
||||
pfn = pa >> PAGE_SHIFT;
|
||||
|
||||
pa = pfn2mfn(d, pfn, &mtype);
|
||||
if (pa == INVALID_MFN) {
|
||||
printk("%s: Dom:%d bad paddr: 0x%lx\n",
|
||||
__func__, d->domain_id, paddr);
|
||||
return 0;
|
||||
}
|
||||
switch (mtype) {
|
||||
case PFN_TYPE_RMA:
|
||||
case PFN_TYPE_LOGICAL:
|
||||
break;
|
||||
default:
|
||||
panic("%s: called with bad memory address type: 0x%lx\n",
|
||||
__func__, paddr);
|
||||
break;
|
||||
case PFN_TYPE_RMA:
|
||||
case PFN_TYPE_LOGICAL:
|
||||
break;
|
||||
case PFN_TYPE_REMOTE:
|
||||
printk("%s: Dom:%d paddr: 0x%lx type: REMOTE\n",
|
||||
__func__, d->domain_id, paddr);
|
||||
WARN();
|
||||
break;
|
||||
default:
|
||||
panic("%s: Dom:%d paddr: 0x%lx bad type:0x%x\n",
|
||||
__func__, d->domain_id, paddr, mtype);
|
||||
break;
|
||||
}
|
||||
pa <<= PAGE_SHIFT;
|
||||
pa |= offset;
|
||||
@@ -85,6 +95,9 @@ xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
|
||||
|
||||
/* first we need to access the descriptor */
|
||||
desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
|
||||
if (desc == NULL)
|
||||
return n;
|
||||
|
||||
if (desc->magic != XENCOMM_MAGIC) {
|
||||
printk("%s: error: %p magic was 0x%x\n",
|
||||
__func__, desc, desc->magic);
|
||||
@@ -117,6 +130,9 @@ xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
|
||||
unsigned int bytes = min(chunksz, n - to_pos);
|
||||
|
||||
src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
|
||||
if (src_maddr == 0)
|
||||
return n - to_pos;
|
||||
|
||||
if (xencomm_debug)
|
||||
printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
|
||||
memcpy((void *)dest, (void *)src_maddr, bytes);
|
||||
@@ -153,6 +169,9 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
|
||||
|
||||
/* first we need to access the descriptor */
|
||||
desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
|
||||
if (desc == NULL)
|
||||
return n;
|
||||
|
||||
if (desc->magic != XENCOMM_MAGIC) {
|
||||
printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
|
||||
return n;
|
||||
@@ -184,6 +203,9 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
|
||||
unsigned int bytes = min(chunksz, n - from_pos);
|
||||
|
||||
dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
|
||||
if (dest_maddr == 0)
|
||||
return -1;
|
||||
|
||||
if (xencomm_debug)
|
||||
printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
|
||||
memcpy((void *)dest_maddr, (void *)source, bytes);
|
||||
@@ -199,16 +221,19 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
|
||||
|
||||
/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
|
||||
* exhausted pages to XENCOMM_INVALID. */
|
||||
void xencomm_add_offset(void *handle, unsigned int bytes)
|
||||
int xencomm_add_offset(void *handle, unsigned int bytes)
|
||||
{
|
||||
struct xencomm_desc *desc;
|
||||
int i = 0;
|
||||
|
||||
/* first we need to access the descriptor */
|
||||
desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
|
||||
if (desc == NULL)
|
||||
return -1;
|
||||
|
||||
if (desc->magic != XENCOMM_MAGIC) {
|
||||
printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* iterate through the descriptor incrementing addresses */
|
||||
@@ -230,6 +255,7 @@ void xencomm_add_offset(void *handle, unsigned int bytes)
|
||||
}
|
||||
bytes -= chunk_skip;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xencomm_handle_is_null(void *ptr)
|
||||
@@ -237,6 +263,9 @@ int xencomm_handle_is_null(void *ptr)
|
||||
struct xencomm_desc *desc;
|
||||
|
||||
desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
|
||||
if (desc == NULL)
|
||||
return 1;
|
||||
|
||||
return (desc->nr_addrs == 0);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
struct vcpu;
|
||||
|
||||
extern volatile struct processor_area * volatile global_cpu_table[];
|
||||
register volatile struct processor_area *parea asm("r13");
|
||||
|
||||
static inline struct vcpu *get_current(void)
|
||||
{
|
||||
return parea->cur_vcpu;
|
||||
|
||||
@@ -35,9 +35,6 @@ DECLARE_PER_CPU(u32, tlbflush_time);
|
||||
|
||||
static inline int NEED_FLUSH(u32 cpu_stamp, u32 lastuse_stamp)
|
||||
{
|
||||
#if 0
|
||||
trap();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
|
||||
unsigned int len, unsigned int skip);
|
||||
extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
|
||||
unsigned int len, unsigned int skip);
|
||||
extern void xencomm_add_offset(void *handle, unsigned int bytes);
|
||||
extern int xencomm_add_offset(void *handle, unsigned int bytes);
|
||||
extern int xencomm_handle_is_null(void *ptr);
|
||||
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ extern ulong isa_io_base;
|
||||
#define readb(port) in_8((void *)(port))
|
||||
#define writeb(val, port) out_8((void *)(port), val)
|
||||
|
||||
extern char *vgabase;
|
||||
#define vga_writeb(val, port) out_8((void *)((ulong)(port) + vgabase), val)
|
||||
|
||||
extern u8 in_8(const volatile u8 *addr);
|
||||
extern void out_8(volatile u8 *addr, int val);
|
||||
|
||||
@@ -212,8 +212,6 @@ static inline int page_is_removable(struct page_info *page)
|
||||
return ((page->count_info & PGC_count_mask) == 1);
|
||||
}
|
||||
|
||||
#define set_machinetophys(_mfn, _pfn) (trap(), 0)
|
||||
|
||||
extern void synchronise_pagetables(unsigned long cpu_mask);
|
||||
|
||||
/* XXX don't know what this is for */
|
||||
@@ -236,6 +234,8 @@ extern int update_grant_va_mapping(unsigned long va,
|
||||
struct domain *,
|
||||
struct vcpu *);
|
||||
|
||||
#define INVALID_MFN (~0UL)
|
||||
#define PFN_TYPE_NONE 0
|
||||
#define PFN_TYPE_RMA 1
|
||||
#define PFN_TYPE_LOGICAL 2
|
||||
#define PFN_TYPE_IO 3
|
||||
|
||||
@@ -29,22 +29,30 @@
|
||||
|
||||
union hid0 {
|
||||
struct hid0_bits {
|
||||
ulong _unused_0_8: 9;
|
||||
ulong nap: 1;
|
||||
ulong _unused_10: 1;
|
||||
ulong dpm: 1; /* Dynamic Power Management */
|
||||
ulong _unused_12_14: 3;
|
||||
ulong nhr: 1; /* Not Hard Reset */
|
||||
ulong inorder: 1;
|
||||
ulong one_ppc: 1; /* One PowerPC AS insn per dispatch group */
|
||||
ulong do_single: 1; /* Single group completion */
|
||||
ulong isync_sc: 1; /* Disable isync scoreboard optimization */
|
||||
ulong ser_gp: 1; /* Serial Group Dispatch */
|
||||
ulong _reserved_04_08: 5;
|
||||
ulong nap: 1; /* Nap */
|
||||
ulong _reserved_10: 1;
|
||||
ulong dpm: 1; /* Dynamic Power Management */
|
||||
ulong _reserved_12: 1;
|
||||
ulong tg: 1; /* Perfmon threshold granualrity control */
|
||||
ulong hang_dis: 1; /* Disable cpu hang detection mechanism */
|
||||
ulong nhr: 1; /* Not Hard Reset */
|
||||
ulong inorder: 1; /* Serial Group Issue */
|
||||
ulong _reserved17: 1;
|
||||
ulong tb_ctrl: 1;
|
||||
ulong ext_tb_enb: 1; /* timebase is linked to external clock */
|
||||
ulong _unused_20_22: 3;
|
||||
ulong hdice: 1; /* HDEC enable */
|
||||
ulong eb_therm: 1; /* Enable ext thermal ints */
|
||||
ulong tb_ctrl: 1; /* Enable time base couting while stopped */
|
||||
ulong ext_tb_enb: 1; /* timebase is linked to external clock */
|
||||
ulong _unused_20_21: 2;
|
||||
ulong ciabr_en: 1; /* CIABR enable */
|
||||
ulong hdice_en: 1; /* HDEC enable */
|
||||
ulong en_therm: 1; /* Enable ext thermal ints */
|
||||
ulong _unused_25_30: 6;
|
||||
ulong en_attn: 1; /* Enable attn instruction */
|
||||
ulong _unused_32_63: 32;
|
||||
ulong en_mck: 1; /* En external machine check interrupts */
|
||||
ulong _unused_33_63: 31;
|
||||
} bits;
|
||||
ulong word;
|
||||
};
|
||||
@@ -62,11 +70,11 @@ union hid1 {
|
||||
ulong en_ic_rec: 1; /* i-cache parity error recovery */
|
||||
ulong en_id_rec: 1; /* i-dir parity error recovery */
|
||||
ulong en_er_rec: 1; /* i-ERAT parity error recovery */
|
||||
ulong ic_pe: 1;
|
||||
ulong icd0_pe: 1;
|
||||
ulong ic_pe: 1; /* Force instruction cache parity error */
|
||||
ulong icd0_pe: 1; /* Force insn cache dir 0 parity error */
|
||||
ulong _reserved_16: 1;
|
||||
ulong ier_pe: 1;
|
||||
ulong en_sp_itw: 1;
|
||||
ulong ier_pe: 1; /* force i-ERAT parity error (inject) */
|
||||
ulong en_sp_itw: 1; /* En speculative tablewalks */
|
||||
ulong _reserved_19_63: 45;
|
||||
} bits;
|
||||
ulong word;
|
||||
@@ -74,32 +82,61 @@ union hid1 {
|
||||
|
||||
union hid4 {
|
||||
struct hid4_bits {
|
||||
ulong lpes0: 1; /* LPAR Environment Selector bit 0 */
|
||||
ulong rmlr12: 2; /* RMLR 1:2 */
|
||||
ulong lpid25: 4; /* LPAR ID bits 2:5 */
|
||||
ulong rmor: 16; /* real mode offset region */
|
||||
ulong rm_ci: 1; /* real mode cache-inhibit */
|
||||
ulong force_ai: 1; /* Force alignment interrupt */
|
||||
ulong _unused: 32;
|
||||
ulong lpes1: 1; /* LPAR Environment Selector bit 1 */
|
||||
ulong rmlr0: 1; /* RMLR 0 */
|
||||
ulong lpes_0: 1; /* LPAR Environment Selector bit 0 */
|
||||
ulong rmlr_1_2: 2; /* RMLR 1:2 */
|
||||
ulong lpid_2_5: 4; /* LPAR ID bits 2:5 */
|
||||
ulong rmor_0_15: 16; /* real mode offset region */
|
||||
ulong rm_ci: 1; /* real mode cache-inhibit */
|
||||
ulong force_ai: 1; /* Force alignment interrupt */
|
||||
ulong dis_pref: 1; /* disable prefetching */
|
||||
ulong res_pref: 1; /* reset data prefetching mechanism */
|
||||
ulong en_sp_dtw: 1; /* enable speculative load tablewalk */
|
||||
ulong l1dc_flsh: 1; /* L1 cache flash invalidate */
|
||||
ulong dis_derpc: 2; /* Disable d-ERAT parity checking */
|
||||
ulong dis_derpg: 1; /* Disable d-ERAT parity generation */
|
||||
ulong dis_derat: 2; /* Disable d-ERAT */
|
||||
ulong dis_dctpc: 2; /* Dis data cache tag paritiy checking */
|
||||
ulong dis_dctpg: 1; /* Dis data cache tag paritiy generation */
|
||||
ulong dis_dcset: 2; /* Disable data cache set */
|
||||
ulong dis_dcpc: 2; /* Disable data cache paritiy checking */
|
||||
ulong dis_dcpg: 1; /* Disable data cache paritiy generation */
|
||||
ulong dis_dcrtpc: 2; /* Disable data cache real add tag parity */
|
||||
ulong dis_tlbpc: 4; /* Disable TLB paritiy checking */
|
||||
ulong dis_tlbpg: 1; /* Disable TLB paritiy generation */
|
||||
ulong dis_tlbset: 4; /* Disable TLB set */
|
||||
ulong dis_slbpc: 1; /* Disable SLB paritiy checking */
|
||||
ulong dis_slbpg: 1; /* Disable SLB paritiy generation */
|
||||
ulong mck_inj: 1; /* Machine check inject enable */
|
||||
ulong dis_stfwd: 1; /* Disbale store forwarding */
|
||||
ulong lpes_1: 1; /* LPAR Environment Selector bit 1 */
|
||||
ulong rmlr_0: 1; /* RMLR 0 */
|
||||
ulong _reserved: 1;
|
||||
ulong dis_splarx: 1; /* Disable spec. lwarx/ldarx */
|
||||
ulong lg_pg_dis: 1; /* Disable large page support */
|
||||
ulong lpid01: 2; /* LPAR ID bits 0:1 */
|
||||
ulong lpid_0_1: 2; /* LPAR ID bits 0:1 */
|
||||
} bits;
|
||||
ulong word;
|
||||
};
|
||||
|
||||
union hid5 {
|
||||
struct hid5_bits {
|
||||
ulong _reserved_0_31: 32;
|
||||
ulong hrmor: 16;
|
||||
ulong _reserver_48_49:2;
|
||||
ulong _unused_50_55: 6;
|
||||
ulong DCBZ_size: 1;
|
||||
ulong DCBZ32_ill: 1;
|
||||
ulong _unused_58_63: 6;
|
||||
ulong _reserved_0_31: 32;
|
||||
ulong hrmor_0_15: 16;
|
||||
ulong _reserved_48_49: 2;
|
||||
ulong DC_mck: 1; /* Machine check enabled for dcache errors */
|
||||
ulong dis_pwrsave: 1; /* Dis pwrsave on on L1 and d-ERAT */
|
||||
ulong force_G: 1; /* Force gaurded load */
|
||||
ulong DC_repl: 1; /* D-Cache replacement algo */
|
||||
ulong hwr_stms: 1; /* Number of available HW prefetch streams */
|
||||
ulong dst_noop: 1; /* D-stream Touch no-op */
|
||||
ulong DCBZ_size: 1; /* make dcbz size 32 bytes */
|
||||
ulong DCBZ32_ill: 1; /* make dzbz 32byte illeagal */
|
||||
ulong tlb_map: 1; /* TLB mapping */
|
||||
ulong lmq_port: 1; /* Demand miss (LMQ to STS) */
|
||||
ulong lmq_size_0: 1; /* number of outstanding req. to STS */
|
||||
ulong _reserved_61: 1;
|
||||
ulong tch_nop: 1; /* make dcbtand dcbtst ack like no-ops */
|
||||
ulong lmq_size_1: 1; /* second bit to lmq_size_0 */
|
||||
} bits;
|
||||
ulong word;
|
||||
};
|
||||
|
||||
@@ -138,6 +138,11 @@ static inline void mthid0(ulong val)
|
||||
__asm__ __volatile__ (
|
||||
"sync\n"
|
||||
"mtspr %0, %1\n"
|
||||
"mfspr %1, %0\n"
|
||||
"mfspr %1, %0\n"
|
||||
"mfspr %1, %0\n"
|
||||
"mfspr %1, %0\n"
|
||||
"mfspr %1, %0\n"
|
||||
"isync\n"
|
||||
: : "i"(SPRN_HID0), "r"(val));
|
||||
}
|
||||
@@ -153,6 +158,7 @@ static inline void mthid1(ulong val)
|
||||
__asm__ __volatile__ (
|
||||
"sync\n"
|
||||
"mtspr %0, %1\n"
|
||||
"mtspr %0, %1\n"
|
||||
"isync\n"
|
||||
: : "i"(SPRN_HID1), "r"(val));
|
||||
}
|
||||
@@ -189,5 +195,23 @@ static inline void mthid5(ulong val)
|
||||
: : "i"(SPRN_HID5), "r"(val));
|
||||
}
|
||||
|
||||
static inline void mthrmor(ulong val)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"sync\n"
|
||||
"mtspr %0, %1\n"
|
||||
"isync\n"
|
||||
: : "i"(SPRN_HRMOR), "r"(val));
|
||||
}
|
||||
|
||||
static inline void mthior(ulong val)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"sync\n"
|
||||
"mtspr %0, %1\n"
|
||||
"isync\n"
|
||||
: : "i"(SPRN_HIOR), "r"(val));
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif
|
||||
@@ -42,6 +42,7 @@ extern void show_execution_state(struct cpu_user_regs *);
|
||||
extern void show_backtrace(ulong sp, ulong lr, ulong pc);
|
||||
extern unsigned int cpu_extent_order(void);
|
||||
extern unsigned int cpu_default_rma_order_pages(void);
|
||||
extern int cpu_rma_valid(unsigned int log);
|
||||
extern uint cpu_large_page_orders(uint *sizes, uint max);
|
||||
extern void cpu_initialize(int cpuid);
|
||||
extern void cpu_init_vcpu(struct vcpu *);
|
||||
@@ -49,7 +50,11 @@ extern void save_cpu_sprs(struct vcpu *);
|
||||
extern void load_cpu_sprs(struct vcpu *);
|
||||
|
||||
/* XXX this could also land us in GDB */
|
||||
#define dump_execution_state() trap()
|
||||
#define dump_execution_state() BUG()
|
||||
|
||||
extern void __warn(char *file, int line);
|
||||
#define WARN() __warn(__FILE__, __LINE__)
|
||||
#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
|
||||
|
||||
#define ARCH_HAS_PREFETCH
|
||||
static inline void prefetch(const void *x) {;}
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
#define SPRN_HSPRG0 304
|
||||
#define SPRN_HSPRG1 305
|
||||
#define SPRN_HDEC 310
|
||||
#define SPRN_HIOR 311
|
||||
#define SPRN_RMOR 312
|
||||
#define SPRN_HRMOR 313
|
||||
#define SPRN_HSRR0 314
|
||||
|
||||
@@ -26,22 +26,11 @@
|
||||
#define shadow_mode_translate(_d) (1)
|
||||
#define shadow_mode_refcounts(_d) (1)
|
||||
|
||||
#define __translate_gpfn_to_mfn(_d, gpfn) \
|
||||
( (shadow_mode_translate(_d)) \
|
||||
? translate_gpfn_to_mfn(_d, gpfn) \
|
||||
: (gpfn) )
|
||||
|
||||
#define __mfn_to_gpfn(_d, mfn) \
|
||||
( (shadow_mode_translate(_d)) \
|
||||
? machine_to_phys_mapping[(mfn)] \
|
||||
: (mfn) )
|
||||
|
||||
static inline unsigned long
|
||||
translate_gpfn_to_mfn(struct domain *rd, unsigned long gpfn)
|
||||
{
|
||||
trap();
|
||||
return 0;
|
||||
}
|
||||
extern void guest_physmap_add_page(
|
||||
struct domain *d, unsigned long gpfn, unsigned long mfn);
|
||||
|
||||
@@ -64,7 +53,7 @@ extern unsigned int shadow_teardown(struct domain *d);
|
||||
extern unsigned int shadow_set_allocation(
|
||||
struct domain *d, unsigned int megabytes, int *preempted);
|
||||
|
||||
/* Return the size of the shadow pool, rounded up to the nearest MB */
|
||||
/* Return the size of the shadow2 pool, rounded up to the nearest MB */
|
||||
static inline unsigned int shadow_get_allocation(struct domain *d)
|
||||
{
|
||||
return (1ULL << (d->arch.htab.order + PAGE_SHIFT)) >> 20;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
extern int smp_num_siblings;
|
||||
|
||||
/* revisit when we support SMP */
|
||||
#define get_hard_smp_processor_id(i) i
|
||||
#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami)
|
||||
#define raw_smp_processor_id() (parea->whoami)
|
||||
#define hard_smp_processor_id() raw_smp_processor_id()
|
||||
extern cpumask_t cpu_sibling_map[];
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#define _ASM_SYSTEM_H_
|
||||
|
||||
#include <xen/config.h>
|
||||
#include <xen/lib.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/misc.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
|
||||
@@ -139,7 +139,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 2:
|
||||
trap(); return 0; /* XXX implement __cmpxchg_u16 ? */
|
||||
BUG(); return 0; /* XXX implement __cmpxchg_u16 ? */
|
||||
case 4:
|
||||
return __cmpxchg_u32(ptr, old, new);
|
||||
case 8:
|
||||
|
||||