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.


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