Files
openbios/arch/sparc32/console.c
Stefan Reinauer d06b24d10f SS10 support by blueswirl
git-svn-id: svn://coreboot.org/openbios/openbios-devel@120 f158a5a8-5612-0410-a976-696ce0be7e32
2007-04-09 12:35:41 +00:00

308 lines
7.2 KiB
C

/*
* Copyright (C) 2003, 2004 Stefan Reinauer
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "openbios/config.h"
#include "openbios/kernel.h"
#include "openbios.h"
#ifdef CONFIG_DEBUG_CONSOLE
/* ******************************************************************
* serial console functions
* ****************************************************************** */
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
static unsigned long kbd_base, serial_base;
#define CTRL(port) (serial_base + (port) * 2 + 0)
#define DATA(port) (serial_base + (port) * 2 + 2)
/* Conversion routines to/from brg time constants from/to bits
* per second.
*/
#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
#define ZS_CLOCK 4915200 /* Zilog input clock rate. */
#define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */
/* Write Register 3 */
#define RxENAB 0x1 /* Rx Enable */
#define Rx8 0xc0 /* Rx 8 Bits/Character */
/* Write Register 4 */
#define SB1 0x4 /* 1 stop bit/char */
#define X16CLK 0x40 /* x16 clock mode */
/* Write Register 5 */
#define RTS 0x2 /* RTS */
#define TxENAB 0x8 /* Tx Enable */
#define Tx8 0x60 /* Tx 8 bits/character */
#define DTR 0x80 /* DTR */
/* Write Register 14 (Misc control bits) */
#define BRENAB 1 /* Baud rate generator enable */
#define BRSRC 2 /* Baud rate generator source */
/* Read Register 0 */
#define Rx_CH_AV 0x1 /* Rx Character Available */
static int uart_charav(int port)
{
return ((inb(CTRL(port)) & Rx_CH_AV) != 0);
}
static char uart_getchar(int port)
{
while (!uart_charav(port));
return ((char) (inb(DATA(port))) & 0177);
}
static void uart_putchar(int port, unsigned char c)
{
if (c == '\n')
uart_putchar(port, '\r');
while (!inb(CTRL(port)) & 4);
outb(c, DATA(port));
}
static void uart_init_line(int port, unsigned long baud)
{
outb(4, CTRL(port)); // reg 4
outb(SB1 | X16CLK, CTRL(port)); // no parity, async, 1 stop
// bit, 16x clock
baud = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
outb(12, CTRL(port)); // reg 12
outb(baud & 0xff, CTRL(port));
outb(13, CTRL(port)); // reg 13
outb((baud >> 8) & 0xff, CTRL(port));
outb(14, CTRL(port)); // reg 14
outb(BRSRC | BRENAB, CTRL(port));
outb(3, CTRL(port)); // reg 3
outb(RxENAB | Rx8, CTRL(port)); // enable rx, 8 bits/char
outb(5, CTRL(port)); // reg 5
outb(RTS | TxENAB | Tx8 | DTR, CTRL(port)); // enable tx, 8
// bits/char, set
// RTS & DTR
}
int uart_init(int port, unsigned long speed)
{
serial_base = ((unsigned long)port) & ~3;
uart_init_line(port & 3, speed);
return -1;
}
static void serial_putchar(int c)
{
uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff));
}
static void serial_cls(void)
{
serial_putchar(27);
serial_putchar('[');
serial_putchar('H');
serial_putchar(27);
serial_putchar('[');
serial_putchar('J');
}
#endif
/* ******************************************************************
* simple polling video/keyboard console functions
* ****************************************************************** */
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
#define VMEM_BASE 0x00800000
#define VMEM_SIZE (1024*768*1)
#define DAC_BASE 0x00200000
#define DAC_SIZE 16
static unsigned char *vmem;
static volatile uint32_t *dac;
typedef struct osi_fb_info {
unsigned long mphys;
int rb, w, h, depth;
} osi_fb_info_t;
int TCX_GetFBInfo( osi_fb_info_t *fb )
{
fb->w = 1024;
fb->h = 768;
fb->depth = 8;
fb->rb = 1024;
fb->mphys = vmem;
return 0;
}
#define openbios_GetFBInfo(x) TCX_GetFBInfo(x)
#include "../../modules/video.c"
#include "../../modules/console.c"
static void video_putchar(int c)
{
char buf[2];
buf[0] = c & 0xff;
buf[1] = 0;
console_draw_str(buf);
}
static void video_cls(void)
{
memset((void *)vmem, 0, VMEM_SIZE);
}
void tcx_init(unsigned long base)
{
vmem = map_io(base + VMEM_BASE, VMEM_SIZE);
dac = map_io(base + DAC_BASE, DAC_SIZE);
console_init();
}
void kbd_init(unsigned long base)
{
kbd_base = base + 4;
}
static const unsigned char sunkbd_keycode[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\\', 13,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
' ',
};
static const unsigned char sunkbd_keycode_shifted[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '|', 13,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
' ',
};
static int shiftstate;
int
keyboard_dataready(void)
{
return ((inb(kbd_base) & 1) == 1);
}
unsigned char
keyboard_readdata(void)
{
unsigned char ch;
while (!keyboard_dataready()) { }
do {
ch = inb(kbd_base + 2) & 0xff;
if (ch == 99)
shiftstate |= 1;
else if (ch == 110)
shiftstate |= 2;
else if (ch == 227)
shiftstate &= ~1;
else if (ch == 238)
shiftstate &= ~2;
//printk("getch: %d\n", ch);
}
while ((ch & 0x80) == 0 || ch == 238 || ch == 227); // Wait for key release
//printk("getch rel: %d\n", ch);
ch &= 0x7f;
if (shiftstate)
ch = sunkbd_keycode_shifted[ch];
else
ch = sunkbd_keycode[ch];
//printk("getch xlate: %d\n", ch);
return ch;
}
#endif
/* ******************************************************************
* common functions, implementing simple concurrent console
* ****************************************************************** */
int putchar(int c)
{
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
serial_putchar(c);
#endif
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
video_putchar(c);
#endif
return c;
}
int availchar(void)
{
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
if (uart_charav(CONFIG_SERIAL_PORT))
return 1;
#endif
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
if (keyboard_dataready())
return 1;
#endif
return 0;
}
int getchar(void)
{
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
if (uart_charav(CONFIG_SERIAL_PORT))
return (uart_getchar(CONFIG_SERIAL_PORT));
#endif
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
if (keyboard_dataready())
return (keyboard_readdata());
#endif
return 0;
}
void cls(void)
{
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
serial_cls();
#endif
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
video_cls();
#endif
}
#endif // CONFIG_DEBUG_CONSOLE