00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <interrupt.h>
00036 #include <arch/cp0.h>
00037 #include <arch/drivers/serial.h>
00038 #include <console/chardev.h>
00039 #include <console/console.h>
00040
00041 static chardev_t console;
00042 static serial_t sconf[SERIAL_MAX];
00043 static bool kb_enabled;
00044
00045 static void serial_write(chardev_t *d, const char ch)
00046 {
00047 serial_t *sd = (serial_t *)d->data;
00048
00049 if (ch == '\n')
00050 serial_write(d, '\r');
00051
00052 while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT)))
00053 ;
00054 SERIAL_WRITE(sd->port, ch);
00055 }
00056
00057 static void serial_enable(chardev_t *d)
00058 {
00059 kb_enabled = true;
00060 }
00061
00062 static void serial_disable(chardev_t *d)
00063 {
00064 kb_enabled = false;
00065 }
00066
00067 int serial_init(void)
00068 {
00069 int i = 0;
00070 if (SERIAL_READ_LSR(SERIAL_COM1) == 0x60) {
00071 sconf[i].port = SERIAL_COM1;
00072 sconf[i].irq = SERIAL_COM1_IRQ;
00073
00074 i++;
00075 }
00076 return i;
00077 }
00078
00080 static char serial_do_read(chardev_t *dev)
00081 {
00082 serial_t *sd = (serial_t *)dev->data;
00083 char ch;
00084
00085 while (!(SERIAL_READ_LSR(sd->port) & 1))
00086 ;
00087 ch = SERIAL_READ(sd->port);
00088
00089 if (ch =='\r')
00090 ch = '\n';
00091 return ch;
00092 }
00093
00094
00096 static void serial_interrupt(int n, void *stack)
00097 {
00098 serial_t *sd = (serial_t *)console.data;
00099 char ch;
00100
00101 if (!(SERIAL_READ_LSR(sd->port) & 1))
00102 return;
00103 ch = SERIAL_READ(sd->port);
00104
00105 if (ch =='\r')
00106 ch = '\n';
00107 chardev_push_character(&console, ch);
00108 }
00109
00110
00111
00112 static chardev_operations_t serial_ops = {
00113 .resume = serial_enable,
00114 .suspend = serial_disable,
00115 .write = serial_write,
00116 .read = serial_do_read
00117 };
00118
00119 iroutine old_timer;
00121 static void timer_replace(int n, istate_t *istate)
00122 {
00123 old_timer(n, istate);
00124 serial_interrupt(n, istate);
00125 }
00126
00127 void serial_console(void)
00128 {
00129 serial_t *sd = &sconf[0];
00130
00131
00132 chardev_initialize("serial_console", &console, &serial_ops);
00133 console.data = sd;
00134 kb_enabled = true;
00135
00136
00137
00138
00139
00140 old_timer = int_register(TIMER_IRQ, "serial_drvr_poll", timer_replace);
00141
00142 stdin = &console;
00143 stdout = &console;
00144 }
00145