+
+
+int alloc_ppages(int count)
+{
+ int i, pg, idx, max, intr_state, found_free = 0;
+
+ intr_state = get_intr_flag();
+ disable_intr();
+
+ idx = last_alloc_idx;
+ max = bmsize / 4;
+
+ while(idx <= max) {
+ /* if at least one bit is 0 then we have at least
+ * one free page. find it and try to allocate a range starting from there
+ */
+ if(bitmap[idx] != 0xffffffff) {
+ for(i=0; i<32; i++) {
+ pg = idx * 32 + i;
+
+ if(IS_FREE(pg)) {
+ if(!found_free) {
+ last_alloc_idx = idx;
+ found_free = 1;
+ }
+
+ if(alloc_ppage_range(pg, count) != -1) {
+ set_intr_flag(intr_state);
+ return pg;
+ }
+ }
+ }
+ }
+ idx++;
+ }
+
+ set_intr_flag(intr_state);
+ return -1;
+}
+
+void free_ppages(int pg0, int count)
+{
+ int i;
+
+ for(i=0; i<count; i++) {
+ free_ppage(pg0++);
+ }
+}
+
+int alloc_ppage_range(int start, int size)
+{
+ int i, pg = start;
+ int intr_state;
+
+ intr_state = get_intr_flag();
+ disable_intr();
+
+ /* first validate that no page in the requested range is allocated */
+ for(i=0; i<size; i++) {
+ if(!IS_FREE(pg)) {
+ return -1;
+ }
+ ++pg;
+ }
+
+ /* all is well, mark them as used */
+ pg = start;
+ for(i=0; i<size; i++) {
+ mark_page(pg++, USED);
+ }
+
+ set_intr_flag(intr_state);
+ return 0;
+}
+
+int free_ppage_range(int start, int size)
+{
+ int i, pg = start;
+
+ for(i=0; i<size; i++) {
+ free_ppage(pg++);
+ }
+ return 0;
+}
+
+/* adds a range of physical memory to the available pool. used during init_mem
+ * when traversing the memory map.
+ */
+static void add_memory(uint32_t start, size_t sz)
+{
+ int i, szpg, pg;
+
+ szpg = ADDR_TO_PAGE(sz + 4095);
+ pg = ADDR_TO_PAGE(start);
+
+ for(i=0; i<szpg; i++) {
+ mark_page(pg++, FREE);
+ }
+}
+
+/* maps a page as used or free in the allocation bitmap */
+static void mark_page(int pg, int used)
+{
+ int idx = BM_IDX(pg);
+ int bit = BM_BIT(pg);
+
+ if(used) {
+ bitmap[idx] |= 1 << bit;
+ } else {
+ bitmap[idx] &= ~(1 << bit);
+ }
+}
+