#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: console.c,v 1.46 2026/04/30 02:56:26 adrian Exp $");
#include "opt_kgdb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/device.h>
#include <sys/bus.h>
#include <machine/machtype.h>
#include <dev/cons.h>
#include <dev/arcbios/arcbios.h>
#include <dev/arcbios/arcbiosvar.h>
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#include <dev/ic/i8042reg.h>
#include <dev/ic/pckbcvar.h>
#include <sgimips/gio/giovar.h>
#include <sgimips/hpc/hpcreg.h>
#include <sgimips/ioc/iocreg.h>
#include <sgimips/mace/macereg.h>
#include "com.h"
#include "scn.h"
#include "zsc.h"
#include "gio.h"
#include "pckbc.h"
#include "zskbd.h"
#include "crmfb.h"
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
#endif
int comcnmode = CONMODE;
extern struct consdev scn_cn;
extern struct consdev zs_cn;
extern void zs_kgdb_init(void);
extern void zskbd_cnattach(int, int);
#if (NCRMFB > 0)
extern int crmfb_probe(void);
#endif
void kgdb_port_init(void);
static int scn_serial_init(const char *);
static int zs_serial_init(const char *);
static int gio_video_init(const char *);
static int mace_serial_init(const char *);
void
consinit(void)
{
const char *consdev;
consdev = arcbios_GetEnvironmentVariable("ConsoleOut");
if (consdev == NULL) {
printf("WARNING: ConsoleOut environment variable not set\n");
return;
}
switch (mach_type) {
case MACH_SGI_IP6 | MACH_SGI_IP10:
if (scn_serial_init(consdev))
return;
break;
case MACH_SGI_IP12:
case MACH_SGI_IP20:
case MACH_SGI_IP22:
if (gio_video_init(consdev) || zs_serial_init(consdev))
return;
break;
case MACH_SGI_IP32:
if (mace_serial_init(consdev))
return;
#if (NCRMFB > 0)
if (crmfb_probe()) {
return;
}
#else
panic("this ip32 kernel does not contain framebuffer support.");
#endif
break;
default:
panic("consinit(): unknown machine type IP%d\n", mach_type);
break;
}
printf("Using ARCS for console I/O.\n");
}
static int
scn_serial_init(const char *consdev)
{
#if (NSCN > 0)
if ((strlen(consdev) == 9) && (!strncmp(consdev, "serial", 6)) &&
(consdev[7] == '0' || consdev[7] == '1')) {
cn_tab = &scn_cn;
(*cn_tab->cn_init)(cn_tab);
return (1);
}
#endif
return (0);
}
static int
zs_serial_init(const char *consdev)
{
#if (NZSC > 0)
if ((strlen(consdev) == 9) && (!strncmp(consdev, "serial", 6)) &&
(consdev[7] == '0' || consdev[7] == '1')) {
cn_tab = &zs_cn;
(*cn_tab->cn_init)(cn_tab);
return (1);
}
#endif
return (0);
}
static int
gio_video_init(const char *consdev)
{
#if (NGIO > 0)
if (strcmp(consdev, "video()") == 0) {
if (gio_cnattach() != 0)
return (0);
switch(mach_type) {
case MACH_SGI_IP12:
case MACH_SGI_IP20:
#if (NZSKBD > 0)
zskbd_cnattach(0, 0);
#endif
break;
case MACH_SGI_IP22:
#if (NPCKBC > 0)
pckbc_cnattach(normal_memt,
HPC_BASE_ADDRESS_0 +
HPC3_PBUS_CH6_DEVREGS + IOC_KB_REGS, KBCMDP,
PCKBC_KBD_SLOT, 0);
#endif
break;
}
return (1);
}
#endif
return (0);
}
static int
mace_serial_init(const char *consdev)
{
#if (NCOM > 0)
const char *dbaud;
int speed;
u_int32_t base;
if ((strlen(consdev) == 9) && (!strncmp(consdev, "serial", 6)) &&
(consdev[7] == '0' || consdev[7] == '1')) {
dbaud = arcbios_GetEnvironmentVariable("dbaud");
speed = strtoul(dbaud, NULL, 10);
base = (consdev[7] == '0') ? MACE_ISA_SER1_BASE :
MACE_ISA_SER2_BASE;
delay(10000);
mace_init_bus();
if (comcnattach(mace_isa_memt, MACE_BASE + base,
speed, COM_FREQ, COM_TYPE_NORMAL, comcnmode) == 0)
return (1);
}
#endif
return (0);
}
#if defined(KGDB)
void
kgdb_port_init(void)
{
# if (NCOM > 0)
# define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
if (mach_type == MACH_SGI_IP32) {
mace_init_bus();
com_kgdb_attach(mace_isa_memt, 0xbf398000, 9600, COM_FREQ, COM_TYPE_NORMAL,
KGDB_DEVMODE);
}
# endif
# if (NZSC > 0)
switch(mach_type) {
case MACH_SGI_IP12:
case MACH_SGI_IP20:
case MACH_SGI_IP22:
zs_kgdb_init();
}
# endif
}
#endif