/* * console routines */ void zskbd_cnattach(int zsunit, int zschan) { wskbd_cnattach(&zskbd_wskbd_consops, zs_get_chan_addr(zsunit, zschan), &sgikbd_wskbd_keymapdata); zskbd_is_console = 1; }
void zscnputc(dev_t dev, int c) { struct zschan *zs; zs = zs_get_chan_addr(0, cons_port); zs_putc(zs, c); }
int zscngetc(dev_t dev) { struct zschan *zs; zs = zs_get_chan_addr(0, cons_port); return zs_getc(zs); }
void zscnputc(dev_t dev, int c) { struct zschan *zs; switch (mach_type) { case MACH_SGI_IP12: case MACH_SGI_IP20: zs = zs_get_chan_addr(1, cons_port); break; case MACH_SGI_IP22: default: zs = zs_get_chan_addr(0, cons_port); break; } zs_putc(zs, c); }
int zscngetc(dev_t dev) { struct zschan *zs; switch (mach_type) { case MACH_SGI_IP12: case MACH_SGI_IP20: zs = zs_get_chan_addr(1, cons_port); break; case MACH_SGI_IP22: default: zs = zs_get_chan_addr(0, cons_port); break; } return zs_getc(zs); }
/* * This function replaces sys/dev/cninit.c * Determine which device is the console using * the PROM "input source" and "output sink". */ void cninit(void) { struct sunromvec *v; struct zschan *zc; struct consdev *cn; int channel, zs_unit, zstty_unit; uint8_t inSource, outSink; extern const struct cdevsw zstty_cdevsw; /* Get the zs driver ready for console duty. */ zs_init(); v = romVectorPtr; inSource = *v->inSource; outSink = *v->outSink; if (inSource != outSink) { mon_printf("cninit: mismatched PROM output selector\n"); } switch (inSource) { default: mon_printf("cninit: invalid inSource=%d\n", inSource); sunmon_abort(); inSource = 0; /* fall through */ case 0: /* keyboard/display */ #if NKBD > 0 zs_unit = 0; channel = 0; cn = &consdev_kd; /* Set cn_dev, cn_pri in kd.c */ break; #else /* NKBD */ mon_printf("cninit: kdb/display not configured\n"); sunmon_abort(); inSource = 1; /* fall through */ #endif /* NKBD */ case 1: /* ttya */ case 2: /* ttyb */ case 3: /* ttyc (rewired keyboard connector) */ case 4: /* ttyd (rewired mouse connector) */ zstty_unit = inSource - 1; zs_unit = zstty_conf[zstty_unit].zs_unit; channel = zstty_conf[zstty_unit].channel; cn = &consdev_tty; cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), zstty_unit); cn->cn_pri = CN_REMOTE; break; } /* Now that inSource has been validated, print it. */ mon_printf("console is %s\n", prom_inSrc_name[inSource]); zc = zs_get_chan_addr(zs_unit, channel); if (zc == NULL) { mon_printf("cninit: zs not mapped.\n"); return; } zs_conschan = zc; zs_hwflags[zs_unit][channel] = ZS_HWFLAG_CONSOLE; cn_tab = cn; (*cn->cn_init)(cn); #ifdef KGDB zs_kgdb_init(); #endif }
/* * Attach a found zs. * * Match slave number to zs unit number, so that misconfiguration will * not set up the keyboard as ttya, etc. */ static void zs_attach(device_t parent, device_t self, void *aux) { struct zsc_softc *zsc = device_private(self); struct confargs *ca = aux; struct zsc_attach_args zsc_args; volatile struct zschan *zc; struct zs_chanstate *cs; int s, zs_unit, channel; static int didintr; zsc->zsc_dev = self; zs_unit = device_unit(self); aprint_normal(": (softpri %d)\n", ZSSOFT_PRI); /* Use the mapping setup by the Sun PROM. */ if (zsaddr[zs_unit] == NULL) panic("zs_attach: zs%d not mapped", zs_unit); /* * Initialize software state for each channel. */ for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zs_unit][channel]; cs = &zsc->zsc_cs_store[channel]; zsc->zsc_cs[channel] = cs; zs_lock_init(cs); cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; cs->cs_brg_clk = PCLK / 16; zc = zs_get_chan_addr(zs_unit, channel); cs->cs_reg_csr = &zc->zc_csr; cs->cs_reg_data = &zc->zc_data; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); /* XXX: Get these from the EEPROM instead? */ /* XXX: See the mvme167 code. Better. */ if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) cs->cs_defspeed = zs_get_speed(cs); else cs->cs_defspeed = zs_defspeed[zs_unit][channel]; cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; cs->cs_wr5_rts = 0; /* * Clear the master interrupt enable. * The INTENA is common to both channels, * so just do it on the A channel. */ if (channel == 0) { zs_write_reg(cs, 9, 0); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ if (!config_found(self, (void *)&zsc_args, zs_print)) { /* No sub-driver. Just reset it. */ uint8_t reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splhigh(); zs_write_reg(cs, 9, reset); splx(s); } } /* * Now safe to install interrupt handlers. Note the arguments * to the interrupt handlers aren't used. Note, we only do this * once since both SCCs interrupt at the same level and vector. */ if (!didintr) { didintr = 1; isr_add_autovect(zshard, NULL, ca->ca_intpri); } zsc->zs_si = softint_establish(SOFTINT_SERIAL, (void (*)(void *))zsc_intr_soft, zsc); /* XXX; evcnt_attach() ? */ /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splhigh(); /* interrupt vector */ zs_write_reg(cs, 2, zs_init_reg[2]); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); /* * XXX: L1A hack - We would like to be able to break into * the debugger during the rest of autoconfiguration, so * lower interrupts just enough to let zs interrupts in. * This is done after both zs devices are attached. */ if (zs_unit == 1) { (void)spl5(); /* splzs - 1 */ } }
/* * Attach a found zs. * * Match slave number to zs unit number, so that misconfiguration will * not set up the keyboard as ttya, etc. */ void zs_ap_attach(device_t parent, device_t self, void *aux) { struct zsc_softc *zsc = device_private(self); struct apbus_attach_args *apa = aux; struct zsc_attach_args zsc_args; volatile struct zschan *zc; struct zs_chanstate *cs; int s, zs_unit, channel; volatile u_int *txBfifo = (void *)(apa->apa_hwbase + PORTB_XPORT); volatile u_int *rxBfifo = (void *)(apa->apa_hwbase + PORTB_RPORT); volatile u_int *txAfifo = (void *)(apa->apa_hwbase + PORTA_XPORT); volatile u_int *rxAfifo = (void *)(apa->apa_hwbase + PORTA_RPORT); volatile u_int *portBctl = (void *)(apa->apa_hwbase + PORTB_OFFSET); volatile u_int *portActl = (void *)(apa->apa_hwbase + PORTA_OFFSET); volatile u_int *esccregs = (void *)(apa->apa_hwbase + ESCC_REG); zsc->zsc_dev = self; zs_unit = device_unit(self); zsaddr[zs_unit] = (void *)apa->apa_hwbase; aprint_normal(" slot%d addr 0x%lx\n", apa->apa_slotno, apa->apa_hwbase); txAfifo[DMA_MODE_REG] = rxAfifo[DMA_MODE_REG] = DMA_EXTRDY; txBfifo[DMA_MODE_REG] = rxBfifo[DMA_MODE_REG] = DMA_EXTRDY; /* assert DTR */ /* XXX */ portBctl[PORT_CTL] = portActl[PORT_CTL] = PORTCTL_DTR; /* select RS-232C (ch1 only) */ portActl[PORT_SEL] = PORTSEL_RS232C; /* enable SCC interrupts */ esccregs[ESCCREG_INTMASK] = INTMASK_SCC; zs_delay = zs_ap_delay; /* * Initialize software state for each channel. */ for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zs_unit][channel]; cs = &zsc->zsc_cs_store[channel]; zsc->zsc_cs[channel] = cs; zs_lock_init(cs); cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; cs->cs_brg_clk = PCLK / 16; zc = zs_get_chan_addr(zs_unit, channel); cs->cs_reg_csr = &zc->zc_csr; cs->cs_reg_data = &zc->zc_data; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); /* XXX: Get these from the EEPROM instead? */ /* XXX: See the mvme167 code. Better. */ if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) cs->cs_defspeed = zs_get_speed(cs); else cs->cs_defspeed = zs_defspeed; cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; cs->cs_wr5_rts = 0; /* * Clear the master interrupt enable. * The INTENA is common to both channels, * so just do it on the A channel. */ if (channel == 0) { zs_write_reg(cs, 9, 0); } /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ if (!config_found(self, (void *)&zsc_args, zs_print)) { /* No sub-driver. Just reset it. */ uint8_t reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splhigh(); zs_write_reg(cs, 9, reset); splx(s); } } /* * Now safe to install interrupt handlers. */ zsc->zsc_si = softint_establish(SOFTINT_SERIAL, (void (*)(void *))zsc_intr_soft, zsc); apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */ NEWS5000_INT1_SCC, 0, /* priority */ zshard_ap, zsc, apa->apa_name, apa->apa_ctlnum); /* XXX; evcnt_attach() ? */ #if 0 { u_int x; /* determine SCC/ESCC type */ x = zs_read_reg(cs, 15); zs_write_reg(cs, 15, x | ZSWR15_ENABLE_ENHANCED); if (zs_read_reg(cs, 15) & ZSWR15_ENABLE_ENHANCED) { /* ESCC Z85230 */ zs_write_reg(cs, 7, ZSWR7P_EXTEND_READ | ZSWR7P_TX_FIFO); } } #endif /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splhigh(); /* interrupt vector */ zs_write_reg(cs, 2, zs_init_reg[2]); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); }