ia64/xen-unstable

annotate xen/arch/ia64/xen/dom_fw_domu.c @ 16785:af3550f53874

[IA64] domheap: Don't pin xenheap down. Now it's unnecessary.

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