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

2024-04-06 Thread Izumi Tsutsui
# tl;dr

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.

# Details

The news68k machines have various framebuffer options, but
most of them are not "dumb" framebuffer that can be handled
by raspos(9) but some of them have own processors (68000 etc.)
to handle various acceleration etc. so it's difficult to implement
framebuffer drivers.

To support "text only" framebuffer console, we can use putchar
functions provided by the firmware PROM.

However, to use getchar() functions we cannot use getchar
provided by PROM because it always stalls until any key is
pressed.

NetBSD/sun3 has the similar framework in sys/arch/sun3/dev/kd.c,
i.e. it uses a PROM function for putchar but use own keyboard
driver (sys/dev/sun/kbd.c) to handle kernel console.

I'd like to implement the similar framework on NetBSD/news68k.
news68k port already has wskbd driver (delived from newsmips port),
but currently a design of wskbd(9) assumes always it used with
wsdisplay(9) tty (i.e. ttyE?) device and there is no API to use
wskbd(9) input for other drivers than wsdisplay(9).

The attached patch provides new two APIs
- wskbd_consdev_kbdinput_register()
- wskbd_consdev_kbdinput_deregister()
to allow a kernel to use wskbd(9) for non-wsdisplay tty device.

Once "sc_consdev_kbdinput()" callback funtion is registered
via the wskbd_consdev_kbdinput_register() by the MD attachment,
MI wskbd(9) just puts the input data from wskbd(9) to the callback
fundtions, if NWSDISPLAY is not configured.

I think the change is minimum and it doesn't break any existing
ports that use wsdisplay(9) ttys, but I'd like to call for
comments about these implementation design.

Supporting non-serial console on news68k port has been in
my TODO list for ~20 years so I'd like to commit this
if there is no particular objection.

There is a video of NetBSD/news68k 9.3 with the similar patch:
 https://www.youtube.com/watch?v=kPOiHG20Ye8


Index: sys/dev/wscons/wskbd.c
===
RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.143
diff -u -p -d -r1.143 wskbd.c
--- sys/dev/wscons/wskbd.c  5 Feb 2019 10:04:49 -   1.143
+++ sys/dev/wscons/wskbd.c  6 Apr 2024 06:59:50 -
@@ -214,6 +214,9 @@ struct wskbd_softc {
/* optional table to translate scancodes in event mode */
int sc_evtrans_len;
keysym_t*sc_evtrans;
+
+   wskbd_consdev_kbdinput *sc_consdev_kbdinput;
+   device_t sc_consdev;
 };
 
 #define MOD_SHIFT_L(1 << 0)
@@ -420,6 +423,8 @@ wskbd_attach(device_t parent, device_t s
sc->sc_hotkeycookie = NULL;
sc->sc_evtrans_len = 0;
sc->sc_evtrans = NULL;
+   sc->sc_consdev_kbdinput = NULL;
+   sc->sc_consdev = NULL;
 
 #if NWSMUX > 0 || NWSDISPLAY > 0
sc->sc_base.me_ops = &wskbd_srcops;
@@ -664,9 +669,7 @@ void
 wskbd_input(device_t dev, u_int type, int value)
 {
struct wskbd_softc *sc = device_private(dev);
-#if NWSDISPLAY > 0
int num, i;
-#endif
 
if (sc->sc_repeating) {
sc->sc_repeating = 0;
@@ -706,6 +709,24 @@ wskbd_input(device_t dev, u_int type, in
}
 #endif
 
+#if NWSDISPLAY == 0
+   if (sc->sc_translating) {
+   keysym_t ks;
+
+   if (sc->sc_consdev_kbdinput) {
+   num = wskbd_translate(sc->id, type, value);
+   for (i = 0; i < num; i++) {
+   ks = sc->id->t_symbols[i];
+   if (KS_GROUP(ks) == KS_GROUP_Plain &&
+   KS_VALUE(ks) <= 0x7f)
+   (*sc->sc_consdev_kbdinput)(
+   sc->sc_consdev, KS_VALUE(ks));
+   }
+   return;
+   }
+   }
+#endif
+
wskbd_deliver_event(sc, type, value);
 
 #if defined(WSKBD_EVENT_AUTOREPEAT)
@@ -1683,6 +1704,36 @@ wskbd_hotkey_deregister(device_t self)
sc->sc_hotkeycookie = NULL;
 }
 
+device_t
+wskbd_consdev_kbdinput_register(device_t self, wskbd_consdev_kbdinput *kifn,
+device_t cons_dv)
+{
+   struct wskbd_softc *sc = device_private(self);
+
+   if (sc == NULL)
+   return NULL;
+
+   if (kifn == NULL)
+   return NULL;
+
+   sc->sc_consdev_kbdinput = kifn;
+   sc->sc_consdev = cons_dv;
+   aprint_verbose_dev(self, "connecting to %s\n", device_xname(cons_dv));
+
+   return sc->sc_base.me_dv;
+}
+
+void
+wskbd_consdev_kbdinput_deregister(device_t self)
+{
+   struct wskbd_softc *sc = device_private(self);
+
+   KASSERT(sc != NULL);
+
+   sc->sc_consdev_kbdinput = NULL;
+   sc->sc_consdev = NULL;
+}
+
 static int
 wskbd_translate(struct wskbd_internal *id, u_int type, int value)
 {
Index: sys/dev/wsc

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

2024-04-06 Thread Valery Ushakov
On Sat, Apr 06, 2024 at 23:56:27 +0900, Izumi Tsutsui wrote:

> To support "text only" framebuffer console, we can use putchar
> functions provided by the firmware PROM.

Is that a console-typewriter--like device without addressable cursor
terminal emulation?  Can you use wsemul_dumb to avoid rasops &c?  It
still uses copy/erase, but with trivial argument values that can be
reversed back to puchar calls for tab/lf (from a very quick look).


> The attached patch provides new two APIs
> - wskbd_consdev_kbdinput_register()
> - wskbd_consdev_kbdinput_deregister()
> to allow a kernel to use wskbd(9) for non-wsdisplay tty device.

AFAIU, there's nothing console-specific in this (except that it's
first use is going to be for a console), so may be it would be better
to drop the "consdev" from the name?


> Index: sys/dev/wscons/wskbd.c
> ===
> RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
> retrieving revision 1.143
> diff -u -p -d -r1.143 wskbd.c
> --- sys/dev/wscons/wskbd.c5 Feb 2019 10:04:49 -   1.143
> +++ sys/dev/wscons/wskbd.c6 Apr 2024 06:59:50 -
[...]
> @@ -706,6 +709,24 @@ wskbd_input(device_t dev, u_int type, in
>   }
>  #endif
>  
> +#if NWSDISPLAY == 0
> + if (sc->sc_translating) {

The #endif above is for NWSDISPLAY > 0, so may be get rid of the
ifdefs and use plain ifs?

Thanks.

-uwe


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

2024-04-06 Thread Michael
Hello,

On Sat, 6 Apr 2024 23:56:27 +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.
> 
> # Details
> 
> The news68k machines have various framebuffer options, but
> most of them are not "dumb" framebuffer that can be handled
> by raspos(9) but some of them have own processors (68000 etc.)
> to handle various acceleration etc. so it's difficult to implement
> framebuffer drivers.

You can use wsdisplay without rasops or a mappable framebuffer.
Examples would be things like newport or crmfb on sgimips.

> To support "text only" framebuffer console, we can use putchar
> functions provided by the firmware PROM.

Does it let you draw characters wherever you want with colours of
inverse attrubute?
If so, that's enough for wsdisplay - sti on hppa does just that. 

have fun
Michael



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

2024-04-06 Thread Izumi Tsutsui
uwe@ wrote:

> On Sat, Apr 06, 2024 at 23:56:27 +0900, Izumi Tsutsui wrote:
> 
> > To support "text only" framebuffer console, we can use putchar
> > functions provided by the firmware PROM.
> 
> Is that a console-typewriter--like device without addressable cursor
> terminal emulation?  Can you use wsemul_dumb to avoid rasops &c?  It
> still uses copy/erase, but with trivial argument values that can be
> reversed back to puchar calls for tab/lf (from a very quick look).

The PROM provides (at least I can use) only a "putchar()" function.
No other framebuffer ops like bitblt.
For now I cannot find any proper implementation example in such case..

> > The attached patch provides new two APIs
> > - wskbd_consdev_kbdinput_register()
> > - wskbd_consdev_kbdinput_deregister()
> > to allow a kernel to use wskbd(9) for non-wsdisplay tty device.
> 
> AFAIU, there's nothing console-specific in this (except that it's
> first use is going to be for a console), so may be it would be better
> to drop the "consdev" from the name?

Hmm.

Actually it is not a "console" device (by sys/dev/cons.c) of the kernel,
but I just intended it as a "screen console (not a serial one)".

What name should we use in such case?
dispdev? scrndev? putchar?
"wskbd_ttyinput_register()" and "ttydev" (for members) or something?

> > Index: sys/dev/wscons/wskbd.c
> > ===
> > RCS file: /cvsroot/src/sys/dev/wscons/wskbd.c,v
> > retrieving revision 1.143
> > diff -u -p -d -r1.143 wskbd.c
> > --- sys/dev/wscons/wskbd.c  5 Feb 2019 10:04:49 -   1.143
> > +++ sys/dev/wscons/wskbd.c  6 Apr 2024 06:59:50 -
> [...]
> > @@ -706,6 +709,24 @@ wskbd_input(device_t dev, u_int type, in
> > }
> >  #endif
> >  
> > +#if NWSDISPLAY == 0
> > +   if (sc->sc_translating) {
> 
> The #endif above is for NWSDISPLAY > 0, so may be get rid of the
> ifdefs and use plain ifs?

It looks wskbd(9) assumes always attached to wsdisplay(9) (ttyE?)
if wsdisplay(4) is configured (in the above #if NWSDISPLAY >0 block)
even if no wsdisplay(4) devices are actually attached.

In my news68k case, I thought we should not override the current
assumptions even in the wskbd_consdev_kbdinput_register() case.

I have a feeling we should have separate 'if (sc->sc_translating)'
blocks for both case. Maybe we can simply use #else like:
#if NWSDISPLAY > 0
 [send kbd inputs to wsdisplay_kbdinput() and return unconditionally]
#else
 [send kbd inputs to sc_consdev_kbdinput() and return if it's registered]
#endif

Thanks,
---
Izumi Tsutsui


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

2024-04-12 Thread Thor Lancelot Simon
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.



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

2024-04-12 Thread Thor Lancelot Simon
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?

Thor


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

2024-04-12 Thread Izumi Tsutsui
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