00001 // EPOS-- MMU Mediator Common Package Implementation 00002 00003 // This work is licensed under the Creative Commons 00004 // Attribution-NonCommercial-NoDerivs License. To view a copy of this license, 00005 // visit http://creativecommons.org/licenses/by-nc-nd/2.0/ or send a letter to 00006 // Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. 00007 00008 #include <mmu.h> 00009 00010 __BEGIN_SYS 00011 00012 // Class attributes 00013 // bool MMU_Common<10, 10, 12>::Frame_List::_frame_list_lock; 00014 00015 // static bool _access_lock; 00016 00017 // static void enter_critical_region() { 00018 // while(CPU::tsl(_access_lock)); 00019 // } 00020 // static void leave_critical_region() { 00021 // _access_lock = false; 00022 // } 00023 00024 // /* 00025 // * This method removes "pages" frames from the _free_frame_list 00026 // */ 00027 // IA32::Phy_Addr MMU_Common<10, 10, 12>::Frame_List::frame_alloc(int n) { 00028 // db<IA32_MMU>(TRC) << "IA32_MMU::Frame_List::frame_alloc(n=" << n << ")\n"; 00029 00030 // enter_critical_region(); 00031 00032 // Node * aux; 00033 // aux = search_hole(n); 00034 // if(!aux) { // If there is no memory 00035 // leave_critical_region(); 00036 // return (unsigned int)0; 00037 // } 00038 // /******** FRAMES FOUND ********/ 00039 // if(aux->size() == static_cast<unsigned int>(n)) { // Memory chunk has exactly the requested size 00040 // if(aux->prev) aux->prev->next = aux->next; 00041 // else { 00042 // head(aux->next); 00043 // aux->next->prev = static_cast<Node *>(0); 00044 // } 00045 // if(aux->next) aux->next->prev = aux->prev; 00046 // else { 00047 // tail(aux->prev); 00048 // aux->prev->next = static_cast<Node *>(0); 00049 // } 00050 // dec_free_frames(n); 00051 // leave_critical_region(); 00052 // return aux->data(); 00053 // } 00054 // //Memory chunk doesn't has the requested size, it is bigger, i. e., it must be splited 00055 // aux->dec_size(n); 00056 // CPU::Phy_Addr old_data = aux->data(); 00057 // aux->inc_data(sizeof(Page) * n); 00058 // Node * new_aux = aux + (n * (sizeof(Page)/sizeof(Node))); 00059 // memcpy(new_aux,aux,sizeof(Node)); 00060 // if(head() == aux) head(new_aux); 00061 // if(tail() == aux) tail(new_aux); 00062 // dec_free_frames(n); 00063 00064 // leave_critical_region(); 00065 00066 // return old_data; 00067 // } 00068 00069 // void MMU_Common<10, 10, 12>::Frame_List::frame_free_ordered(CPU::Phy_Addr addr, int n) { 00070 // db<IA32_MMU>(TRC) << "IA32_MMU::Frame_List::frame_free_ordered(addr=" << addr << ", n=" << n << ")\n"; 00071 00072 // enter_critical_region(); 00073 00074 // CPU::Phy_Addr sys_addr = addr + 0x80000000; 00075 // Node * node; 00076 // Node * aux = search_next(addr); 00077 // if(!aux) { 00078 // leave_critical_region(); 00079 // frame_free(addr,n); 00080 // return; 00081 // } 00082 00083 // // insert before aux 00084 // node = reinterpret_cast<Node *>(static_cast<unsigned int>(sys_addr)); 00085 // node->prev = aux->prev; 00086 // node->next = aux; 00087 // node->data(addr); 00088 // node->size(n); 00089 // if(static_cast<void *>(head()) == static_cast<void *>(aux)) head(node); 00090 // aux->prev = node; 00091 // try_merge(node); 00092 // inc_free_frames(n); 00093 00094 // leave_critical_region(); 00095 // } 00096 00097 // void MMU_Common<10, 10, 12>::Frame_List::frame_free(CPU::Phy_Addr addr, int n) { 00098 // db<IA32_MMU>(TRC) << "IA32_MMU::Frame_List::frame_free(addr=" << addr << ",n=" << n << ")\n"; 00099 00100 // enter_critical_region(); 00101 00102 // CPU::Phy_Addr sys_addr = addr + 0x80000000; 00103 00104 // Node * node = reinterpret_cast<Node *>(static_cast<unsigned int>(sys_addr)); 00105 // node->size(n); 00106 // node->data(addr); 00107 // node->prev = tail(); 00108 // node->next = reinterpret_cast<Node *>(0); 00109 // (tail())->next = node; 00110 // tail(node); 00111 // inc_free_frames(n); 00112 00113 // leave_critical_region(); 00114 // } 00115 00116 // void MMU_Common<10, 10, 12>::Frame_List::try_merge(Node * node) { 00117 // db<IA32_MMU>(TRC) << "IA32_MMU::Frame_List::try_merge(node=" << node << ")\n"; 00118 // if(node->prev && ((node->prev->data() + (sizeof(Page) * node->prev->size())) >= node->data())) { 00119 // node->prev->size(((node->data() + (sizeof(Page) * node->size())) - node->prev->data()) / sizeof(Page)); 00120 // node->prev->next = node->next; 00121 // if(tail() == node) tail(node->prev); 00122 // if(node->next) { 00123 // node->next->prev = node->prev; 00124 // goto try_next; 00125 // } 00126 // } 00127 // if(node->next) { 00128 // try_next: 00129 // try_merge(node->next); 00130 // } 00131 // } 00132 00133 // /* 00134 // * The following method prints the actual _free_frame_list state. This 00135 // * method only works if the debugged Aspect is WATCHED. 00136 // */ 00137 // /* 00138 // void IA32_MMU::print_free_frame_list(OStream & cout) { 00139 // cout << "****************FREE FRAME LIST****************\n"; 00140 // cout << "*nbr data size prev next *\n"; 00141 // Frame_List::Node * aux = _free_frame_list.head(); 00142 // for(int i = 1; aux; i++, aux = aux->next) 00143 // cout << "*" << 00144 // i << " " << 00145 // (unsigned int)aux->data() << " " << 00146 // aux->size() << " " << 00147 // aux->prev << " " << 00148 // aux->next << " *\n"; 00149 // cout << "**********************END**********************\n"; 00150 // } 00151 // */ 00152 00153 __END_SYS