| /* |
| * Copyright (c) 2012 ARM Limited |
| * All rights reserved |
| * |
| * The license below extends only to copyright in the software and shall |
| * not be construed as granting a license to any other intellectual |
| * property including but not limited to intellectual property relating |
| * to a hardware implementation of the functionality of the software |
| * licensed hereunder. You may use the software subject to the license |
| * terms below provided that you ensure that this notice is replicated |
| * unmodified and in its entirety in all distributions of the software, |
| * modified or unmodified, in source code or in binary form. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef __MEM_PHYSICAL_HH__ |
| #define __MEM_PHYSICAL_HH__ |
| |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| |
| #include "base/addr_range.hh" |
| #include "base/addr_range_map.hh" |
| #include "mem/packet.hh" |
| #include "sim/serialize.hh" |
| |
| namespace gem5 |
| { |
| |
| namespace memory |
| { |
| |
| /** |
| * Forward declaration to avoid header dependencies. |
| */ |
| class AbstractMemory; |
| |
| /** |
| * A single entry for the backing store. |
| */ |
| class BackingStoreEntry |
| { |
| public: |
| |
| /** |
| * Create a backing store entry. Don't worry about managing the memory |
| * pointers, because PhysicalMemory is responsible for that. |
| */ |
| BackingStoreEntry(AddrRange range, uint8_t* pmem, |
| bool conf_table_reported, bool in_addr_map, bool kvm_map, |
| int shm_fd=-1, off_t shm_offset=0) |
| : range(range), pmem(pmem), confTableReported(conf_table_reported), |
| inAddrMap(in_addr_map), kvmMap(kvm_map), shmFd(shm_fd), |
| shmOffset(shm_offset) |
| {} |
| |
| /** |
| * The address range covered in the guest. |
| */ |
| AddrRange range; |
| |
| /** |
| * Pointer to the host memory this range maps to. This memory is the same |
| * size as the range field. |
| */ |
| uint8_t* pmem; |
| |
| /** |
| * Whether this memory should be reported to the configuration table |
| */ |
| bool confTableReported; |
| |
| /** |
| * Whether this memory should appear in the global address map |
| */ |
| bool inAddrMap; |
| |
| /** |
| * Whether KVM should map this memory into the guest address space during |
| * acceleration. |
| */ |
| bool kvmMap; |
| |
| /** |
| * If this backing store is based on a shared memory, this is the fd to |
| * the shared memory. Otherwise, it should be -1. |
| */ |
| int shmFd; |
| |
| /** |
| * If this backing store is based on a shared memory, this is the offset |
| * of this backing store in the share memory. Otherwise, the value is 0. |
| */ |
| off_t shmOffset; |
| }; |
| |
| /** |
| * The physical memory encapsulates all memories in the system and |
| * provides basic functionality for accessing those memories without |
| * going through the memory system and interconnect. |
| * |
| * The physical memory is also responsible for providing the host |
| * system backingstore used by the memories in the simulated guest |
| * system. When the system is created, the physical memory allocates |
| * the backing store based on the address ranges that are populated in |
| * the system, and does so independent of how those map to actual |
| * memory controllers. Thus, the physical memory completely abstracts |
| * the mapping of the backing store of the host system and the address |
| * mapping in the guest system. This enables us to arbitrarily change |
| * the number of memory controllers, and their address mapping, as |
| * long as the ranges stay the same. |
| */ |
| class PhysicalMemory : public Serializable |
| { |
| |
| private: |
| |
| // Name for debugging |
| std::string _name; |
| |
| // Global address map |
| AddrRangeMap<AbstractMemory*, 1> addrMap; |
| |
| // All address-mapped memories |
| std::vector<AbstractMemory*> memories; |
| |
| // The total memory size |
| uint64_t size; |
| |
| // Let the user choose if we reserve swap space when calling mmap |
| const bool mmapUsingNoReserve; |
| |
| const std::string sharedBackstore; |
| uint64_t sharedBackstoreSize; |
| |
| long pageSize; |
| |
| // The physical memory used to provide the memory in the simulated |
| // system |
| std::vector<BackingStoreEntry> backingStore; |
| |
| // Prevent copying |
| PhysicalMemory(const PhysicalMemory&); |
| |
| // Prevent assignment |
| PhysicalMemory& operator=(const PhysicalMemory&); |
| |
| /** |
| * Create the memory region providing the backing store for a |
| * given address range that corresponds to a set of memories in |
| * the simulated system. |
| * |
| * @param range The address range covered |
| * @param memories The memories this range maps to |
| * @param kvm_map Should KVM map this memory for the guest |
| */ |
| void createBackingStore(AddrRange range, |
| const std::vector<AbstractMemory*>& _memories, |
| bool conf_table_reported, |
| bool in_addr_map, bool kvm_map); |
| |
| public: |
| |
| /** |
| * Create a physical memory object, wrapping a number of memories. |
| */ |
| PhysicalMemory(const std::string& _name, |
| const std::vector<AbstractMemory*>& _memories, |
| bool mmap_using_noreserve, |
| const std::string& shared_backstore, |
| bool auto_unlink_shared_backstore); |
| |
| /** |
| * Unmap all the backing store we have used. |
| */ |
| ~PhysicalMemory(); |
| |
| /** |
| * Return the name for debugging and for creation of sections for |
| * checkpointing. |
| */ |
| const std::string name() const { return _name; } |
| |
| /** |
| * Check if a physical address is within a range of a memory that |
| * is part of the global address map. |
| * |
| * @param addr A physical address |
| * @return Whether the address corresponds to a memory |
| */ |
| bool isMemAddr(Addr addr) const; |
| |
| /** |
| * Get the memory ranges for all memories that are to be reported |
| * to the configuration table. The ranges are merged before they |
| * are returned such that any interleaved ranges appear as a |
| * single range. |
| * |
| * @return All configuration table memory ranges |
| */ |
| AddrRangeList getConfAddrRanges() const; |
| |
| /** |
| * Get the total physical memory size. |
| * |
| * @return The sum of all memory sizes |
| */ |
| uint64_t totalSize() const { return size; } |
| |
| /** |
| * Get the pointers to the backing store for external host |
| * access. Note that memory in the guest should be accessed using |
| * access() or functionalAccess(). This interface is primarily |
| * intended for CPU models using hardware virtualization. Note |
| * that memories that are null are not present, and that the |
| * backing store may also contain memories that are not part of |
| * the OS-visible global address map and thus are allowed to |
| * overlap. |
| * |
| * @return Pointers to the memory backing store |
| */ |
| std::vector<BackingStoreEntry> getBackingStore() const |
| { return backingStore; } |
| |
| /** |
| * Perform an untimed memory access and update all the state |
| * (e.g. locked addresses) and statistics accordingly. The packet |
| * is turned into a response if required. |
| * |
| * @param pkt Packet performing the access |
| */ |
| void access(PacketPtr pkt); |
| |
| /** |
| * Perform an untimed memory read or write without changing |
| * anything but the memory itself. No stats are affected by this |
| * access. In addition to normal accesses this also facilitates |
| * print requests. |
| * |
| * @param pkt Packet performing the access |
| */ |
| void functionalAccess(PacketPtr pkt); |
| |
| /** |
| * Serialize all the memories in the system. This is independent |
| * of the logical memory layout, and the serialization only sees |
| * the contigous backing store, independent of how this maps to |
| * logical memories in the guest system. |
| * |
| * @param os stream to serialize to |
| */ |
| void serialize(CheckpointOut &cp) const override; |
| |
| /** |
| * Serialize a specific store. |
| * |
| * @param store_id Unique identifier of this backing store |
| * @param range The address range of this backing store |
| * @param pmem The host pointer to this backing store |
| */ |
| void serializeStore(CheckpointOut &cp, unsigned int store_id, |
| AddrRange range, uint8_t* pmem) const; |
| |
| /** |
| * Unserialize the memories in the system. As with the |
| * serialization, this action is independent of how the address |
| * ranges are mapped to logical memories in the guest system. |
| */ |
| void unserialize(CheckpointIn &cp) override; |
| |
| /** |
| * Unserialize a specific backing store, identified by a section. |
| */ |
| void unserializeStore(CheckpointIn &cp); |
| |
| }; |
| |
| } // namespace memory |
| } // namespace gem5 |
| |
| #endif //__MEM_PHYSICAL_HH__ |