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.


created a test directory to hold test guest OSes
[palacios.git] / test / geekos_test_vm / src / geekos / serial.c
diff --git a/test/geekos_test_vm/src/geekos/serial.c b/test/geekos_test_vm/src/geekos/serial.c
new file mode 100644 (file)
index 0000000..0729501
--- /dev/null
@@ -0,0 +1,178 @@
+#include <geekos/serial.h>
+#include <geekos/reboot.h>
+#include <geekos/gdt.h>
+#include <geekos/idt.h>
+
+
+
+
+unsigned short serial_io_addr = 0;
+
+
+static void Serial_Interrupt_Handler(struct Interrupt_State * state) {
+  char rcv_byte;
+  char irq_id;
+
+  Begin_IRQ(state);
+
+  irq_id = In_Byte(serial_io_addr + 2);
+
+
+  if ((irq_id & 0x04) != 0) {
+    rcv_byte = In_Byte(serial_io_addr + 0);
+
+    if (rcv_byte == 'k') {
+      SerialPrint("Restarting Machine\r\n");
+      machine_real_restart();
+    } else if (rcv_byte=='d') { 
+      SerialPrint("Dumping Machine State\n");
+      Dump_Interrupt_State(state);
+      DumpIDT();
+      DumpGDT();
+    }
+      
+#if 0
+      SerialPrint("Unreserved serial byte: %d (%c)\r\n", rcv_byte, rcv_byte);
+#endif
+  }
+  End_IRQ(state);
+}
+
+
+void InitSerialAddr(unsigned short io_addr) {
+  serial_io_addr = io_addr;
+
+  Print("Initializing Polled Serial Output on COM1 - 115200 N81 noflow\n");
+  //  io_adr = 0x3F8;  /* 3F8=COM1, 2F8=COM2, 3E8=COM3, 2E8=COM4 */
+  Out_Byte(io_addr + 3, 0x80);
+  // 115200 /* 115200 / 12 = 9600 baud */
+  Out_Byte(io_addr + 0, 1);
+  Out_Byte(io_addr + 1, 0);
+  /* 8N1 */
+  Out_Byte(io_addr + 3, 0x03);
+  /* all interrupts disabled */
+  //  Out_Byte(io_addr + 1, 0);
+  Out_Byte(io_addr + 1, 0x01);
+  /* turn off FIFO, if any */
+  Out_Byte(io_addr + 2, 0);
+  /* loopback off, interrupts (Out2) off, Out1/RTS/DTR off */
+  //  Out_Byte(io_addr + 4, 0);
+  // enable interrupts (bit 3)
+  Out_Byte(io_addr + 4, 0x08);
+}
+
+
+inline static void SerialPutChar(unsigned char c) {
+ //  static unsigned short io_adr;
+  if (serial_io_addr==0) { 
+    return;
+  }
+
+
+  if (c=='\n') { 
+    /* wait for transmitter ready */
+    while((In_Byte(serial_io_addr + 5) & 0x40) == 0) {
+    }
+    /* send char */
+    Out_Byte(serial_io_addr + 0, '\r');
+    /* wait for transmitter ready */
+  }
+  while((In_Byte(serial_io_addr + 5) & 0x40) == 0) {
+  }
+  /* send char */
+  Out_Byte(serial_io_addr + 0, c);
+}
+
+
+
+void SerialPutLineN(char * line, int len) {
+  int i;
+  for (i = 0; i < len && line[i] != 0; i++) { 
+    SerialPutChar(line[i]); 
+  }
+}
+
+
+void SerialPutLine(char * line) {
+  int i;
+  for (i = 0; line[i]!= 0; i++) { 
+    SerialPutChar(line[i]); 
+  }
+}
+
+
+void SerialPrintHex(unsigned char x)
+{
+  unsigned char z;
+  
+  z = (x>>4) & 0xf ;
+  SerialPrint("%x", z);
+  z = x & 0xf;
+  SerialPrint("%x", z);
+}
+
+void SerialMemDump(unsigned char *start, int n)
+{
+  int i, j;
+
+  for (i=0;i<n;i+=16) {
+    SerialPrint("%8x", (unsigned)(start+i));
+    for (j=i; j<i+16 && j<n; j+=2) {
+      SerialPrint(" ");
+      SerialPrintHex(*((unsigned char *)(start+j)));
+      if ((j+1)<n) { 
+       SerialPrintHex(*((unsigned char *)(start+j+1)));
+      }
+    }
+    SerialPrint(" ");
+    for (j=i; j<i+16 && j<n;j++) {
+      SerialPrint("%c", ((start[j]>=32) && (start[j]<=126)) ? start[j] : '.');
+    }
+    SerialPrint("\n");
+  }
+}
+
+
+static struct Output_Sink serial_output_sink;
+static void Serial_Emit(struct Output_Sink * o, int ch) { 
+  SerialPutChar((unsigned char)ch); 
+}
+static void Serial_Finish(struct Output_Sink * o) { return; }
+
+
+static void __inline__ SerialPrintInternal(const char * format, va_list ap) {
+  Format_Output(&serial_output_sink, format, ap);
+}
+
+
+void SerialPrint(const char * format, ...) {
+  va_list args;
+  bool iflag = Begin_Int_Atomic();
+
+  va_start(args, format);
+  SerialPrintInternal(format, args);
+  va_end(args);
+
+  End_Int_Atomic(iflag);
+}
+
+void SerialPrintList(const char * format, va_list ap) {
+  bool iflag = Begin_Int_Atomic();
+  SerialPrintInternal(format, ap);
+  End_Int_Atomic(iflag);
+
+}
+
+
+
+void InitSerial() {
+  Print("Initialzing Serial\n");
+
+  serial_output_sink.Emit = &Serial_Emit;
+  serial_output_sink.Finish = &Serial_Finish;
+
+  Install_IRQ(COM1_IRQ, Serial_Interrupt_Handler);
+  Enable_IRQ(COM1_IRQ);
+  InitSerialAddr(DEFAULT_SERIAL_ADDR);
+}