packet.hh (10570:dcb908e40547) | packet.hh (10571:c848de089432) |
---|---|
1/* 2 * Copyright (c) 2012-2014 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 --- 638 unchanged lines hidden (view full) --- 647 648 /** 649 * Alternate constructor for copying a packet. Copy all fields 650 * *except* if the original packet's data was dynamic, don't copy 651 * that, as we can't guarantee that the new packet's lifetime is 652 * less than that of the original packet. In this case the new 653 * packet should allocate its own data. 654 */ | 1/* 2 * Copyright (c) 2012-2014 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 --- 638 unchanged lines hidden (view full) --- 647 648 /** 649 * Alternate constructor for copying a packet. Copy all fields 650 * *except* if the original packet's data was dynamic, don't copy 651 * that, as we can't guarantee that the new packet's lifetime is 652 * less than that of the original packet. In this case the new 653 * packet should allocate its own data. 654 */ |
655 Packet(PacketPtr pkt, bool clearFlags = false) | 655 Packet(PacketPtr pkt, bool clear_flags, bool alloc_data) |
656 : cmd(pkt->cmd), req(pkt->req), | 656 : cmd(pkt->cmd), req(pkt->req), |
657 data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL), | 657 data(nullptr), |
658 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size), 659 src(pkt->src), dest(pkt->dest), 660 bytesValidStart(pkt->bytesValidStart), 661 bytesValidEnd(pkt->bytesValidEnd), 662 firstWordDelay(pkt->firstWordDelay), 663 lastWordDelay(pkt->lastWordDelay), 664 senderState(pkt->senderState) 665 { | 658 addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size), 659 src(pkt->src), dest(pkt->dest), 660 bytesValidStart(pkt->bytesValidStart), 661 bytesValidEnd(pkt->bytesValidEnd), 662 firstWordDelay(pkt->firstWordDelay), 663 lastWordDelay(pkt->lastWordDelay), 664 senderState(pkt->senderState) 665 { |
666 if (!clearFlags) | 666 if (!clear_flags) |
667 flags.set(pkt->flags & COPY_FLAGS); 668 669 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE)); | 667 flags.set(pkt->flags & COPY_FLAGS); 668 669 flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE)); |
670 flags.set(pkt->flags & STATIC_DATA); | |
671 | 670 |
672 // if we did not copy the static data pointer, allocate data 673 // dynamically instead 674 if (!data) 675 allocate(); | 671 // should we allocate space for data, or not, the express 672 // snoops do not need to carry any data as they only serve to 673 // co-ordinate state changes 674 if (alloc_data) { 675 // even if asked to allocate data, if the original packet 676 // holds static data, then the sender will not be doing 677 // any memcpy on receiving the response, thus we simply 678 // carry the pointer forward 679 if (pkt->flags.isSet(STATIC_DATA)) { 680 data = pkt->data; 681 flags.set(STATIC_DATA); 682 } else { 683 allocate(); 684 } 685 } |
676 } 677 678 /** 679 * Change the packet type based on request type. 680 */ 681 void 682 refineCommand() 683 { --- 100 unchanged lines hidden (view full) --- 784 785 this->size = size; 786 flags.set(VALID_SIZE); 787 } 788 789 790 /** 791 * Set the data pointer to the following value that should not be | 686 } 687 688 /** 689 * Change the packet type based on request type. 690 */ 691 void 692 refineCommand() 693 { --- 100 unchanged lines hidden (view full) --- 794 795 this->size = size; 796 flags.set(VALID_SIZE); 797 } 798 799 800 /** 801 * Set the data pointer to the following value that should not be |
792 * freed. | 802 * freed. Static data allows us to do a single memcpy even if 803 * multiple packets are required to get from source to destination 804 * and back. In essence the pointer is set calling dataStatic on 805 * the original packet, and whenever this packet is copied and 806 * forwarded the same pointer is passed on. When a packet 807 * eventually reaches the destination holding the data, it is 808 * copied once into the location originally set. On the way back 809 * to the source, no copies are necessary. |
793 */ 794 template <typename T> 795 void 796 dataStatic(T *p) 797 { 798 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 799 data = (PacketDataPtr)p; 800 flags.set(STATIC_DATA); --- 13 unchanged lines hidden (view full) --- 814 { 815 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 816 data = const_cast<PacketDataPtr>(p); 817 flags.set(STATIC_DATA); 818 } 819 820 /** 821 * Set the data pointer to a value that should have delete [] | 810 */ 811 template <typename T> 812 void 813 dataStatic(T *p) 814 { 815 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 816 data = (PacketDataPtr)p; 817 flags.set(STATIC_DATA); --- 13 unchanged lines hidden (view full) --- 831 { 832 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 833 data = const_cast<PacketDataPtr>(p); 834 flags.set(STATIC_DATA); 835 } 836 837 /** 838 * Set the data pointer to a value that should have delete [] |
822 * called on it. | 839 * called on it. Dynamic data is local to this packet, and as the 840 * packet travels from source to destination, forwarded packets 841 * will allocate their own data. When a packet reaches the final 842 * destination it will populate the dynamic data of that specific 843 * packet, and on the way back towards the source, memcpy will be 844 * invoked in every step where a new packet was created e.g. in 845 * the caches. Ultimately when the response reaches the source a 846 * final memcpy is needed to extract the data from the packet 847 * before it is deallocated. |
823 */ 824 template <typename T> 825 void 826 dataDynamic(T *p) 827 { 828 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 829 data = (PacketDataPtr)p; 830 flags.set(DYNAMIC_DATA); --- 31 unchanged lines hidden (view full) --- 862 void set(T v); 863 864 /** 865 * Copy data into the packet from the provided pointer. 866 */ 867 void 868 setData(const uint8_t *p) 869 { | 848 */ 849 template <typename T> 850 void 851 dataDynamic(T *p) 852 { 853 assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); 854 data = (PacketDataPtr)p; 855 flags.set(DYNAMIC_DATA); --- 31 unchanged lines hidden (view full) --- 887 void set(T v); 888 889 /** 890 * Copy data into the packet from the provided pointer. 891 */ 892 void 893 setData(const uint8_t *p) 894 { |
895 // we should never be copying data onto itself, which means we 896 // must idenfity packets with static data, as they carry the 897 // same pointer from source to destination and back 898 assert(p != getPtr<uint8_t>() || flags.isSet(STATIC_DATA)); 899 |
|
870 if (p != getPtr<uint8_t>()) | 900 if (p != getPtr<uint8_t>()) |
901 // for packet with allocated dynamic data, we copy data from 902 // one to the other, e.g. a forwarded response to a response |
|
871 std::memcpy(getPtr<uint8_t>(), p, getSize()); 872 } 873 874 /** 875 * Copy data into the packet from the provided block pointer, 876 * which is aligned to the given block size. 877 */ 878 void --- 111 unchanged lines hidden --- | 903 std::memcpy(getPtr<uint8_t>(), p, getSize()); 904 } 905 906 /** 907 * Copy data into the packet from the provided block pointer, 908 * which is aligned to the given block size. 909 */ 910 void --- 111 unchanged lines hidden --- |