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