/* * Copyright (C) 2005 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include static void ofw_sparc64_putchar(chardev_t *d, const char ch); static char ofw_sparc64_getchar(chardev_t *d); static void ofw_sparc64_suspend(chardev_t *d); static void ofw_sparc64_resume(chardev_t *d); mutex_t canwork; static chardev_t ofw_sparc64_console; static chardev_operations_t ofw_sparc64_console_ops = { .write = ofw_sparc64_putchar, .read = ofw_sparc64_getchar, .resume = ofw_sparc64_resume, .suspend = ofw_sparc64_suspend }; void ofw_sparc64_console_init(void) { chardev_initialize("ofw_sparc64_console", &ofw_sparc64_console, &ofw_sparc64_console_ops); stdin = &ofw_sparc64_console; stdout = &ofw_sparc64_console; mutex_initialize(&canwork); } /** Write one character. * * @param d Character device (ignored). * @param ch Character to be written. */ void ofw_sparc64_putchar(chardev_t *d, const char ch) { pstate_reg_t pstate; /* * 32-bit OpenFirmware depends on PSTATE.AM bit set. */ pstate.value = pstate_read(); pstate.am = true; pstate_write(pstate.value); if (ch == '\n') ofw_putchar('\r'); ofw_putchar(ch); pstate.am = false; pstate_write(pstate.value); } /** Read one character. * * The call is non-blocking. * * @param d Character device (ignored). * @return Character read or zero if no character was read. */ char ofw_sparc64_getchar(chardev_t *d) { char ch; pstate_reg_t pstate; /* * 32-bit OpenFirmware depends on PSTATE.AM bit set. */ pstate.value = pstate_read(); pstate.am = true; pstate_write(pstate.value); ch = ofw_getchar(); pstate.am = false; pstate_write(pstate.value); return ch; } void ofw_sparc64_suspend(chardev_t *d) { mutex_lock(&canwork); } void ofw_sparc64_resume(chardev_t *d) { mutex_unlock(&canwork); } /** Kernel thread for pushing characters read from OFW to input buffer. * * @param arg Ignored. */ void kofwinput(void *arg) { while (1) { char ch = 0; mutex_lock(&canwork); mutex_unlock(&canwork); ch = ofw_sparc64_getchar(NULL); if (ch) { if (ch == '\r') ch = '\n'; chardev_push_character(&ofw_sparc64_console, ch); } thread_usleep(25000); } }