tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [RFC] new APIs to use wskbd(4) input on non-wsdisplay tty devices



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


Home | Main Index | Thread Index | Old Index