0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/kernel.h>
0018 #include <asm/barrier.h>
0019 #include <asm/page.h>
0020 #include <asm/processor.h>
0021 #include <asm/udbg.h>
0022
0023 struct memcons {
0024 char *output_start;
0025 char *output_pos;
0026 char *output_end;
0027 char *input_start;
0028 char *input_pos;
0029 char *input_end;
0030 };
0031
0032 static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
0033 static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
0034
0035 struct memcons memcons = {
0036 .output_start = memcons_output,
0037 .output_pos = memcons_output,
0038 .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
0039 .input_start = memcons_input,
0040 .input_pos = memcons_input,
0041 .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
0042 };
0043
0044 void memcons_putc(char c)
0045 {
0046 char *new_output_pos;
0047
0048 *memcons.output_pos = c;
0049 wmb();
0050 new_output_pos = memcons.output_pos + 1;
0051 if (new_output_pos >= memcons.output_end)
0052 new_output_pos = memcons.output_start;
0053
0054 memcons.output_pos = new_output_pos;
0055 }
0056
0057 int memcons_getc_poll(void)
0058 {
0059 char c;
0060 char *new_input_pos;
0061
0062 if (*memcons.input_pos) {
0063 c = *memcons.input_pos;
0064
0065 new_input_pos = memcons.input_pos + 1;
0066 if (new_input_pos >= memcons.input_end)
0067 new_input_pos = memcons.input_start;
0068 else if (*new_input_pos == '\0')
0069 new_input_pos = memcons.input_start;
0070
0071 *memcons.input_pos = '\0';
0072 wmb();
0073 memcons.input_pos = new_input_pos;
0074 return c;
0075 }
0076
0077 return -1;
0078 }
0079
0080 int memcons_getc(void)
0081 {
0082 int c;
0083
0084 while (1) {
0085 c = memcons_getc_poll();
0086 if (c == -1)
0087 cpu_relax();
0088 else
0089 break;
0090 }
0091
0092 return c;
0093 }
0094
0095 void __init udbg_init_memcons(void)
0096 {
0097 udbg_putc = memcons_putc;
0098 udbg_getc = memcons_getc;
0099 udbg_getc_poll = memcons_getc_poll;
0100 }