pagetable_walker.cc (5895:569e3b31a868) | pagetable_walker.cc (5897:29cecf4fe602) |
---|---|
1/* 2 * Copyright (c) 2007 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 71 unchanged lines hidden (view full) --- 80 Bitfield<4> pcd; 81 Bitfield<3> pwt; 82 Bitfield<2> u; 83 Bitfield<1> w; 84 Bitfield<0> p; 85EndBitUnion(PageTableEntry) 86 87Fault | 1/* 2 * Copyright (c) 2007 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 71 unchanged lines hidden (view full) --- 80 Bitfield<4> pcd; 81 Bitfield<3> pwt; 82 Bitfield<2> u; 83 Bitfield<1> w; 84 Bitfield<0> p; 85EndBitUnion(PageTableEntry) 86 87Fault |
88Walker::doNext(PacketPtr &read, PacketPtr &write) | 88Walker::doNext(PacketPtr &write) |
89{ 90 assert(state != Ready && state != Waiting); 91 write = NULL; 92 PageTableEntry pte; 93 if (size == 8) 94 pte = read->get<uint64_t>(); 95 else 96 pte = read->get<uint32_t>(); --- 210 unchanged lines hidden (view full) --- 307 return NoFault; 308} 309 310Fault 311Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, 312 RequestPtr _req, bool _write, bool _execute) 313{ 314 assert(state == Ready); | 89{ 90 assert(state != Ready && state != Waiting); 91 write = NULL; 92 PageTableEntry pte; 93 if (size == 8) 94 pte = read->get<uint64_t>(); 95 else 96 pte = read->get<uint32_t>(); --- 210 unchanged lines hidden (view full) --- 307 return NoFault; 308} 309 310Fault 311Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, 312 RequestPtr _req, bool _write, bool _execute) 313{ 314 assert(state == Ready); |
315 assert(!tc); | |
316 tc = _tc; 317 req = _req; 318 Addr vaddr = req->getVaddr(); 319 execute = _execute; 320 write = _write; 321 translation = _translation; 322 323 VAddr addr = vaddr; --- 37 unchanged lines hidden (view full) --- 361 Request::Flags flags = Request::PHYSICAL; 362 if (cr3.pcd) 363 flags.set(Request::UNCACHEABLE); 364 RequestPtr request = new Request(top, size, flags); 365 read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast); 366 read->allocate(); 367 Enums::MemoryMode memMode = sys->getMemoryMode(); 368 if (memMode == Enums::timing) { | 315 tc = _tc; 316 req = _req; 317 Addr vaddr = req->getVaddr(); 318 execute = _execute; 319 write = _write; 320 translation = _translation; 321 322 VAddr addr = vaddr; --- 37 unchanged lines hidden (view full) --- 360 Request::Flags flags = Request::PHYSICAL; 361 if (cr3.pcd) 362 flags.set(Request::UNCACHEABLE); 363 RequestPtr request = new Request(top, size, flags); 364 read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast); 365 read->allocate(); 366 Enums::MemoryMode memMode = sys->getMemoryMode(); 367 if (memMode == Enums::timing) { |
368 nextState = state; 369 state = Waiting; |
|
369 timingFault = NoFault; | 370 timingFault = NoFault; |
370 port.sendTiming(read); | 371 sendPackets(); |
371 } else if (memMode == Enums::atomic) { 372 Fault fault; 373 do { 374 port.sendAtomic(read); 375 PacketPtr write = NULL; | 372 } else if (memMode == Enums::atomic) { 373 Fault fault; 374 do { 375 port.sendAtomic(read); 376 PacketPtr write = NULL; |
376 fault = doNext(read, write); | 377 fault = doNext(write); |
377 assert(fault == NoFault || read == NULL); 378 state = nextState; 379 nextState = Ready; 380 if (write) 381 port.sendAtomic(write); 382 } while(read); | 378 assert(fault == NoFault || read == NULL); 379 state = nextState; 380 nextState = Ready; 381 if (write) 382 port.sendAtomic(write); 383 } while(read); |
383 tc = NULL; | |
384 state = Ready; 385 nextState = Waiting; 386 return fault; 387 } else { 388 panic("Unrecognized memory system mode.\n"); 389 } 390 return NoFault; 391} 392 393bool 394Walker::WalkerPort::recvTiming(PacketPtr pkt) 395{ 396 return walker->recvTiming(pkt); 397} 398 399bool 400Walker::recvTiming(PacketPtr pkt) 401{ | 384 state = Ready; 385 nextState = Waiting; 386 return fault; 387 } else { 388 panic("Unrecognized memory system mode.\n"); 389 } 390 return NoFault; 391} 392 393bool 394Walker::WalkerPort::recvTiming(PacketPtr pkt) 395{ 396 return walker->recvTiming(pkt); 397} 398 399bool 400Walker::recvTiming(PacketPtr pkt) 401{ |
402 inflight--; | |
403 if (pkt->isResponse() && !pkt->wasNacked()) { | 402 if (pkt->isResponse() && !pkt->wasNacked()) { |
403 assert(inflight); 404 assert(state == Waiting); 405 assert(!read); 406 inflight--; |
|
404 if (pkt->isRead()) { | 407 if (pkt->isRead()) { |
405 assert(inflight); 406 assert(state == Waiting); 407 assert(!read); | |
408 state = nextState; 409 nextState = Ready; 410 PacketPtr write = NULL; | 408 state = nextState; 409 nextState = Ready; 410 PacketPtr write = NULL; |
411 timingFault = doNext(pkt, write); 412 state = Waiting; | |
413 read = pkt; | 411 read = pkt; |
412 timingFault = doNext(write); 413 state = Waiting; |
|
414 assert(timingFault == NoFault || read == NULL); 415 if (write) { 416 writes.push_back(write); 417 } 418 sendPackets(); 419 } else { 420 sendPackets(); 421 } 422 if (inflight == 0 && read == NULL && writes.size() == 0) { | 414 assert(timingFault == NoFault || read == NULL); 415 if (write) { 416 writes.push_back(write); 417 } 418 sendPackets(); 419 } else { 420 sendPackets(); 421 } 422 if (inflight == 0 && read == NULL && writes.size() == 0) { |
423 tc = NULL; | |
424 state = Ready; 425 nextState = Waiting; 426 if (timingFault == NoFault) { 427 /* 428 * Finish the translation. Now that we now the right entry is 429 * in the TLB, this should work with no memory accesses. 430 * There could be new faults unrelated to the table walk like 431 * permissions violations, so we'll need the return value as --- 8 unchanged lines hidden (view full) --- 440 } else { 441 // There was a fault during the walk. Let the CPU know. 442 translation->finish(timingFault, req, tc, write); 443 } 444 } 445 } else if (pkt->wasNacked()) { 446 pkt->reinitNacked(); 447 if (!port.sendTiming(pkt)) { | 423 state = Ready; 424 nextState = Waiting; 425 if (timingFault == NoFault) { 426 /* 427 * Finish the translation. Now that we now the right entry is 428 * in the TLB, this should work with no memory accesses. 429 * There could be new faults unrelated to the table walk like 430 * permissions violations, so we'll need the return value as --- 8 unchanged lines hidden (view full) --- 439 } else { 440 // There was a fault during the walk. Let the CPU know. 441 translation->finish(timingFault, req, tc, write); 442 } 443 } 444 } else if (pkt->wasNacked()) { 445 pkt->reinitNacked(); 446 if (!port.sendTiming(pkt)) { |
447 inflight--; |
|
448 retrying = true; 449 if (pkt->isWrite()) { 450 writes.push_back(pkt); 451 } else { 452 assert(!read); 453 read = pkt; 454 } | 448 retrying = true; 449 if (pkt->isWrite()) { 450 writes.push_back(pkt); 451 } else { 452 assert(!read); 453 read = pkt; 454 } |
455 } else { 456 inflight++; | |
457 } 458 } 459 return true; 460} 461 462Tick 463Walker::WalkerPort::recvAtomic(PacketPtr pkt) 464{ --- 37 unchanged lines hidden (view full) --- 502Walker::sendPackets() 503{ 504 //If we're already waiting for the port to become available, just return. 505 if (retrying) 506 return; 507 508 //Reads always have priority 509 if (read) { | 455 } 456 } 457 return true; 458} 459 460Tick 461Walker::WalkerPort::recvAtomic(PacketPtr pkt) 462{ --- 37 unchanged lines hidden (view full) --- 500Walker::sendPackets() 501{ 502 //If we're already waiting for the port to become available, just return. 503 if (retrying) 504 return; 505 506 //Reads always have priority 507 if (read) { |
510 if (!port.sendTiming(read)) { | 508 PacketPtr pkt = read; 509 read = NULL; 510 inflight++; 511 if (!port.sendTiming(pkt)) { |
511 retrying = true; | 512 retrying = true; |
513 read = pkt; 514 inflight--; |
|
512 return; | 515 return; |
513 } else { 514 inflight++; 515 delete read->req; 516 delete read; 517 read = NULL; | |
518 } 519 } 520 //Send off as many of the writes as we can. 521 while (writes.size()) { 522 PacketPtr write = writes.back(); | 516 } 517 } 518 //Send off as many of the writes as we can. 519 while (writes.size()) { 520 PacketPtr write = writes.back(); |
521 writes.pop_back(); 522 inflight++; |
|
523 if (!port.sendTiming(write)) { 524 retrying = true; | 523 if (!port.sendTiming(write)) { 524 retrying = true; |
525 writes.push_back(write); 526 inflight--; |
|
525 return; | 527 return; |
526 } else { 527 inflight++; 528 delete write->req; 529 delete write; 530 writes.pop_back(); | |
531 } 532 } 533} 534 535Port * 536Walker::getPort(const std::string &if_name, int idx) 537{ 538 if (if_name == "port") --- 20 unchanged lines hidden --- | 528 } 529 } 530} 531 532Port * 533Walker::getPort(const std::string &if_name, int idx) 534{ 535 if (if_name == "port") --- 20 unchanged lines hidden --- |