00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "src/common/shared.hpp"
00019 #include "src/tty/teletype.hpp"
00020 #include "src/memory/memset.hpp"
00021 #include "src/memory/alloc4k.hpp"
00022 #include "src/memory/zone.hpp"
00023
00024 namespace Memory {
00025
00026
00027
00028 void zone::init (uint32 *buf, uint32 elems, size_t pg_siz) {
00029 page_list.nw((char*)buf,elems);
00030 one_page=pg_siz;
00031 }
00032
00033
00034 void zone::done()
00035 {
00036 sysfail("zone::done() not permitted");
00037 }
00038
00039
00040 void zone::set_length(size_t n) {
00041 page_list.stack_ptr=n;
00042 }
00043
00044
00045 addr_t zone::alloc(size_t cnt)
00046 {
00047 if (page_list.lgth() < cnt)
00048 return NULL;
00049
00050 if (cnt == 1)
00051 return (addr_t) page_list.pop();
00052
00053 uint32 first_ptr, first, count;
00054 int sp=page_list.stack_ptr-1;
00055 bool flag=false;
00056 bool found=false;
00057
00058 while (sp >= 0) {
00059 if (!flag) {
00060 first_ptr=sp; first=page_list.stack[sp];
00061 sp--; flag=true;count=1;
00062 } else {
00063 if (page_list.stack[sp]!=first+count*one_page)
00064 { flag=false;} else
00065 { count++; sp--; if (count==cnt) {found=true;break;} }
00066 }
00067 }
00068
00069 if (!found)
00070 return NULL;
00071
00072
00073 if (first_ptr+1 != page_list.stack_ptr)
00074 memmove(page_list.stack+first_ptr-cnt+1,
00075 page_list.stack+first_ptr+1,
00076 sizeof(uint32)*(page_list.stack_ptr-first_ptr-1));
00077 page_list.stack_ptr-=cnt;
00078
00079 return first;
00080 }
00081
00082
00083 int zone::free(addr_t physical)
00084 {
00085
00086 if (physical & 0xfff)
00087 {
00088 complain("bad page addr");
00089 return -1;
00090 }
00091
00092 page_list.verify();
00093
00094
00095
00096 if (page_list.stack_ptr == 0)
00097 {page_list.stack_ptr=1;
00098 page_list.stack[0]=physical;return 1;}
00099
00100
00101 if (page_list.stack[0] < physical)
00102 {
00103 memmove(page_list.stack+1,page_list.stack,page_list.stack_ptr*4);
00104 page_list.stack[0]=physical;
00105 page_list.stack_ptr++; return 1;
00106 }
00107
00108 if (page_list.stack[page_list.stack_ptr-1] > physical)
00109 {
00110 page_list.stack[page_list.stack_ptr]=physical;
00111 page_list.stack_ptr++; return 1; }
00112
00113 uint32 sp=0;
00114 while (page_list.stack[sp]>physical) sp++;
00115
00116 memmove(page_list.stack+sp+1,
00117 page_list.stack+sp,
00118 4*(page_list.stack_ptr-sp));
00119 page_list.stack[sp]=physical;
00120
00121 page_list.stack_ptr++;
00122 return 1;
00123 }
00124
00125
00126 size_t zone::length() {
00127 return page_list.lgth();
00128 }
00129
00130
00131 };
00132
00133
00134
00135
00136
00137
00138