The IBM full system simulator for PowerPC has its own set of calls used for console interaction, when not simulating actual serial port hardware. This is needed to run the simulator for Cell and can also be used for the PowerPC 970 simulator. It also adds the generic asm/systemsim.h header file that is also used by other device drivers for the system simulator, i.e. the block and network drivers. Signed-off-by: "Ryan S. Arnold" Signed-off-by: Arnd Bergmann Index: linux-2.6.15-rc/drivers/char/hvc_fss.c =================================================================== --- /dev/null +++ linux-2.6.15-rc/drivers/char/hvc_fss.c @@ -0,0 +1,109 @@ +/* + * IBM Full System Simulator driver interface to hvc_console.c + * + * (C) Copyright IBM Corporation 2001-2005 + * Author(s): Maximino Augilar + * : Ryan S. Arnold + * + * 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 + * + * Much of this code was moved here from the IBM Full System Simulator + * Bogus console driver in order to reuse the framework provided by the hvc + * console driver. Ryan S. Arnold + * + * 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 + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "hvc_console.h" + +#define SIM_WRITE_CONSOLE_CODE 0 +#define SIM_READ_CONSOLE_CODE 60 + +#define hvc_fss_cookie 0x1aa70e29 + +static int hvc_fss_write_console(uint32_t vtermno, const char *buf, int count) +{ + int ret; + ret = callthru3(SIM_WRITE_CONSOLE_CODE, (unsigned long)buf, count, 1); + if (ret != 0) + return (count - ret); /* is this right? */ + + /* the calling routine expects to receive the number of bytes sent */ + return count; +} + +static int hvc_fss_read_console(uint32_t vtermno, char *buf, int count) +{ + unsigned long got; + int c, i; + + got = 0; + for (i = 0; i < count; i++) { + if ((c = callthru0(SIM_READ_CONSOLE_CODE)) != -1) { + buf[i] = c; + ++got; + } + else + break; + } + return got; +} + +static struct hv_ops hvc_fss_get_put_ops = { + .get_chars = hvc_fss_read_console, + .put_chars = hvc_fss_write_console, +}; + +static int __init hvc_fss_init(void) +{ + struct hvc_struct *hp; + + /* Allocate an hvc_struct for the console device we instantiated + * earlier. Save off hp so that we can return it on exit */ + hp = hvc_alloc(hvc_fss_cookie, NO_IRQ, &hvc_fss_get_put_ops); + if (IS_ERR(hp)) + return PTR_ERR(hp); + + return 0; +} +module_init(hvc_fss_init); + +/* This will happen prior to module init. There is no tty at this time? */ +static int __init hvc_fss_console_init(void) +{ + /* Don't register if we aren't running on the simulator */ + if (of_find_node_by_path("/mambo")) { + /* Tell the driver we know of one console device. We + * shouldn't get a collision on the index as long as no-one + * else instantiates on hardware they don't have. */ + hvc_instantiate(hvc_fss_cookie, 0, &hvc_fss_get_put_ops ); + add_preferred_console("hvc", 0, NULL); + } + return 0; +} +console_initcall(hvc_fss_console_init); Index: linux-2.6.15-rc/include/asm-powerpc/systemsim.h =================================================================== --- /dev/null +++ linux-2.6.15-rc/include/asm-powerpc/systemsim.h @@ -0,0 +1,132 @@ +/* + * + * Copyright (C) 2001, 2005 IBM + * + * Filename : systemsim.h + * + * Originator : Patrick Bohrer and Charles Lefurgy + * Modified By : Eric Van Hensbegren + * + * Purpose : + * + * This file is compiled with programs that are run under the + * PowerPC Full System simulator. For example, stand-alone programs + * or operating systems. The programs call the callthru wrapper + * functions which use an illegal PowerPC instruction to signal the + * simulator to emulate special support. + * + */ + +#ifndef _SYSTEMSIM_CONFIG_H_ +#define _SYSTEMSIM_CONFIG_H_ +#ifdef __KERNEL__ + +/* The functions callthru0 to callthru5 setup up the arguments for the + * simulator callthru and then use the callthru instruction. Note that + * 0-5 specify the number of arguments after the command */ + +/* Note: Arguments are cast as void* to prevent casting by the + compiler. This way, you can pass pointers, integers, etc. in + machine register and have the simulator interpret what the + register is supposed to be. To help with typing errors when using + callthrus, we provide wrapper functions for each callthru. The + wrappers cast all arguments to void*. Unfortunately, this results + in a lot of compiler warnings that I do not know how to remove. If + you modify this code, be aware that we are trying to pick a type + that is the size of the registers (32-bit or 64-bit) and that is + why are choosing to cast to a void* (it should be the size of a + machine register) */ + +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 callthru1(int command, unsigned long arg1) +{ + register int c asm("r3") = command; + register unsigned long a1 asm("r4") = arg1; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1)); + return (c); +} +static inline int callthru2(int command, unsigned long arg1, unsigned long arg2) +{ + register int c asm("r3") = command; + register unsigned long a1 asm("r4") = arg1; + register unsigned long a2 asm("r5") = arg2; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2)); + 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 callthru4(int command, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4) +{ + 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; + register unsigned long a4 asm("r7") = arg4; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2), + "r"(a3), "r"(a4)); + return (c); +} +static inline int callthru5(int command, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5) +{ + 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; + register unsigned long a4 asm("r7") = arg4; + register unsigned long a5 asm("r8") = arg5; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2), + "r"(a3), "r"(a4), "r"(a5)); + return (c); +} +static inline int callthru6(int command, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5, unsigned long arg6) +{ + 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; + register unsigned long a4 asm("r7") = arg4; + register unsigned long a5 asm("r8") = arg5; + register unsigned long a6 asm("r9") = arg6; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2), + "r"(a3), "r"(a4), "r"(a5), "r"(a6)); + return (c); +} +static inline int callthru7(int command, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5, unsigned long arg6, + unsigned long arg7) +{ + 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; + register unsigned long a4 asm("r7") = arg4; + register unsigned long a5 asm("r8") = arg5; + register unsigned long a6 asm("r9") = arg6; + register unsigned long a7 asm("r10") = arg7; + asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2), + "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7)); + return (c); +} + +#endif /* __KERNEL__ */ +#endif/* _SYSTEMSIM_CONFIG_H_ */ Index: linux-2.6.15-rc/drivers/char/Kconfig =================================================================== --- linux-2.6.15-rc.orig/drivers/char/Kconfig +++ linux-2.6.15-rc/drivers/char/Kconfig @@ -570,6 +570,14 @@ config HVC_CONSOLE console. This driver allows each pSeries partition to have a console which is accessed via the HMC. +config HVC_FSS + bool "IBM Full System Simulator Console support" + depends on PPC_PSERIES || PPC_CELL || PPC_MAPLE + select HVC_DRIVER + help + IBM Full System Simulator Console device driver which makes use of + the HVC_DRIVER front end. + config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES Index: linux-2.6.15-rc/drivers/char/Makefile =================================================================== --- linux-2.6.15-rc.orig/drivers/char/Makefile +++ linux-2.6.15-rc/drivers/char/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_SX) += sx.o generic_serial obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o +obj-$(CONFIG_HVC_FSS) += hvc_fss.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o --