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.


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