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

📄 dom_fw_common.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Xen domain firmware emulation support *  Copyright (C) 2004 Hewlett-Packard Co. *       Dan Magenheimer (dan.magenheimer@hp.com) * * Copyright (c) 2006, 2007 *                    Isaku Yamahata <yamahata at valinux co jp> *                    VA Linux Systems Japan K.K. *                    dom0 vp model support */#ifdef __XEN__#include <asm/system.h>#include <asm/dom_fw_dom0.h>#include <asm/dom_fw_utils.h>#else#include <string.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <inttypes.h>#include <xen/xen.h>#include <asm/bundle.h>#include "xg_private.h"#include "xc_dom.h"#include "ia64/xc_dom_ia64_util.h"#define ia64_fc(addr)   asm volatile ("fc %0" :: "r"(addr) : "memory")#endif /* __XEN__ */#include <xen/acpi.h>#include <acpi/actables.h>#include <asm/dom_fw.h>#include <asm/dom_fw_domu.h>voidxen_ia64_efi_make_md(efi_memory_desc_t *md,		     uint32_t type, uint64_t attr, 		     uint64_t start, uint64_t end){	md->type = type;	md->pad = 0;	md->phys_addr = start;	md->virt_addr = 0;	md->num_pages = (end - start) >> EFI_PAGE_SHIFT;	md->attribute = attr;}#define EFI_HYPERCALL_PATCH(tgt, call)					\	do {								\		dom_efi_hypercall_patch(brkimm,				\					FW_HYPERCALL_##call##_PADDR,	\		                 FW_HYPERCALL_##call, hypercalls_imva);	\		/* Descriptor address.  */                              \		tables->efi_runtime.tgt =                               \		                    FW_FIELD_MPA(func_ptrs) + 8 * pfn;  \		/* Descriptor.  */                                      \		tables->func_ptrs[pfn++] = FW_HYPERCALL_##call##_PADDR;	\		tables->func_ptrs[pfn++] = 0;                     	\	} while (0)/**************************************************************************Hypercall bundle creation**************************************************************************/static voidbuild_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum, uint64_t ret){	INST64_A5 slot0;	INST64_I19 slot1;	INST64_B4 slot2;	IA64_BUNDLE bundle;	// slot1: mov r2 = hypnum (low 20 bits)	slot0.inst = 0;	slot0.qp = 0; slot0.r1 = 2; slot0.r3 = 0; slot0.major = 0x9;	slot0.imm7b = hypnum; slot0.imm9d = hypnum >> 7;	slot0.imm5c = hypnum >> 16; slot0.s = 0;	// slot1: break brkimm	slot1.inst = 0;	slot1.qp = 0; slot1.x6 = 0; slot1.x3 = 0; slot1.major = 0x0;	slot1.imm20 = brkimm; slot1.i = brkimm >> 20;	// if ret slot2:  br.ret.sptk.many rp	// else   slot2:  br.cond.sptk.many rp	slot2.inst = 0; slot2.qp = 0; slot2.p = 1; slot2.b2 = 0;	slot2.wh = 0; slot2.d = 0; slot2.major = 0x0;	if (ret) {		slot2.btype = 4; slot2.x6 = 0x21;	}	else {		slot2.btype = 0; slot2.x6 = 0x20;	}		bundle.i64[0] = 0; bundle.i64[1] = 0;	bundle.template = 0x11;	bundle.slot0 = slot0.inst; bundle.slot2 = slot2.inst;	bundle.slot1a = slot1.inst; bundle.slot1b = slot1.inst >> 18;		imva[0] = bundle.i64[0]; imva[1] = bundle.i64[1];	ia64_fc(imva);	ia64_fc(imva + 1);}static voidbuild_pal_hypercall_bundles(uint64_t *imva, uint64_t brkimm, uint64_t hypnum){	extern unsigned long xen_ia64_pal_call_stub[];	IA64_BUNDLE bundle;	INST64_A5 slot_a5;	INST64_M37 slot_m37;	/*	 * The source of the hypercall stub is	 * the xen_ia64_pal_call_stub function defined in dom_fw_asm.S. 	 */	/* Copy the first bundle and patch the hypercall number.  */	bundle.i64[0] = xen_ia64_pal_call_stub[0];	bundle.i64[1] = xen_ia64_pal_call_stub[1];	slot_a5.inst = bundle.slot0;	slot_a5.imm7b = hypnum;	slot_a5.imm9d = hypnum >> 7;	slot_a5.imm5c = hypnum >> 16;	bundle.slot0 = slot_a5.inst;	imva[0] = bundle.i64[0];	imva[1] = bundle.i64[1];	ia64_fc(imva);	ia64_fc(imva + 1);		/* Copy the second bundle and patch the hypercall vector.  */	bundle.i64[0] = xen_ia64_pal_call_stub[2];	bundle.i64[1] = xen_ia64_pal_call_stub[3];	slot_m37.inst = bundle.slot0;	slot_m37.imm20a = brkimm;	slot_m37.i = brkimm >> 20;	bundle.slot0 = slot_m37.inst;	imva[2] = bundle.i64[0];	imva[3] = bundle.i64[1];	ia64_fc(imva + 2);	ia64_fc(imva + 3);}// builds a hypercall bundle at domain physical addressstatic voiddom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long imva){	unsigned long *entry_imva, *patch_imva;	const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;	const unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;	entry_imva = (unsigned long *)(imva + entry_paddr -	                               FW_HYPERCALL_BASE_PADDR);	patch_imva = (unsigned long *)(imva + patch_paddr -	                               FW_HYPERCALL_BASE_PADDR);	/* Descriptor.  */	*entry_imva++ = patch_paddr;	*entry_imva   = 0;	build_hypercall_bundle(patch_imva, brkimm, FW_HYPERCALL_FPSWA, 1);}// builds a hypercall bundle at domain physical addressstatic voiddom_efi_hypercall_patch(uint64_t brkimm, unsigned long paddr,                        unsigned long hypercall, unsigned long imva){	build_hypercall_bundle((uint64_t *)(imva + paddr -			       FW_HYPERCALL_BASE_PADDR),			       brkimm, hypercall, 1);}// builds a hypercall bundle at domain physical addressstatic voiddom_fw_hypercall_patch(uint64_t brkimm, unsigned long paddr,		       unsigned long hypercall,unsigned long ret,                       unsigned long imva){	build_hypercall_bundle((uint64_t *)(imva + paddr -			       FW_HYPERCALL_BASE_PADDR),			       brkimm, hypercall, ret);}static voiddom_fw_pal_hypercall_patch(uint64_t brkimm, unsigned long paddr, unsigned long imva){	build_pal_hypercall_bundles((uint64_t*)(imva + paddr -	                            FW_HYPERCALL_BASE_PADDR),	                            brkimm, FW_HYPERCALL_PAL_CALL);}static inline voidprint_md(efi_memory_desc_t *md){	uint64_t size;		printk(XENLOG_INFO "dom mem: type=%2u, attr=0x%016lx, "	       "range=[0x%016lx-0x%016lx) ",	       md->type, md->attribute, md->phys_addr,	       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));	size = md->num_pages << EFI_PAGE_SHIFT;	if (size > ONE_MB)		printk("(%luMB)\n", size >> 20);	else		printk("(%luKB)\n", size >> 10);}struct fake_acpi_tables {	struct acpi_table_rsdp rsdp;	struct acpi_table_xsdt xsdt;	uint64_t madt_ptr;	struct acpi_table_fadt fadt;	struct acpi_table_facs facs;	struct acpi_table_header dsdt;	uint8_t aml[8 + 11 * MAX_VIRT_CPUS];	struct acpi_table_madt madt;	struct acpi_table_lsapic lsapic[MAX_VIRT_CPUS];	uint8_t pm1a_event_block[4];	uint8_t pm1a_control_block[1];	uint8_t pm_timer_block[4];};#define ACPI_TABLE_MPA(field)                                       \    FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);/* Create enough of an ACPI structure to make the guest OS ACPI happy. */voiddom_fw_fake_acpi(domain_t *d, struct fake_acpi_tables *tables){	struct acpi_table_rsdp *rsdp = &tables->rsdp;	struct acpi_table_xsdt *xsdt = &tables->xsdt;	struct acpi_table_fadt *fadt = &tables->fadt;	struct acpi_table_facs *facs = &tables->facs;	struct acpi_table_header *dsdt = &tables->dsdt;	struct acpi_table_madt *madt = &tables->madt;	struct acpi_table_lsapic *lsapic = tables->lsapic;	int i;	int aml_len;	int nbr_cpus;	BUILD_BUG_ON(sizeof(struct fake_acpi_tables) >	             (FW_ACPI_END_PADDR - FW_ACPI_BASE_PADDR));	memset(tables, 0, sizeof(struct fake_acpi_tables));	/* setup XSDT (64bit version of RSDT) */	memcpy(xsdt->header.signature, ACPI_SIG_XSDT,	       sizeof(xsdt->header.signature));	/* XSDT points to both the FADT and the MADT, so add one entry */	xsdt->header.length = sizeof(struct acpi_table_xsdt) + sizeof(uint64_t);	xsdt->header.revision = 1;	memcpy(xsdt->header.oem_id, "XEN", 3);	memcpy(xsdt->header.oem_table_id, "Xen/ia64", 8);	memcpy(xsdt->header.asl_compiler_id, "XEN", 3);	xsdt->header.asl_compiler_revision = xen_ia64_version(d);	xsdt->table_offset_entry[0] = ACPI_TABLE_MPA(fadt);	tables->madt_ptr = ACPI_TABLE_MPA(madt);	xsdt->header.checksum = -acpi_tb_checksum((u8*)xsdt,						  xsdt->header.length);	/* setup FADT */	memcpy(fadt->header.signature, ACPI_SIG_FADT,	       sizeof(fadt->header.signature));	fadt->header.length = sizeof(struct acpi_table_fadt);	fadt->header.revision = FADT2_REVISION_ID;	memcpy(fadt->header.oem_id, "XEN", 3);	memcpy(fadt->header.oem_table_id, "Xen/ia64", 8);	memcpy(fadt->header.asl_compiler_id, "XEN", 3);	fadt->header.asl_compiler_revision = xen_ia64_version(d);	memcpy(facs->signature, ACPI_SIG_FACS, sizeof(facs->signature));	facs->version = 1;	facs->length = sizeof(struct acpi_table_facs);	fadt->Xfacs = ACPI_TABLE_MPA(facs);	fadt->Xdsdt = ACPI_TABLE_MPA(dsdt);	/*	 * All of the below FADT entries are filled it to prevent warnings	 * from sanity checks in the ACPI CA.  Emulate required ACPI hardware	 * registers in system memory.

⌨️ 快捷键说明

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