📄 xc_ia64_hvm_build.c
字号:
static const unsigned char config_pal_register_info[64] = { 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255};static const unsigned char config_pal_rse_info[16] = { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static const unsigned char config_pal_test_info[48] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static const unsigned char config_pal_vm_summary[16] = { 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0};static const unsigned char config_pal_vm_info[104] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0};static const unsigned char config_pal_vm_page_size[16] = { 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0};typedef struct{ hob_type_t type; void* data; unsigned long size;} hob_batch_t;static const hob_batch_t hob_batch[]={ { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, &config_pal_bus_get_features_data, sizeof(config_pal_bus_get_features_data) }, { HOB_TYPE_PAL_CACHE_SUMMARY, &config_pal_cache_summary, sizeof(config_pal_cache_summary) }, { HOB_TYPE_PAL_MEM_ATTRIB, &config_pal_mem_attrib, sizeof(config_pal_mem_attrib) }, { HOB_TYPE_PAL_CACHE_INFO, &config_pal_cache_info, sizeof(config_pal_cache_info) }, { HOB_TYPE_PAL_CACHE_PROT_INFO, &config_pal_cache_prot_info, sizeof(config_pal_cache_prot_info) }, { HOB_TYPE_PAL_DEBUG_INFO, &config_pal_debug_info, sizeof(config_pal_debug_info) }, { HOB_TYPE_PAL_FIXED_ADDR, &config_pal_fixed_addr, sizeof(config_pal_fixed_addr) }, { HOB_TYPE_PAL_FREQ_BASE, &config_pal_freq_base, sizeof(config_pal_freq_base) }, { HOB_TYPE_PAL_FREQ_RATIOS, &config_pal_freq_ratios, sizeof(config_pal_freq_ratios) }, { HOB_TYPE_PAL_HALT_INFO, &config_pal_halt_info, sizeof(config_pal_halt_info) }, { HOB_TYPE_PAL_PERF_MON_INFO, &config_pal_perf_mon_info, sizeof(config_pal_perf_mon_info) }, { HOB_TYPE_PAL_PROC_GET_FEATURES, &config_pal_proc_get_features, sizeof(config_pal_proc_get_features) }, { HOB_TYPE_PAL_PTCE_INFO, &config_pal_ptce_info, sizeof(config_pal_ptce_info) }, { HOB_TYPE_PAL_REGISTER_INFO, &config_pal_register_info, sizeof(config_pal_register_info) }, { HOB_TYPE_PAL_RSE_INFO, &config_pal_rse_info, sizeof(config_pal_rse_info) }, { HOB_TYPE_PAL_TEST_INFO, &config_pal_test_info, sizeof(config_pal_test_info) }, { HOB_TYPE_PAL_VM_SUMMARY, &config_pal_vm_summary, sizeof(config_pal_vm_summary) }, { HOB_TYPE_PAL_VM_INFO, &config_pal_vm_info, sizeof(config_pal_vm_info) }, { HOB_TYPE_PAL_VM_PAGE_SIZE, &config_pal_vm_page_size, sizeof(config_pal_vm_page_size) },};static intadd_pal_hob(void* hob_buf){ int i; for (i = 0; i < sizeof(hob_batch)/sizeof(hob_batch_t); i++) { if (hob_add(hob_buf, hob_batch[i].type, hob_batch[i].data, hob_batch[i].size) < 0) return -1; } return 0;}// The most significant bit of nvram file descriptor:// 1: valid; 0: invalid#define VALIDATE_NVRAM_FD(x) ((1UL<<(sizeof(x)*8 - 1)) | x)#define IS_VALID_NVRAM_FD(x) ((uint64_t)x >> (sizeof(x)*8 - 1))static uint64_t nvram_init(const char *nvram_path){ uint64_t fd = 0; fd = open(nvram_path, O_CREAT|O_RDWR, 0644); if ( fd < 0 ) { PERROR("Nvram open failed at %s. Guest will boot without" " nvram support!\n", nvram_path); return -1; } return VALIDATE_NVRAM_FD(fd);}static int copy_from_nvram_to_GFW(int xc_handle, uint32_t dom, int nvram_fd){ unsigned int nr_pages = NVRAM_SIZE >> PAGE_SHIFT; struct stat file_stat; char buf[NVRAM_SIZE] = {0}; if ( fstat(nvram_fd, &file_stat) < 0 ) { PERROR("Cannot get Nvram file info! Guest will boot without " "nvram support!\n"); return -1; } if ( 0 == file_stat.st_size ) { DPRINTF("Nvram file create successful!\n"); return 0; } if ( read(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE ) { PERROR("Load nvram fail. guest will boot without" " nvram support!\n"); return -1; } return xc_ia64_copy_to_domain_pages(xc_handle, dom, buf, NVRAM_START >> PAGE_SHIFT, nr_pages);}/* *Check is the address where NVRAM data located valid */static int is_valid_address(void *addr){ struct nvram_save_addr *p = (struct nvram_save_addr *)addr; if ( p->signature == NVRAM_VALID_SIG ) return 1; else { PERROR("Invalid nvram signature. Nvram save failed!\n"); return 0; }}/* * GFW use 4k page. when doing foreign map, we should 16k align * the address and map one more page to guarantee all 64k nvram data * can be got. */static intcopy_from_GFW_to_nvram(int xc_handle, uint32_t dom, int nvram_fd){ xen_pfn_t *pfn_list = NULL; char *tmp_ptr = NULL; unsigned int nr_pages = 0; uint64_t addr_from_GFW_4k_align = 0; uint32_t offset = 0; uint64_t nvram_base_addr = 0; char buf[NVRAM_SIZE] = {0}; int i; // map one more page nr_pages = (NVRAM_SIZE + PAGE_SIZE) >> PAGE_SHIFT; pfn_list = (xen_pfn_t *)malloc(sizeof(xen_pfn_t) * nr_pages); if ( NULL == pfn_list ) { PERROR("Cannot allocate memory for nvram save!\n"); close(nvram_fd); return -1; } /* * GFW allocate memory dynamicly to save nvram data * and save address of the dynamic memory at NVRAM_START. * To save nvram data to file, we must get the dynamic * memory address first. */ pfn_list[0] = NVRAM_START >> PAGE_SHIFT; tmp_ptr = (char *)xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, pfn_list[0]); if ( NULL == tmp_ptr ) { PERROR("Cannot get nvram data from GFW!\n"); free(pfn_list); close(nvram_fd); return -1; } /* Check is NVRAM data vaild */ if ( !is_valid_address(tmp_ptr) ) { free(pfn_list); munmap(tmp_ptr, PAGE_SIZE); close(nvram_fd); return -1; } addr_from_GFW_4k_align = ((struct nvram_save_addr *)tmp_ptr)->addr; munmap(tmp_ptr, PAGE_SIZE); // align address to 16k offset = addr_from_GFW_4k_align % ( 16 * MEM_K ); addr_from_GFW_4k_align = addr_from_GFW_4k_align - offset; for ( i=0; i<nr_pages; i++ ) pfn_list[i] = (addr_from_GFW_4k_align >> PAGE_SHIFT) + i; tmp_ptr = (char *)xc_map_foreign_pages(xc_handle, dom, PROT_READ | PROT_WRITE, pfn_list, nr_pages); if ( NULL == tmp_ptr ) { PERROR("Cannot get nvram data from GFW!\n"); free(pfn_list); close(nvram_fd); return -1; } // calculate nvram data base addrees nvram_base_addr = (uint64_t)(tmp_ptr + offset); memcpy(buf, (void *)nvram_base_addr, NVRAM_SIZE); free(pfn_list); munmap(tmp_ptr, NVRAM_SIZE + PAGE_SIZE); lseek(nvram_fd, 0, SEEK_SET); if ( write(nvram_fd, buf, NVRAM_SIZE) != NVRAM_SIZE ) { PERROR("Save to nvram fail!\n"); return -1; } close(nvram_fd); DPRINTF("Nvram save successful!\n"); return 0;}int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom) { xc_dominfo_t info; uint64_t nvram_fd = 0; if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1 ) { PERROR("Could not get info for domain"); return -1; } if ( !info.hvm ) return 0; xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd); if ( !IS_VALID_NVRAM_FD(nvram_fd) ) PERROR("Nvram not initialized. Nvram save failed!\n"); else copy_from_GFW_to_nvram(xc_handle, dom, (int)nvram_fd); // although save to nvram maybe fail, we don't return any error number // to Xend. This is quite logical because damage of NVRAM on native would // not block OS's executive path. Return error number will cause an // exception of Xend and block XenU when it destroy. return 0;}#define NVRAM_DIR "/var/lib/xen/nvram/"#define NVRAM_FILE_PREFIX "nvram_"int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom){ uint64_t nvram_fd; char nvram_path[PATH_MAX] = NVRAM_DIR; if ( access(nvram_path, R_OK|W_OK|X_OK) == -1 ) { if ( errno != ENOENT ) { PERROR("Error stat'ing NVRAM dir %s.", nvram_path); return -1; } if ( mkdir(nvram_path, 0755) == -1 ) { PERROR("Unable to create NVRAM store directory %s.", nvram_path); return -1; } } if ( access(nvram_path, R_OK|W_OK|X_OK) == -1 ) { errno = EACCES; PERROR("No RWX permission to NVRAM store directory %s.", nvram_path); return -1; } if ( strlen(nvram_path) + strlen(NVRAM_FILE_PREFIX) + strlen(dom_name) + 1 > sizeof(nvram_path) ) { PERROR("Nvram file path is too long!\n"); return -1; } strcat(nvram_path, NVRAM_FILE_PREFIX); strcat(nvram_path, dom_name); nvram_fd = nvram_init(nvram_path); if ( nvram_fd == (uint64_t)(-1) ) { xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, 0); return -1; } xc_set_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, nvram_fd); return 0; }#define GFW_PAGES (GFW_SIZE >> PAGE_SHIFT)#define VGA_START_PAGE (VGA_IO_START >> PAGE_SHIFT)#define VGA_END_PAGE ((VGA_IO_START + VGA_IO_SIZE) >> PAGE_SHIFT)static voidxc_ia64_setup_md(efi_memory_desc_t *md, unsigned long start, unsigned long end){ md->type = EFI_CONVENTIONAL_MEMORY; md->pad = 0; md->phys_addr = start; md->virt_addr = 0; md->num_pages = (end - start) >> EFI_PAGE_SHIFT; md->attribute = EFI_MEMORY_WB;}static inline unsigned long min(unsigned long lhs, unsigned long rhs){ return (lhs < rhs)? lhs: rhs;}static intxc_ia64_setup_memmap_info(int xc_handle, uint32_t dom,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -