1 /* The SRM console prompt.
2 
3    Copyright (C) 2011 Richard Henderson
4 
5    This file is part of QEMU PALcode.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text
15    of the GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; see the file COPYING.  If not see
19    <http://www.gnu.org/licenses/>.  */
20 
21 #include "protos.h"
22 #include "console.h"
23 #include "vgatables.h"
24 
25 
26 static void
output_crnl(void)27 output_crnl(void)
28 {
29   crb_puts(0, "\r\n", 2);
30 }
31 
32 static void
output_bell(void)33 output_bell(void)
34 {
35   crb_puts(0, "\a", 1);
36 }
37 
38 static void
backspace_and_erase(void)39 backspace_and_erase(void)
40 {
41   crb_puts(0, "\b \b", 3);
42 }
43 
44 static unsigned long
getline(char * buf,unsigned long bufsize)45 getline(char *buf, unsigned long bufsize)
46 {
47   unsigned long len = 0;
48   long c;
49 
50   while (1)
51     {
52       c = crb_getc(0);
53       if (c < 0)
54 	continue;
55       switch ((int)c)
56 	{
57 	case '\r':
58 	case '\n':
59 	  output_crnl();
60 	  buf[len] = 0;
61 	  return len;
62 
63         case '\b':
64 	case 0x7f: /* Delete */
65           if (len > 0)
66 	    {
67 	      backspace_and_erase();
68               len--;
69             }
70 	  else
71 	    output_bell();
72           break;
73 
74         default:
75 	  if (len + 1 < bufsize)
76 	    {
77 	      buf[len] = c;
78               crb_puts(0, buf+len, 1);
79 	      len++;
80 	    }
81 	  else
82 	    output_bell();
83 	  break;
84         }
85     }
86 }
87 
set_console_alarm(void)88 static inline void set_console_alarm(void)
89 {
90   /* Just set a new timeout for 10ms = 10M ns.  */
91   set_alarm_rel(10 * 1000 * 1000);
92 }
93 
94 void
do_entInt(unsigned long type,unsigned long vector)95 do_entInt(unsigned long type, unsigned long vector)
96 {
97   switch (type)
98     {
99     case 0:
100       /* ??? SMP interrupt.  We're going to need this for starting up
101          secondary cpus.  */
102       break;
103     case 1:
104       /* Timer interrupt.  */
105       set_console_alarm();
106       break;
107     case 2:
108       /* ??? Device interrupt.  We're going to need this for virtio disk
109          operations at minimum.  */
110       break;
111     }
112 }
113 
114 void
do_console(void)115 do_console(void)
116 {
117   char line[256];
118   unsigned long len;
119 
120   wrkgp();
121   wrent(entInt, 0);
122   set_console_alarm();
123   swpipl(0);
124 
125   if (have_vga)
126   {
127     unsigned short *vga, attr;
128     vga = pci_mem_base + SEG_CTEXT *16;
129     attr = 0x2000;
130     vga[0] = 'H' + attr;
131     vga[1] = 'e' + attr;
132     vga[2] = 'l' + attr;
133     vga[3] = 'l' + attr;
134     vga[4] = 'o' + attr;
135   }
136 
137   while (1)
138     {
139       crb_puts(0, ">>> ", 4);
140       len = getline(line, sizeof(line));
141       crb_puts(0, "got: ", 5);
142       crb_puts(0, line, len);
143       output_crnl();
144     }
145 }
146