00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "src/common/shared.hpp"
00022 #include "src/common/error.hpp"
00023 #include "src/tty/teletype.hpp"
00024 #include "src/ipc/lock.hpp"
00025 #include "src/thread/thread.hpp"
00026 #include "src/thread/scheduler.hpp"
00027 #include "src/memory/align.hpp"
00028 #include "src/memory/memset.hpp"
00029 #include "src/memory/pager.hpp"
00030 #include "src/memory/zone.hpp"
00031 #include "src/memory/alloc4k.hpp"
00032
00033 namespace Memory {
00034 namespace Physical {
00035
00036
00037 uint32 heap_area_addend = 0;
00038 bool balloc_on=TRUE;
00039 class Memory::zone free_pages_high ;
00040 class Memory::zone free_pages_low;
00041 class Memory::zone zero_pages_high ;
00042 class Memory::zone zero_pages_low ;
00043
00044 IPC::Lock::lock_t lock_pages(const_cast<char*>("pages"));
00045 uint32 first_free_page=(mem_ksize+mem_physical)/PAGE_SIZE;
00046
00047 IPC::Lock::lock_t lock_ZeroVirtFrame(const_cast<char*>("ZeroVirtFrame"));
00048 void *ZeroVirtFrame;
00049
00050
00051
00052 void init()
00053 {
00054 uint32 stack_size; uint32 *stack_addr;
00055 uint32 n,i;
00056
00057 ZeroVirtFrame= (void*)Memory::Physical::ballocate(PAGE_SIZE, PAGE_ALIGN);
00058
00059
00060 stack_size = PAGESCLEANMAX*2;
00061 stack_addr = (uint32*)ballocate(stack_size*sizeof(uint32), PAGE_ALIGN);
00062
00063 for (i=0;i<stack_size*sizeof(uint32);i+=PAGE_SIZE)
00064 Memory::Pager::kmem.pte_map(i+(uint32)stack_addr, (first_free_page*PAGE_SIZE+i)|PTE_PRESENT|PTE_WRITEABLE);
00065
00066 first_free_page+=align_up(stack_size*sizeof(uint32),PAGE_ALIGN)/PAGE_SIZE;
00067
00068 zero_pages_low.init(stack_addr, PAGESCLEANMAX, PAGE_SIZE);
00069 zero_pages_high.init(stack_addr+PAGESCLEANMAX, PAGESCLEANMAX, PAGE_SIZE);
00070
00071
00072 size_t high_mem;
00073 size_t last_page;
00074
00075 high_mem= get_high_memory_size();
00076 last_page=get_memory_size() - PAGE_SIZE;
00077
00078 stack_size = 0x10+high_mem/PAGE_SIZE;
00079 stack_addr = (uint32*)ballocate(stack_size*sizeof(uint32), PAGE_ALIGN);
00080
00081 for (i=0;i<stack_size*sizeof(uint32);i+=PAGE_SIZE)
00082 Memory::Pager::kmem.pte_map(i+(uint32)stack_addr, (first_free_page*PAGE_SIZE+i)|PTE_PRESENT|PTE_WRITEABLE);
00083
00084 first_free_page+=align_up(stack_size*sizeof(uint32),PAGE_ALIGN)/PAGE_SIZE;
00085 free_pages_high.init((uint32*)stack_addr, stack_size, PAGE_SIZE);
00086
00087 i=0;
00088 for (n=last_page; n>=first_free_page*PAGE_SIZE; n-=PAGE_SIZE) {
00089 stack_addr[i]=n;
00090 i++; };
00091 free_pages_high.set_length(i);
00092
00093
00094
00095 stack_size=((mem_low_end-mem_low_start)>>12)+0x10;
00096 stack_addr=(uint32*)ballocate(stack_size*sizeof(uint32),PAGE_ALIGN);
00097
00098
00099
00100 for (i=0;i<stack_size*sizeof(uint32);i+=PAGE_SIZE)
00101 Memory::Pager::kmem.pte_map(i+(uint32)stack_addr, alloc4k(1,true)|PTE_PRESENT|PTE_WRITEABLE);
00102
00103
00104 first_free_page+=align_up(stack_size*sizeof(uint32),PAGE_ALIGN)/PAGE_SIZE;
00105 free_pages_low.init((uint32*)stack_addr, stack_size, PAGE_SIZE);
00106
00107 i=0;
00108 for (n=mem_low_end-PAGE_SIZE;n>=mem_low_start; n-=PAGE_SIZE) {
00109 stack_addr[i]=n;
00110 i++; };
00111
00112 free_pages_low.set_length(i);
00113 }
00114
00115
00116 addr_t ballocate (size_t size, uint32 alignment)
00117 {
00118 addr_t ret;
00119
00120 if (balloc_on == false)
00121 sysfail("not permitted");
00122
00123
00124 heap_area_addend = align_up(heap_area_addend,alignment);
00125
00126 ret = (addr_t) (heap_area_addend + mem_heap_start);
00127 heap_area_addend += size;
00128
00129 return ret;
00130 }
00131
00132
00133 void disable_balloc() {
00134 balloc_on=FALSE;
00135 }
00136
00137
00138 addr_t allocate_page_high (uint32 cnt)
00139 {
00140 addr_t ret;
00141 ret= zero_pages_high.alloc(cnt);
00142 if (ret==NULL)
00143 ret= alloc4kDirty_high(cnt);
00144
00145 return ret;
00146 }
00147
00148
00149 addr_t allocate_page_low (uint32 cnt)
00150 {
00151 addr_t ret;
00152 ret= zero_pages_low.alloc(cnt);
00153 if (ret==NULL)
00154 ret= alloc4kDirty_low(cnt);
00155
00156 return ret;
00157 }
00158
00159
00160 addr_t alloc4kDirty_high(uint32 cnt)
00161 {
00162 addr_t ret;
00163 uint32 i;
00164 ret= free_pages_high.alloc(cnt);
00165 if (ret==NULL)
00166 return NULL;
00167 for (i=0;i<cnt;i++)
00168 {
00169 Memory::Pager::FrameAssign(ZeroVirtFrame, &lock_ZeroVirtFrame, ret+i);
00170 memset(ZeroVirtFrame,0,PAGE_SIZE);
00171 Memory::Pager::FrameRelease(&lock_ZeroVirtFrame);
00172 }
00173
00174 return ret;
00175 }
00176
00177
00178 addr_t alloc4kDirty_low(uint32 cnt)
00179 {
00180 addr_t ret;
00181 uint32 i;
00182 ret= free_pages_low.alloc(cnt);
00183 if (ret==NULL)
00184 return NULL;
00185 for (i=0;i<cnt;i++)
00186 {
00187 Memory::Pager::FrameAssign(ZeroVirtFrame, &lock_ZeroVirtFrame, ret+i);
00188 memset(ZeroVirtFrame,0,PAGE_SIZE);
00189 Memory::Pager::FrameRelease(&lock_ZeroVirtFrame);
00190 }
00191
00192 return ret;
00193 }
00194
00195
00196 int free_page_high(addr_t physical) {
00197 if (physical < mem_1Mib) complain("bad page freed");
00198 return free_pages_high.free(physical);
00199 }
00200
00201
00202 int free_page_low(addr_t physical) {
00203 if (physical > 0xa0000) complain("bad page freed");
00204 if (physical == 0) complain("null page freed");
00205 return free_pages_low.free(physical);
00206 }
00207
00208
00209
00210 size_t get_memory_size() {
00211 return memory_size;
00212 }
00213
00214
00215 size_t get_high_memory_size() {
00216 return memory_size - mem_1Mib;
00217 }
00218
00219
00220 };
00221 };
00222
00223
00224 addr_t alloc4k(uint32 cnt, bool fatal)
00225 {
00226 addr_t ret;
00227 ret=Memory::Physical::allocate_page_high(cnt);
00228 if ((ret == NULL) || (ret == 0xffffffff))
00229 ret=Memory::Physical::allocate_page_low(cnt);
00230 if ((ret == NULL) || (ret==0xffffffff))
00231 if (fatal)
00232 sysfail("alloc4k: out of memory");
00233
00234 return ret;
00235 }
00236
00237
00238 int disalloc4k(addr_t physical)
00239 {
00240 return 1;
00241
00242 if (physical < mem_1Mib)
00243 return Memory::Physical::free_page_low(physical);
00244
00245 return Memory::Physical::free_page_high(physical);
00246 }
00247
00248
00249
00250
00251
00252
00253