gem5  v20.1.0.0
helpers.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include "kern/linux/helpers.hh"
39 
40 #include "config/the_isa.hh"
41 #include "cpu/thread_context.hh"
42 #include "mem/port_proxy.hh"
43 #include "sim/byteswap.hh"
44 #include "sim/system.hh"
45 
46 struct DmesgEntry {
47  uint64_t ts_nsec;
48  uint16_t len;
49  uint16_t text_len;
50  uint16_t dict_len;
51  uint8_t facility;
52  uint8_t flags;
54 
55 static int
56 dumpDmesgEntry(const uint8_t *base, const uint8_t *end, const ByteOrder bo,
57  std::ostream &os)
58 {
59  const size_t max_length = end - base;
60  DmesgEntry de;
61 
62  if (max_length < sizeof(de)) {
63  warn("Malformed dmesg entry\n");
64  return -1;
65  }
66 
67  memcpy(&de, base, sizeof(de));
68  de.ts_nsec = gtoh(de.ts_nsec, bo);
69  de.len = gtoh(de.len, bo);
70  de.text_len = gtoh(de.text_len, bo);
71 
72  if (de.len < sizeof(de) ||
73  max_length < de.len ||
74  max_length < sizeof(DmesgEntry) + de.text_len) {
75 
76  warn("Malformed dmesg entry:\n");
77  warn("\tMax length: %i\n", max_length);
78  warn("\tde.len: %i\n", de.len);
79  warn("\tde.text_len: %i\n", de.text_len);
80  return -1;
81  }
82 
83  ccprintf(os, "[%.6f] ", de.ts_nsec * 10e-9);
84  os.write((char *)base + sizeof(de), de.text_len);
85  os << std::endl;
86 
87  return de.len;
88 }
89 
90 void
91 Linux::dumpDmesg(ThreadContext *tc, std::ostream &os)
92 {
93  System *system = tc->getSystemPtr();
94  const ByteOrder bo = system->getGuestByteOrder();
95  const auto &symtab = system->workload->symtab(tc);
96  PortProxy &proxy = tc->getVirtProxy();
97 
98  auto lb = symtab.find("__log_buf");
99  auto lb_len = symtab.find("log_buf_len");
100  auto first = symtab.find("log_first_idx");
101  auto next = symtab.find("log_next_idx");
102 
103  auto end_it = symtab.end();
104 
105  if (lb == end_it || lb_len == end_it ||
106  first == end_it || next == end_it) {
107  warn("Failed to find kernel dmesg symbols.\n");
108  return;
109  }
110 
111  uint32_t log_buf_len = proxy.read<uint32_t>(lb_len->address, bo);
112  uint32_t log_first_idx = proxy.read<uint32_t>(first->address, bo);
113  uint32_t log_next_idx = proxy.read<uint32_t>(next->address, bo);
114 
115  if (log_first_idx >= log_buf_len || log_next_idx >= log_buf_len) {
116  warn("dmesg pointers/length corrupted\n");
117  return;
118  }
119 
120  // Normalize and read the dmesg ring buffer
121  std::vector<uint8_t> log_buf(log_buf_len);
122  int length;
123  if (log_first_idx < log_next_idx) {
124  length = log_next_idx - log_first_idx;
125  if (length < 0 || length > log_buf.size()) {
126  warn("Unexpected dmesg buffer length\n");
127  return;
128  }
129  proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length);
130  } else {
131  const int length_2 = log_buf_len - log_first_idx;
132  if (length_2 < 0 || length_2 + log_next_idx > log_buf.size()) {
133  warn("Unexpected dmesg buffer length\n");
134  return;
135  }
136  length = log_buf_len;
137  proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length_2);
138  proxy.readBlob(lb->address, log_buf.data() + length_2, log_next_idx);
139  }
140 
141  // Print dmesg buffer content
142  const uint8_t *cur = log_buf.data(), *end = log_buf.data() + length;
143  while (cur < end) {
144  int ret = dumpDmesgEntry(cur, end, bo, os);
145  if (ret < 0)
146  return;
147  cur += ret;
148  }
149 }
X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:803
warn
#define warn(...)
Definition: logging.hh:239
length
uint8_t length
Definition: inet.hh:422
M5_ATTR_PACKED
struct DmesgEntry M5_ATTR_PACKED
DmesgEntry::dict_len
uint16_t dict_len
Definition: helpers.cc:50
system.hh
DmesgEntry::facility
uint8_t facility
Definition: helpers.cc:51
PowerISA::bo
Bitfield< 25, 21 > bo
Definition: types.hh:62
X86ISA::base
Bitfield< 51, 12 > base
Definition: pagetable.hh:141
helpers.hh
std::vector< uint8_t >
DmesgEntry::flags
uint8_t flags
Definition: helpers.cc:52
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
DmesgEntry::ts_nsec
uint64_t ts_nsec
Definition: helpers.cc:47
System
Definition: system.hh:73
DmesgEntry
Definition: helpers.cc:46
port_proxy.hh
DmesgEntry::len
uint16_t len
Definition: helpers.cc:48
DmesgEntry::text_len
uint16_t text_len
Definition: helpers.cc:49
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
ThreadContext::getVirtProxy
virtual PortProxy & getVirtProxy()=0
X86ISA::de
Bitfield< 3 > de
Definition: misc.hh:635
PortProxy
This object is a proxy for a port or other object which implements the functional response protocol,...
Definition: port_proxy.hh:80
PortProxy::read
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:282
dumpDmesgEntry
static int dumpDmesgEntry(const uint8_t *base, const uint8_t *end, const ByteOrder bo, std::ostream &os)
Definition: helpers.cc:56
ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
Linux::dumpDmesg
void dumpDmesg(ThreadContext *tc, std::ostream &os)
Dump Linux's dmesg log buffer to the an output stream.
gtoh
T gtoh(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:162
PortProxy::readBlob
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Definition: port_proxy.hh:177
thread_context.hh
byteswap.hh
ThreadContext::getSystemPtr
virtual System * getSystemPtr()=0

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17