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

Generated on Sun Jul 30 2023 01:56:57 for gem5 by doxygen 1.8.17