tlb.cc (4010:52c2b6941c02) tlb.cc (4070:74449a198a44)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

199 new_entry->used = true;
200 usedEntries++;
201 }
202
203}
204
205
206TlbEntry*
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

199 new_entry->used = true;
200 usedEntries++;
201 }
202
203}
204
205
206TlbEntry*
207TLB::lookup(Addr va, int partition_id, bool real, int context_id)
207TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool
208 update_used)
208{
209 MapIter i;
210 TlbRange tr;
211 TlbEntry *t;
212
213 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
214 va, partition_id, context_id, real);
215 // Assemble full address structure

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

225 DPRINTF(TLB, "TLB: No valid entry found\n");
226 return NULL;
227 }
228
229 // Mark the entries used bit and clear other used bits in needed
230 t = i->second;
231 DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(),
232 t->pte.size());
209{
210 MapIter i;
211 TlbRange tr;
212 TlbEntry *t;
213
214 DPRINTF(TLB, "TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
215 va, partition_id, context_id, real);
216 // Assemble full address structure

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

226 DPRINTF(TLB, "TLB: No valid entry found\n");
227 return NULL;
228 }
229
230 // Mark the entries used bit and clear other used bits in needed
231 t = i->second;
232 DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(),
233 t->pte.size());
233 if (!t->used) {
234
235 // Update the used bits only if this is a real access (not a fake one from
236 // virttophys()
237 if (!t->used && update_used) {
234 t->used = true;
235 usedEntries++;
236 if (usedEntries == size) {
237 clearUsedBits();
238 t->used = true;
239 usedEntries++;
240 }
241 }

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

792 if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
793 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
794 return new DataAccessException;
795 }
796 goto regAccessOk;
797
798handleSparcErrorRegAccess:
799 if (!hpriv) {
238 t->used = true;
239 usedEntries++;
240 if (usedEntries == size) {
241 clearUsedBits();
242 t->used = true;
243 usedEntries++;
244 }
245 }

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

796 if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
797 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
798 return new DataAccessException;
799 }
800 goto regAccessOk;
801
802handleSparcErrorRegAccess:
803 if (!hpriv) {
800 if (priv) {
801 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
804 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
805 if (priv)
802 return new DataAccessException;
806 return new DataAccessException;
803 } else {
804 writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
807 else
805 return new PrivilegedAction;
808 return new PrivilegedAction;
806 }
807 }
808 goto regAccessOk;
809
810
811regAccessOk:
812handleMmuRegAccess:
813 DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
814 req->setMmapedIpr(true);
815 req->setPaddr(req->getVaddr());
816 return NoFault;
817};
818
819Tick
820DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
821{
822 Addr va = pkt->getAddr();
823 ASI asi = (ASI)pkt->req->getAsi();
809 }
810 goto regAccessOk;
811
812
813regAccessOk:
814handleMmuRegAccess:
815 DPRINTF(TLB, "TLB: DTB Translating MM IPR access\n");
816 req->setMmapedIpr(true);
817 req->setPaddr(req->getVaddr());
818 return NoFault;
819};
820
821Tick
822DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
823{
824 Addr va = pkt->getAddr();
825 ASI asi = (ASI)pkt->req->getAsi();
824 uint64_t temp, data;
825 uint64_t tsbtemp, cnftemp;
826 uint64_t temp;
826
827 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
828 (uint32_t)pkt->req->getAsi(), pkt->getAddr());
829
830 switch (asi) {
831 case ASI_LSU_CONTROL_REG:
832 assert(va == 0);
833 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL));

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

937 case 0x80:
938 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID));
939 break;
940 default:
941 goto doMmuReadError;
942 }
943 break;
944 case ASI_DMMU_TSB_PS0_PTR_REG:
827
828 DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
829 (uint32_t)pkt->req->getAsi(), pkt->getAddr());
830
831 switch (asi) {
832 case ASI_LSU_CONTROL_REG:
833 assert(va == 0);
834 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL));

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

938 case 0x80:
939 pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID));
940 break;
941 default:
942 goto doMmuReadError;
943 }
944 break;
945 case ASI_DMMU_TSB_PS0_PTR_REG:
945 temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
946 if (bits(temp,12,0) == 0) {
947 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0);
948 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
949 } else {
950 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0);
951 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
952 }
953 data = mbits(tsbtemp,63,13);
954 data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
955 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
956 pkt->set(data);
946 pkt->set(MakeTsbPtr(Ps0,
947 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS),
948 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0),
949 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG),
950 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0),
951 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG)));
957 break;
958 case ASI_DMMU_TSB_PS1_PTR_REG:
952 break;
953 case ASI_DMMU_TSB_PS1_PTR_REG:
959 temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
960 if (bits(temp,12,0) == 0) {
961 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1);
962 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
963 } else {
964 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
965 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
966 }
967 data = mbits(tsbtemp,63,13);
968 if (bits(tsbtemp,12,12))
969 data |= ULL(1) << (13+bits(tsbtemp,3,0));
970 data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
971 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
972 pkt->set(data);
954 pkt->set(MakeTsbPtr(Ps1,
955 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS),
956 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1),
957 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG),
958 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1),
959 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG)));
973 break;
974 case ASI_IMMU_TSB_PS0_PTR_REG:
960 break;
961 case ASI_IMMU_TSB_PS0_PTR_REG:
975 temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
976 if (bits(temp,12,0) == 0) {
977 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0);
978 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
979 } else {
980 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0);
981 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
982 }
983 data = mbits(tsbtemp,63,13);
984 data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
985 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
986 pkt->set(data);
962 pkt->set(MakeTsbPtr(Ps0,
963 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS),
964 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0),
965 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG),
966 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0),
967 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG)));
987 break;
988 case ASI_IMMU_TSB_PS1_PTR_REG:
968 break;
969 case ASI_IMMU_TSB_PS1_PTR_REG:
989 temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
990 if (bits(temp,12,0) == 0) {
991 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1);
992 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
993 } else {
994 tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1);
995 cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
996 }
997 data = mbits(tsbtemp,63,13);
998 if (bits(tsbtemp,12,12))
999 data |= ULL(1) << (13+bits(tsbtemp,3,0));
1000 data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
1001 mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
1002 pkt->set(data);
970 pkt->set(MakeTsbPtr(Ps1,
971 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS),
972 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1),
973 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG),
974 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1),
975 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG)));
1003 break;
1004
1005 default:
1006doMmuReadError:
1007 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
1008 (uint32_t)asi, va);
1009 }
1010 pkt->result = Packet::Success;

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

1240 panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
1241 (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data);
1242 }
1243 pkt->result = Packet::Success;
1244 return tc->getCpuPtr()->cycles(1);
1245}
1246
1247void
976 break;
977
978 default:
979doMmuReadError:
980 panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
981 (uint32_t)asi, va);
982 }
983 pkt->result = Packet::Success;

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

1213 panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
1214 (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data);
1215 }
1216 pkt->result = Packet::Success;
1217 return tc->getCpuPtr()->cycles(1);
1218}
1219
1220void
1221DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
1222{
1223 uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0);
1224 ptrs[0] = MakeTsbPtr(Ps0, tag_access,
1225 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0),
1226 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG),
1227 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0),
1228 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG));
1229 ptrs[1] = MakeTsbPtr(Ps1, tag_access,
1230 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1),
1231 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG),
1232 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1),
1233 tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG));
1234 ptrs[2] = MakeTsbPtr(Ps0, tag_access,
1235 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0),
1236 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG),
1237 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0),
1238 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
1239 ptrs[3] = MakeTsbPtr(Ps1, tag_access,
1240 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1),
1241 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG),
1242 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1),
1243 tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
1244}
1245
1246
1247
1248
1249
1250uint64_t
1251DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
1252 uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
1253{
1254 uint64_t tsb;
1255 uint64_t config;
1256
1257 if (bits(tag_access, 12,0) == 0) {
1258 tsb = c0_tsb;
1259 config = c0_config;
1260 } else {
1261 tsb = cX_tsb;
1262 config = cX_config;
1263 }
1264
1265 uint64_t ptr = mbits(tsb,63,13);
1266 bool split = bits(tsb,12,12);
1267 int tsb_size = bits(tsb,3,0);
1268 int page_size = (ps == Ps0) ? bits(config, 2,0) : bits(config,10,8);
1269
1270 if (ps == Ps1 && split)
1271 ptr |= ULL(1) << (13 + tsb_size);
1272 ptr |= (tag_access >> (9 + page_size * 3)) & mask(12+tsb_size, 4);
1273
1274 return ptr;
1275}
1276
1277
1278void
1248TLB::serialize(std::ostream &os)
1249{
1250 SERIALIZE_SCALAR(size);
1251 SERIALIZE_SCALAR(usedEntries);
1252 SERIALIZE_SCALAR(lastReplaced);
1253
1254 // convert the pointer based free list into an index based one
1255 int *free_list = (int*)malloc(sizeof(int) * size);

--- 88 unchanged lines hidden ---
1279TLB::serialize(std::ostream &os)
1280{
1281 SERIALIZE_SCALAR(size);
1282 SERIALIZE_SCALAR(usedEntries);
1283 SERIALIZE_SCALAR(lastReplaced);
1284
1285 // convert the pointer based free list into an index based one
1286 int *free_list = (int*)malloc(sizeof(int) * size);

--- 88 unchanged lines hidden ---