page_table.cc (12460:0f221912b014) page_table.cc (12461:a4cb506cda74)
1/*
2 * Copyright (c) 2014 Advanced Micro Devices, Inc.
3 * Copyright (c) 2003 The Regents of The University of Michigan
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

--- 26 unchanged lines hidden (view full) ---

35 * @file
36 * Definitions of functional page table.
37 */
38#include "mem/page_table.hh"
39
40#include <string>
41
42#include "base/trace.hh"
1/*
2 * Copyright (c) 2014 Advanced Micro Devices, Inc.
3 * Copyright (c) 2003 The Regents of The University of Michigan
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

--- 26 unchanged lines hidden (view full) ---

35 * @file
36 * Definitions of functional page table.
37 */
38#include "mem/page_table.hh"
39
40#include <string>
41
42#include "base/trace.hh"
43#include "config/the_isa.hh"
44#include "debug/MMU.hh"
45#include "sim/faults.hh"
46#include "sim/serialize.hh"
47
48using namespace std;
43#include "debug/MMU.hh"
44#include "sim/faults.hh"
45#include "sim/serialize.hh"
46
47using namespace std;
49using namespace TheISA;
50
48
51EmulationPageTable::~EmulationPageTable()
52{
53 for (auto &iter : pTable)
54 delete iter.second;
55}
56
57void
58EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
59{
60 bool clobber = flags & Clobber;
61 // starting address must be page aligned
62 assert(pageOffset(vaddr) == 0);
63
64 DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);
65
66 while (size > 0) {
67 auto it = pTable.find(vaddr);
68 if (it != pTable.end()) {
49void
50EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
51{
52 bool clobber = flags & Clobber;
53 // starting address must be page aligned
54 assert(pageOffset(vaddr) == 0);
55
56 DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);
57
58 while (size > 0) {
59 auto it = pTable.find(vaddr);
60 if (it != pTable.end()) {
69 if (clobber) {
70 delete it->second;
71 } else {
72 // already mapped
73 panic("EmulationPageTable::allocate: addr %#x already mapped",
74 vaddr);
75 }
61 // already mapped
62 panic_if(!clobber,
63 "EmulationPageTable::allocate: addr %#x already mapped",
64 vaddr);
65 it->second = Entry(paddr, flags);
76 } else {
66 } else {
77 it = pTable.emplace(vaddr, nullptr).first;
67 pTable.emplace(vaddr, Entry(paddr, flags));
78 }
79
68 }
69
80 it->second = new TheISA::TlbEntry(pid, vaddr, paddr,
81 flags & Uncacheable,
82 flags & ReadOnly);
83 size -= pageSize;
84 vaddr += pageSize;
85 paddr += pageSize;
86 }
87}
88
89void
90EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)

--- 6 unchanged lines hidden (view full) ---

97
98 while (size > 0) {
99 auto new_it = pTable.find(new_vaddr);
100 auto old_it = pTable.find(vaddr);
101 assert(old_it != pTable.end() && new_it == pTable.end());
102
103 new_it->second = old_it->second;
104 pTable.erase(old_it);
70 size -= pageSize;
71 vaddr += pageSize;
72 paddr += pageSize;
73 }
74}
75
76void
77EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)

--- 6 unchanged lines hidden (view full) ---

84
85 while (size > 0) {
86 auto new_it = pTable.find(new_vaddr);
87 auto old_it = pTable.find(vaddr);
88 assert(old_it != pTable.end() && new_it == pTable.end());
89
90 new_it->second = old_it->second;
91 pTable.erase(old_it);
105 new_it->second->updateVaddr(new_vaddr);
106 size -= pageSize;
107 vaddr += pageSize;
108 new_vaddr += pageSize;
109 }
110}
111
112void
113EmulationPageTable::getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps)
114{
115 for (auto &iter : pTable)
92 size -= pageSize;
93 vaddr += pageSize;
94 new_vaddr += pageSize;
95 }
96}
97
98void
99EmulationPageTable::getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps)
100{
101 for (auto &iter : pTable)
116 addr_maps->push_back(make_pair(iter.first, iter.second->pageStart()));
102 addr_maps->push_back(make_pair(iter.first, iter.second.paddr));
117}
118
119void
120EmulationPageTable::unmap(Addr vaddr, int64_t size)
121{
122 assert(pageOffset(vaddr) == 0);
123
103}
104
105void
106EmulationPageTable::unmap(Addr vaddr, int64_t size)
107{
108 assert(pageOffset(vaddr) == 0);
109
124 DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size);
110 DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr + size);
125
126 while (size > 0) {
127 auto it = pTable.find(vaddr);
128 assert(it != pTable.end());
111
112 while (size > 0) {
113 auto it = pTable.find(vaddr);
114 assert(it != pTable.end());
129 delete it->second;
130 pTable.erase(it);
131 size -= pageSize;
132 vaddr += pageSize;
133 }
134}
135
136bool
137EmulationPageTable::isUnmapped(Addr vaddr, int64_t size)
138{
139 // starting address must be page aligned
140 assert(pageOffset(vaddr) == 0);
141
142 for (int64_t offset = 0; offset < size; offset += pageSize)
143 if (pTable.find(vaddr + offset) != pTable.end())
144 return false;
145
146 return true;
147}
148
115 pTable.erase(it);
116 size -= pageSize;
117 vaddr += pageSize;
118 }
119}
120
121bool
122EmulationPageTable::isUnmapped(Addr vaddr, int64_t size)
123{
124 // starting address must be page aligned
125 assert(pageOffset(vaddr) == 0);
126
127 for (int64_t offset = 0; offset < size; offset += pageSize)
128 if (pTable.find(vaddr + offset) != pTable.end())
129 return false;
130
131 return true;
132}
133
149TheISA::TlbEntry *
134const EmulationPageTable::Entry *
150EmulationPageTable::lookup(Addr vaddr)
151{
152 Addr page_addr = pageAlign(vaddr);
153 PTableItr iter = pTable.find(page_addr);
154 if (iter == pTable.end())
155 return nullptr;
135EmulationPageTable::lookup(Addr vaddr)
136{
137 Addr page_addr = pageAlign(vaddr);
138 PTableItr iter = pTable.find(page_addr);
139 if (iter == pTable.end())
140 return nullptr;
156 return iter->second;
141 return &(iter->second);
157}
158
159bool
160EmulationPageTable::translate(Addr vaddr, Addr &paddr)
161{
142}
143
144bool
145EmulationPageTable::translate(Addr vaddr, Addr &paddr)
146{
162 TheISA::TlbEntry *entry = lookup(vaddr);
147 const Entry *entry = lookup(vaddr);
163 if (!entry) {
164 DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
165 return false;
166 }
148 if (!entry) {
149 DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
150 return false;
151 }
167 paddr = pageOffset(vaddr) + entry->pageStart();
152 paddr = pageOffset(vaddr) + entry->paddr;
168 DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
169 return true;
170}
171
172Fault
173EmulationPageTable::translate(RequestPtr req)
174{
175 Addr paddr;

--- 14 unchanged lines hidden (view full) ---

190{
191 paramOut(cp, "ptable.size", pTable.size());
192
193 PTable::size_type count = 0;
194 for (auto &pte : pTable) {
195 ScopedCheckpointSection sec(cp, csprintf("Entry%d", count++));
196
197 paramOut(cp, "vaddr", pte.first);
153 DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
154 return true;
155}
156
157Fault
158EmulationPageTable::translate(RequestPtr req)
159{
160 Addr paddr;

--- 14 unchanged lines hidden (view full) ---

175{
176 paramOut(cp, "ptable.size", pTable.size());
177
178 PTable::size_type count = 0;
179 for (auto &pte : pTable) {
180 ScopedCheckpointSection sec(cp, csprintf("Entry%d", count++));
181
182 paramOut(cp, "vaddr", pte.first);
198 pte.second->serialize(cp);
183 paramOut(cp, "paddr", pte.second.paddr);
184 paramOut(cp, "flags", pte.second.flags);
199 }
200 assert(count == pTable.size());
201}
202
203void
204EmulationPageTable::unserialize(CheckpointIn &cp)
205{
206 int count;
207 paramIn(cp, "ptable.size", count);
208
209 for (int i = 0; i < count; ++i) {
210 ScopedCheckpointSection sec(cp, csprintf("Entry%d", i));
211
185 }
186 assert(count == pTable.size());
187}
188
189void
190EmulationPageTable::unserialize(CheckpointIn &cp)
191{
192 int count;
193 paramIn(cp, "ptable.size", count);
194
195 for (int i = 0; i < count; ++i) {
196 ScopedCheckpointSection sec(cp, csprintf("Entry%d", i));
197
212 TheISA::TlbEntry *entry = new TheISA::TlbEntry();
213 entry->unserialize(cp);
214
215 Addr vaddr;
198 Addr vaddr;
216 paramIn(cp, "vaddr", vaddr);
199 UNSERIALIZE_SCALAR(vaddr);
200 Addr paddr;
201 uint64_t flags;
202 UNSERIALIZE_SCALAR(paddr);
203 UNSERIALIZE_SCALAR(flags);
217
204
218 pTable[vaddr] = entry;
205 pTable.emplace(vaddr, Entry(paddr, flags));
219 }
220}
221
206 }
207}
208