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 ---