diff options
Diffstat (limited to 'qemu/roms/openhackware/src/mm.c')
-rw-r--r-- | qemu/roms/openhackware/src/mm.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/qemu/roms/openhackware/src/mm.c b/qemu/roms/openhackware/src/mm.c new file mode 100644 index 000000000..e7fa067cc --- /dev/null +++ b/qemu/roms/openhackware/src/mm.c @@ -0,0 +1,145 @@ +/* + * Open Hack'Ware BIOS memory management. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License V2 + * as published by the Free Software Foundation + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdlib.h> +#include "bios.h" + +#if 0 +static uint8_t *page_bitmap; +static uint32_t memory_size; + +static void mark_page_in_use (uint32_t page_nb) +{ + uint32_t offset, bit; + + offset = page_nb >> 3; + bit = page_nb & 7; + page_bitmap[offset] |= 1 << bit; +} + +static void mark_page_free (uint32_t page_nb) +{ + uint32_t offset, bit; + + offset = page_nb >> 3; + bit = page_nb & 7; + page_bitmap[offset] &= ~(1 << bit); +} + +static int is_page_in_use (uint32_t page_nb) +{ + uint32_t offset, bit; + + offset = page_nb >> 3; + bit = page_nb & 7; + + return (page_bitmap[offset] & (~(1 << bit))) != 0; +} + +void mm_init (uint32_t memsize) +{ + uint32_t page_start, page_ram_start, page, ram_start; + uint32_t nb_pages, bitmap_size; + + /* Init bitmap */ + ram_start = (uint32_t)(&_ram_start); + ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1); + page_bitmap = (void *)ram_start; + nb_pages = (memsize + (1 << 12) - 1) >> 12; + bitmap_size = (nb_pages + 7) >> 3; + /* First mark all pages as free */ + memset(page_bitmap, 0, bitmap_size); + /* Mark all pages used by the BIOS as used (code + data + bitmap) */ + page_start = (uint32_t)(0x05800000) >> 12; /* TO FIX */ + ram_start += bitmap_size; + ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1); + page_ram_start = ram_start >> 12; + for (page = page_start; page < page_ram_start; page++) + mark_page_in_use(page); + memory_size = memsize; +} + +void *page_get (int nb_pages) +{ + uint32_t page_start, page_end, page; + int nb; + + page_start = (uint32_t)(0x05800000) >> 12; /* TO FIX */ + page_end = memory_size >> 12; + for (page = page_start; page < page_end; ) { + /* Skip all full "blocs" */ + for (; page < page_end; page += 8) { + if (page_bitmap[page >> 3] != 0xFF) + break; + } + for (nb = 0; page < page_end; page++) { + if (!is_page_in_use(page)) { + nb++; + if (nb == nb_pages) { + /* Found ! */ + for (; nb >= 0; nb--, page--) + mark_page_in_use(page); + + return (void *)(page << 12); + } + } + } + } + + return NULL; +} + +void page_put (void *addr, int nb_pages) +{ + uint32_t page_start, page_end, page; + + page_start = (uint32_t)addr >> 12; + page_end = page_start + nb_pages; + for (page = page_start; page < page_end; page++) { + if (!is_page_in_use(page)) + printf("ERROR: page %u has already been freed !\n", page); + mark_page_free(page); + } +} +#else +static uint8_t *page_alloc; + +void mm_init (unused uint32_t memsize) +{ + uint32_t ram_start; + ram_start = (uint32_t)(&_ram_start); + ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1); + page_alloc = (void *)ram_start; +} + +void *page_get (unused int nb_pages) +{ + void *ret; + + ret = page_alloc; + page_alloc += nb_pages << 12; + memset(ret, 0, nb_pages << 12); + + return ret; +} + +void page_put (unused void *addr, unused int nb_pages) +{ +} +#endif |