source: trunk/packages/xen-3.1/xen-3.1/tools/libxc/xc_dom_powerpc.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 7.2 KB
Line 
1/*
2 * Xen domain builder -- powerpc bits.
3 *
4 * Most architecture-specific code for powerpc goes here.
5 *
6 * This code is licenced under the GPL.
7 * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
8 *
9 * Copyright IBM Corp. 2007
10 *
11 * Authors: Gerd Hoffmann <kraxel@suse.de>
12 *          Hollis Blanchard <hollisb@us.ibm.com>
13 *
14 */
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <inttypes.h>
19
20#include <xen/xen.h>
21
22#include "xg_private.h"
23#include "xc_dom.h"
24#include "powerpc64/flatdevtree.h"
25#include "powerpc64/mk_flatdevtree.h"
26
27#define RMA_LOG 26 /* 64 MB */
28#define EXTENT_LOG 24 /* 16 MB */
29#define EXTENT_ORDER (EXTENT_LOG - PAGE_SHIFT)
30
31/* ------------------------------------------------------------------------ */
32
33static int alloc_magic_pages(struct xc_dom_image *dom)
34{
35    struct ft_cxt devtree;
36    void *guest_devtree;
37    unsigned long shadow_mb;
38    int rma_pages;
39    int rc;
40
41    /* Allocate special pages from the end of the RMA. */
42    rma_pages = 1 << (dom->realmodearea_log - PAGE_SHIFT);
43    dom->shared_info_pfn = --rma_pages;
44    dom->console_pfn = --rma_pages;
45    dom->xenstore_pfn = --rma_pages;
46
47    /* Gather shadow allocation info for the device tree. */
48    rc = xc_shadow_control(dom->guest_xc, dom->guest_domid,
49                           XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION, NULL, 0, 
50                           &shadow_mb, 0, NULL);
51    if (rc < 0 || shadow_mb == 0) {
52        xc_dom_printf("Couldn't get shadow allocation size or it was 0.\n");
53        return rc;
54    }
55
56    /* Build device tree. */
57    rc = make_devtree(&devtree, dom, shadow_mb);
58    if (rc < 0) {
59        xc_dom_printf("Failed to create flattened device tree.\n");
60        return rc;
61    }
62
63    /* Find a spot for it. */
64    rc = xc_dom_alloc_segment(dom, &dom->devicetree_seg, "devtree", 0,
65                              devtree.bph->totalsize);
66    if (rc)
67        goto out;
68
69    /* Copy the device tree into place. */
70    guest_devtree = xc_dom_seg_to_ptr(dom, &dom->devicetree_seg);
71    if (!guest_devtree) {
72        xc_dom_printf("Couldn't map guest memory for device tree.\n");
73        rc = -1;
74        goto out;
75    }
76    memcpy(guest_devtree, devtree.bph, devtree.bph->totalsize);
77
78out:
79    free_devtree(&devtree);
80    return rc;
81}
82
83static int shared_info(struct xc_dom_image *dom, void *ptr)
84{
85    shared_info_t *shared_info = ptr;
86
87    xc_dom_printf("%s: called\n", __FUNCTION__);
88
89    memset(shared_info, 0, sizeof(*shared_info));
90    return 0;
91}
92
93static int vcpu(struct xc_dom_image *dom, void *ptr)
94{
95    vcpu_guest_context_t *ctxt = ptr;
96
97    memset(ctxt, 0x55, sizeof(*ctxt));
98    ctxt->user_regs.pc = dom->parms.virt_entry;
99    ctxt->user_regs.msr = 0;
100    ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */
101    ctxt->user_regs.gprs[3] = dom->devicetree_seg.pfn << PAGE_SHIFT;
102    ctxt->user_regs.gprs[4] = dom->kernel_seg.pfn << PAGE_SHIFT;
103    ctxt->user_regs.gprs[5] = 0;
104
105    /* There is a buggy kernel that does not zero the "local_paca", so
106     * we must make sure this register is 0 */
107    ctxt->user_regs.gprs[13] = 0;
108
109    xc_dom_printf("%s: initial vcpu:\n", __FUNCTION__);
110    xc_dom_printf("  pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
111                  "  r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
112                  " %016"PRIx64"\n",
113                  ctxt->user_regs.pc, ctxt->user_regs.msr,
114                  ctxt->user_regs.gprs[1],
115                  ctxt->user_regs.gprs[2],
116                  ctxt->user_regs.gprs[3],
117                  ctxt->user_regs.gprs[4],
118                  ctxt->user_regs.gprs[5]);
119
120    return 0;
121}
122
123/* ------------------------------------------------------------------------ */
124
125static struct xc_dom_arch xc_dom_arch = {
126    .guest_type = "xen-3.0-powerpc64",
127    .page_shift = PAGE_SHIFT,
128    .alloc_magic_pages = alloc_magic_pages,
129    .shared_info = shared_info,
130    .vcpu = vcpu,
131};
132
133static void __init register_arch_hooks(void)
134{
135    xc_dom_register_arch_hooks(&xc_dom_arch);
136}
137
138int arch_setup_meminit(struct xc_dom_image *dom)
139{
140    xen_pfn_t *extent_list;
141    unsigned long total_mem = dom->total_pages << PAGE_SHIFT;
142    unsigned long rma_bytes;
143    unsigned long rma_nr_pages;
144    unsigned long nr_extents;
145    int rc = 0;
146    int i;
147
148    /* XXX RMA size is processor-dependent. */
149    dom->realmodearea_log = RMA_LOG;
150    rma_bytes = 1 << dom->realmodearea_log;
151    rma_nr_pages = rma_bytes >> PAGE_SHIFT;
152
153    xc_dom_printf("dom%u memory: %lu MB RMA, %lu MB additional.\n",
154            dom->guest_domid, rma_bytes >> 20, (total_mem - rma_bytes) >> 20);
155
156    if (total_mem < rma_bytes) {
157        xc_dom_printf("Domain must have at least %lu MB\n", rma_bytes >> 20);
158        return -EINVAL;
159    }
160
161    /* Allocate the first chunk of memory. */
162    rc = xc_alloc_real_mode_area(dom->guest_xc, dom->guest_domid,
163                                 dom->realmodearea_log);
164    if (rc) {
165        xc_dom_printf("Failed to allocate real mode area.\n");
166        return rc;
167    }
168
169    /* Allocate p2m map. */
170    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
171    if (dom->p2m_host == NULL) {
172        xc_dom_printf("Couldn't allocate p2m map.\n");
173        return -ENOMEM;
174    }
175
176    nr_extents = (dom->total_pages - rma_nr_pages) >> EXTENT_ORDER;
177    if (nr_extents) {
178        /* Allocate extent list for populate_physmap() call. */
179        extent_list = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nr_extents);
180        if (extent_list == NULL) {
181            xc_dom_printf("Couldn't allocate extent list.\n");
182            return -ENOMEM;
183        }
184
185        /* Allocate the remaining (non-RMA) memory. */
186        for (i = 0; i < nr_extents; i++) {
187            /* Use PFNs above the RMA memory we already allocated. */
188            extent_list[i] = rma_nr_pages + i * (1<<EXTENT_ORDER);
189        }
190        rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
191                                               nr_extents, EXTENT_ORDER, 0,
192                                               extent_list);
193        if (rc < 0) {
194            xc_dom_printf("populate_physmap(0x%lx extents order %u) -> 0x%x\n",
195                          nr_extents, EXTENT_ORDER, rc);
196            return rc;
197        }
198    }
199
200    /* Populate the p2m map. */
201    rc = xc_get_pfn_list(dom->guest_xc, dom->guest_domid, dom->p2m_host,
202                         dom->total_pages);
203    if (rc < 0) {
204        xc_dom_printf("Couldn't get p2m translation.\n");
205        return rc;
206    }
207
208    xc_dom_printf("%s: success\n", __func__);
209
210    return 0;
211}
212
213int arch_setup_bootearly(struct xc_dom_image *dom)
214{
215    xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
216    return 0;
217}
218
219int arch_setup_bootlate(struct xc_dom_image *dom)
220{
221    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
222    shared_info_t *shared_info;
223
224    /* setup shared_info page */
225    xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n",
226                  __FUNCTION__, dom->shared_info_mfn);
227    shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
228                                       page_size,
229                                       PROT_READ | PROT_WRITE,
230                                       dom->shared_info_mfn);
231    if ( shared_info == NULL )
232        return -1;
233    dom->arch_hooks->shared_info(dom, shared_info);
234    munmap(shared_info, page_size);
235    return 0;
236}
Note: See TracBrowser for help on using the repository browser.