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 | |
---|
16 | #include <xen/xen.h> |
---|
17 | #include <xen/foreign/ia64.h> |
---|
18 | |
---|
19 | #include "xg_private.h" |
---|
20 | #include "xc_dom.h" |
---|
21 | #include "xenctrl.h" |
---|
22 | |
---|
23 | /* ------------------------------------------------------------------------ */ |
---|
24 | |
---|
25 | static int alloc_magic_pages(struct xc_dom_image *dom) |
---|
26 | { |
---|
27 | /* allocate special pages */ |
---|
28 | dom->console_pfn = dom->total_pages -1; |
---|
29 | dom->xenstore_pfn = dom->total_pages -2; |
---|
30 | dom->start_info_pfn = dom->total_pages -3; |
---|
31 | return 0; |
---|
32 | } |
---|
33 | |
---|
34 | static int start_info_ia64(struct xc_dom_image *dom) |
---|
35 | { |
---|
36 | start_info_ia64_t *start_info = |
---|
37 | xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); |
---|
38 | struct xen_ia64_boot_param_ia64 *bp = |
---|
39 | (struct xen_ia64_boot_param_ia64 *)(start_info + 1); |
---|
40 | |
---|
41 | xc_dom_printf("%s\n", __FUNCTION__); |
---|
42 | |
---|
43 | memset(start_info, 0, sizeof(*start_info)); |
---|
44 | sprintf(start_info->magic, dom->guest_type); |
---|
45 | start_info->flags = dom->flags; |
---|
46 | start_info->nr_pages = dom->total_pages; |
---|
47 | start_info->store_mfn = dom->xenstore_pfn; |
---|
48 | start_info->store_evtchn = dom->xenstore_evtchn; |
---|
49 | start_info->console.domU.mfn = dom->console_pfn; |
---|
50 | start_info->console.domU.evtchn = dom->console_evtchn; |
---|
51 | |
---|
52 | if ( dom->ramdisk_blob ) |
---|
53 | { |
---|
54 | start_info->mod_start = dom->ramdisk_seg.vstart; |
---|
55 | start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; |
---|
56 | bp->initrd_start = start_info->mod_start; |
---|
57 | bp->initrd_size = start_info->mod_len; |
---|
58 | } |
---|
59 | bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64) |
---|
60 | + offsetof(start_info_t, cmd_line); |
---|
61 | if ( dom->cmdline ) |
---|
62 | { |
---|
63 | strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); |
---|
64 | start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; |
---|
65 | } |
---|
66 | return 0; |
---|
67 | } |
---|
68 | |
---|
69 | static int shared_info_ia64(struct xc_dom_image *dom, void *ptr) |
---|
70 | { |
---|
71 | shared_info_ia64_t *shared_info = ptr; |
---|
72 | int i; |
---|
73 | |
---|
74 | xc_dom_printf("%s: called\n", __FUNCTION__); |
---|
75 | |
---|
76 | memset(shared_info, 0, sizeof(*shared_info)); |
---|
77 | for (i = 0; i < MAX_VIRT_CPUS; i++) |
---|
78 | shared_info->vcpu_info[i].evtchn_upcall_mask = 1; |
---|
79 | shared_info->arch.start_info_pfn = dom->start_info_pfn; |
---|
80 | return 0; |
---|
81 | } |
---|
82 | |
---|
83 | extern unsigned long xc_ia64_fpsr_default(void); |
---|
84 | |
---|
85 | static int vcpu_ia64(struct xc_dom_image *dom, void *ptr) |
---|
86 | { |
---|
87 | vcpu_guest_context_ia64_t *ctxt = ptr; |
---|
88 | |
---|
89 | xc_dom_printf("%s: called\n", __FUNCTION__); |
---|
90 | |
---|
91 | /* clear everything */ |
---|
92 | memset(ctxt, 0, sizeof(*ctxt)); |
---|
93 | |
---|
94 | ctxt->flags = 0; |
---|
95 | ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ |
---|
96 | ctxt->user_regs.cr_iip = dom->parms.virt_entry; |
---|
97 | ctxt->user_regs.cr_ifs = (uint64_t) 1 << 63; |
---|
98 | #ifdef __ia64__ /* FIXME */ |
---|
99 | ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); |
---|
100 | #endif |
---|
101 | ctxt->user_regs.r28 = (dom->start_info_pfn << PAGE_SHIFT_IA64) |
---|
102 | + sizeof(start_info_ia64_t); |
---|
103 | return 0; |
---|
104 | } |
---|
105 | |
---|
106 | /* ------------------------------------------------------------------------ */ |
---|
107 | |
---|
108 | static struct xc_dom_arch xc_dom_arch = { |
---|
109 | .guest_type = "xen-3.0-ia64", |
---|
110 | .page_shift = PAGE_SHIFT_IA64, |
---|
111 | .alloc_magic_pages = alloc_magic_pages, |
---|
112 | .start_info = start_info_ia64, |
---|
113 | .shared_info = shared_info_ia64, |
---|
114 | .vcpu = vcpu_ia64, |
---|
115 | }; |
---|
116 | |
---|
117 | static struct xc_dom_arch xc_dom_arch_ia64be = { |
---|
118 | .guest_type = "xen-3.0-ia64be", |
---|
119 | .page_shift = PAGE_SHIFT_IA64, |
---|
120 | .alloc_magic_pages = alloc_magic_pages, |
---|
121 | .start_info = start_info_ia64, |
---|
122 | .shared_info = shared_info_ia64, |
---|
123 | .vcpu = vcpu_ia64, |
---|
124 | }; |
---|
125 | |
---|
126 | static void __init register_arch_hooks(void) |
---|
127 | { |
---|
128 | xc_dom_register_arch_hooks(&xc_dom_arch); |
---|
129 | xc_dom_register_arch_hooks(&xc_dom_arch_ia64be); |
---|
130 | } |
---|
131 | |
---|
132 | int arch_setup_meminit(struct xc_dom_image *dom) |
---|
133 | { |
---|
134 | xen_pfn_t pfn; |
---|
135 | int rc; |
---|
136 | |
---|
137 | /* setup initial p2m */ |
---|
138 | dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); |
---|
139 | for ( pfn = 0; pfn < dom->total_pages; pfn++ ) |
---|
140 | dom->p2m_host[pfn] = pfn; |
---|
141 | |
---|
142 | /* allocate guest memory */ |
---|
143 | rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, |
---|
144 | dom->total_pages, 0, 0, |
---|
145 | dom->p2m_host); |
---|
146 | return rc; |
---|
147 | } |
---|
148 | |
---|
149 | int arch_setup_bootearly(struct xc_dom_image *dom) |
---|
150 | { |
---|
151 | DECLARE_DOMCTL; |
---|
152 | int rc; |
---|
153 | |
---|
154 | xc_dom_printf("%s: setup firmware\n", __FUNCTION__); |
---|
155 | |
---|
156 | memset(&domctl, 0, sizeof(domctl)); |
---|
157 | domctl.cmd = XEN_DOMCTL_arch_setup; |
---|
158 | domctl.domain = dom->guest_domid; |
---|
159 | domctl.u.arch_setup.flags = 0; |
---|
160 | |
---|
161 | domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT) |
---|
162 | + sizeof(start_info_t); |
---|
163 | /* 3 = start info page, xenstore page and console page */ |
---|
164 | domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT; |
---|
165 | rc = do_domctl(dom->guest_xc, &domctl); |
---|
166 | return rc; |
---|
167 | } |
---|
168 | |
---|
169 | int arch_setup_bootlate(struct xc_dom_image *dom) |
---|
170 | { |
---|
171 | unsigned int page_size = XC_DOM_PAGE_SIZE(dom); |
---|
172 | shared_info_t *shared_info; |
---|
173 | |
---|
174 | /* setup shared_info page */ |
---|
175 | xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n", |
---|
176 | __FUNCTION__, dom->shared_info_mfn); |
---|
177 | shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, |
---|
178 | page_size, |
---|
179 | PROT_READ | PROT_WRITE, |
---|
180 | dom->shared_info_mfn); |
---|
181 | if ( shared_info == NULL ) |
---|
182 | return -1; |
---|
183 | dom->arch_hooks->shared_info(dom, shared_info); |
---|
184 | munmap(shared_info, page_size); |
---|
185 | return 0; |
---|
186 | } |
---|
187 | |
---|
188 | /* |
---|
189 | * Local variables: |
---|
190 | * mode: C |
---|
191 | * c-set-style: "BSD" |
---|
192 | * c-basic-offset: 4 |
---|
193 | * tab-width: 4 |
---|
194 | * indent-tabs-mode: nil |
---|
195 | * End: |
---|
196 | */ |
---|