summaryrefslogtreecommitdiff
path: root/src/mem/physical.hh
blob: 3fb3510b8de30d4855b6090e082b0e3c80f84c10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*
 * 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.
 *
 * Authors: Andreas Hansson
 */

#ifndef __MEM_PHYSICAL_HH__
#define __MEM_PHYSICAL_HH__

#include "base/addr_range_map.hh"
#include "mem/packet.hh"

/**
 * 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)
        : range(range), pmem(pmem), confTableReported(conf_table_reported),
          inAddrMap(in_addr_map), kvmMap(kvm_map)
        {}

    /**
     * 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;
};

/**
 * 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;

    // 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);

    /**
     * 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);

};

#endif //__MEM_PHYSICAL_HH__