00001 /* 00002 * Copyright (C) 2003 Josef Cejka 00003 * Copyright (C) 2005 Jakub Jermar 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * - Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * - Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * - The name of the author may not be used to endorse or promote products 00016 * derived from this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00019 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00020 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00021 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00023 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00024 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00025 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00027 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00036 #include <console/console.h> 00037 #include <console/chardev.h> 00038 #include <synch/waitq.h> 00039 #include <synch/spinlock.h> 00040 #include <arch/types.h> 00041 #include <typedefs.h> 00042 #include <arch.h> 00043 #include <func.h> 00044 #include <print.h> 00045 #include <atomic.h> 00046 00047 #define BUFLEN 2048 00048 static char debug_buffer[BUFLEN]; 00049 static size_t offset = 0; 00054 static void null_putchar(chardev_t *d, const char ch) 00055 { 00056 if (offset >= BUFLEN) 00057 offset = 0; 00058 debug_buffer[offset++] = ch; 00059 } 00060 00061 static chardev_operations_t null_stdout_ops = { 00062 .write = null_putchar 00063 }; 00064 chardev_t null_stdout = { 00065 .name = "null", 00066 .op = &null_stdout_ops 00067 }; 00068 00070 chardev_t *stdin = NULL; 00071 chardev_t *stdout = &null_stdout; 00072 00079 __u8 _getc(chardev_t *chardev) 00080 { 00081 __u8 ch; 00082 ipl_t ipl; 00083 00084 if (atomic_get(&haltstate)) { 00085 /* If we are here, we are hopefully on the processor, that 00086 * issued the 'halt' command, so proceed to read the character 00087 * directly from input 00088 */ 00089 if (chardev->op->read) 00090 return chardev->op->read(chardev); 00091 /* no other way of interacting with user, halt */ 00092 if (CPU) 00093 printf("cpu%d: ", CPU->id); 00094 else 00095 printf("cpu: "); 00096 printf("halted - no kconsole\n"); 00097 cpu_halt(); 00098 } 00099 00100 waitq_sleep(&chardev->wq); 00101 ipl = interrupts_disable(); 00102 spinlock_lock(&chardev->lock); 00103 ch = chardev->buffer[(chardev->index - chardev->counter) % CHARDEV_BUFLEN]; 00104 chardev->counter--; 00105 spinlock_unlock(&chardev->lock); 00106 interrupts_restore(ipl); 00107 00108 chardev->op->resume(chardev); 00109 00110 return ch; 00111 } 00112 00124 count_t gets(chardev_t *chardev, char *buf, size_t buflen) 00125 { 00126 index_t index = 0; 00127 char ch; 00128 00129 while (index < buflen) { 00130 ch = _getc(chardev); 00131 if (ch == '\b') { 00132 if (index > 0) { 00133 index--; 00134 /* Space backspace, space */ 00135 putchar('\b'); 00136 putchar(' '); 00137 putchar('\b'); 00138 } 00139 continue; 00140 } 00141 putchar(ch); 00142 00143 if (ch == '\n') { /* end of string => write 0, return */ 00144 buf[index] = '\0'; 00145 return (count_t) index; 00146 } 00147 buf[index++] = ch; 00148 } 00149 return (count_t) index; 00150 } 00151 00153 __u8 getc(chardev_t *chardev) 00154 { 00155 __u8 ch; 00156 00157 ch = _getc(chardev); 00158 putchar(ch); 00159 return ch; 00160 } 00161 00162 void putchar(char c) 00163 { 00164 if (stdout->op->write) 00165 stdout->op->write(stdout, c); 00166 } 00167