Import of openhackware-0.4.1
[openhackware.git] / src / mm.c
blobe7fa067ccbe5090e6c0c74d132cd6d6231aec557
1 /*
2 * Open Hack'Ware BIOS memory management.
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License V2
8 * as published by the Free Software Foundation
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdlib.h>
21 #include "bios.h"
23 #if 0
24 static uint8_t *page_bitmap;
25 static uint32_t memory_size;
27 static void mark_page_in_use (uint32_t page_nb)
29 uint32_t offset, bit;
31 offset = page_nb >> 3;
32 bit = page_nb & 7;
33 page_bitmap[offset] |= 1 << bit;
36 static void mark_page_free (uint32_t page_nb)
38 uint32_t offset, bit;
40 offset = page_nb >> 3;
41 bit = page_nb & 7;
42 page_bitmap[offset] &= ~(1 << bit);
45 static int is_page_in_use (uint32_t page_nb)
47 uint32_t offset, bit;
49 offset = page_nb >> 3;
50 bit = page_nb & 7;
52 return (page_bitmap[offset] & (~(1 << bit))) != 0;
55 void mm_init (uint32_t memsize)
57 uint32_t page_start, page_ram_start, page, ram_start;
58 uint32_t nb_pages, bitmap_size;
60 /* Init bitmap */
61 ram_start = (uint32_t)(&_ram_start);
62 ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1);
63 page_bitmap = (void *)ram_start;
64 nb_pages = (memsize + (1 << 12) - 1) >> 12;
65 bitmap_size = (nb_pages + 7) >> 3;
66 /* First mark all pages as free */
67 memset(page_bitmap, 0, bitmap_size);
68 /* Mark all pages used by the BIOS as used (code + data + bitmap) */
69 page_start = (uint32_t)(0x05800000) >> 12; /* TO FIX */
70 ram_start += bitmap_size;
71 ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1);
72 page_ram_start = ram_start >> 12;
73 for (page = page_start; page < page_ram_start; page++)
74 mark_page_in_use(page);
75 memory_size = memsize;
78 void *page_get (int nb_pages)
80 uint32_t page_start, page_end, page;
81 int nb;
83 page_start = (uint32_t)(0x05800000) >> 12; /* TO FIX */
84 page_end = memory_size >> 12;
85 for (page = page_start; page < page_end; ) {
86 /* Skip all full "blocs" */
87 for (; page < page_end; page += 8) {
88 if (page_bitmap[page >> 3] != 0xFF)
89 break;
91 for (nb = 0; page < page_end; page++) {
92 if (!is_page_in_use(page)) {
93 nb++;
94 if (nb == nb_pages) {
95 /* Found ! */
96 for (; nb >= 0; nb--, page--)
97 mark_page_in_use(page);
99 return (void *)(page << 12);
105 return NULL;
108 void page_put (void *addr, int nb_pages)
110 uint32_t page_start, page_end, page;
112 page_start = (uint32_t)addr >> 12;
113 page_end = page_start + nb_pages;
114 for (page = page_start; page < page_end; page++) {
115 if (!is_page_in_use(page))
116 printf("ERROR: page %u has already been freed !\n", page);
117 mark_page_free(page);
120 #else
121 static uint8_t *page_alloc;
123 void mm_init (unused uint32_t memsize)
125 uint32_t ram_start;
126 ram_start = (uint32_t)(&_ram_start);
127 ram_start = (ram_start + (1 << 12) - 1) & ~((1 << 12) - 1);
128 page_alloc = (void *)ram_start;
131 void *page_get (unused int nb_pages)
133 void *ret;
135 ret = page_alloc;
136 page_alloc += nb_pages << 12;
137 memset(ret, 0, nb_pages << 12);
139 return ret;
142 void page_put (unused void *addr, unused int nb_pages)
145 #endif