1*32cad1ffSPhilippe Mathieu-Daudé /* 2*32cad1ffSPhilippe Mathieu-Daudé * QEMU memory mapping 3*32cad1ffSPhilippe Mathieu-Daudé * 4*32cad1ffSPhilippe Mathieu-Daudé * Copyright Fujitsu, Corp. 2011, 2012 5*32cad1ffSPhilippe Mathieu-Daudé * 6*32cad1ffSPhilippe Mathieu-Daudé * Authors: 7*32cad1ffSPhilippe Mathieu-Daudé * Wen Congyang <wency@cn.fujitsu.com> 8*32cad1ffSPhilippe Mathieu-Daudé * 9*32cad1ffSPhilippe Mathieu-Daudé * This work is licensed under the terms of the GNU GPL, version 2 or later. 10*32cad1ffSPhilippe Mathieu-Daudé * See the COPYING file in the top-level directory. 11*32cad1ffSPhilippe Mathieu-Daudé * 12*32cad1ffSPhilippe Mathieu-Daudé */ 13*32cad1ffSPhilippe Mathieu-Daudé 14*32cad1ffSPhilippe Mathieu-Daudé #ifndef MEMORY_MAPPING_H 15*32cad1ffSPhilippe Mathieu-Daudé #define MEMORY_MAPPING_H 16*32cad1ffSPhilippe Mathieu-Daudé 17*32cad1ffSPhilippe Mathieu-Daudé #include "qemu/queue.h" 18*32cad1ffSPhilippe Mathieu-Daudé #include "exec/cpu-common.h" 19*32cad1ffSPhilippe Mathieu-Daudé 20*32cad1ffSPhilippe Mathieu-Daudé typedef struct GuestPhysBlock { 21*32cad1ffSPhilippe Mathieu-Daudé /* visible to guest, reflects PCI hole, etc */ 22*32cad1ffSPhilippe Mathieu-Daudé hwaddr target_start; 23*32cad1ffSPhilippe Mathieu-Daudé 24*32cad1ffSPhilippe Mathieu-Daudé /* implies size */ 25*32cad1ffSPhilippe Mathieu-Daudé hwaddr target_end; 26*32cad1ffSPhilippe Mathieu-Daudé 27*32cad1ffSPhilippe Mathieu-Daudé /* points into host memory */ 28*32cad1ffSPhilippe Mathieu-Daudé uint8_t *host_addr; 29*32cad1ffSPhilippe Mathieu-Daudé 30*32cad1ffSPhilippe Mathieu-Daudé /* points to the MemoryRegion that this block belongs to */ 31*32cad1ffSPhilippe Mathieu-Daudé MemoryRegion *mr; 32*32cad1ffSPhilippe Mathieu-Daudé 33*32cad1ffSPhilippe Mathieu-Daudé QTAILQ_ENTRY(GuestPhysBlock) next; 34*32cad1ffSPhilippe Mathieu-Daudé } GuestPhysBlock; 35*32cad1ffSPhilippe Mathieu-Daudé 36*32cad1ffSPhilippe Mathieu-Daudé /* point-in-time snapshot of guest-visible physical mappings */ 37*32cad1ffSPhilippe Mathieu-Daudé typedef struct GuestPhysBlockList { 38*32cad1ffSPhilippe Mathieu-Daudé unsigned num; 39*32cad1ffSPhilippe Mathieu-Daudé QTAILQ_HEAD(, GuestPhysBlock) head; 40*32cad1ffSPhilippe Mathieu-Daudé } GuestPhysBlockList; 41*32cad1ffSPhilippe Mathieu-Daudé 42*32cad1ffSPhilippe Mathieu-Daudé /* The physical and virtual address in the memory mapping are contiguous. */ 43*32cad1ffSPhilippe Mathieu-Daudé typedef struct MemoryMapping { 44*32cad1ffSPhilippe Mathieu-Daudé hwaddr phys_addr; 45*32cad1ffSPhilippe Mathieu-Daudé vaddr virt_addr; 46*32cad1ffSPhilippe Mathieu-Daudé ram_addr_t length; 47*32cad1ffSPhilippe Mathieu-Daudé QTAILQ_ENTRY(MemoryMapping) next; 48*32cad1ffSPhilippe Mathieu-Daudé } MemoryMapping; 49*32cad1ffSPhilippe Mathieu-Daudé 50*32cad1ffSPhilippe Mathieu-Daudé struct MemoryMappingList { 51*32cad1ffSPhilippe Mathieu-Daudé unsigned int num; 52*32cad1ffSPhilippe Mathieu-Daudé MemoryMapping *last_mapping; 53*32cad1ffSPhilippe Mathieu-Daudé QTAILQ_HEAD(, MemoryMapping) head; 54*32cad1ffSPhilippe Mathieu-Daudé }; 55*32cad1ffSPhilippe Mathieu-Daudé 56*32cad1ffSPhilippe Mathieu-Daudé /* 57*32cad1ffSPhilippe Mathieu-Daudé * add or merge the memory region [phys_addr, phys_addr + length) into the 58*32cad1ffSPhilippe Mathieu-Daudé * memory mapping's list. The region's virtual address starts with virt_addr, 59*32cad1ffSPhilippe Mathieu-Daudé * and is contiguous. The list is sorted by phys_addr. 60*32cad1ffSPhilippe Mathieu-Daudé */ 61*32cad1ffSPhilippe Mathieu-Daudé void memory_mapping_list_add_merge_sorted(MemoryMappingList *list, 62*32cad1ffSPhilippe Mathieu-Daudé hwaddr phys_addr, 63*32cad1ffSPhilippe Mathieu-Daudé hwaddr virt_addr, 64*32cad1ffSPhilippe Mathieu-Daudé ram_addr_t length); 65*32cad1ffSPhilippe Mathieu-Daudé 66*32cad1ffSPhilippe Mathieu-Daudé void memory_mapping_list_free(MemoryMappingList *list); 67*32cad1ffSPhilippe Mathieu-Daudé 68*32cad1ffSPhilippe Mathieu-Daudé void memory_mapping_list_init(MemoryMappingList *list); 69*32cad1ffSPhilippe Mathieu-Daudé 70*32cad1ffSPhilippe Mathieu-Daudé void guest_phys_blocks_free(GuestPhysBlockList *list); 71*32cad1ffSPhilippe Mathieu-Daudé void guest_phys_blocks_init(GuestPhysBlockList *list); 72*32cad1ffSPhilippe Mathieu-Daudé void guest_phys_blocks_append(GuestPhysBlockList *list); 73*32cad1ffSPhilippe Mathieu-Daudé 74*32cad1ffSPhilippe Mathieu-Daudé bool qemu_get_guest_memory_mapping(MemoryMappingList *list, 75*32cad1ffSPhilippe Mathieu-Daudé const GuestPhysBlockList *guest_phys_blocks, 76*32cad1ffSPhilippe Mathieu-Daudé Error **errp); 77*32cad1ffSPhilippe Mathieu-Daudé 78*32cad1ffSPhilippe Mathieu-Daudé /* get guest's memory mapping without do paging(virtual address is 0). */ 79*32cad1ffSPhilippe Mathieu-Daudé void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list, 80*32cad1ffSPhilippe Mathieu-Daudé const GuestPhysBlockList *guest_phys_blocks); 81*32cad1ffSPhilippe Mathieu-Daudé 82*32cad1ffSPhilippe Mathieu-Daudé void memory_mapping_filter(MemoryMappingList *list, int64_t begin, 83*32cad1ffSPhilippe Mathieu-Daudé int64_t length); 84*32cad1ffSPhilippe Mathieu-Daudé 85*32cad1ffSPhilippe Mathieu-Daudé #endif 86