1 /* $NetBSD: cons_machdep.c,v 1.8 2015/06/15 16:53:17 matt Exp $ */
2
3 /*-
4 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: cons_machdep.c,v 1.8 2015/06/15 16:53:17 matt Exp $");
34
35 #include <sys/param.h>
36 #include <sys/conf.h>
37 #include <sys/cpu.h>
38 #include <sys/systm.h>
39
40 #include <dev/cons.h>
41
42 #include <machine/sbdvar.h>
43
44 #include <ews4800mips/ews4800mips/cons_machdep.h>
45
46 cons_decl(rom_);
47
48 struct cons cons;
49 struct consdev consdev_rom = {
50 rom_cnprobe,
51 rom_cninit,
52 rom_cngetc,
53 rom_cnputc,
54 rom_cnpollc,
55 NULL,
56 NULL,
57 NULL,
58 NODEV,
59 CN_DEAD
60 };
61
62 void
consinit(void)63 consinit(void)
64 {
65 static int initted;
66
67 if (initted)
68 return;
69
70 if (platform.consinit) {
71 (*platform.consinit)();
72 initted = 1;
73 } else
74 rom_cons_init(); /* XXX */
75 }
76
77 void
rom_cons_init(void)78 rom_cons_init(void)
79 {
80
81 cons.type = CONS_ROM;
82 cn_tab = &consdev_rom;
83 (*cn_tab->cn_init)(cn_tab);
84 }
85
86 void
rom_cnprobe(struct consdev * cn)87 rom_cnprobe(struct consdev *cn)
88 {
89
90 cn->cn_pri = CN_INTERNAL;
91 }
92
93 void
rom_cninit(struct consdev * cn)94 rom_cninit(struct consdev *cn)
95 {
96 static int initted;
97
98 if (initted)
99 return;
100
101 cons.x = X_INIT;
102 #if 0
103 cons.y = Y_INIT;
104 #else
105 cons.y = 20; /* XXX no way to get the previous cursor position */
106 #endif
107 initted = 1;
108 }
109
110 void
rom_cnputc(dev_t dev,int c)111 rom_cnputc(dev_t dev, int c)
112 {
113 int i;
114 struct lwp *curlwp_save;
115
116 curlwp_save = curlwp;
117
118 switch (c) {
119 default:
120 ROM_PUTC(cons.x * ROM_FONT_WIDTH, cons.y * ROM_FONT_HEIGHT, c);
121 if (++cons.x == CONS_WIDTH) {
122 cons.x = X_INIT;
123 cons.y++;
124 }
125 break;
126 case '\b':
127 ROM_PUTC(cons.x * ROM_FONT_WIDTH, cons.y * ROM_FONT_HEIGHT, c);
128 cons.x = cons.x == X_INIT ? X_INIT : cons.x - 1;
129 break;
130 case '\t':
131 for (i = cons.x % 8; i < 8; i++) {
132 ROM_PUTC(cons.x * ROM_FONT_WIDTH,
133 cons.y * ROM_FONT_HEIGHT, ' ');
134 if (++cons.x == CONS_WIDTH) {
135 cons.x = X_INIT;
136 if (++cons.y == CONS_HEIGHT)
137 cons.y = Y_INIT;
138 }
139 }
140 break;
141 case '\r':
142 ROM_PUTC(cons.x * ROM_FONT_WIDTH, cons.y * ROM_FONT_HEIGHT, c);
143 cons.x = X_INIT;
144 break;
145 case '\n':
146 ROM_PUTC(cons.x * ROM_FONT_WIDTH, cons.y * ROM_FONT_HEIGHT,
147 '\r');
148 ROM_PUTC(cons.x * ROM_FONT_WIDTH, cons.y * ROM_FONT_HEIGHT, c);
149 cons.x = X_INIT;
150 cons.y++;
151 break;
152 }
153
154 curlwp = curlwp_save;
155
156 if (cons.y == CONS_HEIGHT)
157 cons.y = Y_INIT;
158 }
159
160 int
rom_cngetc(dev_t dev)161 rom_cngetc(dev_t dev)
162 {
163 int rval;
164 struct lwp *curlwp_save;
165
166 curlwp_save = curlwp;
167 rval = ROM_GETC();
168 curlwp = curlwp_save;
169
170 return rval;
171 }
172
173 void
rom_cnpollc(dev_t dev,int on)174 rom_cnpollc(dev_t dev, int on)
175 {
176 static bool __polling = false;
177 static int s;
178
179 if (on && !__polling) {
180 s = splhigh(); /* Disable interrupt driven I/O */
181 __polling = true;
182 } else if (!on && __polling) {
183 __polling = false;
184 splx(s); /* Enable interrupt driven I/O */
185 }
186 }
187