145 lines
2.7 KiB
C
145 lines
2.7 KiB
C
/* The SRM console prompt.
|
|
|
|
Copyright (C) 2011 Richard Henderson
|
|
|
|
This file is part of QEMU PALcode.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the text
|
|
of the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include "protos.h"
|
|
#include "console.h"
|
|
#include "vgatables.h"
|
|
|
|
|
|
static void
|
|
output_crnl(void)
|
|
{
|
|
crb_puts(0, "\r\n", 2);
|
|
}
|
|
|
|
static void
|
|
output_bell(void)
|
|
{
|
|
crb_puts(0, "\a", 1);
|
|
}
|
|
|
|
static void
|
|
backspace_and_erase(void)
|
|
{
|
|
crb_puts(0, "\b \b", 3);
|
|
}
|
|
|
|
static unsigned long
|
|
getline(char *buf, unsigned long bufsize)
|
|
{
|
|
unsigned long len = 0;
|
|
long c;
|
|
|
|
while (1)
|
|
{
|
|
c = crb_getc(0);
|
|
if (c < 0)
|
|
continue;
|
|
switch ((int)c)
|
|
{
|
|
case '\r':
|
|
case '\n':
|
|
output_crnl();
|
|
buf[len] = 0;
|
|
return len;
|
|
|
|
case '\b':
|
|
case 0x7f: /* Delete */
|
|
if (len > 0)
|
|
{
|
|
backspace_and_erase();
|
|
len--;
|
|
}
|
|
else
|
|
output_bell();
|
|
break;
|
|
|
|
default:
|
|
if (len + 1 < bufsize)
|
|
{
|
|
buf[len] = c;
|
|
crb_puts(0, buf+len, 1);
|
|
len++;
|
|
}
|
|
else
|
|
output_bell();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void set_console_alarm(void)
|
|
{
|
|
/* Just set a new timeout for 10ms = 10M ns. */
|
|
set_alarm_rel(10 * 1000 * 1000);
|
|
}
|
|
|
|
void
|
|
do_entInt(unsigned long type, unsigned long vector)
|
|
{
|
|
switch (type)
|
|
{
|
|
case 0:
|
|
/* ??? SMP interrupt. We're going to need this for starting up
|
|
secondary cpus. */
|
|
break;
|
|
case 1:
|
|
/* Timer interrupt. */
|
|
set_console_alarm();
|
|
break;
|
|
case 2:
|
|
/* ??? Device interrupt. We're going to need this for virtio disk
|
|
operations at minimum. */
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
do_console(void)
|
|
{
|
|
char line[256];
|
|
unsigned long len;
|
|
|
|
wrkgp();
|
|
wrent(entInt, 0);
|
|
set_console_alarm();
|
|
swpipl(0);
|
|
|
|
if (have_vga)
|
|
{
|
|
unsigned short *vga, attr;
|
|
vga = pci_mem_base + SEG_CTEXT *16;
|
|
attr = 0x2000;
|
|
vga[0] = 'H' + attr;
|
|
vga[1] = 'e' + attr;
|
|
vga[2] = 'l' + attr;
|
|
vga[3] = 'l' + attr;
|
|
vga[4] = 'o' + attr;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
crb_puts(0, ">>> ", 4);
|
|
len = getline(line, sizeof(line));
|
|
crb_puts(0, "got: ", 5);
|
|
crb_puts(0, line, len);
|
|
output_crnl();
|
|
}
|
|
}
|