gem5  v21.1.0.2
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"
40 
41 namespace gem5
42 {
43 
45 namespace linux
46 {
47 
48 int
49 printk(std::string &str, ThreadContext *tc, Addr format_ptr,
50  PrintkVarArgs args)
51 {
52  std::string format;
53  std::ostringstream out;
54  tc->getVirtProxy().readString(format, format_ptr);
55 
56  const char *p = format.c_str();
57 
58  while (*p) {
59  switch (*p) {
60  case '%': {
61  bool more = true;
62  bool islong = false;
63  bool leftjustify = false;
64  bool format = false;
65  bool zero = false;
66  int width = 0;
67  while (more && *++p) {
68  switch (*p) {
69  case 'l':
70  case 'L':
71  islong = true;
72  break;
73  case '-':
74  leftjustify = true;
75  break;
76  case '#':
77  format = true;
78  break;
79  case '0':
80  if (width)
81  width *= 10;
82  else
83  zero = true;
84  break;
85  default:
86  if (*p >= '1' && *p <= '9')
87  width = 10 * width + *p - '0';
88  else
89  more = false;
90  break;
91  }
92  }
93 
94  bool hexnum = false;
95  bool octal = false;
96  bool sign = false;
97  switch (*p) {
98  case 'X':
99  case 'x':
100  hexnum = true;
101  break;
102  case 'O':
103  case 'o':
104  octal = true;
105  break;
106  case 'D':
107  case 'd':
108  sign = true;
109  break;
110  case 'P':
111  format = true;
113  case 'p':
114  hexnum = true;
115  break;
116  }
117 
118  switch (*p) {
119  case 'D':
120  case 'd':
121  case 'U':
122  case 'u':
123  case 'X':
124  case 'x':
125  case 'O':
126  case 'o':
127  case 'P':
128  case 'p': {
129  if (hexnum)
130  out << std::hex;
131 
132  if (octal)
133  out << std::oct;
134 
135  if (format) {
136  if (!zero)
137  out.setf(std::ios::showbase);
138  else {
139  if (hexnum) {
140  out << "0x";
141  width -= 2;
142  } else if (octal) {
143  out << "0";
144  width -= 1;
145  }
146  }
147  }
148 
149  if (zero)
150  out.fill('0');
151 
152  if (width > 0)
153  out.width(width);
154 
155  if (leftjustify && !zero)
156  out.setf(std::ios::left);
157 
158  if (sign) {
159  if (islong)
160  out << args.get<int64_t>();
161  else
162  out << args.get<int32_t>();
163  } else {
164  if (islong)
165  out << args.get<uint64_t>();
166  else
167  out << args.get<uint32_t>();
168  }
169 
170  if (zero)
171  out.fill(' ');
172 
173  if (width > 0)
174  out.width(0);
175 
176  out << std::dec;
177  }
178  break;
179 
180  case 's': {
181  Addr s_ptr = args.get<Addr>();
182  std::string s;
183  if (s_ptr)
184  tc->getVirtProxy().readString(s, s_ptr);
185  else
186  s = "<NULL>";
187 
188  if (width > 0)
189  out.width(width);
190  if (leftjustify)
191  out.setf(std::ios::left);
192 
193  out << s;
194  }
195  break;
196  case 'C':
197  case 'c': {
198  uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
199  uint64_t num;
200  int cwidth;
201 
202  if (islong) {
203  num = args.get<uint64_t>();
204  cwidth = sizeof(uint64_t);
205  } else {
206  num = args.get<uint32_t>();
207  cwidth = sizeof(uint32_t);
208  }
209 
210  while (cwidth-- > 0) {
211  char c = (char)(num & mask);
212  if (c)
213  out << c;
214  num >>= 8;
215  }
216  }
217  break;
218  case 'b': {
219  uint64_t n = args.get<uint64_t>();
220  Addr s_ptr = args.get<Addr>();
221  std::string s;
222  tc->getVirtProxy().readString(s, s_ptr);
223  out << s << ": " << n;
224  }
225  break;
226  case '%':
227  out << '%';
228  break;
229  }
230  ++p;
231  }
232  break;
233  case '\n':
234  out << std::endl;
235  ++p;
236  break;
237  case '\r':
238  ++p;
239  if (*p != '\n')
240  out << std::endl;
241  break;
242 
243  default: {
244  size_t len = strcspn(p, "%\n\r\0");
245  out.write(p, len);
246  p += len;
247  }
248  }
249  }
250 
251  str = out.str();
252  return str.length();
253 }
254 
255 } // namespace linux
256 } // namespace gem5
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:444
gem5::ArmISA::format
Bitfield< 31, 29 > format
Definition: misc_types.hh:646
gem5::linux::printk
int printk(std::string &str, ThreadContext *tc, Addr format_ptr, PrintkVarArgs args)
Definition: printk.cc:49
gem5::PortProxy::readString
void readString(std::string &str, Addr addr) const
Same as tryReadString, but insists on success.
Definition: port_proxy.hh:260
GEM5_FALLTHROUGH
#define GEM5_FALLTHROUGH
Definition: compiler.hh:61
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::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
gem5::ThreadContext::getVirtProxy
virtual PortProxy & getVirtProxy()=0
gem5::ArmISA::width
Bitfield< 4 > width
Definition: misc_types.hh:71
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ArmISA::s
Bitfield< 4 > s
Definition: misc_types.hh:561
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:455
gem5::guest_abi::VarArgs
Definition: varargs.hh:150
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
thread_context.hh
gem5::loader::Linux
@ Linux
Definition: object_file.hh:73
printk.hh

Generated on Tue Sep 21 2021 12:25:25 for gem5 by doxygen 1.8.17