printk.cc revision 11793:ef606668d247
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 * Authors: Nathan Binkert
29 *          Ali Saidi
30 */
31
32#include "kern/linux/printk.hh"
33
34#include <sys/types.h>
35
36#include <algorithm>
37
38#include "base/trace.hh"
39#include "cpu/thread_context.hh"
40#include "sim/arguments.hh"
41
42using namespace std;
43
44
45void
46Printk(stringstream &out, Arguments args)
47{
48    char *p = (char *)args++;
49
50    while (*p) {
51        switch (*p) {
52          case '%': {
53              bool more = true;
54              bool islong = false;
55              bool leftjustify = false;
56              bool format = false;
57              bool zero = false;
58              int width = 0;
59              while (more && *++p) {
60                  switch (*p) {
61                    case 'l':
62                    case 'L':
63                      islong = true;
64                      break;
65                    case '-':
66                      leftjustify = true;
67                      break;
68                    case '#':
69                      format = true;
70                      break;
71                    case '0':
72                      if (width)
73                          width *= 10;
74                      else
75                          zero = true;
76                      break;
77                    default:
78                      if (*p >= '1' && *p <= '9')
79                          width = 10 * width + *p - '0';
80                      else
81                          more = false;
82                      break;
83                  }
84              }
85
86              bool hexnum = false;
87              bool octal = false;
88              bool sign = false;
89              switch (*p) {
90                case 'X':
91                case 'x':
92                  hexnum = true;
93                  break;
94                case 'O':
95                case 'o':
96                  octal = true;
97                  break;
98                case 'D':
99                case 'd':
100                  sign = true;
101                  break;
102                case 'P':
103                  format = true;
104                case 'p':
105                  hexnum = true;
106                  break;
107              }
108
109              switch (*p) {
110                case 'D':
111                case 'd':
112                case 'U':
113                case 'u':
114                case 'X':
115                case 'x':
116                case 'O':
117                case 'o':
118                case 'P':
119                case 'p': {
120                  if (hexnum)
121                      out << hex;
122
123                  if (octal)
124                      out << oct;
125
126                  if (format) {
127                      if (!zero)
128                          out.setf(ios::showbase);
129                      else {
130                          if (hexnum) {
131                              out << "0x";
132                              width -= 2;
133                          } else if (octal) {
134                              out << "0";
135                              width -= 1;
136                          }
137                      }
138                  }
139
140                  if (zero)
141                      out.fill('0');
142
143                  if (width > 0)
144                      out.width(width);
145
146                  if (leftjustify && !zero)
147                      out.setf(ios::left);
148
149                  if (sign) {
150                      if (islong)
151                          out << (int64_t)args;
152                      else
153                          out << (int32_t)args;
154                  } else {
155                      if (islong)
156                          out << (uint64_t)args;
157                      else
158                          out << (uint32_t)args;
159                  }
160
161                  if (zero)
162                      out.fill(' ');
163
164                  if (width > 0)
165                      out.width(0);
166
167                  out << dec;
168
169                  ++args;
170                }
171                  break;
172
173                case 's': {
174                    const char *s = (char *)args;
175                    if (!s)
176                        s = "<NULL>";
177
178                    if (width > 0)
179                        out.width(width);
180                    if (leftjustify)
181                        out.setf(ios::left);
182
183                    out << s;
184                    ++args;
185                }
186                  break;
187                case 'C':
188                case 'c': {
189                    uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
190                    uint64_t num;
191                    int cwidth;
192
193                    if (islong) {
194                        num = (uint64_t)args;
195                        cwidth = sizeof(uint64_t);
196                    } else {
197                        num = (uint32_t)args;
198                        cwidth = sizeof(uint32_t);
199                    }
200
201                    while (cwidth-- > 0) {
202                        char c = (char)(num & mask);
203                        if (c)
204                            out << c;
205                        num >>= 8;
206                    }
207
208                    ++args;
209                }
210                  break;
211                case 'b': {
212                  uint64_t n = (uint64_t)args++;
213                  char *s = (char *)args++;
214                  out << s << ": " << n;
215                }
216                  break;
217                case 'n':
218                case 'N': {
219                    args += 2;
220#if 0
221                    uint64_t n = (uint64_t)args++;
222                    struct reg_values *rv = (struct reg_values *)args++;
223#endif
224                }
225                  break;
226                case 'r':
227                case 'R': {
228                    args += 2;
229#if 0
230                    uint64_t n = (uint64_t)args++;
231                    struct reg_desc *rd = (struct reg_desc *)args++;
232#endif
233                }
234                  break;
235                case '%':
236                  out << '%';
237                  break;
238              }
239              ++p;
240          }
241            break;
242          case '\n':
243            out << endl;
244            ++p;
245            break;
246          case '\r':
247            ++p;
248            if (*p != '\n')
249                out << endl;
250            break;
251
252          default: {
253              size_t len = strcspn(p, "%\n\r\0");
254              out.write(p, len);
255              p += len;
256          }
257        }
258    }
259
260}
261
262