debuggers.hg

view tools/libxc/xc_dom_ia64.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 5333e6497af6
children 3ffdb094c2c0 779c0ef9682c
line source
1 /*
2 * Xen domain builder -- ia64 bits.
3 *
4 * Most architecture-specific code for ia64 goes here.
5 * - fill architecture-specific structs.
6 *
7 * This code is licenced under the GPL.
8 * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
9 *
10 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <inttypes.h>
15 #include <assert.h>
16 #include <asm/kregs.h>
18 #include <xen/xen.h>
19 #include <xen/foreign/ia64.h>
20 #include <xen/io/protocols.h>
22 #include "xg_private.h"
23 #include "xc_dom.h"
24 #include "xenctrl.h"
26 #include <asm/dom_fw_common.h>
27 #include "ia64/xc_dom_ia64_util.h"
29 /* ------------------------------------------------------------------------ */
31 static int alloc_magic_pages(struct xc_dom_image *dom)
32 {
33 /* allocate special pages */
34 dom->console_pfn = dom->total_pages -1;
35 dom->xenstore_pfn = dom->total_pages -2;
36 dom->start_info_pfn = dom->total_pages -3;
37 return 0;
38 }
40 int start_info_ia64(struct xc_dom_image *dom)
41 {
42 start_info_ia64_t *start_info =
43 xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
44 struct xen_ia64_boot_param_ia64 *bp =
45 (struct xen_ia64_boot_param_ia64 *)(start_info + 1);
47 xc_dom_printf("%s\n", __FUNCTION__);
49 memset(start_info, 0, sizeof(*start_info));
50 sprintf(start_info->magic, dom->guest_type);
51 start_info->flags = dom->flags;
52 start_info->nr_pages = dom->total_pages;
53 start_info->store_mfn = dom->xenstore_pfn;
54 start_info->store_evtchn = dom->xenstore_evtchn;
55 start_info->console.domU.mfn = dom->console_pfn;
56 start_info->console.domU.evtchn = dom->console_evtchn;
58 /*
59 * domain_start and domain_size are abused for arch_setup hypercall
60 * so that we need to clear them here.
61 */
62 XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = 0;
63 XEN_IA64_MEMMAP_INFO_PFN(bp) = 0;
65 if ( dom->ramdisk_blob )
66 {
67 start_info->mod_start = dom->ramdisk_seg.vstart;
68 start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
69 bp->initrd_start = start_info->mod_start;
70 bp->initrd_size = start_info->mod_len;
71 }
72 bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64)
73 + offsetof(start_info_t, cmd_line);
74 if ( dom->cmdline )
75 {
76 strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
77 start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0';
78 }
79 return 0;
80 }
82 int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
83 {
84 shared_info_ia64_t *shared_info = ptr;
85 int i;
87 xc_dom_printf("%s: called\n", __FUNCTION__);
89 memset(shared_info, 0, sizeof(*shared_info));
90 for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++)
91 shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
92 shared_info->arch.start_info_pfn = dom->start_info_pfn;
93 shared_info->arch.memmap_info_num_pages = 1; //XXX
94 shared_info->arch.memmap_info_pfn = dom->start_info_pfn - 1;
95 return 0;
96 }
98 extern unsigned long xc_ia64_fpsr_default(void);
100 static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
101 {
102 vcpu_guest_context_ia64_t *ctxt = ptr;
104 xc_dom_printf("%s: called\n", __FUNCTION__);
106 /* clear everything */
107 memset(ctxt, 0, sizeof(*ctxt));
109 ctxt->flags = 0;
110 /* PSR is set according to SAL 3.2.4: AC, IC and BN are set. */
111 ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_IC | IA64_PSR_BN;
112 ctxt->regs.ip = dom->parms.virt_entry;
113 ctxt->regs.cfm = 1UL << 63;
114 #ifdef __ia64__ /* FIXME */
115 ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();
116 #endif
117 ctxt->regs.r[28] = (dom->start_info_pfn << PAGE_SHIFT_IA64)
118 + sizeof(start_info_ia64_t);
119 return 0;
120 }
122 /* ------------------------------------------------------------------------ */
124 static struct xc_dom_arch xc_dom_arch = {
125 .guest_type = "xen-3.0-ia64",
126 .native_protocol = XEN_IO_PROTO_ABI_IA64,
127 .page_shift = PAGE_SHIFT_IA64,
128 .alloc_magic_pages = alloc_magic_pages,
129 .start_info = start_info_ia64,
130 .shared_info = shared_info_ia64,
131 .vcpu = vcpu_ia64,
132 };
134 static struct xc_dom_arch xc_dom_arch_ia64be = {
135 .guest_type = "xen-3.0-ia64be",
136 .native_protocol = XEN_IO_PROTO_ABI_IA64,
137 .page_shift = PAGE_SHIFT_IA64,
138 .alloc_magic_pages = alloc_magic_pages,
139 .start_info = start_info_ia64,
140 .shared_info = shared_info_ia64,
141 .vcpu = vcpu_ia64,
142 };
144 static void __init register_arch_hooks(void)
145 {
146 xc_dom_register_arch_hooks(&xc_dom_arch);
147 xc_dom_register_arch_hooks(&xc_dom_arch_ia64be);
148 }
150 #include "xc_efi.h"
152 int arch_setup_meminit(struct xc_dom_image *dom)
153 {
154 xen_pfn_t pfn;
155 int rc;
156 unsigned long start;
157 unsigned long nbr;
159 /* setup initial p2m */
160 if (dom->guest_type && strcmp(dom->guest_type,
161 "hvm-3.0-ia64-sioemu") == 0) {
162 start = FW_MEM_BASE >> PAGE_SHIFT_IA64;
163 nbr = FW_MEM_SIZE >> PAGE_SHIFT_IA64;
164 } else {
165 start = 0;
166 nbr = dom->total_pages;
167 }
169 /* setup initial p2m */
170 dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr);
171 for ( pfn = 0; pfn < nbr; pfn++ )
172 dom->p2m_host[pfn] = start + pfn;
174 /* allocate guest memory */
175 rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
176 nbr, 0, 0,
177 dom->p2m_host);
178 return rc;
179 }
181 static int ia64_setup_memmap(struct xc_dom_image *dom)
182 {
183 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
184 unsigned long memmap_info_num_pages;
185 unsigned long memmap_info_pfn;
186 xen_ia64_memmap_info_t* memmap_info;
187 unsigned int num_mds;
188 efi_memory_desc_t *md;
190 char* start_info;
191 struct xen_ia64_boot_param* bp;
193 /* setup memmap page */
194 memmap_info_num_pages = 1;
195 memmap_info_pfn = dom->start_info_pfn - 1;
196 xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx\n",
197 __FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
198 memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
199 page_size * memmap_info_num_pages,
200 PROT_READ | PROT_WRITE,
201 memmap_info_pfn);
202 if (NULL == memmap_info)
203 return -1;
204 /* [0, total_pages) */
205 memmap_info->efi_memdesc_size = sizeof(md[0]);
206 memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
207 num_mds = 0;
208 md = (efi_memory_desc_t*)&memmap_info->memdesc;
209 md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
210 md[num_mds].pad = 0;
211 md[num_mds].phys_addr = 0;
212 md[num_mds].virt_addr = 0;
213 md[num_mds].num_pages = dom->total_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
214 md[num_mds].attribute = EFI_MEMORY_WB;
215 num_mds++;
216 memmap_info->efi_memmap_size = num_mds * sizeof(md[0]);
217 munmap(memmap_info, page_size * memmap_info_num_pages);
218 assert(num_mds <=
219 (page_size * memmap_info_num_pages -
220 offsetof(typeof(*memmap_info), memdesc))/sizeof(*md));
222 /*
223 * kludge: we need to pass memmap_info page's pfn and other magic pages
224 * somehow.
225 * we use xen_ia64_boot_param::efi_memmap::{efi_memmap, efi_memmap_size}
226 * for this purpose
227 */
228 start_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
229 page_size,
230 PROT_READ | PROT_WRITE,
231 dom->start_info_pfn);
232 if (NULL == start_info)
233 return -1;
234 bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t));
235 memset(bp, 0, sizeof(*bp));
236 XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = memmap_info_num_pages;
237 XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn;
238 munmap(start_info, page_size);
239 return 0;
240 }
242 int arch_setup_bootearly(struct xc_dom_image *dom)
243 {
244 DECLARE_DOMCTL;
245 int rc;
247 xc_dom_printf("%s: setup firmware for %s\n", __FUNCTION__, dom->guest_type);
249 if (dom->guest_type && strcmp(dom->guest_type,
250 "hvm-3.0-ia64-sioemu") == 0) {
251 memset(&domctl, 0, sizeof(domctl));
252 domctl.u.arch_setup.flags = XEN_DOMAINSETUP_sioemu_guest;
253 domctl.u.arch_setup.bp = 0;
254 domctl.u.arch_setup.maxmem = 0;
255 domctl.cmd = XEN_DOMCTL_arch_setup;
256 domctl.domain = dom->guest_domid;
257 rc = xc_domctl(dom->guest_xc, &domctl);
258 xc_dom_printf("%s: hvm-3.0-ia64-sioemu: %d\n", __FUNCTION__, rc);
259 return rc;
260 }
262 rc = ia64_setup_memmap(dom);
263 if (rc)
264 return rc;
266 memset(&domctl, 0, sizeof(domctl));
267 domctl.cmd = XEN_DOMCTL_arch_setup;
268 domctl.domain = dom->guest_domid;
269 domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;
270 rc = do_domctl(dom->guest_xc, &domctl);
271 if (rc)
272 return rc;
273 rc = xen_ia64_dom_fw_setup(dom, domctl.u.arch_setup.hypercall_imm,
274 (dom->start_info_pfn << PAGE_SHIFT) +
275 sizeof(start_info_t),
276 dom->total_pages << PAGE_SHIFT);
277 if (rc)
278 return rc;
280 memset(&domctl, 0, sizeof(domctl));
281 domctl.cmd = XEN_DOMCTL_arch_setup;
282 domctl.domain = dom->guest_domid;
283 domctl.u.arch_setup.flags = 0;
285 domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
286 + sizeof(start_info_t);
287 domctl.u.arch_setup.maxmem = dom->total_pages << PAGE_SHIFT;
288 domctl.u.arch_setup.vhpt_size_log2 = dom->vhpt_size_log2;
289 rc = do_domctl(dom->guest_xc, &domctl);
290 return rc;
291 }
293 int arch_setup_bootlate(struct xc_dom_image *dom)
294 {
295 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
296 shared_info_t *shared_info;
298 /* setup shared_info page */
299 xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n",
300 __FUNCTION__, dom->shared_info_mfn);
301 shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
302 page_size,
303 PROT_READ | PROT_WRITE,
304 dom->shared_info_mfn);
305 if ( shared_info == NULL )
306 return -1;
307 dom->arch_hooks->shared_info(dom, shared_info);
308 munmap(shared_info, page_size);
309 return 0;
310 }
312 /*
313 * Local variables:
314 * mode: C
315 * c-set-style: "BSD"
316 * c-basic-offset: 4
317 * tab-width: 4
318 * indent-tabs-mode: nil
319 * End:
320 */