tls@ wrote: > On Fri, Apr 12, 2024 at 09:13:17AM -0400, Thor Lancelot Simon wrote: > > On Sat, Apr 06, 2024 at 11:56:27PM +0900, Izumi Tsutsui wrote: > > > > > > I'd like to add new APIs to use wskbd(4) input on non-wsdisplay > > > tty devices, especially news68k that can use a putchar function > > > provided by firmware PROM as a kernel console device. > > > > Wouldn't a tty be a better abstraction for this? Lots of minicomputers > > had incredibly dumb serial consoles. > > I think the above is not clear. To rephrase my question: what is the > wscons layer actually adding here? Would it not be simpler to interface > at the tty layer instead?
- The tty layer requires both getchar() and putchar(). - For a glass console, completely different two drivers are necessary, i.e. keyboard driver for getchar() and display driver for putchar(). - On news68k, it's not easy to implement framebuffer driver due to lack of information, but we can use a putchar() function provided by a NEWS PROM firmware because it also supports VT emulation. - On the other hand, we cannot use getchar() function provided by a NEWS PROM firmware for useland because it uses busy loop to wait keyboard input. But we already has a wskbd driver for NEWS machines. - So I would like propose adding APIs "to use wskbd driver just for keyboard inputs" for non-wscons(4) tty drivers See sys/arch/sun3/dev/kd.c for another example that use "PROM function for putchar() to display and sys/dev/sun/kbd.c via zs(4) for getchar() from keyboard". https://github.com/NetBSD/src/blob/6053b8d/sys/arch/sun3/dev/kd.c --- static void kdstart(struct tty *tp) { struct clist *cl; int s1, s2; s1 = splsoftclock(); s2 = spltty(); if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT)) goto out; cl = &tp->t_outq; if (ttypull(tp)) { if (kd_is_console) { tp->t_state |= TS_BUSY; if ((s1 & PSL_IPL) == 0) { /* called at level zero - update screen now. */ splx(s2); kd_putfb(tp); [...] } [...] /* * Put text on the screen using the PROM monitor. * This can take a while, so to avoid missing * interrupts, this is called at splsoftclock. */ static void kd_putfb(struct tty *tp) { char buf[PUT_WSIZE]; struct clist *cl = &tp->t_outq; char *p, *end; int len; while ((len = q_to_b(cl, buf, PUT_WSIZE-1)) > 0) { /* PROM will barf if high bits are set. */ p = buf; end = buf + len; while (p < end) *p++ &= 0x7f; (romVectorPtr->fbWriteStr)(buf, len); } } [...] /* * Our "interrupt" routine for input. This is called by * the keyboard driver (dev/sun/kbd.c) at spltty. */ void kd_cons_input(int c) { struct kd_softc *kd = &kd_softc; struct tty *tp; /* XXX: Make sure the device is open. */ tp = kd->kd_tty; if (tp == NULL) return; if ((tp->t_state & TS_ISOPEN) == 0) return; (*tp->t_linesw->l_rint)(c, tp); } --- sys/arch/news68k/news68k/romcons.c has the similar implementation: https://github.com/tsutsui/netbsd-src/blob/c74b64a/sys/arch/news68k/news68k/romcons.c --- static void romcons_start(struct tty *tp) { int s, len; uint8_t buf[BURSTLEN]; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { splx(s); return; } tp->t_state |= TS_BUSY; splx(s); len = q_to_b(&tp->t_outq, buf, BURSTLEN); s = splhigh(); rom_write(1, buf, len); splx(s); s = spltty(); tp->t_state &= ~TS_BUSY; if (ttypull(tp)) { tp->t_state |= TS_TIMEOUT; callout_schedule(&tp->t_rstrt_ch, 1); } splx(s); } [...] #if NWSKBD > 0 static void romcons_kbdinput(device_t self, int ks) { struct romcons_softc *sc = device_private(self); struct tty *tp; KASSERT(sc != NULL); tp = sc->sc_tty; if (tp && (tp->t_state & TS_ISOPEN)) (*tp->t_linesw->l_rint)(ks, tp); } #endif --- Izumi Tsutsui