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

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