debuggers.hg

view tools/libxc/xc_dom_powerpc.c @ 16715:c5deb251b9dc

Update version to 3.2.0-rc4
author Keir Fraser <keir.fraser@citrix.com>
date Sat Dec 29 17:57:37 2007 +0000 (2007-12-29)
parents 2c087916aaba
children
line source
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>
20 #include <xen/xen.h>
22 #include "xg_private.h"
23 #include "xc_dom.h"
24 #include "powerpc64/flatdevtree.h"
25 #include "powerpc64/mk_flatdevtree.h"
27 #define RMA_LOG 26 /* 64 MB */
28 #define EXTENT_LOG 24 /* 16 MB */
29 #define EXTENT_ORDER (EXTENT_LOG - PAGE_SHIFT)
31 /* ------------------------------------------------------------------------ */
33 static 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;
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;
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 }
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 }
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;
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);
78 out:
79 free_devtree(&devtree);
80 return rc;
81 }
83 static int shared_info(struct xc_dom_image *dom, void *ptr)
84 {
85 shared_info_t *shared_info = ptr;
87 xc_dom_printf("%s: called\n", __FUNCTION__);
89 memset(shared_info, 0, sizeof(*shared_info));
90 return 0;
91 }
93 static int vcpu(struct xc_dom_image *dom, void *ptr)
94 {
95 vcpu_guest_context_t *ctxt = ptr;
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;
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;
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]);
120 return 0;
121 }
123 /* ------------------------------------------------------------------------ */
125 static 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 };
133 static void __init register_arch_hooks(void)
134 {
135 xc_dom_register_arch_hooks(&xc_dom_arch);
136 }
138 int 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;
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;
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);
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 }
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 }
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 }
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 }
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 }
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 }
208 xc_dom_printf("%s: success\n", __func__);
210 return 0;
211 }
213 int arch_setup_bootearly(struct xc_dom_image *dom)
214 {
215 xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
216 return 0;
217 }
219 int 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;
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 }