generic_timer.cc (10845:75df7a87be83) | generic_timer.cc (10847:1826ee736709) |
---|---|
1/* 2 * Copyright (c) 2013, 2015 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 29 unchanged lines hidden (view full) --- 38 * Andreas Sandberg 39 */ 40 41#include "dev/arm/generic_timer.hh" 42 43#include "arch/arm/system.hh" 44#include "debug/Timer.hh" 45#include "dev/arm/base_gic.hh" | 1/* 2 * Copyright (c) 2013, 2015 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 29 unchanged lines hidden (view full) --- 38 * Andreas Sandberg 39 */ 40 41#include "dev/arm/generic_timer.hh" 42 43#include "arch/arm/system.hh" 44#include "debug/Timer.hh" 45#include "dev/arm/base_gic.hh" |
46#include "mem/packet_access.hh" |
|
46#include "params/GenericTimer.hh" | 47#include "params/GenericTimer.hh" |
48#include "params/GenericTimerMem.hh" |
|
47 48SystemCounter::SystemCounter() 49 : _freq(0), _period(0), _resetTick(0), _regCntkctl(0) 50{ 51 setFreq(0x01800000); 52} 53 54void --- 419 unchanged lines hidden (view full) --- 474 475 default: 476 warn("Reading from unknown register: %s\n", miscRegName[reg]); 477 return 0; 478 } 479} 480 481 | 49 50SystemCounter::SystemCounter() 51 : _freq(0), _period(0), _resetTick(0), _regCntkctl(0) 52{ 53 setFreq(0x01800000); 54} 55 56void --- 419 unchanged lines hidden (view full) --- 476 477 default: 478 warn("Reading from unknown register: %s\n", miscRegName[reg]); 479 return 0; 480 } 481} 482 483 |
484 485GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p) 486 : PioDevice(p), 487 ctrlRange(RangeSize(p->base, TheISA::PageBytes)), 488 timerRange(RangeSize(p->base + TheISA::PageBytes, TheISA::PageBytes)), 489 addrRanges{ctrlRange, timerRange}, 490 systemCounter(), 491 physTimer(csprintf("%s.phys_timer0", name()), 492 *this, systemCounter, 493 ArchTimer::Interrupt(*p->gic, p->int_phys)), 494 virtTimer(csprintf("%s.virt_timer0", name()), 495 *this, systemCounter, 496 ArchTimer::Interrupt(*p->gic, p->int_virt)) 497{ 498} 499 500void 501GenericTimerMem::serialize(std::ostream &os) 502{ 503 paramOut(os, "timer_count", 1); 504 505 nameOut(os, csprintf("%s.sys_counter", name())); 506 systemCounter.serialize(os); 507 508 nameOut(os, physTimer.name()); 509 physTimer.serialize(os); 510 511 nameOut(os, virtTimer.name()); 512 virtTimer.serialize(os); 513} 514 515void 516GenericTimerMem::unserialize(Checkpoint *cp, const std::string §ion) 517{ 518 systemCounter.unserialize(cp, csprintf("%s.sys_counter", section)); 519 520 unsigned timer_count; 521 UNSERIALIZE_SCALAR(timer_count); 522 // The timer count variable is just here for future versions where 523 // we support more than one set of timers. 524 if (timer_count != 1) 525 panic("Incompatible checkpoint: Only one set of timers supported"); 526 527 physTimer.unserialize(cp, csprintf("%s.phys_timer0", section)); 528 virtTimer.unserialize(cp, csprintf("%s.virt_timer0", section)); 529} 530 531Tick 532GenericTimerMem::read(PacketPtr pkt) 533{ 534 const unsigned size(pkt->getSize()); 535 const Addr addr(pkt->getAddr()); 536 uint64_t value; 537 538 pkt->makeResponse(); 539 if (ctrlRange.contains(addr)) { 540 value = ctrlRead(addr - ctrlRange.start(), size); 541 } else if (timerRange.contains(addr)) { 542 value = timerRead(addr - timerRange.start(), size); 543 } else { 544 panic("Invalid address: 0x%x\n", addr); 545 } 546 547 DPRINTF(Timer, "Read 0x%x <- 0x%x(%i)\n", value, addr, size); 548 549 if (size == 8) { 550 pkt->set<uint64_t>(value); 551 } else if (size == 4) { 552 pkt->set<uint32_t>(value); 553 } else { 554 panic("Unexpected access size: %i\n", size); 555 } 556 557 return 0; 558} 559 560Tick 561GenericTimerMem::write(PacketPtr pkt) 562{ 563 const unsigned size(pkt->getSize()); 564 if (size != 8 && size != 4) 565 panic("Unexpected access size\n"); 566 567 const Addr addr(pkt->getAddr()); 568 const uint64_t value(size == 8 ? 569 pkt->get<uint64_t>() : pkt->get<uint32_t>()); 570 571 DPRINTF(Timer, "Write 0x%x -> 0x%x(%i)\n", value, addr, size); 572 if (ctrlRange.contains(addr)) { 573 ctrlWrite(addr - ctrlRange.start(), size, value); 574 } else if (timerRange.contains(addr)) { 575 timerWrite(addr - timerRange.start(), size, value); 576 } else { 577 panic("Invalid address: 0x%x\n", addr); 578 } 579 580 pkt->makeResponse(); 581 return 0; 582} 583 584uint64_t 585GenericTimerMem::ctrlRead(Addr addr, size_t size) const 586{ 587 if (size == 4) { 588 switch (addr) { 589 case CTRL_CNTFRQ: 590 return systemCounter.freq(); 591 592 case CTRL_CNTTIDR: 593 return 0x3; // Frame 0 implemented with virtual timers 594 595 case CTRL_CNTNSAR: 596 case CTRL_CNTACR_BASE: 597 warn("Reading from unimplemented control register (0x%x)\n", addr); 598 return 0; 599 600 case CTRL_CNTVOFF_LO_BASE: 601 return virtTimer.offset(); 602 603 case CTRL_CNTVOFF_HI_BASE: 604 return virtTimer.offset() >> 32; 605 606 default: 607 warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size); 608 return 0; 609 } 610 } else if (size == 8) { 611 switch (addr) { 612 case CTRL_CNTVOFF_LO_BASE: 613 return virtTimer.offset(); 614 615 default: 616 warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size); 617 return 0; 618 } 619 } else { 620 panic("Invalid access size: %i\n", size); 621 } 622} 623 624void 625GenericTimerMem::ctrlWrite(Addr addr, size_t size, uint64_t value) 626{ 627 if (size == 4) { 628 switch (addr) { 629 case CTRL_CNTFRQ: 630 case CTRL_CNTNSAR: 631 case CTRL_CNTTIDR: 632 case CTRL_CNTACR_BASE: 633 warn("Write to unimplemented control register (0x%x)\n", addr); 634 return; 635 636 case CTRL_CNTVOFF_LO_BASE: 637 virtTimer.setOffset( 638 insertBits(virtTimer.offset(), 31, 0, value)); 639 return; 640 641 case CTRL_CNTVOFF_HI_BASE: 642 virtTimer.setOffset( 643 insertBits(virtTimer.offset(), 63, 32, value)); 644 return; 645 646 default: 647 warn("Ignoring write to unexpected address (0x%x:%i)\n", 648 addr, size); 649 return; 650 } 651 } else if (size == 8) { 652 switch (addr) { 653 case CTRL_CNTVOFF_LO_BASE: 654 virtTimer.setOffset(value); 655 return; 656 657 default: 658 warn("Ignoring write to unexpected address (0x%x:%i)\n", 659 addr, size); 660 return; 661 } 662 } else { 663 panic("Invalid access size: %i\n", size); 664 } 665} 666 667uint64_t 668GenericTimerMem::timerRead(Addr addr, size_t size) const 669{ 670 if (size == 4) { 671 switch (addr) { 672 case TIMER_CNTPCT_LO: 673 return physTimer.value(); 674 675 case TIMER_CNTPCT_HI: 676 return physTimer.value() >> 32; 677 678 case TIMER_CNTVCT_LO: 679 return virtTimer.value(); 680 681 case TIMER_CNTVCT_HI: 682 return virtTimer.value() >> 32; 683 684 case TIMER_CNTFRQ: 685 return systemCounter.freq(); 686 687 case TIMER_CNTEL0ACR: 688 warn("Read from unimplemented timer register (0x%x)\n", addr); 689 return 0; 690 691 case CTRL_CNTVOFF_LO_BASE: 692 return virtTimer.offset(); 693 694 case CTRL_CNTVOFF_HI_BASE: 695 return virtTimer.offset() >> 32; 696 697 case TIMER_CNTP_CVAL_LO: 698 return physTimer.compareValue(); 699 700 case TIMER_CNTP_CVAL_HI: 701 return physTimer.compareValue() >> 32; 702 703 case TIMER_CNTP_TVAL: 704 return physTimer.timerValue(); 705 706 case TIMER_CNTP_CTL: 707 return physTimer.control(); 708 709 case TIMER_CNTV_CVAL_LO: 710 return virtTimer.compareValue(); 711 712 case TIMER_CNTV_CVAL_HI: 713 return virtTimer.compareValue() >> 32; 714 715 case TIMER_CNTV_TVAL: 716 return virtTimer.timerValue(); 717 718 case TIMER_CNTV_CTL: 719 return virtTimer.control(); 720 721 default: 722 warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size); 723 return 0; 724 } 725 } else if (size == 8) { 726 switch (addr) { 727 case TIMER_CNTPCT_LO: 728 return physTimer.value(); 729 730 case TIMER_CNTVCT_LO: 731 return virtTimer.value(); 732 733 case CTRL_CNTVOFF_LO_BASE: 734 return virtTimer.offset(); 735 736 case TIMER_CNTP_CVAL_LO: 737 return physTimer.compareValue(); 738 739 case TIMER_CNTV_CVAL_LO: 740 return virtTimer.compareValue(); 741 742 default: 743 warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size); 744 return 0; 745 } 746 } else { 747 panic("Invalid access size: %i\n", size); 748 } 749} 750 751void 752GenericTimerMem::timerWrite(Addr addr, size_t size, uint64_t value) 753{ 754 if (size == 4) { 755 switch (addr) { 756 case TIMER_CNTEL0ACR: 757 warn("Unimplemented timer register (0x%x)\n", addr); 758 return; 759 760 case TIMER_CNTP_CVAL_LO: 761 physTimer.setCompareValue( 762 insertBits(physTimer.compareValue(), 31, 0, value)); 763 return; 764 765 case TIMER_CNTP_CVAL_HI: 766 physTimer.setCompareValue( 767 insertBits(physTimer.compareValue(), 63, 32, value)); 768 return; 769 770 case TIMER_CNTP_TVAL: 771 physTimer.setTimerValue(value); 772 return; 773 774 case TIMER_CNTP_CTL: 775 physTimer.setControl(value); 776 return; 777 778 case TIMER_CNTV_CVAL_LO: 779 virtTimer.setCompareValue( 780 insertBits(virtTimer.compareValue(), 31, 0, value)); 781 return; 782 783 case TIMER_CNTV_CVAL_HI: 784 virtTimer.setCompareValue( 785 insertBits(virtTimer.compareValue(), 63, 32, value)); 786 return; 787 788 case TIMER_CNTV_TVAL: 789 virtTimer.setTimerValue(value); 790 return; 791 792 case TIMER_CNTV_CTL: 793 virtTimer.setControl(value); 794 return; 795 796 default: 797 warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size); 798 return; 799 } 800 } else if (size == 8) { 801 switch (addr) { 802 case TIMER_CNTP_CVAL_LO: 803 return physTimer.setCompareValue(value); 804 805 case TIMER_CNTV_CVAL_LO: 806 return virtTimer.setCompareValue(value); 807 808 default: 809 warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size); 810 return; 811 } 812 } else { 813 panic("Invalid access size: %i\n", size); 814 } 815} 816 |
|
482GenericTimer * 483GenericTimerParams::create() 484{ 485 return new GenericTimer(this); 486} | 817GenericTimer * 818GenericTimerParams::create() 819{ 820 return new GenericTimer(this); 821} |
822 823GenericTimerMem * 824GenericTimerMemParams::create() 825{ 826 return new GenericTimerMem(this); 827} |
|