2 * Open Hack'Ware BIOS memory management.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
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
24 static uint8_t *page_bitmap
;
25 static uint32_t memory_size
;
27 static void mark_page_in_use (uint32_t page_nb
)
31 offset
= page_nb
>> 3;
33 page_bitmap
[offset
] |= 1 << bit
;
36 static void mark_page_free (uint32_t page_nb
)
40 offset
= page_nb
>> 3;
42 page_bitmap
[offset
] &= ~(1 << bit
);
45 static int is_page_in_use (uint32_t page_nb
)
49 offset
= page_nb
>> 3;
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
;
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
;
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)
91 for (nb
= 0; page
< page_end
; page
++) {
92 if (!is_page_in_use(page
)) {
96 for (; nb
>= 0; nb
--, page
--)
97 mark_page_in_use(page
);
99 return (void *)(page
<< 12);
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
);
121 static uint8_t *page_alloc
;
123 void mm_init (unused
uint32_t memsize
)
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
)
136 page_alloc
+= nb_pages
<< 12;
137 memset(ret
, 0, nb_pages
<< 12);
142 void page_put (unused
void *addr
, unused
int nb_pages
)