2 * Copyright 2019 Google Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "sim/kernel_workload.hh"
30 #include "debug/Loader.hh"
31 #include "params/KernelWorkload.hh"
32 #include "sim/system.hh"
34 KernelWorkload::KernelWorkload(const Params
&p
) : Workload(p
), _params(p
),
35 _loadAddrMask(p
.load_addr_mask
), _loadAddrOffset(p
.load_addr_offset
),
36 commandLine(p
.command_line
)
38 if (params().object_file
== "") {
39 inform("No kernel set for full system simulation. "
40 "Assuming you know what you're doing.");
42 kernelObj
= Loader::createObjectFile(params().object_file
);
43 inform("kernel located at: %s", params().object_file
);
46 "Could not load kernel file %s", params().object_file
);
48 image
= kernelObj
->buildImage();
50 _start
= image
.minAddr();
51 _end
= image
.maxAddr();
53 // If load_addr_mask is set to 0x0, then calculate the smallest mask to
54 // cover all kernel addresses so gem5 can relocate the kernel to a new
56 if (_loadAddrMask
== 0)
57 _loadAddrMask
= mask(findMsbSet(_end
- _start
) + 1);
59 image
.move([this](Addr a
) {
60 return (a
& _loadAddrMask
) + _loadAddrOffset
;
63 kernelSymtab
= kernelObj
->symtab();
64 Loader::debugSymbolTable
.insert(kernelSymtab
);
67 // Loading only needs to happen once and after memory system is
68 // connected so it will happen in initState()
70 std::vector
<Addr
> extras_addrs
= p
.extras_addrs
;
71 if (extras_addrs
.empty())
72 extras_addrs
.resize(p
.extras
.size(), MaxAddr
);
73 fatal_if(p
.extras
.size() != extras_addrs
.size(),
74 "Additional kernel objects, not all load addresses specified\n");
75 for (int ker_idx
= 0; ker_idx
< p
.extras
.size(); ker_idx
++) {
76 const std::string
&obj_name
= p
.extras
[ker_idx
];
77 const bool raw
= extras_addrs
[ker_idx
] != MaxAddr
;
78 auto *obj
= Loader::createObjectFile(obj_name
, raw
);
79 fatal_if(!obj
, "Failed to build additional kernel object '%s'.\n",
81 extras
.push_back(obj
);
86 KernelWorkload::initState()
88 auto &phys_mem
= system
->physProxy
;
90 * Load the kernel code into memory.
92 auto mapper
= [this](Addr a
) {
93 return (a
& _loadAddrMask
) + _loadAddrOffset
;
95 if (params().object_file
!= "") {
96 if (params().addr_check
) {
97 // Validate kernel mapping before loading binary
98 fatal_if(!system
->isMemAddr(mapper(_start
)) ||
99 !system
->isMemAddr(mapper(_end
)),
100 "Kernel is mapped to invalid location (not memory). "
101 "start (%#x) - end (%#x) %#x:%#x\n",
102 _start
, _end
, mapper(_start
), mapper(_end
));
104 // Load program sections into memory
105 image
.write(phys_mem
);
107 DPRINTF(Loader
, "Kernel start = %#x\n", _start
);
108 DPRINTF(Loader
, "Kernel end = %#x\n", _end
);
109 DPRINTF(Loader
, "Kernel entry = %#x\n", kernelObj
->entryPoint());
110 DPRINTF(Loader
, "Kernel loaded...\n");
113 std::vector
<Addr
> extras_addrs
= params().extras_addrs
;
114 if (extras_addrs
.empty())
115 extras_addrs
.resize(params().extras
.size(), MaxAddr
);
116 for (int idx
= 0; idx
< extras
.size(); idx
++) {
117 const Addr load_addr
= extras_addrs
[idx
];
118 auto image
= extras
[idx
]->buildImage();
119 if (load_addr
!= MaxAddr
)
120 image
= image
.offset(load_addr
);
122 image
= image
.move(mapper
);
123 image
.write(phys_mem
);
128 KernelWorkload::serialize(CheckpointOut
&cp
) const
130 kernelSymtab
.serialize("symtab", cp
);
134 KernelWorkload::unserialize(CheckpointIn
&cp
)
136 kernelSymtab
.unserialize("symtab", cp
);