Add EBUS bridge, refactor PC serial and keyboard, generalize floppy

git-svn-id: svn://coreboot.org/openbios/openbios-devel@377 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Blue Swirl
2009-01-10 11:37:34 +00:00
parent 0c3877f095
commit 91a9c7865a
15 changed files with 508 additions and 398 deletions

View File

@@ -16,229 +16,11 @@
#include "sys_info.h" #include "sys_info.h"
#include "boot.h" #include "boot.h"
/* ******************************************************************
* serial console functions
* ****************************************************************** */
#define SER_SIZE 8
#define RBR(x) x==2?0x2f8:0x3f8
#define THR(x) x==2?0x2f8:0x3f8
#define IER(x) x==2?0x2f9:0x3f9
#define IIR(x) x==2?0x2fa:0x3fa
#define LCR(x) x==2?0x2fb:0x3fb
#define MCR(x) x==2?0x2fc:0x3fc
#define LSR(x) x==2?0x2fd:0x3fd
#define MSR(x) x==2?0x2fe:0x3fe
#define SCR(x) x==2?0x2ff:0x3ff
#define DLL(x) x==2?0x2f8:0x3f8
#define DLM(x) x==2?0x2f9:0x3f9
static int uart_charav(int port)
{
return ((inb(LSR(port)) & 1) != 0);
}
static char uart_getchar(int port)
{
while (!uart_charav(port));
return ((char) inb(RBR(port)) & 0177);
}
static void uart_putchar(int port, unsigned char c)
{
if (c == '\n')
uart_putchar(port, '\r');
while (!(inb(LSR(port)) & 0x20));
outb(c, THR(port));
}
static void uart_init_line(int port, unsigned long baud)
{
int i, baudconst;
switch (baud) {
case 115200:
baudconst = 1;
break;
case 57600:
baudconst = 2;
break;
case 38400:
baudconst = 3;
break;
case 19200:
baudconst = 6;
break;
case 9600:
default:
baudconst = 12;
break;
}
outb(0x87, LCR(port));
outb(0x00, DLM(port));
outb(baudconst, DLL(port));
outb(0x07, LCR(port));
outb(0x0f, MCR(port));
for (i = 10; i > 0; i--) {
if (inb(LSR(port)) == (unsigned int) 0)
break;
inb(RBR(port));
}
}
#ifdef CONFIG_DEBUG_CONSOLE
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
static void serial_cls(void);
static void serial_putchar(int c);
int uart_init(int port, unsigned long speed)
{
uart_init_line(port, 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 * simple polling video/keyboard console functions
* ****************************************************************** */ * ****************************************************************** */
/* #ifdef CONFIG_DEBUG_CONSOLE
* keyboard driver
*/
static const char normal[] = {
0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
'=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
};
static const char shifted[] = {
0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
'+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
'9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
};
static int key_ext;
static int key_lshift = 0, key_rshift = 0, key_caps = 0;
static char last_key;
static void keyboard_cmd(unsigned char cmd, unsigned char val)
{
outb(cmd, 0x60);
/* wait until keyboard controller accepts cmds: */
while (inb(0x64) & 2);
outb(val, 0x60);
while (inb(0x64) & 2);
}
static void keyboard_controller_cmd(unsigned char cmd, unsigned char val)
{
outb(cmd, 0x64);
/* wait until keyboard controller accepts cmds: */
while (inb(0x64) & 2);
outb(val, 0x60);
while (inb(0x64) & 2);
}
static char keyboard_poll(void)
{
unsigned int c;
if (inb(0x64) & 1) {
c = inb(0x60);
switch (c) {
case 0xe0:
key_ext = 1;
return 0;
case 0x2a:
key_lshift = 1;
return 0;
case 0x36:
key_rshift = 1;
return 0;
case 0xaa:
key_lshift = 0;
return 0;
case 0xb6:
key_rshift = 0;
return 0;
case 0x3a:
if (key_caps) {
key_caps = 0;
keyboard_cmd(0xed, 0);
} else {
key_caps = 1;
keyboard_cmd(0xed, 4); /* set caps led */
}
return 0;
}
if (key_ext) {
// void printk(const char *format, ...);
printk("extended keycode: %x\n", c);
key_ext = 0;
return 0;
}
if (c & 0x80) /* unhandled key release */
return 0;
if (key_lshift || key_rshift)
return key_caps ? normal[c] : shifted[c];
else
return key_caps ? shifted[c] : normal[c];
}
return 0;
}
static int keyboard_dataready(void)
{
if (last_key)
return 1;
last_key = keyboard_poll();
return (last_key != 0);
}
static unsigned char keyboard_readdata(void)
{
char tmp;
while (!keyboard_dataready());
tmp = last_key;
last_key = 0;
return tmp;
}
/* ****************************************************************** /* ******************************************************************
* common functions, implementing simple concurrent console * common functions, implementing simple concurrent console
* ****************************************************************** */ * ****************************************************************** */
@@ -258,7 +40,7 @@ int availchar(void)
return 1; return 1;
#endif #endif
#ifdef CONFIG_DEBUG_CONSOLE_VGA #ifdef CONFIG_DEBUG_CONSOLE_VGA
if (keyboard_dataready()) if (pc_kbd_dataready())
return 1; return 1;
#endif #endif
return 0; return 0;
@@ -271,8 +53,8 @@ int getchar(void)
return (uart_getchar(CONFIG_SERIAL_PORT)); return (uart_getchar(CONFIG_SERIAL_PORT));
#endif #endif
#ifdef CONFIG_DEBUG_CONSOLE_VGA #ifdef CONFIG_DEBUG_CONSOLE_VGA
if (keyboard_dataready()) if (pc_kbd_dataready())
return (keyboard_readdata()); return (pc_kbd_readdata());
#endif #endif
return 0; return 0;
} }
@@ -280,153 +62,13 @@ int getchar(void)
void cls(void) void cls(void)
{ {
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
serial_cls(); serial_putchar(27);
serial_putchar('[');
serial_putchar('H');
serial_putchar(27);
serial_putchar('[');
serial_putchar('J');
#endif #endif
} }
#endif // CONFIG_DEBUG_CONSOLE #endif // CONFIG_DEBUG_CONSOLE
/* ( addr len -- actual ) */
static void
su_read(unsigned long *address)
{
char *addr;
int len;
len = POP();
addr = (char *)POP();
if (len != 1)
printk("su_read: bad len, addr %lx len %x\n", (unsigned long)addr, len);
if (uart_charav(*address)) {
*addr = (char)uart_getchar(*address);
PUSH(1);
} else {
PUSH(0);
}
}
/* ( addr len -- actual ) */
static void
su_read_keyboard(void)
{
unsigned char *addr;
int len;
len = POP();
addr = (unsigned char *)POP();
if (len != 1)
printk("su_read: bad len, addr %lx len %x\n", (unsigned long)addr, len);
if (keyboard_dataready()) {
*addr = keyboard_readdata();
PUSH(1);
} else {
PUSH(0);
}
}
/* ( addr len -- actual ) */
static void
su_write(unsigned long *address)
{
unsigned char *addr;
int i, len;
len = POP();
addr = (unsigned char *)POP();
for (i = 0; i < len; i++) {
uart_putchar(*address, addr[i]);
}
PUSH(len);
}
static void
su_close(void)
{
}
static void
su_open(unsigned long *address)
{
int len;
phandle_t ph;
unsigned long *prop;
char *args;
fword("my-self");
fword("ihandle>phandle");
ph = (phandle_t)POP();
prop = (unsigned long *)get_property(ph, "address", &len);
*address = *prop;
fword("my-args");
args = pop_fstr_copy();
RET ( -1 );
}
DECLARE_UNNAMED_NODE(su, INSTALL_OPEN, sizeof(unsigned long));
NODE_METHODS(su) = {
{ "open", su_open },
{ "close", su_close },
{ "read", su_read },
{ "write", su_write },
};
DECLARE_UNNAMED_NODE(su_keyboard, INSTALL_OPEN, sizeof(unsigned long));
NODE_METHODS(su_keyboard) = {
{ "open", su_open },
{ "close", su_close },
{ "read", su_read_keyboard },
};
void
ob_su_init(uint64_t base, uint64_t offset, int intr)
{
push_str("/pci/isa");
fword("find-device");
fword("new-device");
push_str("su");
fword("device-name");
push_str("serial");
fword("device-type");
PUSH((base + offset) >> 32);
fword("encode-int");
PUSH((base + offset) & 0xffffffff);
fword("encode-int");
fword("encode+");
PUSH(SER_SIZE);
fword("encode-int");
fword("encode+");
push_str("reg");
fword("property");
fword("finish-device");
REGISTER_NODE_METHODS(su, "/pci/isa/su");
push_str("/chosen");
fword("find-device");
push_str("/pci/isa/su");
fword("open-dev");
fword("encode-int");
push_str("stdin");
fword("property");
push_str("/pci/isa/su");
fword("open-dev");
fword("encode-int");
push_str("stdout");
fword("property");
keyboard_controller_cmd(0x60, 0x40); // Write mode command, translated mode
}

View File

@@ -326,6 +326,7 @@ void arch_nvram_get(char *data)
uint64_t ram_size; uint64_t ram_size;
uint32_t clock_frequency; uint32_t clock_frequency;
uint16_t machine_id; uint16_t machine_id;
const char *stdin_path, *stdout_path;
nvram_read(0, (char *)&nv_info, sizeof(ohwcfg_v3_t)); nvram_read(0, (char *)&nv_info, sizeof(ohwcfg_v3_t));
@@ -413,9 +414,9 @@ void arch_nvram_get(char *data)
fword("find-device"); fword("find-device");
if (nv_info.boot_devices[0] == 'c') if (nv_info.boot_devices[0] == 'c')
bootpath = "/pci/isa/ide0/disk@0,0:a"; bootpath = "disk:a";
else else
bootpath = "/pci/isa/ide1/cdrom@0,0:a"; bootpath = "cdrom:a";
push_str(bootpath); push_str(bootpath);
fword("encode-string"); fword("encode-string");
push_str("bootpath"); push_str("bootpath");
@@ -425,6 +426,24 @@ void arch_nvram_get(char *data)
fword("encode-string"); fword("encode-string");
push_str("bootargs"); push_str("bootargs");
fword("property"); fword("property");
if (fw_cfg_read_i16(FW_CFG_NOGRAPHIC)) {
stdin_path = stdout_path = "/pci/pci/pci/ebus/su";
} else {
stdin_path = "/pci/pci/pci/ebus/kb_ps2";
stdout_path = "/pci/pci/pci/QEMU,VGA";
}
push_str(stdin_path);
fword("open-dev");
fword("encode-int");
push_str("stdin");
fword("property");
push_str(stdout_path);
fword("open-dev");
fword("encode-int");
push_str("stdout");
fword("property");
} }
void arch_nvram_put(char *data) void arch_nvram_put(char *data)
@@ -466,17 +485,11 @@ arch_init( void )
modules_init(); modules_init();
// XXX use PCI IDE // XXX use PCI IDE
setup_timers(); setup_timers();
ob_ide_init("/pci/isa", 0x1f0, 0x3f4, 0x170, 0x374); ob_ide_init("/pci/pci/pci/ebus", 0x1f0, 0x3f4, 0x170, 0x374);
#ifdef CONFIG_DRIVER_PCI #ifdef CONFIG_DRIVER_PCI
ob_pci_init(); ob_pci_init();
#endif #endif
#ifdef CONFIG_DRIVER_FLOPPY
ob_floppy_init();
#endif
nvconf_init(); nvconf_init();
ob_su_init(0x1fe02000000ULL, 0x3f8ULL, 0);
device_end(); device_end();
bind_func("platform-boot", boot ); bind_func("platform-boot", boot );

View File

@@ -21,7 +21,6 @@ int openbios(void);
/* console.c */ /* console.c */
#ifdef CONFIG_DEBUG_CONSOLE #ifdef CONFIG_DEBUG_CONSOLE
extern int uart_init(int port, unsigned long speed);
extern void video_init(void); extern void video_init(void);
#endif #endif

View File

@@ -32,17 +32,3 @@ finish-device
" /openprom" find-device " /openprom" find-device
" OBP 3.10.24 1999/01/01 01:01" encode-string " version" property " OBP 3.10.24 1999/01/01 01:01" encode-string " version" property
dev /
\ simple pci bus node
new-device
" pci" device-name
finish-device
dev /pci
\ simple isa bus node
new-device
" isa" device-name
finish-device

View File

@@ -48,7 +48,7 @@ arch_init( void )
ob_ide_init("/pci/isa", 0x1f0, 0x3f4, 0x170, 0x374); ob_ide_init("/pci/isa", 0x1f0, 0x3f4, 0x170, 0x374);
#endif #endif
#ifdef CONFIG_DRIVER_FLOPPY #ifdef CONFIG_DRIVER_FLOPPY
ob_floppy_init(); ob_floppy_init("/isa", "floppy0");
#endif #endif
#ifdef CONFIG_XBOX #ifdef CONFIG_XBOX
init_video(phys_to_virt(0x3C00000), 640, 480, 32, 2560); init_video(phys_to_virt(0x3C00000), 640, 480, 32, 2560);

View File

@@ -74,5 +74,8 @@
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/> <option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/>
<option name="CONFIG_DEBUG_FLOPPY" type="boolean" value="false"/> <option name="CONFIG_DEBUG_FLOPPY" type="boolean" value="false"/>
<option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/> <option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_EBUS" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_PC_KBD" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_PC_SERIAL" type="boolean" value="true"/>
</config> </config>

View File

@@ -74,5 +74,8 @@
<option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/> <option name="CONFIG_DRIVER_FLOPPY" type="boolean" value="true"/>
<option name="CONFIG_DEBUG_FLOPPY" type="boolean" value="false"/> <option name="CONFIG_DEBUG_FLOPPY" type="boolean" value="false"/>
<option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/> <option name="CONFIG_DRIVER_VGA" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_EBUS" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_PC_KBD" type="boolean" value="true"/>
<option name="CONFIG_DRIVER_PC_SERIAL" type="boolean" value="true"/>
</config> </config>

View File

@@ -19,6 +19,8 @@
<object source="vga_set_mode.c" condition="DRIVER_VGA"/> <object source="vga_set_mode.c" condition="DRIVER_VGA"/>
<object source="vga_vbe.c" condition="DRIVER_VGA"/> <object source="vga_vbe.c" condition="DRIVER_VGA"/>
<object source="macio.c" condition="DRIVER_MACIO"/> <object source="macio.c" condition="DRIVER_MACIO"/>
<object source="pc_kbd.c" condition="DRIVER_PC_KBD"/>
<object source="pc_serial.c" condition="DRIVER_PC_SERIAL"/>
</library> </library>
<dictionary name="openbios" target="forth"> <dictionary name="openbios" target="forth">
@@ -26,5 +28,5 @@
<object source="sbus.fs" condition="DRIVER_SBUS"/> <object source="sbus.fs" condition="DRIVER_SBUS"/>
<object source="esp.fs" condition="DRIVER_ESP"/> <object source="esp.fs" condition="DRIVER_ESP"/>
</dictionary> </dictionary>
</build> </build>

View File

@@ -1112,9 +1112,12 @@ NODE_METHODS(ob_floppy) = {
}; };
int ob_floppy_init(void) int ob_floppy_init(const char *path, const char *dev_name)
{ {
REGISTER_NAMED_NODE(ob_floppy, "/isa/floppy0"); char nodebuff[128];
snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name);
REGISTER_NAMED_NODE(ob_floppy, nodebuff);
floppy_init(); floppy_init();
return 0; return 0;
} }

216
drivers/pc_kbd.c Normal file
View File

@@ -0,0 +1,216 @@
/*
* 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/bindings.h"
#include "openbios/kernel.h"
#include "openbios/drivers.h"
#include "libc/vsprintf.h"
/* ******************************************************************
* simple polling video/keyboard console functions
* ****************************************************************** */
/*
* keyboard driver
*/
static const char normal[] = {
0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
'=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
};
static const char shifted[] = {
0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
'+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
'9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
};
static int key_ext;
static int key_lshift = 0, key_rshift = 0, key_caps = 0;
static char last_key;
static void pc_kbd_cmd(unsigned char cmd, unsigned char val)
{
outb(cmd, 0x60);
/* wait until keyboard controller accepts cmds: */
while (inb(0x64) & 2);
outb(val, 0x60);
while (inb(0x64) & 2);
}
static void pc_kbd_controller_cmd(unsigned char cmd, unsigned char val)
{
outb(cmd, 0x64);
/* wait until keyboard controller accepts cmds: */
while (inb(0x64) & 2);
outb(val, 0x60);
while (inb(0x64) & 2);
}
static char pc_kbd_poll(void)
{
unsigned int c;
if (inb(0x64) & 1) {
c = inb(0x60);
switch (c) {
case 0xe0:
key_ext = 1;
return 0;
case 0x2a:
key_lshift = 1;
return 0;
case 0x36:
key_rshift = 1;
return 0;
case 0xaa:
key_lshift = 0;
return 0;
case 0xb6:
key_rshift = 0;
return 0;
case 0x3a:
if (key_caps) {
key_caps = 0;
pc_kbd_cmd(0xed, 0);
} else {
key_caps = 1;
pc_kbd_cmd(0xed, 4); /* set caps led */
}
return 0;
}
if (key_ext) {
// void printk(const char *format, ...);
printk("extended keycode: %x\n", c);
key_ext = 0;
return 0;
}
if (c & 0x80) /* unhandled key release */
return 0;
if (key_lshift || key_rshift)
return key_caps ? normal[c] : shifted[c];
else
return key_caps ? shifted[c] : normal[c];
}
return 0;
}
int pc_kbd_dataready(void)
{
if (last_key)
return 1;
last_key = pc_kbd_poll();
return (last_key != 0);
}
unsigned char pc_kbd_readdata(void)
{
char tmp;
while (!pc_kbd_dataready());
tmp = last_key;
last_key = 0;
return tmp;
}
/* ( addr len -- actual ) */
static void
pc_kbd_read(void)
{
unsigned char *addr;
int len;
len = POP();
addr = (unsigned char *)POP();
if (len != 1)
printk("pc_kbd_read: bad len, addr %lx len %x\n", (unsigned long)addr, len);
if (pc_kbd_dataready()) {
*addr = pc_kbd_readdata();
PUSH(1);
} else {
PUSH(0);
}
}
static void
pc_kbd_close(void)
{
}
static void
pc_kbd_open(unsigned long *address)
{
int len;
phandle_t ph;
unsigned long *prop;
char *args;
fword("my-self");
fword("ihandle>phandle");
ph = (phandle_t)POP();
prop = (unsigned long *)get_property(ph, "address", &len);
*address = *prop;
fword("my-args");
args = pop_fstr_copy();
RET ( -1 );
}
DECLARE_UNNAMED_NODE(pc_kbd, INSTALL_OPEN, sizeof(unsigned long));
NODE_METHODS(pc_kbd) = {
{ "open", pc_kbd_open },
{ "close", pc_kbd_close },
{ "read", pc_kbd_read },
};
void
ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base,
uint64_t offset, int intr)
{
phandle_t chosen, aliases;
char nodebuff[128];
snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name);
REGISTER_NAMED_NODE(pc_kbd, nodebuff);
push_str(nodebuff);
fword("find-device");
push_str(dev_name);
fword("device-name");
push_str("keyboard");
fword("device-type");
chosen = find_dev("/chosen");
push_str(nodebuff);
fword("open-dev");
set_int_property(chosen, "keyboard", POP());
aliases = find_dev("/aliases");
set_property(aliases, "keyboard", nodebuff, strlen(nodebuff) + 1);
pc_kbd_controller_cmd(0x60, 0x40); // Write mode command, translated mode
}

195
drivers/pc_serial.c Normal file
View File

@@ -0,0 +1,195 @@
/*
* 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/bindings.h"
#include "openbios/kernel.h"
#include "openbios/drivers.h"
#include "libc/vsprintf.h"
/* ******************************************************************
* serial console functions
* ****************************************************************** */
#define SER_SIZE 8
#define RBR(x) x==2?0x2f8:0x3f8
#define THR(x) x==2?0x2f8:0x3f8
#define IER(x) x==2?0x2f9:0x3f9
#define IIR(x) x==2?0x2fa:0x3fa
#define LCR(x) x==2?0x2fb:0x3fb
#define MCR(x) x==2?0x2fc:0x3fc
#define LSR(x) x==2?0x2fd:0x3fd
#define MSR(x) x==2?0x2fe:0x3fe
#define SCR(x) x==2?0x2ff:0x3ff
#define DLL(x) x==2?0x2f8:0x3f8
#define DLM(x) x==2?0x2f9:0x3f9
int uart_charav(int port)
{
return ((inb(LSR(port)) & 1) != 0);
}
char uart_getchar(int port)
{
while (!uart_charav(port));
return ((char) inb(RBR(port)) & 0177);
}
static void uart_putchar(int port, unsigned char c)
{
if (c == '\n')
uart_putchar(port, '\r');
while (!(inb(LSR(port)) & 0x20));
outb(c, THR(port));
}
static void uart_init_line(int port, unsigned long baud)
{
int i, baudconst;
switch (baud) {
case 115200:
baudconst = 1;
break;
case 57600:
baudconst = 2;
break;
case 38400:
baudconst = 3;
break;
case 19200:
baudconst = 6;
break;
case 9600:
default:
baudconst = 12;
break;
}
outb(0x87, LCR(port));
outb(0x00, DLM(port));
outb(baudconst, DLL(port));
outb(0x07, LCR(port));
outb(0x0f, MCR(port));
for (i = 10; i > 0; i--) {
if (inb(LSR(port)) == (unsigned int) 0)
break;
inb(RBR(port));
}
}
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
int uart_init(int port, unsigned long speed)
{
uart_init_line(port, speed);
return -1;
}
void serial_putchar(int c)
{
uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff));
}
#endif
/* ( addr len -- actual ) */
static void
pc_serial_read(unsigned long *address)
{
char *addr;
int len;
len = POP();
addr = (char *)POP();
if (len != 1)
printk("pc_serial_read: bad len, addr %lx len %x\n", (unsigned long)addr, len);
if (uart_charav(*address)) {
*addr = (char)uart_getchar(*address);
PUSH(1);
} else {
PUSH(0);
}
}
/* ( addr len -- actual ) */
static void
pc_serial_write(unsigned long *address)
{
unsigned char *addr;
int i, len;
len = POP();
addr = (unsigned char *)POP();
for (i = 0; i < len; i++) {
uart_putchar(*address, addr[i]);
}
PUSH(len);
}
static void
pc_serial_close(void)
{
}
static void
pc_serial_open(unsigned long *address)
{
int len;
phandle_t ph;
unsigned long *prop;
char *args;
fword("my-self");
fword("ihandle>phandle");
ph = (phandle_t)POP();
prop = (unsigned long *)get_property(ph, "address", &len);
*address = *prop;
fword("my-args");
args = pop_fstr_copy();
RET ( -1 );
}
DECLARE_UNNAMED_NODE(pc_serial, INSTALL_OPEN, sizeof(unsigned long));
NODE_METHODS(pc_serial) = {
{ "open", pc_serial_open },
{ "close", pc_serial_close },
{ "read", pc_serial_read },
{ "write", pc_serial_write },
};
void
ob_pc_serial_init(const char *path, const char *dev_name, uint64_t base,
uint64_t offset, int intr)
{
char nodebuff[128];
snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name);
REGISTER_NAMED_NODE(pc_serial, nodebuff);
push_str(nodebuff);
fword("find-device");
push_str("serial");
fword("device-type");
PUSH((base + offset) >> 32);
fword("encode-int");
PUSH((base + offset) & 0xffffffff);
fword("encode-int");
fword("encode+");
PUSH(SER_SIZE);
fword("encode-int");
fword("encode+");
push_str("reg");
fword("property");
}

View File

@@ -415,6 +415,24 @@ int vga_config_cb (const pci_config_t *config)
return 0; return 0;
} }
int ebus_config_cb(const pci_config_t *config)
{
printk("ebus config %s addr %x size %x\n", config->path,
config->assigned[0] & ~0x0000000F, config->sizes[0]);
#ifdef CONFIG_DRIVER_EBUS
#ifdef CONFIG_DRIVER_FLOPPY
ob_floppy_init(config->path, "fdthree");
#endif
#ifdef CONFIG_DRIVER_PC_SERIAL
ob_pc_serial_init(config->path, "su", arch->io_base, 0x3f8ULL, 0);
#endif
#ifdef CONFIG_DRIVER_PC_KBD
ob_pc_kbd_init(config->path, "kb_ps2", arch->io_base, 0x60ULL, 0);
#endif
#endif
return 0;
}
static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev, static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
const pci_config_t *config) const pci_config_t *config)
{ {

View File

@@ -312,6 +312,21 @@ static const pci_dev_t PCIbrg_devices[] = {
}, },
}; };
static const pci_dev_t miscbrg_devices[] = {
{
0x108e, 0x1000, NULL,
"ebus", "ebus", "pci108e,1000\0pciclass,068000\0",
3, 2, 1,
ebus_config_cb, NULL,
},
{
0xFFFF, 0xFFFF,
NULL, NULL, NULL, NULL,
-1, -1, -1,
NULL, NULL,
},
};
static const pci_subclass_t bridg_subclass[] = { static const pci_subclass_t bridg_subclass[] = {
{ {
0x00, "PCI host bridge", NULL, hbrg_devices, NULL, 0x00, "PCI host bridge", NULL, hbrg_devices, NULL,
@@ -358,7 +373,7 @@ static const pci_subclass_t bridg_subclass[] = {
NULL, NULL, NULL, NULL,
}, },
{ {
0x80, "misc PCI bridge", NULL, NULL, NULL, 0x80, "misc PCI bridge", NULL, miscbrg_devices, NULL,
NULL, NULL, NULL, NULL,
}, },
{ {

View File

@@ -31,6 +31,7 @@ extern int macio_config_cb(const pci_config_t *config);
extern int vga_config_cb(const pci_config_t *config); extern int vga_config_cb(const pci_config_t *config);
extern int host_config_cb(const pci_config_t *config); extern int host_config_cb(const pci_config_t *config);
extern int bridge_config_cb(const pci_config_t *config); extern int bridge_config_cb(const pci_config_t *config);
extern int ebus_config_cb(const pci_config_t *config);
static inline int pci_compat_len(const pci_dev_t *dev) static inline int pci_compat_len(const pci_dev_t *dev)
{ {

View File

@@ -74,7 +74,21 @@ extern uint32_t cmdline_size;
extern char boot_device; extern char boot_device;
#endif #endif
#ifdef CONFIG_DRIVER_FLOPPY #ifdef CONFIG_DRIVER_FLOPPY
int ob_floppy_init(void); int ob_floppy_init(const char *path, const char *dev_name);
#endif
#ifdef CONFIG_DRIVER_PC_KBD
void ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base,
uint64_t offset, int intr);
int pc_kbd_dataready(void);
unsigned char pc_kbd_readdata(void);
#endif
#ifdef CONFIG_DRIVER_PC_SERIAL
void ob_pc_serial_init(const char *path, const char *dev_name, uint64_t base,
uint64_t offset, int intr);
int uart_init(int port, unsigned long speed);
int uart_charav(int port);
char uart_getchar(int port);
void serial_putchar(int c);
#endif #endif
#endif /* OPENBIOS_DRIVERS_H */ #endif /* OPENBIOS_DRIVERS_H */