ia64/xen-unstable

view tools/libxc/xc_dom_ia64.c @ 16187:dc2ff26bbdf6

ia64: Fix ia64 PV domain creation with new vhpt-size parameter.
Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
author Keir Fraser <keir@xensource.com>
date Mon Oct 22 14:21:13 2007 +0100 (2007-10-22)
parents c5530fbbe9d0
children 031c8f407e01
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 static 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 static 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 < MAX_VIRT_CPUS; 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;
157 /* setup initial p2m */
158 dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
159 for ( pfn = 0; pfn < dom->total_pages; pfn++ )
160 dom->p2m_host[pfn] = pfn;
162 /* allocate guest memory */
163 rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
164 dom->total_pages, 0, 0,
165 dom->p2m_host);
166 return rc;
167 }
169 static int ia64_setup_memmap(struct xc_dom_image *dom)
170 {
171 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
172 unsigned long memmap_info_num_pages;
173 unsigned long memmap_info_pfn;
174 xen_ia64_memmap_info_t* memmap_info;
175 unsigned int num_mds;
176 efi_memory_desc_t *md;
178 char* start_info;
179 struct xen_ia64_boot_param* bp;
181 /* setup memmap page */
182 memmap_info_num_pages = 1;
183 memmap_info_pfn = dom->start_info_pfn - 1;
184 xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx\n",
185 __FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
186 memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
187 page_size * memmap_info_num_pages,
188 PROT_READ | PROT_WRITE,
189 memmap_info_pfn);
190 if (NULL == memmap_info)
191 return -1;
192 /* [0, total_pages) */
193 memmap_info->efi_memdesc_size = sizeof(md[0]);
194 memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
195 num_mds = 0;
196 md = (efi_memory_desc_t*)&memmap_info->memdesc;
197 md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
198 md[num_mds].pad = 0;
199 md[num_mds].phys_addr = 0;
200 md[num_mds].virt_addr = 0;
201 md[num_mds].num_pages = dom->total_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
202 md[num_mds].attribute = EFI_MEMORY_WB;
203 num_mds++;
204 memmap_info->efi_memmap_size = num_mds * sizeof(md[0]);
205 munmap(memmap_info, page_size * memmap_info_num_pages);
206 assert(num_mds <=
207 (page_size * memmap_info_num_pages -
208 offsetof(typeof(*memmap_info), memdesc))/sizeof(*md));
210 /*
211 * kludge: we need to pass memmap_info page's pfn and other magic pages
212 * somehow.
213 * we use xen_ia64_boot_param::efi_memmap::{efi_memmap, efi_memmap_size}
214 * for this purpose
215 */
216 start_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
217 page_size,
218 PROT_READ | PROT_WRITE,
219 dom->start_info_pfn);
220 if (NULL == start_info)
221 return -1;
222 bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t));
223 memset(bp, 0, sizeof(*bp));
224 XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = memmap_info_num_pages;
225 XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn;
226 munmap(start_info, page_size);
227 return 0;
228 }
230 int arch_setup_bootearly(struct xc_dom_image *dom)
231 {
232 DECLARE_DOMCTL;
233 int rc;
235 xc_dom_printf("%s: setup firmware\n", __FUNCTION__);
237 rc = ia64_setup_memmap(dom);
238 if (rc)
239 return rc;
241 memset(&domctl, 0, sizeof(domctl));
242 domctl.cmd = XEN_DOMCTL_arch_setup;
243 domctl.domain = dom->guest_domid;
244 domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;
245 rc = do_domctl(dom->guest_xc, &domctl);
246 if (rc)
247 return rc;
248 rc = xen_ia64_dom_fw_setup(dom, domctl.u.arch_setup.hypercall_imm,
249 (dom->start_info_pfn << PAGE_SHIFT) +
250 sizeof(start_info_t),
251 dom->total_pages << PAGE_SHIFT);
252 if (rc)
253 return rc;
255 memset(&domctl, 0, sizeof(domctl));
256 domctl.cmd = XEN_DOMCTL_arch_setup;
257 domctl.domain = dom->guest_domid;
258 domctl.u.arch_setup.flags = 0;
260 domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
261 + sizeof(start_info_t);
262 domctl.u.arch_setup.maxmem = dom->total_pages << PAGE_SHIFT;
263 domctl.u.arch_setup.vhpt_size_log2 = dom->vhpt_size_log2;
264 rc = do_domctl(dom->guest_xc, &domctl);
265 return rc;
266 }
268 int arch_setup_bootlate(struct xc_dom_image *dom)
269 {
270 unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
271 shared_info_t *shared_info;
273 /* setup shared_info page */
274 xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n",
275 __FUNCTION__, dom->shared_info_mfn);
276 shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
277 page_size,
278 PROT_READ | PROT_WRITE,
279 dom->shared_info_mfn);
280 if ( shared_info == NULL )
281 return -1;
282 dom->arch_hooks->shared_info(dom, shared_info);
283 munmap(shared_info, page_size);
284 return 0;
285 }
287 /*
288 * Local variables:
289 * mode: C
290 * c-set-style: "BSD"
291 * c-basic-offset: 4
292 * tab-width: 4
293 * indent-tabs-mode: nil
294 * End:
295 */