2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2011-2012 Robert N. M. Watson
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH research programme.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
38 #include <sys/endian.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/reboot.h>
47 #include <machine/cpuregs.h>
49 #define GC_LOCK_INIT() mtx_init(&gc_lock, "gc_lock", NULL, MTX_SPIN)
51 #define GC_LOCK() do { \
53 mtx_lock_spin(&gc_lock); \
56 #define GC_LOCK_ASSERT() do { \
58 mtx_assert(&gc_lock, MA_OWNED); \
61 #define GC_UNLOCK() do { \
63 mtx_unlock_spin(&gc_lock); \
67 static struct mtx gc_lock;
70 * Low-level console driver functions.
72 static cn_probe_t gxemul_cons_cnprobe;
73 static cn_init_t gxemul_cons_cninit;
74 static cn_term_t gxemul_cons_cnterm;
75 static cn_getc_t gxemul_cons_cngetc;
76 static cn_putc_t gxemul_cons_cnputc;
77 static cn_grab_t gxemul_cons_cngrab;
78 static cn_ungrab_t gxemul_cons_cnungrab;
83 static tsw_outwakeup_t gxemul_cons_outwakeup;
85 static struct ttydevsw gxemul_cons_ttydevsw = {
86 .tsw_flags = TF_NOPREFIX,
87 .tsw_outwakeup = gxemul_cons_outwakeup,
90 static struct callout gxemul_cons_callout;
91 static u_int gxemul_cons_polltime = 10;
93 static int gxemul_cons_alt_break_state;
96 static void gxemul_cons_timeout(void *);
99 * I/O routines lifted from Deimos.
101 * XXXRW: Should be using FreeBSD's bus routines here, but they are not
102 * available until later in the boot.
105 static inline vm_offset_t
106 mips_phys_to_uncached(vm_paddr_t phys)
109 return (MIPS_PHYS_TO_DIRECT_UNCACHED(phys));
112 static inline uint8_t
113 mips_ioread_uint8(vm_offset_t vaddr)
117 __asm__ __volatile__ ("lbu %0, 0(%1)" : "=r" (v) : "r" (vaddr));
122 mips_iowrite_uint8(vm_offset_t vaddr, uint8_t v)
125 __asm__ __volatile__ ("sb %0, 0(%1)" : : "r" (v), "r" (vaddr));
129 * gxemul-specific constants.
131 #define GXEMUL_CONS_BASE 0x10000000 /* gxemul console device. */
134 * Routines for interacting with the gxemul test console. Programming details
135 * are a result of manually inspecting the source code for gxemul's
136 * dev_cons.cc and dev_cons.h.
138 * Offsets of I/O channels relative to the base.
140 #define GXEMUL_PUTGETCHAR_OFF 0x00000000
141 #define GXEMUL_CONS_HALT 0x00000010
144 * One-byte buffer as we can't check whether the console is readable without
145 * actually reading from it.
147 static char buffer_data;
148 static int buffer_valid;
151 * Low-level read and write routines.
153 static inline uint8_t
154 gxemul_cons_data_read(void)
157 return (mips_ioread_uint8(mips_phys_to_uncached(GXEMUL_CONS_BASE +
158 GXEMUL_PUTGETCHAR_OFF)));
162 gxemul_cons_data_write(uint8_t v)
165 mips_iowrite_uint8(mips_phys_to_uncached(GXEMUL_CONS_BASE +
166 GXEMUL_PUTGETCHAR_OFF), v);
170 gxemul_cons_writable(void)
177 gxemul_cons_readable(void)
185 v = gxemul_cons_data_read();
195 gxemul_cons_write(char ch)
200 while (!gxemul_cons_writable());
201 gxemul_cons_data_write(ch);
205 gxemul_cons_read(void)
210 while (!gxemul_cons_readable());
212 return (buffer_data);
216 * Implementation of a FreeBSD low-level, polled console driver.
219 gxemul_cons_cnprobe(struct consdev *cp)
222 sprintf(cp->cn_name, "ttyu0");
223 cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
227 gxemul_cons_cninit(struct consdev *cp)
234 gxemul_cons_cnterm(struct consdev *cp)
240 gxemul_cons_cngetc(struct consdev *cp)
245 ret = gxemul_cons_read();
251 gxemul_cons_cnputc(struct consdev *cp, int c)
255 gxemul_cons_write(c);
260 gxemul_cons_cngrab(struct consdev *cp)
266 gxemul_cons_cnungrab(struct consdev *cp)
271 CONSOLE_DRIVER(gxemul_cons);
274 * TTY-level functions for gxemul_cons.
277 gxemul_cons_ttyinit(void *unused)
281 tp = tty_alloc(&gxemul_cons_ttydevsw, NULL);
282 tty_init_console(tp, 0);
283 tty_makedev(tp, NULL, "%s", "ttyu0");
284 callout_init(&gxemul_cons_callout, 1);
285 callout_reset(&gxemul_cons_callout, gxemul_cons_polltime,
286 gxemul_cons_timeout, tp);
289 SYSINIT(gxemul_cons_ttyinit, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
290 gxemul_cons_ttyinit, NULL);
293 gxemul_cons_outwakeup(struct tty *tp)
299 * XXXRW: Would be nice not to do blocking writes to the console here,
300 * rescheduling on our timer tick if work remains to be done..
303 len = ttydisc_getc(tp, &ch, sizeof(ch));
307 gxemul_cons_write(ch);
313 gxemul_cons_timeout(void *v)
321 while (gxemul_cons_readable()) {
322 c = gxemul_cons_read();
325 kdb_alt_break(c, &gxemul_cons_alt_break_state);
327 ttydisc_rint(tp, c, 0);
331 ttydisc_rint_done(tp);
333 callout_reset(&gxemul_cons_callout, gxemul_cons_polltime,
334 gxemul_cons_timeout, tp);