Rev 1816 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1816 | Rev 1831 | ||
---|---|---|---|
Line 37... | Line 37... | ||
37 | #include <arch/drivers/xconsole.h> |
37 | #include <arch/drivers/xconsole.h> |
38 | #include <putchar.h> |
38 | #include <putchar.h> |
39 | #include <console/chardev.h> |
39 | #include <console/chardev.h> |
40 | #include <console/console.h> |
40 | #include <console/console.h> |
41 | #include <arch/hypercall.h> |
41 | #include <arch/hypercall.h> |
- | 42 | #include <mm/frame.h> |
|
42 | 43 | ||
- | 44 | #define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1)) |
|
- | 45 | ||
- | 46 | typedef struct { |
|
- | 47 | char in[1024]; |
|
- | 48 | char out[2048]; |
|
- | 49 | uint32_t in_cons; |
|
- | 50 | uint32_t in_prod; |
|
- | 51 | uint32_t out_cons; |
|
- | 52 | uint32_t out_prod; |
|
- | 53 | } xencons_t; |
|
- | 54 | ||
- | 55 | static bool asynchronous = false; |
|
43 | static void xen_putchar(chardev_t *d, const char ch); |
56 | static void xen_putchar(chardev_t *d, const char ch); |
44 | 57 | ||
45 | chardev_t xen_console; |
58 | chardev_t xen_console; |
46 | static chardev_operations_t xen_ops = { |
59 | static chardev_operations_t xen_ops = { |
47 | .write = xen_putchar |
60 | .write = xen_putchar |
Line 49... | Line 62... | ||
49 | 62 | ||
50 | void xen_console_init(void) |
63 | void xen_console_init(void) |
51 | { |
64 | { |
52 | chardev_initialize("xen_out", &xen_console, &xen_ops); |
65 | chardev_initialize("xen_out", &xen_console, &xen_ops); |
53 | stdout = &xen_console; |
66 | stdout = &xen_console; |
- | 67 | if (!(start_info.flags & SIF_INITDOMAIN)) |
|
- | 68 | asynchronous = true; |
|
54 | } |
69 | } |
55 | 70 | ||
56 | void xen_putchar(chardev_t *d, const char ch) |
71 | void xen_putchar(chardev_t *d, const char ch) |
57 | { |
72 | { |
- | 73 | if (asynchronous) { |
|
- | 74 | xencons_t *console = (xencons_t *) PA2KA(MA2PA(PFN2ADDR(start_info.console_mfn))); |
|
- | 75 | uint32_t cons = console->out_cons; |
|
- | 76 | uint32_t prod = console->out_prod; |
|
- | 77 | ||
- | 78 | memory_barrier(); |
|
- | 79 | ||
- | 80 | if ((prod - cons) > sizeof(console->out)) |
|
- | 81 | return; |
|
- | 82 | ||
- | 83 | if (ch == '\n') |
|
- | 84 | console->out[MASK_INDEX(prod++, console->out)] = '\r'; |
|
- | 85 | console->out[MASK_INDEX(prod++, console->out)] = ch; |
|
- | 86 | ||
- | 87 | write_barrier(); |
|
- | 88 | ||
- | 89 | console->out_prod = prod; |
|
- | 90 | ||
- | 91 | xen_notify_remote(start_info.console_evtchn); |
|
- | 92 | } else |
|
58 | xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
93 | xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
59 | } |
94 | } |
60 | 95 | ||
61 | /** @} |
96 | /** @} |
62 | */ |
97 | */ |