]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_prompt_module.cpp
Inital import
[l4.git] / kernel / fiasco / src / jdb / jdb_prompt_module.cpp
1 IMPLEMENTATION:
2
3 #include <cstdio>
4 #include <cstring>
5
6 #include "jdb.h"
7 #include "jdb_module.h"
8 #include "jdb_screen.h"
9 #include "kernel_console.h"
10 #include "static_init.h"
11
12
13 //===================
14 // Std JDB modules
15 //===================
16
17 /**
18  * Jdb-prompt module.
19  *
20  * This module handles some commands that
21  * change Jdb prompt and screen settings.
22  */
23 class Jdb_pcm : public Jdb_module
24 {
25 public:
26   Jdb_pcm() FIASCO_INIT;
27 private:
28   static char subcmd;
29   static char prompt_color;
30   static char direct_enable;
31   static int  screen_height;
32   static int  screen_width;
33 };
34
35 char Jdb_pcm::subcmd;
36 char Jdb_pcm::prompt_color;
37 char Jdb_pcm::direct_enable;
38 int  Jdb_pcm::screen_height;
39 int  Jdb_pcm::screen_width;
40
41 static Jdb_pcm jdb_pcm INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
42
43 PRIVATE
44 int
45 Jdb_pcm::get_coords(Console *cons, unsigned &x, unsigned &y)
46 {
47   cons->write("\033[6n", 4);
48
49   if (!wait_for_escape(cons))
50     return 0;
51
52   if (cons->getchar(true) != '[')
53     return 0;
54
55   for (y=0; ;)
56     {
57       int c = cons->getchar(true);
58       if (c == ';')
59         break;
60       if (c < '0' || c > '9')
61         return 0;
62       y = y*10+c-'0';
63     }
64   for (x=0; ;)
65     {
66       int c = cons->getchar(true);
67       if (c == 'R')
68         break;
69       if (c < '0' || c > '9')
70         return 0;
71       x = x*10+c-'0';
72     }
73   return 1;
74 }
75
76 PRIVATE
77 void
78 Jdb_pcm::detect_screensize()
79 {
80   unsigned x, y, max_x, max_y;
81   char str[20];
82   Console *uart;
83
84   if (!(uart = Kconsole::console()->find_console(Console::UART)))
85     return;
86
87   while (uart->getchar(false) != -1)
88     ;
89   if (!get_coords(uart, x, y))
90     return;
91   // set scroll region to the max + set cursor to the max
92   uart->write("\033[1;199r\033[199;199H", 18);
93   if (!get_coords(uart, max_x, max_y))
94     return;
95   Jdb_screen::set_width(max_x);
96   Jdb_screen::set_height(max_y);
97   // adapt scroll region, restore cursor
98   snprintf(str, sizeof(str), "\033[1;%ur\033[%u;%uH", max_y, y, x);
99   uart->write(str, strlen(str));
100 }
101
102 PUBLIC
103 Jdb_module::Action_code
104 Jdb_pcm::action(int cmd, void *&args, char const *&fmt, int &)
105 {
106   if (cmd)
107     return NOTHING;
108
109   if (args == &subcmd)
110     {
111       switch (subcmd)
112         {
113         case 'c':
114           fmt  = " promptcolor=%c";
115           args = &prompt_color;
116           return EXTRA_INPUT;
117         case 'd':
118           fmt = "%c";
119           args = &direct_enable;
120           return EXTRA_INPUT;
121         case 'h':
122           fmt  = " screenheight=%d";
123           args = &screen_height;
124           return EXTRA_INPUT;
125         case 'w':
126           fmt  = " screenwidth=%d";
127           args = &screen_width;
128           return EXTRA_INPUT;
129         case 'H':
130         case 'S':
131           detect_screensize();
132           return NOTHING;
133         case 'o':
134           printf("\nConnected consoles:\n");
135           Kconsole::console()->list_consoles();
136           return NOTHING;
137         case 'i':
138           printf("\nScreen dimensions: %dx%d Cols: %ld\n",
139                  Jdb_screen::width(), Jdb_screen::height(),
140                  Jdb_screen::cols());
141           return NOTHING;
142         default:
143           return ERROR;
144         }
145     }
146   else if (args == &screen_height)
147     {
148       // set screen height
149       if (24 < screen_height && screen_height < 100)
150         Jdb_screen::set_height(screen_height);
151     }
152   else if (args == &screen_width)
153     {
154       // set screen height
155       if (80 < screen_width && screen_width < 600)
156         Jdb_screen::set_width(screen_width);
157     }
158   else if (args == &prompt_color)
159     {
160       if (!Jdb::set_prompt_color(prompt_color) )
161         {
162           putchar(prompt_color);
163           puts(" - color expected (lLrRgGbByYmMcCwW)!");
164         }
165     }
166   else if (args == &direct_enable)
167     {
168       printf(" Direct console %s\n",
169           direct_enable == '+' ? "enabled" : "disabled");
170       Jdb_screen::enable_direct(direct_enable == '+');
171       if (direct_enable == '+')
172         Kconsole::console()->change_state(Console::DIRECT, 0,
173                                           ~0U, Console::OUTENABLED);
174       else
175         Kconsole::console()->change_state(Console::DIRECT, 0,
176                                           ~Console::OUTENABLED, 0);
177     }
178
179   return NOTHING;
180 }
181
182 PUBLIC
183 int Jdb_pcm::num_cmds() const
184 {
185   return 1;
186 }
187
188 PUBLIC
189 Jdb_module::Cmd const * Jdb_pcm::cmds() const
190 {
191   static Cmd cs[] =
192     {
193         { 0, "J", "Jdb options", "%c",
194            "Jc<color>\tset the Jdb prompt color, <color> must be:\n"
195            "\tnN: noir(black), rR: red, gG: green, bB: blue,\n"
196            "\tyY: yellow, mM: magenta, cC: cyan, wW: white;\n"
197            "\tthe capital letters are for bold text.\n"
198            "Jd{+|-}\ton/off Jdb output to VGA/Hercules console\n"
199            "Jh\tset Jdb screen height\n"
200            "Jw\tset Jdb screen width\n"
201            "JS\tdetect screen size using ESCape sequence ESC [ 6 n\n"
202            "Ji\tshow screen information\n"
203            "Jo\tlist attached consoles",
204            &subcmd }
205     };
206
207   return cs;
208 }
209
210 IMPLEMENT
211 Jdb_pcm::Jdb_pcm()
212   : Jdb_module("GENERAL")
213 {}
214
215
216 IMPLEMENTATION[ia32,ux,amd64,ppc32]:
217
218 #include "cpu.h"
219
220 PRIVATE
221 int
222 Jdb_pcm::wait_for_escape(Console *cons)
223 {
224   Unsigned64 to = Cpu::boot_cpu()->ns_to_tsc (Cpu::boot_cpu()->tsc_to_ns (Cpu::rdtsc()) + 200000000);
225
226   // This is just a sanity check to ensure that a tool like minicom is attached
227   // at the other end of the serial line and this tools responds to the magical
228   // escape sequence.
229   for (;;)
230     {
231       int c = cons->getchar(false);
232       if (c == '\033')
233         return 1;
234       if (c != -1 || Cpu::rdtsc() > to)
235         return 0;
236       Proc::pause();
237     }
238 }
239
240
241 IMPLEMENTATION[arm]:
242
243 #include "processor.h"
244
245 PRIVATE
246 int
247 Jdb_pcm::wait_for_escape(Console *cons)
248 {
249   for (Mword cnt=100000; ; cnt--)
250     {
251       int c = cons->getchar(false);
252       if (c == '\033')
253         return 1;
254       if (!cnt)
255         return 0;
256       Proc::pause();
257     }
258 }