diff options
Diffstat (limited to 'chips/dz_hdw.c')
-rw-r--r-- | chips/dz_hdw.c | 649 |
1 files changed, 0 insertions, 649 deletions
diff --git a/chips/dz_hdw.c b/chips/dz_hdw.c deleted file mode 100644 index fa472828..00000000 --- a/chips/dz_hdw.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * File: dz_hdw.c - * Author: Alessandro Forin, Carnegie Mellon University - * Date: 9/90 - * - * Hardware-level operations for the DZ Serial Line Driver - */ - -#include <dz_.h> -#if NDZ_ > 0 -#include <bm.h> -#include <platforms.h> - -#include <mach_kdb.h> - -#include <machine/machspl.h> /* spl definitions */ -#include <device/io_req.h> -#include <device/tty.h> - -#include <chips/busses.h> -#include <chips/screen_defs.h> -#include <chips/serial_defs.h> - -#include <chips/dz_7085.h> - - -#ifdef DECSTATION -#include <mips/mips_cpu.h> -#include <mips/PMAX/kn01.h> -#define DZ_REGS_DEFAULT (vm_offset_t)PHYS_TO_K1SEG(KN01_SYS_DZ) -#define PAD(n) char n[6]; -#endif /*DECSTATION*/ - -#ifdef VAXSTATION -#define DZ_REGS_DEFAULT 0 -#define wbflush() -#define check_memory(addr,dow) ((dow) ? wbadaddr(addr,4) : badaddr(addr,4)) -#define PAD(n) char n[2]; -#endif /*VAXSTATION*/ - -#ifndef PAD -#define PAD(n) -#endif - -typedef struct { - volatile unsigned short dz_csr; /* Control and Status */ - PAD(pad0) - volatile unsigned short dz_rbuf; /* Rcv buffer (RONLY) */ - PAD(pad1) - volatile unsigned short dz_tcr; /* Xmt control (R/W)*/ - PAD(pad2) - volatile unsigned short dz_tbuf; /* Xmt buffer (WONLY)*/ -# define dz_lpr dz_rbuf /* Line parameters (WONLY)*/ -# define dz_msr dz_tbuf /* Modem status (RONLY)*/ - PAD(pad3) -} dz_padded_regmap_t; - - -/* this is ok both for rcv (char) and xmt (csr) */ -#define LINEOF(x) (((x) >> 8) & 0x3) - -/* - * Driver status - */ -struct dz7085_softc { - dz_padded_regmap_t *regs; - unsigned short breaks; - unsigned short fake; /* missing rs232 bits */ - int polling_mode; - unsigned short prev_msr; - char softCAR; -} dz7085_softc_data[NDZ_]; - -typedef struct dz7085_softc *dz7085_softc_t; - -dz7085_softc_t dz7085_softc[NDZ_]; - -static void check_car(); -static void check_ring(); - -dz7085_softCAR(unit, line, on) -{ - if (on) - dz7085_softc[unit]->softCAR |= 1<<line; - else - dz7085_softc[unit]->softCAR &= ~(1 << line); -} - -static -short dz7085_speeds[] = - { 0, DZ_LPAR_50, DZ_LPAR_75, DZ_LPAR_110, DZ_LPAR_134_5, DZ_LPAR_150, - 0, DZ_LPAR_300, DZ_LPAR_600, DZ_LPAR_1200, DZ_LPAR_1800, DZ_LPAR_2400, - DZ_LPAR_4800, DZ_LPAR_9600, DZ_LPAR_MAX_SPEED, 0 }; - - -/* - * Definition of the driver for the auto-configuration program. - */ - -int dz7085_probe(), dz7085_intr(); -static void dz7085_attach(); - -vm_offset_t dz7085_std[NDZ_] = { DZ_REGS_DEFAULT, }; -struct bus_device *dz7085_info[NDZ_]; -struct bus_driver dz_driver = - { dz7085_probe, 0, dz7085_attach, 0, dz7085_std, "dz", dz7085_info,}; - -/* - * Adapt/Probe/Attach functions - */ - -static boolean_t dz7085_full_modem = FALSE; -boolean_t dz7085_uses_modem_control = FALSE;/* patch this with adb */ - -set_dz_address( unit, regs, has_modem) - vm_offset_t regs; - boolean_t has_modem; -{ - extern int dz7085_probe(), dz7085_param(), dz7085_start(), - dz7085_putc(), dz7085_getc(), - dz7085_pollc(), dz7085_mctl(), dz7085_softCAR(); - - dz7085_std[unit] = regs; - dz7085_full_modem = has_modem & dz7085_uses_modem_control; - - /* Do this here */ - console_probe = dz7085_probe; - console_param = dz7085_param; - console_start = dz7085_start; - console_putc = dz7085_putc; - console_getc = dz7085_getc; - console_pollc = dz7085_pollc; - console_mctl = dz7085_mctl; - console_softCAR = dz7085_softCAR; - -} - -dz7085_probe( xxx, ui) - struct bus_device *ui; -{ - int unit = ui->unit; - dz7085_softc_t sc; - register int cntr; - register dz_padded_regmap_t *regs; - - static int probed_once = 0; - - regs = (dz_padded_regmap_t *)dz7085_std[unit]; /* like the old days! */ - if (regs == 0) - return 0; - /* - * If this is not there we are toast - */ - if (check_memory(regs, 0)) - return 0; - - if (probed_once++) - return 1; - - sc = &dz7085_softc_data[unit]; - dz7085_softc[unit] = sc; - sc->regs = regs; - - for (cntr = unit*NDZ_LINE; cntr < NDZ_LINE*(unit+1); cntr++) { - console_tty[cntr]->t_addr = (char*)regs; - console_tty[cntr]->t_state |= TS_MIN; - } - - /* pmaxen et al. lack many modem bits */ - dz7085_set_modem_control(sc, dz7085_full_modem); - - regs->dz_tcr = 0;/* disable all lines, drop RTS,DTR */ - return 1; -} - -boolean_t dz7085_timer_started = FALSE; - -static void -dz7085_attach(ui) - register struct bus_device *ui; -{ - int unit = ui->unit; - extern dz7085_scan(); - extern int tty_inq_size; - int i; - - /* We only have 4 ttys, but always at 9600 - * Give em a lot of room - */ - tty_inq_size = 2048; - for (i = 0; i < (NDZ_*NDZ_LINE); i++) - ttychars(console_tty[i]); - - if (!dz7085_timer_started) { - dz7085_timer_started = TRUE; - dz7085_scan(); - } - -#if NBM > 0 - if (SCREEN_ISA_CONSOLE()) { - printf("\n sl0: "); lk201_attach(0, unit); - printf("\n sl1: "); mouse_attach(0, unit); - printf("\n sl2: \n sl3: "); - if (rcline == 3) printf("( rconsole )"); - } else { -#endif /*NBM > 0*/ - printf("\n sl0:\n sl1:\n sl2:\n sl3: ( alternate console )"); -#if NBM > 0 - } -#endif -} - -/* - * Would you like to make a phone call ? - */ -dz7085_set_modem_control(sc, on) - dz7085_softc_t sc; - boolean_t on; -{ - if (on) - /* your problem if the hardware then is broke */ - sc->fake = 0; - else - sc->fake = DZ_MSR_CTS3|DZ_MSR_DSR3|DZ_MSR_CD3| - DZ_MSR_CTS2|DZ_MSR_CD2; -} - -/* - * Polled I/O (debugger) - */ -dz7085_pollc(unit, on) - boolean_t on; -{ - dz7085_softc_t sc = dz7085_softc[unit]; - - if (on) { - sc->polling_mode++; -#if NBM > 0 - screen_on_off(unit, TRUE); -#endif NBM > 0 - } else - sc->polling_mode--; -} - -/* - * Interrupt routine - */ -dz_intr(unit,spllevel) - spl_t spllevel; -{ - dz7085_softc_t sc = dz7085_softc[unit]; - register dz_padded_regmap_t *regs = sc->regs; - register short csr; - - csr = regs->dz_csr; - - if (csr & DZ_CSR_TRDY) { - register int c; - - c = cons_simple_tint(unit*NDZ_LINE + LINEOF(csr), FALSE); - if (c == -1) { - /* no more data for this line */ - regs->dz_tcr &= ~(1 << LINEOF(csr)); - c = cons_simple_tint(unit*NDZ_LINE + LINEOF(csr), TRUE); - /* because funny race possible ifnot */ - } - if (c != -1) { - regs->dz_tbuf = (c & 0xff) | sc->breaks; - /* and leave it enabled */ - } - } - if (sc->polling_mode) - return; - - while (regs->dz_csr & DZ_CSR_RDONE) { - short c = regs->dz_rbuf; - spl_t oldspl; - -#ifdef DECSTATION - oldspl = splhigh(); - splx(spllevel); -#endif /*DECSTATION*/ - cons_simple_rint(unit*NDZ_LINE+LINEOF(c), LINEOF(c), - c&0xff, c&0xff00); -#ifdef DECSTATION - splx(oldspl); -#endif /*DECSTATION*/ - } -} - -/* - * Start transmission on a line - */ -dz7085_start(tp) - struct tty *tp; -{ - register dz_padded_regmap_t *regs; - register int line; - - line = tp->t_dev; - - regs = (dz_padded_regmap_t*)tp->t_addr; - regs->dz_tcr |= (1<<(line&3)); - - /* no, we do not need a char out to interrupt */ -} - -/* - * Get a char from a specific DZ line - */ -dz7085_getc( unit, line, wait, raw ) - boolean_t wait; - boolean_t raw; -{ - dz7085_softc_t sc = dz7085_softc[unit]; - spl_t s = spltty(); - register dz_padded_regmap_t *regs = sc->regs; - unsigned short c; - int rl; - -again: - /* - * wait till something in silo - */ - while ((regs->dz_csr & DZ_CSR_RDONE) == 0 && wait) - delay(10); - c = regs->dz_rbuf; - - /* - * check if right line. For keyboard, rconsole is ok too - */ - rl = LINEOF(c); - if (wait && (line != rl) && - !((line == DZ_LINE_KEYBOARD) && rcline == rl)) - goto again; - /* - * bad chars not ok - */ - if ((c & (DZ_RBUF_PERR | DZ_RBUF_OERR | DZ_RBUF_FERR)) && wait) - goto again; - - splx(s); - - /* - * if nothing found return -1 - */ - if ( ! (c & DZ_RBUF_VALID)) - return -1; - -#if NBM > 0 - if ((rl == DZ_LINE_KEYBOARD) && !raw && SCREEN_ISA_CONSOLE()) - return lk201_rint(SCREEN_CONS_UNIT(), c, wait, sc->polling_mode); - else -#endif NBM > 0 - return c & DZ_RBUF_CHAR; -} - -/* - * Put a char on a specific DZ line - */ -dz7085_putc( unit, line, c ) -{ - dz7085_softc_t sc = dz7085_softc[unit]; - register dz_padded_regmap_t *regs = sc->regs; - spl_t s = spltty(); - - /* - * do not change the break status of other lines - */ - c = (c & 0xff) | sc->breaks; - - /* - * Xmit line info only valid if TRDY, - * but never TRDY if no xmit enabled - */ - if ((regs->dz_tcr & DZ_TCR_LNENB) == 0) - goto select_it; - - while ((regs->dz_csr & DZ_CSR_TRDY) == 0) - delay(100); - - /* - * see if by any chance we are already on the right line - */ - if (LINEOF(regs->dz_csr) == line) - regs->dz_tbuf = c; - else { - unsigned short tcr; -select_it: - tcr = regs->dz_tcr; - regs->dz_tcr = (1 << line) | (tcr & 0xff00); - wbflush(); - - do - delay(2); - while ((regs->dz_csr & DZ_CSR_TRDY) == 0 || - (LINEOF(regs->dz_csr) != line)); - - regs->dz_tbuf = c; - wbflush(); - - /* restore previous settings */ - regs->dz_tcr = tcr; - } - - splx(s); -} - - -dz7085_param(tp, line) - register struct tty *tp; - register int line; -{ - register dz_padded_regmap_t *regs; - register int lpr; - - line = tp->t_dev; - regs = dz7085_softc[line/NDZ_LINE]->regs; - - /* - * Do not let user fool around with kbd&mouse - */ -#if NBM > 0 - if (screen_captures(line)) { - tp->t_ispeed = tp->t_ospeed = B4800; - tp->t_flags |= TF_LITOUT; - } -#endif NBM > 0 - regs->dz_csr = DZ_CSR_MSE|DZ_CSR_RIE|DZ_CSR_TIE; - if (tp->t_ispeed == 0) { - (void) (*console_mctl)(tp->t_dev, TM_HUP, DMSET); /* hang up line */ - return; - } -/* 19200/38400 here */ - lpr = dz7085_speeds[tp->t_ispeed] | (line&DZ_LPAR_LINE) | DZ_LPAR_ENABLE; - lpr |= DZ_LPAR_8BITS; - - if ((tp->t_flags & (TF_ODDP|TF_EVENP)) == TF_ODDP) - lpr |= DZ_LPAR_ODD_PAR; - - if (tp->t_ispeed == B110) - lpr |= DZ_LPAR_STOP; - regs->dz_lpr = lpr; -} - -/* - * This is a total mess: not only are bits spread out in - * various registers, but we have to fake some for pmaxen. - */ -dz7085_mctl(dev, bits, how) - int dev; - int bits, how; -{ - register dz_padded_regmap_t *regs; - register int unit; - register int tcr, msr, brk, n_tcr, n_brk; - int b; - spl_t s; - dz7085_softc_t sc; - - unit = dev; - - /* no modem support on lines 0 & 1 */ -/* XXX break on 0&1 */ - if ((unit & 2) == 0) - return TM_LE|TM_DTR|TM_CTS|TM_CAR|TM_DSR; - - b = 1 ^ (unit & 1); /* line 2 ? */ - - sc = dz7085_softc[unit>>2]; - regs = sc->regs; - s = spltty(); - - tcr = ((regs->dz_tcr | (sc->fake>>4)) & 0xf00) >> (8 + b*2); - brk = (sc->breaks >> (8 + (unit&3))) & 1; /* THE break bit */ - - n_tcr = (bits & (TM_RTS|TM_DTR)) >> 1; - n_brk = (bits & TM_BRK) >> 9; - - /* break transitions, must 'send' a char out */ - bits = (brk ^ n_brk) & 1; - - switch (how) { - case DMSET: - tcr = n_tcr; - brk = n_brk; - break; - - case DMBIS: - tcr |= n_tcr; - brk |= n_brk; - break; - - case DMBIC: - tcr &= ~n_tcr; - brk = 0; - break; - - case DMGET: - msr = ((regs->dz_msr|sc->fake) & 0xf0f) >> (b*8); - (void) splx(s); - return (tcr<<1)|/* DTR, RTS */ - ((msr&1)<<5)|/* CTS */ - ((msr&2)<<7)|/* DSR */ - ((msr&0xc)<<4)|/* CD, RNG */ - (brk << 9)|/* BRK */ - TM_LE; - } - n_tcr = (regs->dz_tcr & ~(3 << (8 + b*2))) | - (tcr << (8 + b*2)); - - regs->dz_tcr = n_tcr; - sc->fake = (sc->fake & 0xf0f) | (n_tcr<<4&0xf000); - - sc->breaks = (sc->breaks & ~(1 << (8 + (unit&3)))) | - (brk << (8 + (unit&3))); - if(bits) (*console_putc)( unit>>2, unit&3, 0);/* force break, now */ - (void) splx(s); - return 0;/* useless to compute it */ -} - -/* - * Periodically look at the CD signals: - * they do not generate interrupts. - */ -dz7085_scan() -{ - register i; - register dz_padded_regmap_t *regs; - register msr; - register struct tty *tp; - - for (i = 0; i < NDZ_; i++) { - dz7085_softc_t sc = dz7085_softc[i]; - register int temp; - - if (sc == 0) - continue; - regs = sc->regs; - - tp = console_tty[i * NDZ_LINE]; - - msr = regs->dz_msr | (sc->fake & 0xf0f); - if (temp = sc->softCAR) { - if (temp & 0x4) - msr |= DZ_MSR_CD2 | DZ_MSR_CTS2; - if (temp & 0x8) - msr |= DZ_MSR_CD3 | DZ_MSR_CTS3; - } - - /* Lines 0 and 1 have carrier on by definition */ - /* [horrid casts cuz compiler stupid] */ - check_car((char*)tp + 0*sizeof(struct tty), 1); - check_car((char*)tp + 1*sizeof(struct tty), 1); - check_car((char*)tp + 2*sizeof(struct tty), msr & DZ_MSR_CD2); - check_car((char*)tp + 3*sizeof(struct tty), msr & DZ_MSR_CD3); - - /* nothing else to do if no msr transitions */ - if ((temp = sc->prev_msr) == msr) - continue; - else - sc->prev_msr = msr; - - /* see if we have an incoming call */ -#define RING (DZ_MSR_RI2|DZ_MSR_RI3) - if ((msr & RING) != (temp & RING)) { -/*printf("%s %x->%x\n", "ET Phone RI", temp & RING, msr & RING);*/ - check_ring((char*)tp + 2*sizeof(struct tty), - msr & DZ_MSR_RI2, temp & DZ_MSR_RI2); - check_ring((char*)tp + 3*sizeof(struct tty), - msr & DZ_MSR_RI3, temp & DZ_MSR_RI3); - } -#undef RING - /* see if we must do flow-control */ - if ((msr ^ temp) & DZ_MSR_CTS2) { - tty_cts((char*)tp + 2*sizeof(struct tty), - msr & DZ_MSR_CTS2); - } - if ((msr ^ temp) & DZ_MSR_CTS3) { - tty_cts((char*)tp + 3*sizeof(struct tty), - msr & DZ_MSR_CTS3); - } - } - timeout(dz7085_scan, (vm_offset_t)0, 2*hz); -} - -static dz7085_hup(tp) - register struct tty *tp; -{ - (*console_mctl)(tp->t_dev, TM_DTR, DMBIC); -} - -static void check_car(tp, car) - register struct tty *tp; -{ - if (car) { - /* cancel modem timeout if need to */ - if (car & (DZ_MSR_CD2|DZ_MSR_CD3)) - untimeout(dz7085_hup, (vm_offset_t)tp); - - /* I think this belongs in the MI code */ - if (tp->t_state & TS_WOPEN) - tp->t_state |= TS_ISOPEN; - /* carrier present */ - if ((tp->t_state & TS_CARR_ON) == 0) - (void)ttymodem(tp, 1); - } else if ((tp->t_state&TS_CARR_ON) && ttymodem(tp, 0) == 0) - (*console_mctl)( tp->t_dev, TM_DTR, DMBIC); -} - -int dz7085_ring_timeout = 60; /* seconds, patchable */ - -static void check_ring(tp, ring, oring) - register struct tty *tp; -{ - if (ring == oring) - return; - if (ring) { - (*console_mctl)( tp->t_dev, TM_DTR, DMBIS); - /* give it ample time to find the right carrier */ - timeout(dz7085_hup, (vm_offset_t)tp, dz7085_ring_timeout*hz); - } -} -#endif NDZ_ > 0 |