gem5  v21.2.1.1
printk.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "kern/linux/printk.hh"
30 
31 #include <sys/types.h>
32 
33 #include <algorithm>
34 #include <iostream>
35 #include <sstream>
36 
37 #include "base/compiler.hh"
38 #include "cpu/thread_context.hh"
39 #include "mem/port_proxy.hh"
41 
42 namespace gem5
43 {
44 
46 namespace linux
47 {
48 
49 int
50 printk(std::string &str, ThreadContext *tc, Addr format_ptr,
51  PrintkVarArgs args)
52 {
53  std::string format;
54  std::ostringstream out;
55  TranslatingPortProxy proxy(tc);
56  proxy.readString(format, format_ptr);
57 
58  const char *p = format.c_str();
59 
60  while (*p) {
61  switch (*p) {
62  case '%': {
63  bool more = true;
64  bool islong = false;
65  bool leftjustify = false;
66  bool format = false;
67  bool zero = false;
68  int width = 0;
69  while (more && *++p) {
70  switch (*p) {
71  case 'l':
72  case 'L':
73  islong = true;
74  break;
75  case '-':
76  leftjustify = true;
77  break;
78  case '#':
79  format = true;
80  break;
81  case '0':
82  if (width)
83  width *= 10;
84  else
85  zero = true;
86  break;
87  default:
88  if (*p >= '1' && *p <= '9')
89  width = 10 * width + *p - '0';
90  else
91  more = false;
92  break;
93  }
94  }
95 
96  bool hexnum = false;
97  bool octal = false;
98  bool sign = false;
99  switch (*p) {
100  case 'X':
101  case 'x':
102  hexnum = true;
103  break;
104  case 'O':
105  case 'o':
106  octal = true;
107  break;
108  case 'D':
109  case 'd':
110  sign = true;
111  break;
112  case 'P':
113  format = true;
114  [[fallthrough]];
115  case 'p':
116  hexnum = true;
117  break;
118  }
119 
120  switch (*p) {
121  case 'D':
122  case 'd':
123  case 'U':
124  case 'u':
125  case 'X':
126  case 'x':
127  case 'O':
128  case 'o':
129  case 'P':
130  case 'p': {
131  if (hexnum)
132  out << std::hex;
133 
134  if (octal)
135  out << std::oct;
136 
137  if (format) {
138  if (!zero)
139  out.setf(std::ios::showbase);
140  else {
141  if (hexnum) {
142  out << "0x";
143  width -= 2;
144  } else if (octal) {
145  out << "0";
146  width -= 1;
147  }
148  }
149  }
150 
151  if (zero)
152  out.fill('0');
153 
154  if (width > 0)
155  out.width(width);
156 
157  if (leftjustify && !zero)
158  out.setf(std::ios::left);
159 
160  if (sign) {
161  if (islong)
162  out << args.get<int64_t>();
163  else
164  out << args.get<int32_t>();
165  } else {
166  if (islong)
167  out << args.get<uint64_t>();
168  else
169  out << args.get<uint32_t>();
170  }
171 
172  if (zero)
173  out.fill(' ');
174 
175  if (width > 0)
176  out.width(0);
177 
178  out << std::dec;
179  }
180  break;
181 
182  case 's': {
183  Addr s_ptr = args.get<Addr>();
184  std::string s;
185  if (s_ptr)
186  proxy.readString(s, s_ptr);
187  else
188  s = "<NULL>";
189 
190  if (width > 0)
191  out.width(width);
192  if (leftjustify)
193  out.setf(std::ios::left);
194 
195  out << s;
196  }
197  break;
198  case 'C':
199  case 'c': {
200  uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
201  uint64_t num;
202  int cwidth;
203 
204  if (islong) {
205  num = args.get<uint64_t>();
206  cwidth = sizeof(uint64_t);
207  } else {
208  num = args.get<uint32_t>();
209  cwidth = sizeof(uint32_t);
210  }
211 
212  while (cwidth-- > 0) {
213  char c = (char)(num & mask);
214  if (c)
215  out << c;
216  num >>= 8;
217  }
218  }
219  break;
220  case 'b': {
221  uint64_t n = args.get<uint64_t>();
222  Addr s_ptr = args.get<Addr>();
223  std::string s;
224  proxy.readString(s, s_ptr);
225  out << s << ": " << n;
226  }
227  break;
228  case '%':
229  out << '%';
230  break;
231  }
232  ++p;
233  }
234  break;
235  case '\n':
236  out << std::endl;
237  ++p;
238  break;
239  case '\r':
240  ++p;
241  if (*p != '\n')
242  out << std::endl;
243  break;
244 
245  default: {
246  size_t len = strcspn(p, "%\n\r\0");
247  out.write(p, len);
248  p += len;
249  }
250  }
251  }
252 
253  str = out.str();
254  return str.length();
255 }
256 
257 } // namespace linux
258 } // namespace gem5
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:445
gem5::ArmISA::format
Bitfield< 31, 29 > format
Definition: misc_types.hh:647
gem5::linux::printk
int printk(std::string &str, ThreadContext *tc, Addr format_ptr, PrintkVarArgs args)
Definition: printk.cc:50
gem5::PortProxy::readString
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:260
translating_port_proxy.hh
gem5::guest_abi::VarArgs::get
Arg get()
Definition: varargs.hh:165
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::TranslatingPortProxy
This proxy attempts to translate virtual addresses using the TLBs.
Definition: translating_port_proxy.hh:60
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:94
gem5::ArmISA::width
Bitfield< 4 > width
Definition: misc_types.hh:72
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ArmISA::s
Bitfield< 4 > s
Definition: misc_types.hh:562
port_proxy.hh
compiler.hh
gem5::ArmISA::c
Bitfield< 29 > c
Definition: misc_types.hh:53
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::GEM5_DEPRECATED_NAMESPACE
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:456
gem5::guest_abi::VarArgs
Definition: varargs.hh:150
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: tlb.cc:60
thread_context.hh
gem5::loader::Linux
@ Linux
Definition: object_file.hh:73
printk.hh

Generated on Wed May 4 2022 12:13:59 for gem5 by doxygen 1.8.17