Xenner does its own memory management bookkeeping which can be kept platform agnostic. This patch adds that.
Signed-off-by: Alexander Graf <ag...@suse.de> --- pc-bios/xenner/xenner-mm.c | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 105 insertions(+), 0 deletions(-) create mode 100644 pc-bios/xenner/xenner-mm.c diff --git a/pc-bios/xenner/xenner-mm.c b/pc-bios/xenner/xenner-mm.c new file mode 100644 index 0000000..ccbd48a --- /dev/null +++ b/pc-bios/xenner/xenner-mm.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) Red Hat 2007 + * Copyright (C) Novell Inc. 2010 + * + * Author(s): Gerd Hoffmann <kra...@redhat.com> + * Alexander Graf <ag...@suse.de> + * + * Xenner generic memory management + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +static int heap_type = HEAP_EMU; +static void *heap_emu = NULL; +static void *heap_high_start = NULL; +static void *heap_high = NULL; + +unsigned long heap_size(void) +{ + unsigned long r = 0; + + switch (heap_type) { + case HEAP_EMU: + r = (unsigned long)heap_emu - (unsigned long)_vstop; + break; + case HEAP_HIGH: + r = (unsigned long)heap_high - (unsigned long)heap_high_start; + break; + } + + return r; +} + +void switch_heap(int _heap_type) +{ + if ((_heap_type == HEAP_HIGH) && !heap_high) { +#if defined(CONFIG_32BIT) + heap_high = (void*)(uintptr_t)XEN_IPT; +#elif defined(CONFIG_64BIT) + uintptr_t mfn_guest = emudev_get(EMUDEV_CONF_GUEST_START_PFN, 0); + uintptr_t init_pt_pfn = emudev_get(EMUDEV_CONF_PFN_INIT_PT, 0); + + heap_high = map_page(frame_to_addr(mfn_guest + init_pt_pfn)); +#endif + heap_high_start = heap_high; + } + + switch (_heap_type) { + case HEAP_EMU: + case HEAP_HIGH: + heap_type = _heap_type; + break; + } +} + +void *get_pages(int pages, const char *purpose) +{ + void **heap_cur = &heap_emu; + void *ptr; + + if (!heap_emu) { + heap_emu = _vstop; + } + + switch (heap_type) { + case HEAP_EMU: + heap_cur = &heap_emu; + break; + case HEAP_HIGH: + heap_cur = &heap_high; + break; + } + + ptr = *heap_cur; + *heap_cur += pages * PAGE_SIZE; + printk(2, "%s: %d page(s) at %p (for %s)\n", + __FUNCTION__, pages, ptr, purpose); + memset(ptr, 0, pages * PAGE_SIZE); + return ptr; +} + +void *get_memory(int bytes, const char *purpose) +{ + int pages = (bytes + PAGE_SIZE -1) / PAGE_SIZE; + return get_pages(pages, purpose); +} + +void paging_start(struct xen_cpu *cpu) +{ + ureg_t cr3_mfn; + + cr3_mfn = cpu->init_ctxt->ctrlreg[3] >> PAGE_SHIFT; + update_emu_mappings(cr3_mfn); + pv_write_cr3(cpu, cr3_mfn); +} -- 1.6.0.2