Beginnings of the SRM console prompt.

This commit is contained in:
Richard Henderson
2011-05-05 13:06:24 -07:00
parent 9e75c89f00
commit 369d1d9a68
6 changed files with 373 additions and 13 deletions

View File

@ -12,7 +12,7 @@ CPPFLAGS = -DSYSTEM_H='"sys-$(SYSTEM).h"'
CFLAGS += -mcpu=ev67
OBJS = pal.o sys-$(SYSTEM).o init.o crb.o uart.o memset.o printf.o
OBJS = pal.o sys-$(SYSTEM).o init.o crb.o uart.o console.o console-low.o memset.o printf.o
all: palcode-$(SYSTEM)
@ -28,3 +28,4 @@ init.o: init.c hwrpb.h osf.h uart.h sys-$(SYSTEM).h core-$(CORE).h
printf.o: printf.c uart.h
uart.o: uart.c uart.h protos.h
crb.o: crb.c hwrpb.h protos.h console.h uart.h
console.o: console.c console.h protos.h

126
console-low.S Normal file
View File

@ -0,0 +1,126 @@
/* Assembly helper routines for the emulation SRM console.
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/>. */
.set nomacro
.set noat
.text
.cfi_sections .debug_frame
#define SAVE_ALL_SIZE (18*8)
.globl entInt
.type entInt, @function
.cfi_startproc simple
entInt:
.cfi_return_column 64
.cfi_def_cfa $sp, 48
.cfi_rel_offset 64, 8
.cfi_rel_offset $gp, 16
.cfi_rel_offset $16, 24
.cfi_rel_offset $17, 32
.cfi_rel_offset $18, 40
lda $sp, -SAVE_ALL_SIZE($sp)
.cfi_adjust_cfa_offset SAVE_ALL_SIZE
stq $0, 0*8($sp)
stq $1, 1*8($sp)
stq $2, 2*8($sp)
stq $3, 3*8($sp)
stq $4, 4*8($sp)
stq $5, 5*8($sp)
stq $6, 6*8($sp)
stq $7, 7*8($sp)
stq $8, 9*8($sp)
stq $19, 9*8($sp)
stq $20, 10*8($sp)
stq $21, 11*8($sp)
stq $22, 12*8($sp)
stq $23, 13*8($sp)
stq $24, 14*8($sp)
stq $25, 15*8($sp)
stq $26, 16*8($sp)
stq $27, 17*8($sp)
stq $28, 18*8($sp)
.cfi_rel_offset $0, 0*8
.cfi_rel_offset $1, 1*8
.cfi_rel_offset $2, 2*8
.cfi_rel_offset $3, 3*8
.cfi_rel_offset $4, 4*8
.cfi_rel_offset $5, 5*8
.cfi_rel_offset $6, 6*8
.cfi_rel_offset $7, 7*8
.cfi_rel_offset $8, 8*8
.cfi_rel_offset $19, 9*8
.cfi_rel_offset $20, 10*8
.cfi_rel_offset $21, 11*8
.cfi_rel_offset $22, 12*8
.cfi_rel_offset $23, 13*8
.cfi_rel_offset $24, 14*8
.cfi_rel_offset $25, 15*8
.cfi_rel_offset $26, 16*8
.cfi_rel_offset $27, 17*8
.cfi_rel_offset $28, 18*8
bsr $26, do_entInt !samegp
ldq $0, 0*8($sp)
ldq $1, 1*8($sp)
ldq $2, 2*8($sp)
ldq $3, 3*8($sp)
ldq $4, 4*8($sp)
ldq $5, 5*8($sp)
ldq $6, 6*8($sp)
ldq $7, 7*8($sp)
ldq $8, 9*8($sp)
ldq $19, 9*8($sp)
ldq $20, 10*8($sp)
ldq $21, 11*8($sp)
ldq $22, 12*8($sp)
ldq $23, 13*8($sp)
ldq $24, 14*8($sp)
ldq $25, 15*8($sp)
ldq $26, 16*8($sp)
ldq $27, 17*8($sp)
ldq $28, 18*8($sp)
lda $sp, SAVE_ALL_SIZE($sp)
.cfi_adjust_cfa_offset -SAVE_ALL_SIZE
.cfi_restore $0
.cfi_restore $1
.cfi_restore $2
.cfi_restore $3
.cfi_restore $4
.cfi_restore $5
.cfi_restore $6
.cfi_restore $7
.cfi_restore $8
.cfi_restore $19
.cfi_restore $20
.cfi_restore $21
.cfi_restore $22
.cfi_restore $23
.cfi_restore $24
.cfi_restore $25
.cfi_restore $26
.cfi_restore $27
.cfi_restore $28
call_pal 0x3f // rti
.cfi_endproc
.size entInt, . - entInt

132
console.c Normal file
View File

@ -0,0 +1,132 @@
/* 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"
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);
while (1)
{
crb_puts(0, ">>> ", 4);
len = getline(line, sizeof(line));
crb_puts(0, "got: ", 5);
crb_puts(0, line, len);
output_crnl();
}
}

10
init.c
View File

@ -230,14 +230,6 @@ init_pcb (void)
pcb.flags = 1; /* FEN */
}
void
do_hello(void)
{
uart_puts(COM1, "Hello, World!\n");
asm ("halt");
__builtin_unreachable ();
}
void
do_start(unsigned long memsize, void (*kernel_entry)(void), long cpus)
{
@ -254,7 +246,7 @@ do_start(unsigned long memsize, void (*kernel_entry)(void), long cpus)
register unsigned long pa_pcb __asm__("$18");
register unsigned long vptptr __asm__("$19");
pc = (kernel_entry ? kernel_entry : do_hello);
pc = (kernel_entry ? kernel_entry : do_console);
pa_pcb = PA(&pcb);
vptptr = VPTPTR;
asm("call_pal 0x0a" : : "r"(variant), "r"(pc), "r"(pa_pcb), "r"(vptptr));

102
protos.h
View File

@ -21,6 +21,60 @@
#ifndef PROTOS_H
#define PROTOS_H 1
/*
* Call_Pal functions.
*/
static inline void wrent(void *cb, unsigned long which)
{
register void *a0 __asm__("$16") = cb;
register unsigned long a1 __asm__("$17") = which;
asm volatile ("call_pal 0x34"
: "+r"(a0), "+r"(a1)
: : "$1", "$22", "$23", "$24", "$25");
}
static inline unsigned long swpipl(unsigned long newipl)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = newipl;
asm volatile ("call_pal 0x35"
: "=r"(v0), "+r"(a0)
: : "$1", "$22", "$23", "$24", "$25");
return v0;
}
static inline unsigned long rdps(void)
{
register unsigned long v0 __asm__("$0");
asm volatile ("call_pal 0x36"
: "=r"(v0) : : "$1", "$22", "$23", "$24", "$25");
return v0;
}
static inline void wrkgp(void)
{
asm volatile ("mov $29, $16\n\tcall_pal 0x37"
: : : "$16", "$1", "$22", "$23", "$24", "$25");
}
static inline unsigned long wtint(unsigned long skip)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = skip;
asm volatile ("call_pal 0x3e"
: "=r"(v0), "+r"(a0)
: : "$1", "$22", "$23", "$24", "$25");
return v0;
}
/*
* Cserve functions.
*/
@ -41,7 +95,7 @@ static inline unsigned long ldq_p(unsigned long addr)
static inline unsigned long stq_p(unsigned long port, unsigned long val)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 4;
register unsigned long a0 __asm__("$16") = 2;
register unsigned long a1 __asm__("$17") = port;
register unsigned long a2 __asm__("$18") = val;
@ -52,6 +106,46 @@ static inline unsigned long stq_p(unsigned long port, unsigned long val)
return v0;
}
static inline unsigned long get_wall_time(void)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 3;
asm("call_pal 9" : "=r"(v0), "+r"(a0) : : "$17", "$18", "$19", "$20", "$21");
return v0;
}
static inline unsigned long get_alarm(void)
{
register unsigned long v0 __asm__("$0");
register unsigned long a0 __asm__("$16") = 4;
asm("call_pal 9" : "=r"(v0), "+r"(a0) : : "$17", "$18", "$19", "$20", "$21");
return v0;
}
static inline void set_alarm_rel(unsigned long nsec)
{
register unsigned long a0 __asm__("$16") = 5;
register unsigned long a1 __asm__("$17") = nsec;
asm volatile ("call_pal 9"
: "+r"(a0), "+r"(a1)
: : "$0", "$18", "$19", "$20", "$21");
}
static inline void set_alarm_abs(unsigned long nsec)
{
register unsigned long a0 __asm__("$16") = 6;
register unsigned long a1 __asm__("$17") = nsec;
asm volatile ("call_pal 9"
: "+r"(a0), "+r"(a1)
: : "$0", "$18", "$19", "$20", "$21");
}
/*
* I/O functions
*/
@ -67,4 +161,10 @@ extern unsigned long crb_dispatch(long select, long a1, long a2,
long a3, long a4);
extern unsigned long crb_fixup(unsigned long vptptr, unsigned long hwrpb);
/*
* The Console
*/
extern void do_console(void);
extern void entInt(void);
#endif /* PROTOS_H */

13
uart.c
View File

@ -46,8 +46,17 @@ uart_charav(int offset)
int
uart_getchar(int offset)
{
while (!uart_charav(offset))
continue;
/* If interrupts are enabled, use wtint assuming that either the
device itself will wake us, or that a clock interrupt will. */
if ((rdps() & 7) == 0) {
while (!uart_charav(offset)) {
wtint(0);
}
} else {
while (!uart_charav(offset))
continue;
}
return inb(com2Rbr + offset);
}