On 2012-02-09 04:20, Wen Congyang wrote: > The memory mapping list stores virtual address and physical address mapping. > The folloing patch will use this information to create PT_LOAD in the vmcore. > > Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> > --- > Makefile.target | 1 + > memory_mapping.c | 130 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > memory_mapping.h | 38 ++++++++++++++++ > 3 files changed, 169 insertions(+), 0 deletions(-) > create mode 100644 memory_mapping.c > create mode 100644 memory_mapping.h > > diff --git a/Makefile.target b/Makefile.target > index 68481a3..e35e464 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -200,6 +200,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o > obj-$(CONFIG_NO_KVM) += kvm-stub.o > obj-$(CONFIG_VGA) += vga.o > obj-y += memory.o savevm.o > +obj-y += memory_mapping.o > LIBS+=-lz > > obj-i386-$(CONFIG_KVM) += hyperv.o > diff --git a/memory_mapping.c b/memory_mapping.c > new file mode 100644 > index 0000000..d83b7d7 > --- /dev/null > +++ b/memory_mapping.c > @@ -0,0 +1,130 @@ > +/* > + * QEMU memory mapping > + * > + * Copyright Fujitsu, Corp. 2011 > + * > + * Authors: > + * Wen Congyang <we...@cn.fujitsu.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the COPYING file in the top-level directory. > + * > + */ > + > +#include "cpu.h" > +#include "cpu-all.h" > +#include "memory_mapping.h" > + > +static MemoryMapping *last_mapping; > + > +static void create_new_memory_mapping(MemoryMappingList *list, > + target_phys_addr_t phys_addr, > + target_phys_addr_t virt_addr, > + ram_addr_t length) > +{ > + MemoryMapping *memory_mapping, *p; > + > + memory_mapping = g_malloc(sizeof(MemoryMapping)); > + memory_mapping->phys_addr = phys_addr; > + memory_mapping->virt_addr = virt_addr; > + memory_mapping->length = length; > + last_mapping = memory_mapping; > + list->num++; > + QTAILQ_FOREACH(p, &list->head, next) { > + if (p->phys_addr >= memory_mapping->phys_addr) { > + QTAILQ_INSERT_BEFORE(p, memory_mapping, next); > + return; > + } > + } > + QTAILQ_INSERT_TAIL(&list->head, memory_mapping, next); > + return; > +} > + > +void create_new_memory_mapping_head(MemoryMappingList *list, > + target_phys_addr_t phys_addr, > + target_phys_addr_t virt_addr, > + ram_addr_t length) > +{ > + MemoryMapping *memory_mapping; > + > + memory_mapping = g_malloc(sizeof(MemoryMapping)); > + memory_mapping->phys_addr = phys_addr; > + memory_mapping->virt_addr = virt_addr; > + memory_mapping->length = length; > + last_mapping = memory_mapping; > + list->num++; > + QTAILQ_INSERT_HEAD(&list->head, memory_mapping, next); > + return; > +} > + > +void add_to_memory_mapping(MemoryMappingList *list, > + target_phys_addr_t phys_addr, > + target_phys_addr_t virt_addr, > + ram_addr_t length) > +{ > + MemoryMapping *memory_mapping; > + > + if (QTAILQ_EMPTY(&list->head)) { > + create_new_memory_mapping(list, phys_addr, virt_addr, length); > + return; > + } > + > + if (last_mapping) { > + if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) > && > + (virt_addr == (last_mapping->virt_addr + last_mapping->length))) > { > + last_mapping->length += length; > + return; > + } > + } > + > + QTAILQ_FOREACH(memory_mapping, &list->head, next) { > + last_mapping = memory_mapping; > + if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) > && > + (virt_addr == (last_mapping->virt_addr + last_mapping->length))) > { > + last_mapping->length += length; > + return; > + } > + > + if (!(phys_addr >= (last_mapping->phys_addr)) || > + !(phys_addr < (last_mapping->phys_addr + last_mapping->length))) > { > + /* last_mapping does not contain this region */ > + continue; > + } > + if (!(virt_addr >= (last_mapping->virt_addr)) || > + !(virt_addr < (last_mapping->virt_addr + last_mapping->length))) > { > + /* last_mapping does not contain this region */ > + continue; > + } > + if ((virt_addr - last_mapping->virt_addr) != > + (phys_addr - last_mapping->phys_addr)) { > + /* > + * last_mapping contains this region, but we should create > another > + * mapping region. > + */ > + break; > + } > + > + /* merge this region into last_mapping */ > + if ((virt_addr + length) > > + (last_mapping->virt_addr + last_mapping->length)) { > + last_mapping->length = virt_addr + length - > last_mapping->virt_addr; > + } > + return; > + } > + > + /* this region can not be merged into any existed memory mapping. */ > + create_new_memory_mapping(list, phys_addr, virt_addr, length); > + return; > +} > + > +void free_memory_mapping_list(MemoryMappingList *list) > +{ > + MemoryMapping *p, *q; > + > + QTAILQ_FOREACH_SAFE(p, &list->head, next, q) { > + QTAILQ_REMOVE(&list->head, p, next); > + g_free(p); > + } > + > + list->num = 0; > +} > diff --git a/memory_mapping.h b/memory_mapping.h > new file mode 100644 > index 0000000..a4b1532 > --- /dev/null > +++ b/memory_mapping.h > @@ -0,0 +1,38 @@ > +#ifndef MEMORY_MAPPING_H > +#define MEMORY_MAPPING_H > + > +#include "qemu-queue.h" > + > +typedef struct MemoryMapping { > + target_phys_addr_t phys_addr; > + target_ulong virt_addr; > + ram_addr_t length; > + QTAILQ_ENTRY(MemoryMapping) next; > +} MemoryMapping; > + > +typedef struct MemoryMappingList { > + unsigned int num;
This field looks unused by this series. Unless I miss something, you probably want to drop it. > + QTAILQ_HEAD(, MemoryMapping) head; > +} MemoryMappingList; > + > +/* > + * crash needs some memory mapping should be at the head of the list. It will > + * cause the list is not sorted. So the caller must add the special memory > + * mapping after adding all the normal memory mapping into list. > + */ > +void create_new_memory_mapping_head(MemoryMappingList *list, > + target_phys_addr_t phys_addr, > + target_phys_addr_t virt_addr, > + ram_addr_t length); > +/* > + * add or merge the memory region into the memory mapping's list. The list is > + * sorted by phys_addr. > + */ > +void add_to_memory_mapping(MemoryMappingList *list, > + target_phys_addr_t phys_addr, > + target_phys_addr_t virt_addr, > + ram_addr_t length); > + > +void free_memory_mapping_list(MemoryMappingList *list); > + > +#endif A bit hard to understand and use the API. I would suggest: memory_mapping_list_add_sorted(MemoryMappingList *list, ...); memory_mapping_list_add_head(MemoryMappingList *list, ...); memory_mapping_list_free(MemoryMappingList *list); memory_mapping_list_add_head should set a flag in the MemoryMapping appended to the list or let the MemoryMappingList point to the firs sorted entry. That way, the adding order becomes irrelevant. Moreover, you are lacking some memory_mapping_list_init(MemoryMappingList *list). Cleaner than open-coding this. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux