⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dom_fw_dom0.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> *                    VA Linux Systems Japan K.K. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *//* *  Xen domain firmware emulation support *  Copyright (C) 2004 Hewlett-Packard Co. *       Dan Magenheimer (dan.magenheimer@hp.com) */#include <xen/config.h>#include <xen/errno.h>#include <xen/sched.h>#include <xen/list.h>#include <xen/acpi.h>#include <acpi/actables.h>#include <asm/dom_fw.h>#include <asm/dom_fw_common.h>#include <asm/dom_fw_dom0.h>#include <asm/dom_fw_utils.h>#include <linux/sort.h>struct acpi_backup_table_entry {	struct list_head list;	unsigned long pa;	unsigned long size;	unsigned char data[0];};static LIST_HEAD(acpi_backup_table_list);static u32 lsapic_nbr;/* Modify lsapic table.  Provides LPs.  */static int __initacpi_update_lsapic(struct acpi_subtable_header * header, const unsigned long end){	struct acpi_table_lsapic *lsapic;	int enable;	lsapic = (struct acpi_table_lsapic *)header;	if (!lsapic)		return -EINVAL;	if (lsapic_nbr < MAX_VIRT_CPUS && dom0->vcpu[lsapic_nbr] != NULL)		enable = 1;	else		enable = 0;	if (lsapic->flags.enabled && enable) {		printk("enable lsapic entry: 0x%lx\n", (u64) lsapic);		lsapic->id = lsapic_nbr;		lsapic->eid = 0;		lsapic_nbr++;	} else if (lsapic->flags.enabled) {		printk("DISABLE lsapic entry: 0x%lx\n", (u64) lsapic);		lsapic->flags.enabled = 0;		lsapic->id = 0;		lsapic->eid = 0;	}	return 0;}static int __initacpi_patch_plat_int_src(struct acpi_subtable_header * header,			const unsigned long end){	struct acpi_table_plat_int_src *plintsrc;	plintsrc = (struct acpi_table_plat_int_src *)header;	if (!plintsrc)		return -EINVAL;	if (plintsrc->type == ACPI_INTERRUPT_CPEI) {		printk("ACPI_INTERRUPT_CPEI disabled for Domain0\n");		plintsrc->type = -1;	}	return 0;}static int __initacpi_update_madt_checksum(struct acpi_table_header *table){	struct acpi_table_madt *acpi_madt;	if (!table)		return -EINVAL;	acpi_madt = (struct acpi_table_madt *)table;	acpi_madt->header.checksum = 0;	acpi_madt->header.checksum = -acpi_tb_checksum((u8*)acpi_madt,						       table->length);	return 0;}static int __initacpi_backup_table(struct acpi_table_header *table){	struct acpi_backup_table_entry *entry;	entry = xmalloc_bytes(sizeof(*entry) + table->length);	if (!entry) {		dprintk(XENLOG_WARNING, "Failed to allocate memory for "		        "%.4s table backup\n", table->signature);		return -ENOMEM;	}	entry->pa = __pa(table);	entry->size = table->length;	memcpy(entry->data, table, table->length);	list_add(&entry->list, &acpi_backup_table_list);	printk(XENLOG_INFO "Backup %.4s table stored @0x%p\n",	       table->signature, entry->data);	return 0;}voidacpi_restore_tables(){	struct acpi_backup_table_entry *entry;	list_for_each_entry(entry, &acpi_backup_table_list, list) {		printk(XENLOG_INFO "Restoring backup %.4s table @0x%p\n",		       ((struct acpi_table_header *)entry->data)->signature,		       entry->data);		memcpy(__va(entry->pa), entry->data, entry->size);		/* Only called from kexec path, no need to free entries */	}}static int __init __acpi_table_disable(struct acpi_table_header *header){	printk("Disabling ACPI table: %4.4s\n", header->signature);	memcpy(header->oem_id, "xxxxxx", 6);	memcpy(header->oem_id+1, header->signature, 4);	memcpy(header->oem_table_id, "Xen     ", 8);	memcpy(header->signature, "OEMx", 4);	header->checksum = 0;	header->checksum = -acpi_tb_checksum((u8*)header, header->length);	return 0;}static void __init acpi_table_disable(char *id){	acpi_table_parse(id, __acpi_table_disable);}/* base is physical address of acpi table */static void __init touch_acpi_table(void){	struct acpi_table_header *madt = NULL;	lsapic_nbr = 0;	acpi_get_table(ACPI_SIG_MADT, 0, &madt);	/*	 * Modify dom0 MADT:	 *  - Disable CPUs that would exceed max vCPUs for the domain	 *  - Virtualize id/eid for indexing into domain vCPU array	 *  - Hide CPEI interrupt source	 *	 * ACPI tables must be backed-up before modification!	 *	 * We update the checksum each time we modify to keep the	 * ACPI CA from warning about invalid checksums.	 */	acpi_table_parse(ACPI_SIG_MADT, acpi_backup_table);	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)		printk("Error parsing MADT - no LAPIC entries\n");	acpi_update_madt_checksum(madt);	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,				  acpi_patch_plat_int_src, 0) < 0)		printk("Error parsing MADT - no PLAT_INT_SRC entries\n");	acpi_update_madt_checksum(madt);	/*	 * SRAT & SLIT tables aren't useful for Dom0 until	 * we support more NUMA configuration information in Xen.	 *	 * NB - backup ACPI tables first.	 */	acpi_table_parse(ACPI_SIG_SRAT, acpi_backup_table);	acpi_table_parse(ACPI_SIG_SLIT, acpi_backup_table);	acpi_table_disable(ACPI_SIG_SRAT);	acpi_table_disable(ACPI_SIG_SLIT);	return;}void __init efi_systable_init_dom0(struct fw_tables *tables){	int i = 1;	touch_acpi_table();	/* Write messages to the console.  */	printk("Domain0 EFI passthrough:");	if (efi.mps != EFI_INVALID_TABLE_ADDR) {		tables->efi_tables[i].guid = MPS_TABLE_GUID;		tables->efi_tables[i].table = efi.mps;		printk(" MPS=0x%lx", tables->efi_tables[i].table);		i++;	}	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) {		tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;		tables->efi_tables[i].table = efi.acpi20;		printk(" ACPI 2.0=0x%lx", tables->efi_tables[i].table);		i++;	}	if (efi.acpi != EFI_INVALID_TABLE_ADDR) {		tables->efi_tables[i].guid = ACPI_TABLE_GUID;		tables->efi_tables[i].table = efi.acpi;		printk(" ACPI=0x%lx", tables->efi_tables[i].table);		i++;	}	if (efi.smbios != EFI_INVALID_TABLE_ADDR) {		tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;		tables->efi_tables[i].table = efi.smbios;		printk(" SMBIOS=0x%lx", tables->efi_tables[i].table);		i++;	}	if (efi.hcdp != EFI_INVALID_TABLE_ADDR) {		tables->efi_tables[i].guid = HCDP_TABLE_GUID;		tables->efi_tables[i].table = efi.hcdp;		printk(" HCDP=0x%lx", tables->efi_tables[i].table);		i++;	}	printk("\n");	BUG_ON(i > NUM_EFI_SYS_TABLES);}static void __initsetup_dom0_memmap_info(struct domain *d, struct fw_tables *tables){	int i;	size_t size;	unsigned int num_pages;	efi_memory_desc_t *md;	efi_memory_desc_t *last_mem_md = NULL;	xen_ia64_memmap_info_t *memmap_info;	unsigned long paddr_start;	unsigned long paddr_end;	size = sizeof(*memmap_info) +		(tables->num_mds + 1) * sizeof(tables->efi_memmap[0]);	num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;	for (i = tables->num_mds - 1; i >= 0; i--) {		md = &tables->efi_memmap[i];		if (md->attribute == EFI_MEMORY_WB &&		    md->type == EFI_CONVENTIONAL_MEMORY &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -