Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


modified copyright tags
[palacios.git] / palacios / src / geekos / serial.c
1 /* (c) 2008, Peter Dinda <pdinda@northwestern.edu> */
2 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
3 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
4
5 #include <geekos/serial.h>
6 #include <geekos/reboot.h>
7 #include <geekos/gdt.h>
8 #include <geekos/idt.h>
9 #include <geekos/fmtout.h>
10
11
12
13
14 unsigned short serial_io_addr = 0;
15 uint_t serial_print_level;
16
17 static void Serial_Interrupt_Handler(struct Interrupt_State * state) {
18   char rcv_byte;
19   char irq_id;
20
21   Begin_IRQ(state);
22
23   irq_id = In_Byte(serial_io_addr + 2);
24
25
26   if ((irq_id & 0x04) != 0) {
27     rcv_byte = In_Byte(serial_io_addr + 0);
28
29     if (rcv_byte == 'k') {
30       SerialPrint("Restarting Machine\r\n");
31       machine_real_restart();
32     } else if (rcv_byte=='d') { 
33       SerialPrint("Dumping Machine State\n");
34       Dump_Interrupt_State(state);
35       DumpIDT();
36       DumpGDT();
37     }
38       
39 #if 0
40       SerialPrint("Unreserved serial byte: %d (%c)\r\n", rcv_byte, rcv_byte);
41 #endif
42   }
43   End_IRQ(state);
44 }
45
46
47
48 void InitSerialAddr(unsigned short io_addr) {
49   serial_io_addr = io_addr;
50
51   Print("Initializing Polled Serial Output on COM1 - 115200 N81 noflow\n");
52   //  io_adr = 0x3F8;   /* 3F8=COM1, 2F8=COM2, 3E8=COM3, 2E8=COM4 */
53   Out_Byte(io_addr + 3, 0x80);
54   // 115200 /* 115200 / 12 = 9600 baud */
55   Out_Byte(io_addr + 0, 1);
56   Out_Byte(io_addr + 1, 0);
57   /* 8N1 */
58   Out_Byte(io_addr + 3, 0x03);
59   /* all interrupts disabled */
60   //  Out_Byte(io_addr + 1, 0);
61   Out_Byte(io_addr + 1, 0x01);
62   /* turn off FIFO, if any */
63   Out_Byte(io_addr + 2, 0);
64   /* loopback off, interrupts (Out2) off, Out1/RTS/DTR off */
65   //  Out_Byte(io_addr + 4, 0);
66   // enable interrupts (bit 3)
67   Out_Byte(io_addr + 4, 0x08);
68 }
69
70
71
72
73 void SerialPutChar(unsigned char c) {
74  
75  //  static unsigned short io_adr;
76   if (serial_io_addr==0) { 
77     return;
78   }
79
80
81   if (c=='\n') { 
82     /* wait for transmitter ready */
83     while((In_Byte(serial_io_addr + 5) & 0x40) == 0) {
84     }
85     /* send char */
86     Out_Byte(serial_io_addr + 0, '\r');
87     /* wait for transmitter ready */
88   }
89   while((In_Byte(serial_io_addr + 5) & 0x40) == 0) {
90   }
91   /* send char */
92   Out_Byte(serial_io_addr + 0, c);
93 }
94
95
96
97 void SerialPutLineN(char * line, int len) {
98   int i;
99   for (i = 0; i < len && line[i] != 0; i++) { 
100     SerialPutChar(line[i]); 
101   }
102 }
103
104
105 void SerialPutLine(char * line) {
106   int i;
107   for (i = 0; line[i]!= 0; i++) { 
108     SerialPutChar(line[i]); 
109   }
110 }
111
112
113 void SerialPrintHex(unsigned char x)
114 {
115   unsigned char z;
116   
117   z = (x>>4) & 0xf ;
118   SerialPrint("%x", z);
119   z = x & 0xf;
120   SerialPrint("%x", z);
121 }
122
123 void SerialMemDump(unsigned char *start, int n)
124 {
125   int i, j;
126
127   for (i=0;i<n;i+=16) {
128     SerialPrint("%8x", (unsigned)(start+i));
129     for (j=i; j<i+16 && j<n; j+=2) {
130       SerialPrint(" ");
131       SerialPrintHex(*((unsigned char *)(start+j)));
132       if ((j+1)<n) { 
133         SerialPrintHex(*((unsigned char *)(start+j+1)));
134       }
135     }
136     SerialPrint(" ");
137     for (j=i; j<i+16 && j<n;j++) {
138       SerialPrint("%c", ((start[j]>=32) && (start[j]<=126)) ? start[j] : '.');
139     }
140     SerialPrint("\n");
141   }
142 }
143
144
145 static struct Output_Sink serial_output_sink;
146 static void Serial_Emit(struct Output_Sink * o, int ch) { 
147   SerialPutChar((unsigned char)ch); 
148 }
149 static void Serial_Finish(struct Output_Sink * o) { return; }
150
151
152 static void __inline__ SerialPrintInternal(const char * format, va_list ap) {
153   Format_Output(&serial_output_sink, format, ap);
154 }
155
156
157 void SerialPrint(const char * format, ...) {
158   va_list args;
159   bool iflag = Begin_Int_Atomic();
160
161   va_start(args, format);
162   SerialPrintInternal(format, args);
163   va_end(args);
164
165   End_Int_Atomic(iflag);
166 }
167
168 void SerialPrintList(const char * format, va_list ap) {
169   bool iflag = Begin_Int_Atomic();
170   SerialPrintInternal(format, ap);
171   End_Int_Atomic(iflag);
172
173 }
174
175
176
177
178 void SerialPrintLevel(int level, const char * format, ...) {
179   if (level > serial_print_level) {
180     va_list args;
181     bool iflag = Begin_Int_Atomic();
182     
183     va_start(args, format);
184     SerialPrintInternal(format, args);
185     va_end(args);
186     
187     End_Int_Atomic(iflag);   
188   }
189 }
190
191
192
193
194 void Init_Serial() {
195
196   serial_print_level = SERIAL_PRINT_DEBUG_LEVEL;
197
198   Print("Initialzing Serial\n");
199
200   serial_output_sink.Emit = &Serial_Emit;
201   serial_output_sink.Finish = &Serial_Finish;
202
203   Install_IRQ(COM1_IRQ, Serial_Interrupt_Handler);
204   Enable_IRQ(COM1_IRQ);
205   InitSerialAddr(DEFAULT_SERIAL_ADDR);
206 }