ia64/xen-unstable

view xen/arch/ia64/xen/dom_fw_domu.c @ 17338:a8328ea7853d

ia64 build fix.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Mar 27 14:43:20 2008 +0000 (2008-03-27)
parents c0cdcebc0377
children 615ee2933137
line source
1 /******************************************************************************
2 *
3 * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
4 * VA Linux Systems Japan K.K.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21 /*
22 * Xen domain firmware emulation support
23 * Copyright (C) 2004 Hewlett-Packard Co.
24 * Dan Magenheimer (dan.magenheimer@hp.com)
25 */
27 #ifdef __XEN__
28 #include <xen/sched.h>
29 #include <asm/dom_fw_utils.h>
30 #include <linux/sort.h>
31 #define xen_ia64_dom_fw_map(d, mpaddr) domain_mpa_to_imva((d), (mpaddr))
32 #define xen_ia64_dom_fw_unmap(d, vaddr) do { } while (0)
33 #else
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <assert.h>
37 #include <errno.h>
38 #include <inttypes.h>
40 #include <xen/xen.h>
41 #include <xen/arch-ia64.h>
43 #include "xg_private.h"
44 #include "xc_dom.h"
45 #include "ia64/xc_dom_ia64_util.h"
46 #endif
48 #include <asm/dom_fw.h>
49 #include <asm/dom_fw_domu.h>
51 void efi_systable_init_domu(struct fw_tables *tables)
52 {
53 int i = 1;
55 printk(XENLOG_GUEST XENLOG_INFO "DomainU EFI build up:");
57 tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
58 tables->efi_tables[i].table = FW_ACPI_BASE_PADDR;
59 printk(" ACPI 2.0=0x%lx", tables->efi_tables[i].table);
60 i++;
61 printk("\n");
62 BUG_ON(i > NUM_EFI_SYS_TABLES);
63 }
65 int
66 complete_domu_memmap(domain_t * d,
67 struct fw_tables *tables,
68 unsigned long maxmem,
69 unsigned long memmap_info_pfn,
70 unsigned long memmap_info_num_pages)
71 {
72 efi_memory_desc_t *md;
73 int create_memmap = 0;
74 xen_ia64_memmap_info_t *memmap_info;
75 unsigned long memmap_info_size;
76 unsigned long paddr_start;
77 unsigned long paddr_end;
78 void *p;
79 void *memmap_start;
80 void *memmap_end;
82 if (memmap_info_pfn == 0 || memmap_info_num_pages == 0) {
83 /* old domain builder which doesn't setup
84 * memory map. create it for compatibility */
85 memmap_info_pfn = (maxmem >> PAGE_SHIFT) - 1;
86 memmap_info_num_pages = 1;
87 create_memmap = 1;
88 }
90 memmap_info_size = memmap_info_num_pages << PAGE_SHIFT;
91 paddr_start = memmap_info_pfn << PAGE_SHIFT;
92 /* 3 = start info page, xenstore page and console page */
93 paddr_end = paddr_start + memmap_info_size + 3 * PAGE_SIZE;
94 memmap_info = xen_ia64_dom_fw_map(d, paddr_start);
96 if (memmap_info->efi_memmap_size == 0) {
97 create_memmap = 1;
98 } else if (memmap_info->efi_memdesc_size != sizeof(md[0]) ||
99 memmap_info->efi_memdesc_version !=
100 EFI_MEMORY_DESCRIPTOR_VERSION) {
101 printk(XENLOG_WARNING
102 "%s: Warning: unknown memory map "
103 "memmap size %" PRIu64 " "
104 "memdesc size %" PRIu64 " "
105 "version %" PRIu32 "\n",
106 __func__,
107 memmap_info->efi_memmap_size,
108 memmap_info->efi_memdesc_size,
109 memmap_info->efi_memdesc_version);
110 create_memmap = 1;
111 } else if (memmap_info_size < memmap_info->efi_memmap_size) {
112 printk(XENLOG_WARNING
113 "%s: Warning: too short memmap info size %" PRIu64 "\n",
114 __func__, memmap_info_size);
115 xen_ia64_dom_fw_unmap(d, memmap_info);
116 return -EINVAL;
117 } else if (memmap_info->efi_memmap_size >
118 PAGE_SIZE - sizeof(*memmap_info)) {
119 /*
120 * curently memmap spanning more than single page isn't
121 * supported.
122 */
123 printk(XENLOG_WARNING
124 "%s: Warning: too large efi_memmap_size %" PRIu64 "\n",
125 __func__, memmap_info->efi_memmap_size);
126 xen_ia64_dom_fw_unmap(d, memmap_info);
127 return -ENOSYS;
128 }
130 if (create_memmap) {
131 /*
132 * old domain builder which doesn't setup
133 * memory map. create it for compatibility
134 */
135 memmap_info->efi_memdesc_size = sizeof(md[0]);
136 memmap_info->efi_memdesc_version =
137 EFI_MEMORY_DESCRIPTOR_VERSION;
138 memmap_info->efi_memmap_size = 1 * sizeof(md[0]);
140 md = (efi_memory_desc_t *) & memmap_info->memdesc;
141 md->type = EFI_CONVENTIONAL_MEMORY;
142 md->pad = 0;
143 md->phys_addr = 0;
144 md->virt_addr = 0;
145 md->num_pages = maxmem >> EFI_PAGE_SHIFT;
146 md->attribute = EFI_MEMORY_WB;
147 }
149 memmap_start = &memmap_info->memdesc;
150 memmap_end = memmap_start + memmap_info->efi_memmap_size;
152 /* XXX Currently the table must be in a single page. */
153 if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE) {
154 xen_ia64_dom_fw_unmap(d, memmap_info);
155 return -EINVAL;
156 }
158 /* sort it bofore use
159 * XXX: this is created by user space domain builder so that
160 * we should check its integrity */
161 sort(&memmap_info->memdesc,
162 memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
163 memmap_info->efi_memdesc_size, efi_mdt_cmp, NULL);
165 for (p = memmap_start; p < memmap_end;
166 p += memmap_info->efi_memdesc_size) {
167 unsigned long start;
168 unsigned long end;
170 md = p;
171 start = md->phys_addr;
172 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
174 if (start < tables->fw_end_paddr)
175 start = tables->fw_end_paddr;
176 if (end <= start)
177 continue;
179 /* exclude [paddr_start, paddr_end) */
180 if (paddr_end <= start || end <= paddr_start) {
181 xen_ia64_efi_make_md(&tables->
182 efi_memmap[tables->num_mds],
183 EFI_CONVENTIONAL_MEMORY,
184 EFI_MEMORY_WB, start, end);
185 tables->num_mds++;
186 } else if (paddr_start <= start && paddr_end < end) {
187 xen_ia64_efi_make_md(&tables->
188 efi_memmap[tables->num_mds],
189 EFI_CONVENTIONAL_MEMORY,
190 EFI_MEMORY_WB, paddr_end, end);
191 tables->num_mds++;
192 } else if (start < paddr_start && end <= paddr_end) {
193 xen_ia64_efi_make_md(&tables->
194 efi_memmap[tables->num_mds],
195 EFI_CONVENTIONAL_MEMORY,
196 EFI_MEMORY_WB, start, paddr_start);
197 tables->num_mds++;
198 } else {
199 xen_ia64_efi_make_md(&tables->
200 efi_memmap[tables->num_mds],
201 EFI_CONVENTIONAL_MEMORY,
202 EFI_MEMORY_WB, start, paddr_start);
203 tables->num_mds++;
204 xen_ia64_efi_make_md(&tables->
205 efi_memmap[tables->num_mds],
206 EFI_CONVENTIONAL_MEMORY,
207 EFI_MEMORY_WB, paddr_end, end);
208 tables->num_mds++;
209 }
210 }
212 /* memmap info page. */
213 xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
214 EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB,
215 paddr_start, paddr_end);
216 tables->num_mds++;
218 /* Create an entry for IO ports. */
219 xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
220 EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
221 IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
222 tables->num_mds++;
224 sort(tables->efi_memmap, tables->num_mds, sizeof(efi_memory_desc_t),
225 efi_mdt_cmp, NULL);
227 xen_ia64_dom_fw_unmap(d, memmap_info);
228 return tables->num_mds;
229 }
231 /*
232 * Local variables:
233 * mode: C
234 * c-set-style: "linux"
235 * c-basic-offset: 8
236 * tab-width: 8
237 * indent-tabs-mode: t
238 * End:
239 */