Configs: Add support for the InOrder CPU model
[gem5.git] / src / mem / translating_port.cc
index ee4d277b6f49609741c45cd48209274c5fc102e0..54de6625e089b7416e5e087f0adce244fea277ea 100644 (file)
@@ -24,6 +24,9 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ron Dreslinski
+ *          Steve Reinhardt
  */
 
 #include <string>
 #include "mem/port.hh"
 #include "mem/translating_port.hh"
 #include "mem/page_table.hh"
+#include "sim/process.hh"
 
 using namespace TheISA;
 
 TranslatingPort::TranslatingPort(const std::string &_name,
-                                 PageTable *p_table, bool alloc)
-    : FunctionalPort(_name), pTable(p_table), allocating(alloc)
+                                 Process *p, AllocType alloc)
+    : FunctionalPort(_name), pTable(p->pTable), process(p),
+      allocating(alloc)
 { }
 
 TranslatingPort::~TranslatingPort()
@@ -78,13 +83,18 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
     for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
 
         if (!pTable->translate(gen.addr(), paddr)) {
-            if (allocating) {
+            if (allocating == Always) {
                 pTable->allocate(roundDown(gen.addr(), VMPageSize),
                                  VMPageSize);
-                pTable->translate(gen.addr(), paddr);
+            } else if (allocating == NextPage) {
+                // check if we've accessed the next page on the stack
+                if (!process->checkAndAllocNextPage(gen.addr()))
+                    panic("Page table fault when accessing virtual address %#x "
+                            "during functional write\n", gen.addr());
             } else {
                 return false;
             }
+            pTable->translate(gen.addr(), paddr);
         }
 
         Port::writeBlob(paddr, p + prevSize, gen.size());
@@ -110,7 +120,7 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
     for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
 
         if (!pTable->translate(gen.addr(), paddr)) {
-            if (allocating) {
+            if (allocating == Always) {
                 pTable->allocate(roundDown(gen.addr(), VMPageSize),
                                  VMPageSize);
                 pTable->translate(gen.addr(), paddr);