| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include <linux/kernel.h> |
| #include <asm/barrier.h> |
| #include <asm/page.h> |
| #include <asm/processor.h> |
| #include <asm/udbg.h> |
| |
| struct memcons { |
| <------>char *output_start; |
| <------>char *output_pos; |
| <------>char *output_end; |
| <------>char *input_start; |
| <------>char *input_pos; |
| <------>char *input_end; |
| }; |
| |
| static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE]; |
| static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE]; |
| |
| struct memcons memcons = { |
| <------>.output_start = memcons_output, |
| <------>.output_pos = memcons_output, |
| <------>.output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE], |
| <------>.input_start = memcons_input, |
| <------>.input_pos = memcons_input, |
| <------>.input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE], |
| }; |
| |
| void memcons_putc(char c) |
| { |
| <------>char *new_output_pos; |
| |
| <------>*memcons.output_pos = c; |
| <------>wmb(); |
| <------>new_output_pos = memcons.output_pos + 1; |
| <------>if (new_output_pos >= memcons.output_end) |
| <------><------>new_output_pos = memcons.output_start; |
| |
| <------>memcons.output_pos = new_output_pos; |
| } |
| |
| int memcons_getc_poll(void) |
| { |
| <------>char c; |
| <------>char *new_input_pos; |
| |
| <------>if (*memcons.input_pos) { |
| <------><------>c = *memcons.input_pos; |
| |
| <------><------>new_input_pos = memcons.input_pos + 1; |
| <------><------>if (new_input_pos >= memcons.input_end) |
| <------><------><------>new_input_pos = memcons.input_start; |
| <------><------>else if (*new_input_pos == '\0') |
| <------><------><------>new_input_pos = memcons.input_start; |
| |
| <------><------>*memcons.input_pos = '\0'; |
| <------><------>wmb(); |
| <------><------>memcons.input_pos = new_input_pos; |
| <------><------>return c; |
| <------>} |
| |
| <------>return -1; |
| } |
| |
| int memcons_getc(void) |
| { |
| <------>int c; |
| |
| <------>while (1) { |
| <------><------>c = memcons_getc_poll(); |
| <------><------>if (c == -1) |
| <------><------><------>cpu_relax(); |
| <------><------>else |
| <------><------><------>break; |
| <------>} |
| |
| <------>return c; |
| } |
| |
| void udbg_init_memcons(void) |
| { |
| <------>udbg_putc = memcons_putc; |
| <------>udbg_getc = memcons_getc; |
| <------>udbg_getc_poll = memcons_getc_poll; |
| } |
| |