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

Reply via email to