Using serial port 1 interrupt to get the char
from serial input, and send it to serial output.
You can use terminal to watch the result.
---
configs/uart-demo.c | 84 ++++++++++++++++++++++++++++++++++++
inmates/demos/x86/Makefile | 3 +-
inmates/demos/x86/uart-demo.c | 99 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+), 1 deletion(-)
create mode 100644 configs/uart-demo.c
create mode 100644 inmates/demos/x86/uart-demo.c
diff --git a/configs/uart-demo.c b/configs/uart-demo.c
new file mode 100644
index 0000000..49cb33a
--- /dev/null
+++ b/configs/uart-demo.c
@@ -0,0 +1,84 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Minimal configuration for demo inmates, 1 CPU, 1 MB RAM, 1 serial port
+ *
+ * Copyright (c) Siemens AG, 2013, 2014
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/types.h>
+#include <jailhouse/cell-config.h>
+
+#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
+
+struct {
+ struct jailhouse_cell_desc cell;
+ __u64 cpus[1];
+ struct jailhouse_memory mem_regions[2];
+ struct jailhouse_cache cache_regions[1];
+ struct jailhouse_irqchip irqchips[1];
+ __u8 pio_bitmap[0x2000];
+} __attribute__((packed)) config = {
+ .cell = {
+ .signature = JAILHOUSE_CELL_DESC_SIGNATURE,
+ .name = "uart-demo",
+ .flags = JAILHOUSE_CELL_PASSIVE_COMMREG,
+
+ .cpu_set_size = sizeof(config.cpus),
+ .num_memory_regions = ARRAY_SIZE(config.mem_regions),
+ .num_cache_regions = ARRAY_SIZE(config.cache_regions),
+ .num_irqchips = ARRAY_SIZE(config.irqchips),
+ .pio_bitmap_size = ARRAY_SIZE(config.pio_bitmap),
+ .num_pci_devices = 0,
+ },
+
+ .cpus = {
+ 0x4,
+ },
+
+ .mem_regions = {
+ /* RAM */ {
+ .phys_start = 0x3f100000,
+ .virt_start = 0,
+ .size = 0x00100000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_LOADABLE,
+ },
+ /* communication region */ {
+ .virt_start = 0x00100000,
+ .size = 0x00001000,
+ .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
+ JAILHOUSE_MEM_COMM_REGION,
+ },
+ },
+
+ .cache_regions = {
+ {
+ .start = 2,
+ .size = 1,
+ .type = JAILHOUSE_CACHE_L3,
+ },
+ },
+
+ .irqchips = {
+ /* IOAPIC */ {
+ .address = 0xfec00000,
+ .id = 0xff01,
+ .pin_bitmap = 0x0000010, /*for serial 1*/
+ },
+ },
+
+ .pio_bitmap = {
+ [ 0/8 ... 0x3f7/8] = -1,
+ [ 0x3f8/8 ... 0x3ff/8] = 0, /* serial2 */
+ [ 0x400/8 ... 0xdfff/8] = -1,
+ [0xe000/8 ... 0xe007/8] = 0, /* OXPCIe952 serial2 */
+ [0xe008/8 ... 0xffff/8] = -1,
+ },
+};
diff --git a/inmates/demos/x86/Makefile b/inmates/demos/x86/Makefile
index 8defc67..0d8ece6 100644
--- a/inmates/demos/x86/Makefile
+++ b/inmates/demos/x86/Makefile
@@ -13,7 +13,7 @@
include $(INMATES_LIB)/Makefile.lib
INMATES := tiny-demo.bin apic-demo.bin ioapic-demo.bin 32-bit-demo.bin \
- pci-demo.bin e1000-demo.bin ivshmem-demo.bin smp-demo.bin
+ pci-demo.bin e1000-demo.bin ivshmem-demo.bin smp-demo.bin uart-demo.bin
tiny-demo-y := tiny-demo.o
apic-demo-y := apic-demo.o
@@ -22,6 +22,7 @@ pci-demo-y := pci-demo.o
e1000-demo-y := e1000-demo.o
ivshmem-demo-y := ivshmem-demo.o
smp-demo-y := smp-demo.o
+uart-demo-y := uart-demo.o
$(eval $(call DECLARE_32_BIT,32-bit-demo))
32-bit-demo-y := 32-bit-demo.o
diff --git a/inmates/demos/x86/uart-demo.c b/inmates/demos/x86/uart-demo.c
new file mode 100644
index 0000000..59337ca
--- /dev/null
+++ b/inmates/demos/x86/uart-demo.c
@@ -0,0 +1,99 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2013
+ *
+ * Authors:
+ * Jan Kiszka <
jan.k...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <inmate.h>
+
+#ifdef CONFIG_UART_OXPCIE952
+#define UART_BASE 0xe000
+#else
+#define UART_BASE 0x3f8
+#endif
+
+#define IRQ_BASE 32
+#define IRQ_UART_1 4
+
+#define UART_RX 0x0
+#define UART_TX 0x0
+#define UART_DLL 0x0
+#define UART_DLM 0x1
+#define UART_IER 0x1
+#define UART_IIR 0x2
+#define UART_IIR_RDA 0x4
+#define UART_LCR 0x3
+#define UART_LCR_8N1 0x03
+#define UART_LCR_DLAB 0x80
+#define UART_LSR 0x5
+#define UART_LSR_THRE 0x20
+
+static void uart_write(const unsigned char c)
+{
+
+ while (!(inb(printk_uart_base + UART_LSR) & UART_LSR_THRE))
+ cpu_relax();
+ outb(c, printk_uart_base + UART_TX);
+}
+
+static void uart_read(void){
+ unsigned char c;
+
+ c = inb( printk_uart_base + UART_RX);
+
+ switch(c) {
+ case 0: //null
+ break;
+ case 13: //enter press
+ uart_write('\n');
+ break;
+ case 127:
+ uart_write('\b');
+ default:
+ uart_write(c);
+ }
+}
+
+static void uart_init(void)
+{
+ printk("interrupt initialization\n");
+ int_init();
+ int_set_handler(IRQ_UART_1 + IRQ_BASE, uart_read);
+
+ ioapic_init();
+ ioapic_pin_set_vector( IRQ_UART_1, TRIGGER_LEVEL_ACTIVE_HIGH, IRQ_UART_1 + IRQ_BASE);
+
+ outb(0x1,printk_uart_base + UART_IER); //uart interrupt enable
+ asm volatile("sti");
+
+ printk("interrupt initialization complete\n");
+
+}
+
+void inmate_main(void)
+{
+ bool terminate = false;
+
+ printk_uart_base = UART_BASE;
+ printk("Hello from this tiny uart demo cell!\n");
+
+ uart_init();
+
+ while (!terminate) {
+ asm volatile("hlt");
+ if(JAILHOUSE_MSG_SHUTDOWN_REQUEST == comm_region->msg_to_cell)
+ terminate = true;
+ else
+ jailhouse_send_reply_from_cell(comm_region,
+ JAILHOUSE_MSG_UNKNOWN);
+ }
+
+ printk("Stopped tiny uart demo\n");
+ comm_region->cell_state = JAILHOUSE_CELL_SHUT_DOWN;
+}
--
2.5.0