📄 gq.c
字号:
#ifndef lintstatic char *sccsid = "@(#)gq.c 4.5 (ULTRIX) 10/9/90";#endif lint/************************************************************************ * * * Copyright (c) 1990 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * 13-Sep-90 Joe Szczypek * Added new TURBOchannel console ROM support. osconsole environment * variable now returns 1 slot number is serial line, else 2 slot numbers * if graphics. Use this to determine how to do setup. Note that new * ROMs do not support multiple outputs... * * 21-Jun-90 Sam Hsu * Add sampling of cpu idle time, and a incr count after each sample. * Used for PEX EB/RB tuning. * * 17-May-90 Sam Hsu * It'd be nice if we put cmap[0] back for video_on, wouldn't it? * Propogate page count for N10 pagein requests to server. Doesn't * seem like R3K reading intr_coproc using intr addr is harmful, as * is the case when the N10 does this to the R3K, but we'll use the * SRAM addr anyway to be clean. * * 07-May-90 Sam Hsu * Catch bad addr xlation requests from N10 and let server try to * pagein which should result in a segv at an informative point. * Allow dynamic setting of behavior when N10 perceived dead. * * 19-Apr-90 Sam Hsu * HWDEBUG no longer used in here. PROTO_3DA controls whether a counter * board is mapped to the server, and whether the N10/server is killed * when the N10 doesn't respond to our interrupt. Entire board is mapped * to server, instead of just SRAM (no additional pte resources used). * * 04-Apr-90 Sam Hsu * Change cprintf -> printf so it gets logged. Enable console/N10 * sync. * * 28-Mar-90 Sam Hsu * Change gxPriv to K0. gq_ptpt stays K1. Fix intr_coproc retry * loop (never timed out, but might someday). Add counts for poll * STIC pint timeout, and dropped packets (poll dma -> stamp_busy). * Will reset STIC and retry (once) on a dropped packet. * Add _gx_modtype linkage. * * 07-Mar-90 Sam Hsu * Add vdac reset linkage. getPacket checks for active server, and * either syncs with N10 or returns no buffer. * * 26-Feb-90 Sam Hsu * Add sync with N10 on console output when xcons not active. gq_ioctl * now called by gx_ioctl. intr_coproc checks for 2 possible response * values from N10 (0/1). Sync code cannot be activated until ucode can * handle intr from R3K. * * 29-Jan-90 Sam Hsu * Fix vm_hook to check if device closed since N10 would be halted * already. Only really works in !HWDEBUG mode, and when server close * coincides with process death. Dynamic debug levels. gq_close hook * to halt N10 and reset process' vm_hook vector. * * 18-Jan-90 Sam Hsu * Fix gq_cons_init() - don't PHYS_TO_K1 the kn02where_option() * until after the test == 0! Zero out gq_ptpt on each server * open. Add debugging output on N10 interrupts. * * 18-Dec-89 Sam Hsu * Add some "heartbeat" counters to interrupt code. Clear * interrupt before signal'ing server to service pagein. * Add _gx_init <- gq_init() to halt N10 and clear interrupt. * Update interrupt code to use most recent board map struct. * Add gq_getPixBuff() => readspans buffer. * * 15-Dec-89 Alan Frechette * Changes to "ws_display_type" and "ws_display_units". * * 17-Dec-89 Sam Hsu * Move gq_init_stic() to gx.c and use linkage var _gx_stic. * Use gx_decode_option() and gx_devtype() for configuration. * * 30-Nov-89 Sam Hsu * Merge into 4.0 source pool. Breakup into gx/ga/gq modules. * Compiles and links, but I'd be amazed if it still runs. * * 19-Oct-89 Sam Hsu * Allow non-exclusive open of the graphics device. Only * the 1st process will have get the events/tcs mapped into * its address space. This is DEBUGGING code and could be * removed before SDC. It will allow the DMA simulator to * access GRAM while the server has /dev/mouse open... * * 21-Sep-89 Sam Hsu * Modifications for KMAX 3D. Graphics console supported. * Extraneous PMAX code removed. No server transport yet. * Consistent(?) naming: pm_<> internal, pm<> external. * * 21-Aug-89 Sam Hsu * Modifications for KMAX w/ 3D graphics board, keyboard, mouse, * but no bitmap console and something in SLU 3 port for console * output. Look for "KMAX3D" to find changes... * * $Header: /nfs/kodak/local/4.0-12/io/tc/RCS/gq.c,v 1.19 90/05/08 20:41:47 fhsu Exp Locker: fhsu $ * * The dark ages: see gx.c * ************************************************************************/#define _GQ_C_#include "../data/gx_data.c"#include "../io/tc/gq.h"/* * Definition of the driver for the auto-configuration program. */int gq_probe(), gq_attach(), gqintr();int gq_ioctl();struct uba_driver gqdriver = { gq_probe, 0, gq_attach, 0, gxstd, "gq", gxinfo };/* * Internal routines. */int gq_config(), gq_init(), gq_init_cons(), gq_cons_init();int *gq_getPacket(), gq_sendPacket();int gq_intr_noop(), gq_intr_pagein(), gq_intr_xlate(), gq_intr_vblank(), gq_intr_vrfy(), gq_vm_hook(), gq_intr_coproc(), gq_intr_stic();void gq_cpu_idleSample();/* * These are really for internal use, but declared global so nkvar can * access and change them. */gqMap *gqo;int *gq_ptpt;int gq_N1OK = 0; /* whether N10 supposed to be alive */ /* also controls whether cpu_idle */ /* is being sampled */int gq_debug = 0; /* flags controlling exceptional */ /* behavior */#define GQ_KILL_N10 0x1#ifndef GX_NODEBUGint gq_intrPending = 0;int gq_invalALL = 0;int gq_invalOK = 0;int gq_thrash = 0;#endif/* * wait for stic to be ready to accept next packet. note that we never * wait forever. we'll time out and go ahead and see if the stic will * accept a packet anyway. if not, _then_ we consider complaining... */#define _POLL_STIC_PINT(I) \ for ((I) = 0; (I) < STAMP_RETRIES; (I)++) { \ if (_gx_stic->ipdvint & STIC_INT_P) \ break; \ DELAY(STAMP_DELAY); \ } \ if ((I) == STAMP_RETRIES) gx_pint_timeout++;/****************************************************************** ** ** ** Routine to return a one(1). ** ** ** ******************************************************************/gq_probe(reg){ GX_DEBUG(GX_BLAB, gx_puts("gqprobe()\n"); ); return(1);}/* end gq_probe. *//****************************************************************** ** ** ** Routine to attach to the graphic device. ** ** ** ******************************************************************/gq_attach(reg){/* Moved to gq_cons_init() where it occurs much earlier. gq_init_cons(reg); */ printf("gq0 ( %d+%d+%dZ+%dX plane %dx%d stamp )\n", gxp->nplanes, gxp->dplanes, gxp->zplanes, gxp->zzplanes, gxp->stamp_width, gxp->stamp_height); /* * init the "latest mouse report" structure */ gx_last_rep.state = 0; gx_last_rep.dx = 0; gx_last_rep.dy = 0; gx_last_rep.bytcnt = 0; gx_keyboard.hold = 0; /* "Hold Screen" key is pressed if 1 */ if(!gx_inkbdreset) /* init the keyboard */ gx_kbdreset(); return 0;}/* end gq_attach. *//****************************************************************** ** ** ** Graphic device ioctl routine. ** ** ** ******************************************************************//*ARGSUSED*/gq_ioctl(dev, cmd, data, flag) dev_t dev; register caddr_t data;{ int unit; int smid; int tmp1; int errcode; gxInfo *infop; gxPriv *gqp; switch( cmd ) { case QIOCGINFO: /* return screen info */ /* check for server already done... */ errcode = GX_ERR_PRIV; unit = minor(dev); if ((smid = vm_system_smget(DWN_(gx_priv), GQ_PRIV_PGBYTES, 0600)) < 0) goto bad; if ((tmp1 = (int)smat(smid, 0, 0)) < 0) goto bad; if (smctl(smid, IPC_RMID, 0)) goto bad; gqp = (gxPriv *)(tmp1 | ((int)gx_priv & (CLBYTES-1))); infop = &gx_infos[unit].info; infop->qe.events = gqp->events; infop->qe.tcs = gqp->tcs; /*infop->curs_bits = gqp->cursor;*/ /*infop->colormap = gqp->colormap;*/ infop->rb_addr = (int *)gqp + gx_rboffset; infop->rb_phys = svtophy(gx_ringbuffer); infop->rb_size = GQ_RBUF_SIZE; infop->ptpt_phys = svtophy(gq_ptpt); infop->ptpt_size = GQ_PTPT_ENTRIES; /* * 3D option board -- the whole thing */ errcode = GX_ERR_GQO; if((smid=vm_system_smget(DWN_(gqo), RND_(sizeof(gqMap)), 0600)) < 0) goto bad; if((tmp1 = (int)smat(smid,0, 0)) < 0) goto bad; if (smctl(smid, IPC_RMID, 0)) goto bad; tmp1 |= (int) gqo & (CLBYTES-1); infop->gxo = (char *) tmp1; infop->gram = (int *) GQ_RAM(tmp1);# ifdef PROTO_3DA /* * unID'd board in slot 2 of low/mid-3D is a smorg-as-board counter * board, so map its 2 registers in the unused 2D fields */ if (infop->stamp_height == 1) { extern unsigned gx_slots; u_long slot_addr; GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: looking for smorg-as-board...\n"); ); if ((gx_slots & (1<<2)) == 0) { GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: slot 2 empty\n"); ); goto NoTimer; } slot_addr = PHYS_TO_K1(tc_slotaddr[2]); if ((smid = vm_system_smget(DWN_(slot_addr), RND_(0x4), 0600)) < 0) { printf("gq_ioctl: failed to map counter = %d\n", u.u_error); GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: 0x%x 0x%x 0600\n", DWN_(slot_addr), RND_(0x80004)); ); goto NoTimer; } if ((tmp1 = (int) smat(smid, 0, 0)) < 0) { GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: failed to attach slot 2 = %d\n", u.u_error); ); goto NoTimer; } if (smctl(smid, IPC_RMID, 0)) { GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: failed to ctl slot 2\n"); ); goto NoTimer; } infop->stic_dma_rb = (int *) tmp1; infop->stic_reg = (int *) tmp1; GX_DEBUG(GX_GAB, gx_printf("gq_ioctl: smorg-as-board mapped 0x%x\n", tmp1); ); NoTimer: ; }# endif proto_3da# ifdef notdef errcode = GX_ERR_SRAM; if((smid = vm_system_smget(DWN_(GQ_RAM(gqo)), RND_(sizeof(gqRAM)), 0600)) < 0) goto bad; if((tmp1 = (int)smat(smid,0, 0)) < 0) goto bad; if (smctl(smid, IPC_RMID, 0)) goto bad; tmp1 |= (int) GQ_RAM(gqo) & (CLBYTES-1); infop->gram = (int *) tmp1;# endif notdef *(gxInfo **)data = gx_infos[unit].shmat = &(gqp->infos[unit].info); break; bad: *(gxInfo **)data = 0; return (errcode); case QIO_N10RESET:# ifdef p_dev_VM_maint if (GX_IAMSERVER) { gx_serverp->p_dev_VM_maint = 0; GX_DEBUG(GX_YAK, gx_printf("gq_ioctl: i860 stop %d\n", gx_serverp->p_pid); ); }# endif *GQ_RESET(gqo) = gq_N1OK = 0; wbflush(); break; case QIO_N10START: bzero(gq_ptpt, GQ_PTPT_SIZE); *GQ_START(gqo) = gq_N1OK = 1; wbflush(); timeout(gq_cpu_idleSample, (char *)0, GQ_CPU_IDLESAMPLE);# ifdef p_dev_VM_maint if (GX_IAMSERVER) { /* express interest in server's vm activity... */ gx_serverp->p_dev_VM_maint = gq_vm_hook; GX_DEBUG(GX_YAK, gx_printf("gq_ioctl: i860 go %d\n", gx_serverp->p_pid); ); }# endif break; case QIO_N10INTR: GX_DEBUG(GX_CONSOLE, tmp1 = gq_intr_coproc(*(int *)data); /*gx_printf("gq_ioctl: n10intr 0x%x -> 0x%x\n", *(int *)data, tmp1);*/ *(int *)data = tmp1; ); break; default: /* not ours ?? */ return GX_ERR_NOOP; } return GX_ERR_NONE;}/* end gqioctl. */gq_init_cons(){ GX_DEBUG(GX_BLAB, gx_puts("gq_init_cons()\n"); ); ws_display_type = GQ_DTYPE; ws_display_units = 1; return gx_setup();}/* end gq_init_cons. */gq_init(){ GX_DEBUG(GX_BLAB, gx_puts("gq_init()\n"); ); *GQ_RESET(gqo) = gq_N1OK = 0; /* halt the N10 */ *GQ_INTRH(gqo) = GQ_INTR_ACK; /* clear intr word */ GX_DEBUG(GX_SILENT, gq_invalALL = gq_invalOK = 0; ); wbflush();# ifdef p_dev_VM_maint if (GX_HAVESERVER) { gx_serverp->p_dev_VM_maint = 0; }# endif return 0;}/* end gq_init. */int (*gq_intr_vec[])() = { gq_intr_noop, /* 0 */ gq_intr_pagein, /* 1 */ gq_intr_xlate, /* 2 */ gq_intr_vblank, /* 3 */ gq_intr_vrfy, /* 4 */ gq_intr_noop, /* 5 */ gq_intr_noop, /* 6 */ gq_intr_noop, /* 7 */ gq_intr_noop, /* 8 */ gq_intr_noop, /* 9 */ gq_intr_noop, /* 10 */ gq_intr_noop, /* 11 */ gq_intr_noop, /* 12 */ gq_intr_noop, /* 13 */ gq_intr_noop, /* 14 */ gq_intr_noop, /* 15 */};int gq_intr_send[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };int gq_intr_recv[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };gq_intr_stic(){ if (_gx_stic->ipdvint & STIC_INT_E) { gx_init_stic(); printf("gq_intr_stic: 0x%x CSR 0x%x B:CSR 0x%x addr 0x%x dat 0x%x\n", _gx_stic->ipdvint, _gx_stic->sticsr, _gx_stic->buscsr, _gx_stic->busadr, _gx_stic->busdat); } return 0;}/* end gq_intr_stic. */gq_intr_noop(va) int va;{ *GQ_INTRH(gqo) = GQ_INTR_ACK; wbflush(); GX_DEBUG(GX_GAB, gx_printf("gq_intr_noop: 0x%x (%d)\n", va, gq_intr_recv[0]); ); return gq_intr_stic();}/* end gq_intr_noop. */static_gq_intr_pagein(va) int va;{ *GQ_INTRH(gqo) = va; /* clear the R3K interrupt line */ wbflush(); gx_info.ptpt_pgin = (int *)(va & (HST_INTR_MASK|HST_INTR_PMSK)); /* need to do a pagein */ GX_DEBUG(GX_TERSE, static int lastVA = 0; if (lastVA == (va & HST_INTR_MASK)) { gx_putchar('\007'); gq_thrash++; } else lastVA = (va & HST_INTR_MASK); ); GX_DEBUG(GX_TALK, gx_printf("PI(0x%x)\n", va & HST_INTR_MASK); ); psignal(gx_serverp, SIGUSR1); return 0;}/* end _gq_intr_pagein. */gq_intr_pagein(va) int va;{ register int tmpVA; register struct pte *pte; tmpVA = (va & HST_INTR_MASK);# ifndef notdef /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -