IBM Full System Simulator Bogus Console Device Driver This patch allows users of the IBM Full System Simulator to have terminal and console input without having any bridge support. This driver uses the IBM Full System Simulator sim call routines. From: Maximino Aguilar Signed-off-by: Arnd Bergmann --- arch/ppc64/configs/bpa_defconfig | 1 arch/ppc64/configs/cbesim_defconfig | 3 drivers/char/Kconfig | 6 drivers/char/Makefile | 1 drivers/char/bogus_console.c | 315 ++++++++++++++++++++++++++++++++++++ 5 files changed, 325 insertions(+), 1 deletion(-) Index: linux-2.6.14-rc/arch/ppc64/configs/cbesim_defconfig =================================================================== --- linux-2.6.14-rc.orig/arch/ppc64/configs/cbesim_defconfig 2005-10-22 01:18:01.000000000 +0200 +++ linux-2.6.14-rc/arch/ppc64/configs/cbesim_defconfig 2005-10-22 01:18:12.000000000 +0200 @@ -321,7 +321,8 @@ # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set -CONFIG_RTASCONS=y +# CONFIG_RTASCONS is not set +CONFIG_BOGUS_CONSOLE=y # # IPMI Index: linux-2.6.14-rc/drivers/char/Makefile =================================================================== --- linux-2.6.14-rc.orig/drivers/char/Makefile 2005-10-22 01:17:30.000000000 +0200 +++ linux-2.6.14-rc/drivers/char/Makefile 2005-10-22 01:18:12.000000000 +0200 @@ -41,6 +41,7 @@ obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_RTASCONS) += rtascons.o +obj-$(CONFIG_BOGUS_CONSOLE) +=bogus_console.o obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o Index: linux-2.6.14-rc/drivers/char/bogus_console.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.14-rc/drivers/char/bogus_console.c 2005-10-22 01:18:12.000000000 +0200 @@ -0,0 +1,315 @@ +/* + * Bogus console driver using IBM Full System Simulator + * + * (C) Copyright IBM Corporation 2001-2005 + * + * Bogus Console Driver + * + * Author: Maximino Aguilar + * + * inspired by drivers/char/hvc_console.c + * written by Anton Blanchard and Paul Mackerras + * + * Some code is from the IBM Full System Simulator Group in ARL. + * Author: Patrick Bohrer + * + * 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, 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define bog_console_major 240 +#define bog_console_minor 0 +#define BOG_TTY_BUF_SIZE 512 + +static inline int callthru0(int command) +{ + register int c asm ("r3") = command; + + asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c)); + return((c)); +} + +static inline int callthru3(int command, unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + register int c asm ("r3") = command; + register unsigned long a1 asm ("r4") = arg1; + register unsigned long a2 asm ("r5") = arg2; + register unsigned long a3 asm ("r6") = arg3; + + asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c), "r" (a1), "r" (a2), "r" (a3)); + return((c)); +} + +static inline int WriteConsole(char *string) +{ + return(callthru3(0, (unsigned long)string, + (unsigned long)strlen(string), (unsigned long)1)); +} + +static inline int ReadConsole(void) +{ + return(callthru0(60)); +} + +typedef struct { + struct tty_struct *tty; + unsigned char buf[BOG_TTY_BUF_SIZE]; + unsigned short int buf_count; + spinlock_t lock; +} bog_tty_data_struct; + +static bog_tty_data_struct bog_tty_data = { }; + +static struct tty_driver bog_tty_driver; +static struct termios *bog_tty_termios[1]; +static struct termios *bog_tty_termios_locked[1]; +static int bog_tty_refcount = 0; + +static int +bog_tty_open (struct tty_struct *tty, struct file *filp) +{ + if (tty->index != 0) + return -ENODEV; + + tty->driver_data = &bog_tty_data; + bog_tty_data.buf_count = 0; + bog_tty_data.tty = tty; + tty->low_latency = 0; + bog_tty_data.buf[0]=0; + return 0; +} + +static void +bog_tty_close (struct tty_struct *tty, struct file *filp) +{ + if (tty->count > 1) + return; + bog_tty_data.tty = NULL; +} + +static int +bog_tty_write (struct tty_struct *tty, const unsigned char *buf, int count) +{ + return 0; +} + +static int +bog_tty_write_room (struct tty_struct *tty) +{ + return BOG_TTY_BUF_SIZE; +} + +static void +bog_tty_put_char (struct tty_struct *tty, unsigned char ch) +{ + char buff[BOG_TTY_BUF_SIZE]; + int i; + + if (bog_tty_data.buf_count >= BOG_TTY_BUF_SIZE) { + for (i=0;iflip.char_buf_ptr; + flagptr=tty->flip.flag_buf_ptr; + rc=tty->flip.count; + + count=bog_tty_input(buff); + if (count!=0) + { + for (i=0;icomm,"kbogconsd"); + sigfillset(¤t->blocked); + + for (;;) { + bog_poll(); + set_current_state(TASK_INTERRUPTIBLE); + /* We schedule often to allow for a better typing experience */ + schedule_timeout(1); + } +} + +static struct tty_operations con_ops = { + .open = bog_tty_open, + .close = bog_tty_close, + .write = bog_tty_write, + .write_room = bog_tty_write_room, + .put_char = bog_tty_put_char, + .flush_chars = bog_tty_flush_chars, + .chars_in_buffer = bog_tty_chars_in_buffer, + .flush_buffer = bog_tty_flush_buffer, +}; + +int __init bog_tty_init (void) +{ + bog_tty_driver.magic = TTY_DRIVER_MAGIC; + bog_tty_driver.driver_name = "bogus"; + bog_tty_driver.name = "bogus"; + bog_tty_driver.name_base = 0; + bog_tty_driver.major = bog_console_major; + bog_tty_driver.minor_start = bog_console_minor; + bog_tty_driver.num = 1; + bog_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM; + bog_tty_driver.subtype = SYSTEM_TYPE_TTY; + bog_tty_driver.init_termios = tty_std_termios; + bog_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR; + bog_tty_driver.init_termios.c_oflag = ONLCR; + bog_tty_driver.init_termios.c_lflag = ISIG | ECHO; + bog_tty_driver.flags = TTY_DRIVER_REAL_RAW; + bog_tty_driver.refcount = bog_tty_refcount; + bog_tty_driver.termios = bog_tty_termios; + bog_tty_driver.termios_locked = bog_tty_termios_locked; + + tty_set_operations(&bog_tty_driver, &con_ops); + + if (tty_register_driver(&bog_tty_driver)) + printk(KERN_ERR "Couldn't register bog_tty driver\n"); + + kernel_thread((void *)kbogconsd, NULL, CLONE_KERNEL); + return 0; +} + +static int __init bog_console_setup(struct console *co, char *options) +{ + return 0; +} + +static void __exit bog_exit(void) +{ +} + +void +bog_console_write(struct console *console, const char *message, unsigned count) +{ + char buff[count+1]; + int i; + + for (i=0;iindex; + return &bog_tty_driver; +} + +struct console bog_console = { + .name = "bogus", + .write = bog_console_write, + .device = bog_console_device, + .setup = bog_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static int __init bog_console_init (void) +{ + register_console(&bog_console); + return 0; +} + +console_initcall(bog_console_init); +module_init(bog_tty_init); +module_exit(bog_exit); Index: linux-2.6.14-rc/drivers/char/Kconfig =================================================================== --- linux-2.6.14-rc.orig/drivers/char/Kconfig 2005-10-22 01:17:30.000000000 +0200 +++ linux-2.6.14-rc/drivers/char/Kconfig 2005-10-22 01:18:12.000000000 +0200 @@ -566,6 +566,12 @@ help RTAS console support. +config BOGUS_CONSOLE + bool "Simulator bogus console support" + depends on PPC_PSERIES || PPC_BPA + help + IBM System Simulator bogus console device driver. + config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES --