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

📄 efi.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef XENstatic void__efi_unmap_pal_code (void *pal_vaddr){	ia64_ptr(0x1, GRANULEROUNDDOWN((unsigned long)pal_vaddr),		 IA64_GRANULE_SHIFT);}voidefi_unmap_pal_code (void){	void *pal_vaddr = efi_get_pal_addr ();	u64 psr;	if (!pal_vaddr)		return;	/*	 * Cannot write to CRx with PSR.ic=1	 */	psr = ia64_clear_ic();	__efi_unmap_pal_code(pal_vaddr);	ia64_set_psr(psr);		/* restore psr */	ia64_srlz_i();}#endifvoidefi_map_pal_code (void){	void *pal_vaddr = efi_get_pal_addr ();	u64 psr;	if (!pal_vaddr)		return;	/*	 * Cannot write to CRx with PSR.ic=1	 */	psr = ia64_clear_ic();#ifdef XEN	/* pal_vaddr must be unpinned before pinning	 * This is needed in the case of a nested EFI, PAL or SAL call */	__efi_unmap_pal_code(pal_vaddr);#endif	ia64_itr(0x1, IA64_TR_PALCODE, GRANULEROUNDDOWN((unsigned long) pal_vaddr),		 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),		 IA64_GRANULE_SHIFT);	ia64_set_psr(psr);		/* restore psr */	ia64_srlz_i();}void __initefi_init (void){	void *efi_map_start, *efi_map_end;	efi_config_table_t *config_tables;	efi_char16_t *c16;	u64 efi_desc_size;	char *cp, vendor[100] = "unknown";	int i;	/* it's too early to be able to use the standard kernel command line support... */#ifdef XEN	extern char saved_command_line[];	for (cp = saved_command_line; *cp; ) {#else	for (cp = boot_command_line; *cp; ) {#endif		if (memcmp(cp, "mem=", 4) == 0) {			mem_limit = memparse(cp + 4, &cp);		} else if (memcmp(cp, "max_addr=", 9) == 0) {			max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));		} else if (memcmp(cp, "min_addr=", 9) == 0) {			min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));		} else {			while (*cp != ' ' && *cp)				++cp;			while (*cp == ' ')				++cp;		}	}	if (min_addr != 0UL)		printk(KERN_INFO "Ignoring memory below %luMB\n", min_addr >> 20);	if (max_addr != ~0UL)		printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20);	efi.systab = __va(ia64_boot_param->efi_systab);	/*	 * Verify the EFI Table	 */	if (efi.systab == NULL)		panic("Woah! Can't find EFI system table.\n");	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)		panic("Woah! EFI system table signature incorrect\n");	if ((efi.systab->hdr.revision >> 16) == 0)		printk(KERN_WARNING "Warning: EFI system table version "		       "%d.%02d, expected 1.00 or greater\n",		       efi.systab->hdr.revision >> 16,		       efi.systab->hdr.revision & 0xffff);	config_tables = __va(efi.systab->tables);	/* Show what we know for posterity */	c16 = __va(efi.systab->fw_vendor);	if (c16) {		for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i)			vendor[i] = *c16++;		vendor[i] = '\0';	}	printk(KERN_INFO "EFI v%u.%.02u by %s:",	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);	efi.mps        = EFI_INVALID_TABLE_ADDR;	efi.acpi       = EFI_INVALID_TABLE_ADDR;	efi.acpi20     = EFI_INVALID_TABLE_ADDR;	efi.smbios     = EFI_INVALID_TABLE_ADDR;	efi.sal_systab = EFI_INVALID_TABLE_ADDR;	efi.boot_info  = EFI_INVALID_TABLE_ADDR;	efi.hcdp       = EFI_INVALID_TABLE_ADDR;	efi.uga        = EFI_INVALID_TABLE_ADDR;	for (i = 0; i < (int) efi.systab->nr_tables; i++) {		if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {			efi.mps = config_tables[i].table;			printk(" MPS=0x%lx", config_tables[i].table);		} else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {			efi.acpi20 = config_tables[i].table;			printk(" ACPI 2.0=0x%lx", config_tables[i].table);		} else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {			efi.acpi = config_tables[i].table;			printk(" ACPI=0x%lx", config_tables[i].table);		} else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {			efi.smbios = config_tables[i].table;			printk(" SMBIOS=0x%lx", config_tables[i].table);		} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {			efi.sal_systab = config_tables[i].table;			printk(" SALsystab=0x%lx", config_tables[i].table);		} else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {			efi.hcdp = config_tables[i].table;			printk(" HCDP=0x%lx", config_tables[i].table);		}	}	printk("\n");	runtime = __va(efi.systab->runtime);	efi.get_time = phys_get_time;	efi.set_time = phys_set_time;	efi.get_wakeup_time = phys_get_wakeup_time;	efi.set_wakeup_time = phys_set_wakeup_time;	efi.get_variable = phys_get_variable;	efi.get_next_variable = phys_get_next_variable;	efi.set_variable = phys_set_variable;	efi.get_next_high_mono_count = phys_get_next_high_mono_count;	efi.reset_system = phys_reset_system;	efi_map_start = __va(ia64_boot_param->efi_memmap);	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;	efi_desc_size = ia64_boot_param->efi_memdesc_size;#if EFI_DEBUG	/* print EFI memory map: */	{		efi_memory_desc_t *md;		void *p;		for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {			md = p;			printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",			       i, md->type, md->attribute, md->phys_addr,			       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),			       md->num_pages >> (20 - EFI_PAGE_SHIFT));		}	}#endif#ifndef XEN	efi_map_pal_code();#endif	efi_enter_virtual_mode();}voidefi_enter_virtual_mode (void){	void *efi_map_start, *efi_map_end, *p;	efi_memory_desc_t *md;	efi_status_t status;	u64 efi_desc_size;	efi_map_start = __va(ia64_boot_param->efi_memmap);	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;	efi_desc_size = ia64_boot_param->efi_memdesc_size;	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {		md = p;#ifdef XEN		if (md->attribute & EFI_MEMORY_RUNTIME) {			if (md->attribute & EFI_MEMORY_WB)				md->virt_addr = __IA64_EFI_CACHED_OFFSET|						md->phys_addr;			else if (md->attribute & (EFI_MEMORY_UC|EFI_MEMORY_WC|						  EFI_MEMORY_WT))				md->virt_addr = __IA64_EFI_UNCACHED_OFFSET|						md->phys_addr;		}#else		if (md->attribute & EFI_MEMORY_RUNTIME) {			/*			 * Some descriptors have multiple bits set, so the order of			 * the tests is relevant.			 */			if (md->attribute & EFI_MEMORY_WB) {				md->virt_addr = (u64) __va(md->phys_addr);			} else if (md->attribute & EFI_MEMORY_UC) {				md->virt_addr = (u64) ioremap(md->phys_addr, 0);			} else if (md->attribute & EFI_MEMORY_WC) {#if 0				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P									   | _PAGE_D									   | _PAGE_MA_WC									   | _PAGE_PL_0									   | _PAGE_AR_RW));#else				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");				md->virt_addr = (u64) ioremap(md->phys_addr, 0);#endif			} else if (md->attribute & EFI_MEMORY_WT) {#if 0				md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P									   | _PAGE_D | _PAGE_MA_WT									   | _PAGE_PL_0									   | _PAGE_AR_RW));#else				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");				md->virt_addr = (u64) ioremap(md->phys_addr, 0);#endif			}		}#endif	}	status = efi_call_phys(__va(runtime->set_virtual_address_map),			       ia64_boot_param->efi_memmap_size,			       efi_desc_size, ia64_boot_param->efi_memdesc_version,			       ia64_boot_param->efi_memmap);	if (status != EFI_SUCCESS) {		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode "		       "(status=%lu)\n", status);		return;	}	/*	 * Now that EFI is in virtual mode, we call the EFI functions more efficiently:	 */	efi.get_time = virt_get_time;	efi.set_time = virt_set_time;	efi.get_wakeup_time = virt_get_wakeup_time;	efi.set_wakeup_time = virt_set_wakeup_time;	efi.get_variable = virt_get_variable;	efi.get_next_variable = virt_get_next_variable;	efi.set_variable = virt_set_variable;	efi.get_next_high_mono_count = virt_get_next_high_mono_count;	efi.reset_system = virt_reset_system;}/* * Walk the EFI memory map looking for the I/O port range.  There can only be one entry of * this type, other I/O port ranges should be described via ACPI. */u64efi_get_iobase (void){	void *efi_map_start, *efi_map_end, *p;	efi_memory_desc_t *md;	u64 efi_desc_size;	efi_map_start = __va(ia64_boot_param->efi_memmap);	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;	efi_desc_size = ia64_boot_param->efi_memdesc_size;	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {		md = p;		if (md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {			if (md->attribute & EFI_MEMORY_UC)				return md->phys_addr;		}	}	return 0;}static struct kern_memdesc *kern_memory_descriptor (unsigned long phys_addr){	struct kern_memdesc *md;	for (md = kern_memmap; md->start != ~0UL; md++) {		if (phys_addr - md->start < (md->num_pages << EFI_PAGE_SHIFT))			 return md;	}	return NULL;}static efi_memory_desc_t *efi_memory_descriptor (unsigned long phys_addr){	void *efi_map_start, *efi_map_end, *p;	efi_memory_desc_t *md;	u64 efi_desc_size;	efi_map_start = __va(ia64_boot_param->efi_memmap);	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;	efi_desc_size = ia64_boot_param->efi_memdesc_size;	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {		md = p;		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))			 return md;	}	return NULL;}u32efi_mem_type (unsigned long phys_addr){	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);	if (md)		return md->type;	return 0;}u64efi_mem_attributes (unsigned long phys_addr){	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);	if (md)		return md->attribute;	return 0;}EXPORT_SYMBOL(efi_mem_attributes);u64efi_mem_attribute (unsigned long phys_addr, unsigned long size){	unsigned long end = phys_addr + size;	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);	u64 attr;	if (!md)		return 0;	/*	 * EFI_MEMORY_RUNTIME is not a memory attribute; it just tells	 * the kernel that firmware needs this region mapped.	 */	attr = md->attribute & ~EFI_MEMORY_RUNTIME;	do {		unsigned long md_end = efi_md_end(md);		if (end <= md_end)			return attr;		md = efi_memory_descriptor(md_end);		if (!md || (md->attribute & ~EFI_MEMORY_RUNTIME) != attr)			return 0;	} while (md);	return 0;}u64kern_mem_attribute (unsigned long phys_addr, unsigned long size){	unsigned long end = phys_addr + size;	struct kern_memdesc *md;	u64 attr;	/*	 * This is a hack for ioremap calls before we set up kern_memmap.	 * Maybe we should do efi_memmap_init() earlier instead.	 */	if (!kern_memmap) {		attr = efi_mem_attribute(phys_addr, size);		if (attr & EFI_MEMORY_WB)			return EFI_MEMORY_WB;		return 0;	}	md = kern_memory_descriptor(phys_addr);	if (!md)		return 0;	attr = md->attribute;	do {		unsigned long md_end = kmd_end(md);		if (end <= md_end)			return attr;		md = kern_memory_descriptor(md_end);		if (!md || md->attribute != attr)			return 0;	} while (md);	return 0;}EXPORT_SYMBOL(kern_mem_attribute);#ifndef XENintvalid_phys_addr_range (unsigned long phys_addr, unsigned long size){	u64 attr;	/*	 * /dev/mem reads and writes use copy_to_user(), which implicitly	 * uses a granule-sized kernel identity mapping.  It's really	 * only safe to do this for regions in kern_memmap.  For more	 * details, see Documentation/ia64/aliasing.txt.	 */	attr = kern_mem_attribute(phys_addr, size);	if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC)		return 1;	return 0;}intvalid_mmap_phys_addr_range (unsigned long pfn, unsigned long size){	/*	 * MMIO regions are often missing from the EFI memory map.	 * We must allow mmap of them for programs like X, so we	 * currently can't do any useful validation.	 */	return 1;}pgprot_tphys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size,		     pgprot_t vma_prot){	unsigned long phys_addr = pfn << PAGE_SHIFT;

⌨️ 快捷键说明

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