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.


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