⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)qd.c	7.1 (Berkeley) 6/28/91 *//*************************************************************************									**			Copyright (c) 1985-1988 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.	**									**************************************************************************//* * qd.c - QDSS display driver for VAXSTATION-II GPX workstation */#include "qd.h"#if NQD > 0#include "../include/pte.h"#include "../include/mtpr.h"#include "sys/param.h"#include "../include/cpu.h"#include "sys/conf.h"#include "sys/user.h"#include "qdioctl.h"#include "sys/tty.h"#include "sys/map.h"#include "sys/buf.h"#include "sys/vm.h"#include "sys/clist.h"#include "sys/file.h"#include "sys/uio.h"#include "sys/kernel.h"#include "sys/exec.h"#include "sys/proc.h"#include "ubareg.h"#include "ubavar.h"#include "sys/syslog.h"#include "qduser.h"	/* definitions shared with user level client */#include "qdreg.h"	/* QDSS device register structures *//* * QDSS driver status flags for tracking operational state  */struct qdflags {	u_int inuse;		/* which minor dev's are in use now */	u_int config;		/* I/O page register content */	u_int mapped;		/* user mapping status word */	u_int kernel_loop;	/* if kernel console is redirected */	u_int user_dma;		/* DMA from user space in progress */	u_short pntr_id;	/* type code of pointing device */	u_short duart_imask;	/* shadowing for duart intrpt mask reg */	u_short adder_ie;	/* shadowing for adder intrpt enbl reg */	u_short curs_acc;	/* cursor acceleration factor */	u_short curs_thr;	/* cursor acceleration threshold level */	u_short tab_res;	/* tablet resolution factor */	u_short selmask;	/* mask for active qd select entries */};/* * bit definitions for 'inuse' entry   */#define CONS_DEV	0x01#define GRAPHIC_DEV	0x04/* * bit definitions for 'mapped' member of flag structure  */#define MAPDEV		0x01		/* hardware is mapped */#define MAPDMA		0x02		/* DMA buffer mapped */#define MAPEQ		0x04		/* event queue buffer mapped */#define MAPSCR		0x08		/* scroll param area mapped */#define MAPCOLOR	0x10		/* color map writing buffer mapped *//* * bit definitions for 'selmask' member of qdflag structure  */#define SEL_READ	0x01		/* read select is active */#define SEL_WRITE	0x02		/* write select is active *//* * constants used in shared memory operations  */#define EVENT_BUFSIZE  1024	/* # of bytes per device's event buffer */#define MAXEVENTS  ( (EVENT_BUFSIZE - sizeof(struct qdinput))	 \	/ sizeof(struct _vs_event) )#define DMA_BUFSIZ	(1024 * 10)#define COLOR_BUFSIZ  ((sizeof(struct color_buf) + 512) & ~0x01FF)/* * reference to an array of "uba_device" structures built by the auto * configuration program.  The uba_device structure decribes the device * sufficiently for the driver to talk to it.  The auto configuration code * fills in the uba_device structures (located in ioconf.c) from user * maintained info.   */struct uba_device *qdinfo[NQD];  /* array of pntrs to each QDSS's */struct tty qd_tty[NQD*4];	/* teletype structures for each.. */extern char qvmem[][128*NBPG];extern struct pte QVmap[][128];#define CHUNK	  (64 * 1024)#define QMEMSIZE  (1024 * 1024 * 4)	/* 4 meg *//* * static storage used by multiple functions in this code   */int Qbus_unmap[NQD];		/* Qbus mapper release code */struct qdflags qdflags[NQD];	/* QDSS device status flags */struct qdmap qdmap[NQD];	/* QDSS register map structure */caddr_t qdbase[NQD];		/* base address of each QDSS unit */struct buf qdbuf[NQD];		/* buf structs used by strategy */short qdopened[NQD];		/* graphics device is open exclusive use *//* * the array "event_shared[]" is made up of a number of event queue buffers * equal to the number of QDSS's configured into the running kernel (NQD). * Each event queue buffer begins with an event queue header (struct qdinput) * followed by a group of event queue entries (struct _vs_event).  The array * "*eq_header[]" is an array of pointers to the start of each event queue * buffer in "event_shared[]".   */#define EQSIZE ((EVENT_BUFSIZE * NQD) + 512)char event_shared[EQSIZE];	    /* reserve space for event bufs */struct qdinput *eq_header[NQD];     /* event queue header pntrs *//* * This allocation method reserves enough memory pages for NQD shared DMA I/O * buffers.  Each buffer must consume an integral number of memory pages to * guarantee that a following buffer will begin on a page boundary.  Also, * enough space is allocated so that the FIRST I/O buffer can start at the * 1st page boundary after "&DMA_shared".  Page boundaries are used so that * memory protections can be turned on/off for individual buffers.  */#define IOBUFSIZE  ((DMA_BUFSIZ * NQD) + 512)char DMA_shared[IOBUFSIZE];	    /* reserve I/O buffer space */struct DMAreq_header *DMAheader[NQD];  /* DMA buffer header pntrs *//* * The driver assists a client in scroll operations by loading dragon * registers from an interrupt service routine.	The loading is done using * parameters found in memory shrade between the driver and it's client. * The scroll parameter structures are ALL loacted in the same memory page * for reasons of memory economy.   */char scroll_shared[2 * 512];	/* reserve space for scroll structs */struct scroll *scroll[NQD];	/* pointers to scroll structures *//* * the driver is programmable to provide the user with color map write * services at VSYNC interrupt time.  At interrupt time the driver loads * the color map with any user-requested load data found in shared memory  */#define COLOR_SHARED  ((COLOR_BUFSIZ * NQD) + 512)char color_shared[COLOR_SHARED];      /* reserve space: color bufs */struct color_buf *color_buf[NQD];     /* pointers to color bufs *//* * mouse input event structures  */struct mouse_report last_rep[NQD];struct mouse_report current_rep[NQD];struct proc *qdrsel[NQD]; 	/* process waiting for select */struct _vs_cursor cursor[NQD];	/* console cursor */int qdcount = 0;		/* count of successfully probed qd's */int nNQD = NQD;int DMAbuf_size = DMA_BUFSIZ;int QDlast_DMAtype;             /* type of the last DMA operation */#define QDSSMAJOR	41	/* QDSS major device number *//* * macro to get system time.  Used to time stamp event queue entries  */#define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000))int qdprobe();int qdattach();int qddint();			/* DMA gate array intrpt service */int qdaint();			/* Dragon ADDER intrpt service */int qdiint();u_short qdstd[] = { 0 };struct uba_driver qddriver = {	qdprobe,		/* device probe entry */	0,			/* no slave device */	qdattach,		/* device attach entry */	0,			/* no "fill csr/ba to start" */	qdstd,			/* device addresses */	"qd",			/* device name string */	qdinfo			/* ptr to QDSS's uba_device struct */};#define QDPRIOR (PZERO-1)		/* must be negative */#define FALSE	0#define TRUE	~FALSE#define BAD	-1#define GOOD	0/* * macro to create a system virtual page number from system virtual adrs  */#define VTOP(x)  (((int)x & ~0xC0000000) >> PGSHIFT)/* * QDSS register address offsets from start of QDSS address space  */#define QDSIZE	 (52 * 1024)	/* size of entire QDSS foot print */#define TMPSIZE  (16 * 1024)	/* template RAM is 8k SHORT WORDS */#define TMPSTART 0x8000 	/* offset of template RAM from base adrs */#define REGSIZE  (5 * 512)	/* regs touch 2.5k (5 pages) of addr space */#define REGSTART 0xC000 	/* offset of reg pages from base adrs */#define ADDER	(REGSTART+0x000)#define DGA	(REGSTART+0x200)#define DUART	(REGSTART+0x400)#define MEMCSR	(REGSTART+0x800)#define CLRSIZE  (3 * 512)		/* color map size */#define CLRSTART (REGSTART+0xA00)	/* color map start offset from base *//*  0x0C00 really */#define RED	(CLRSTART+0x000)#define BLUE	(CLRSTART+0x200)#define GREEN	(CLRSTART+0x400)/* * QDSS minor device numbers.  The *real* minor device numbers are in * the bottom two bits of the major/minor device spec.  Bits 2 and up are * used to specify the QDSS device number (ie: which one?)  */#define CONS		0#define GRAPHIC 	2/* * console cursor bitmap (white block cursor)   */short cons_cursor[32] = {	/* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,	0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,	/* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,	0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF};/* * constants used in font operations  */#define CHARS		190 			/* # of chars in the font */#define CHAR_HEIGHT	15			/* char height in pixels */#define CHAR_WIDTH	8			/* char width in pixels*/#define FONT_WIDTH	(CHAR_WIDTH * CHARS)	/* font width in pixels */#define ROWS		CHAR_HEIGHT#define FONT_X		0			/* font's off screen adrs */#define FONT_Y		(2048 - CHAR_HEIGHT)/* Offset to second row characters (XXX - should remove) */#define FONT_OFFSET	((MAX_SCREEN_X/CHAR_WIDTH)*CHAR_HEIGHT)extern char q_font[];		/* reference font object code */extern	u_short q_key[];	/* reference key xlation tables */extern	u_short q_shift_key[];extern	char *q_special[];/* * definitions for cursor acceleration reporting   */#define ACC_OFF 	0x01		/* acceleration is inactive *//* * virtual console support. */extern (*v_putc)();#ifdef KADBextern (*v_getc)();extern (*v_poll)();#endifextern struct cdevsw *consops;int qdputc();int qdgetc();int qdpoll();int qdstart();int qdpolling = 0;/* * LK-201 state storage for input console keyboard conversion to ASCII  */struct q_keyboard {	int shift;			/* state variables	*/	int cntrl;	int lock;	int lastcode;			/* last keycode typed	*/	unsigned kup[8];		/* bits for each keycode*/	unsigned dkeys[8];		/* down/up mode keys	*/	char last;			/* last character	*/} q_keyboard;/* * tty settings on first open */#define IFLAG (BRKINT|ISTRIP|IXON|IXANY|ICRNL|IMAXBEL)#define OFLAG (OPOST|OXTABS|ONLCR)#define LFLAG (ISIG|ICANON|ECHO|IEXTEN)#define CFLAG (PARENB|CREAD|CS7|CLOCAL)/* * Init QDSS as console (before probe routine) */qdcons_init(){	register unit;	caddr_t phys_adr;		/* physical QDSS base adrs */	u_int mapix;			/* index into QVmap[] array */	struct percpu *pcpu;		/* pointer to cpusw structure  */	register struct qbus *qb;	u_short *qdaddr;		/* address of QDSS IO page CSR */	u_short *devptr;		/* vitual device space */	extern cnputc();#define QDSSCSR 0x1F00	if (v_putc != cnputc)	    return 0;	unit = 0;	/*	 * find the cpusw entry that matches this machine. 	 */	for (pcpu = percpu; pcpu && pcpu->pc_cputype != cpu; pcpu++)		;	if (pcpu == NULL)	    return 0;	if (pcpu->pc_io->io_type != IO_QBUS)	    return 0;	/*	 * Map device registers - the last 8K of qvmem.	 */	qb = (struct qbus *)pcpu->pc_io->io_details;	ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize,		 UBAIOPAGES * NBPG);	devptr = (u_short *)((char *)umem[0]+(qb->qb_memsize * NBPG));	qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR));	if (badaddr((caddr_t)qdaddr, sizeof(short)))		return 0;	/*	 * Map q-bus memory used by qdss. (separate map)	 */	mapix = QMEMSIZE - (CHUNK * (unit + 1));	phys_adr = qb->qb_maddr + mapix;	ioaccess(phys_adr, QVmap[0], (CHUNK*NQD));	/*	 * tell QDSS which Q memory address base to decode 	 * (shifted right 16 bits - its in 64K units)	 */	*qdaddr = (u_short)((int)mapix >> 16);	qdflags[unit].config = *(u_short *)qdaddr;	/*	 * load qdmap struct with the virtual addresses of the QDSS elements 	 */	qdbase[unit] = (caddr_t) (qvmem[0]);	qdmap[unit].template = qdbase[unit] + TMPSTART;	qdmap[unit].adder = qdbase[unit] + ADDER;	qdmap[unit].dga = qdbase[unit] + DGA;	qdmap[unit].duart = qdbase[unit] + DUART;	qdmap[unit].memcsr = qdbase[unit] + MEMCSR;	qdmap[unit].red = qdbase[unit] + RED;	qdmap[unit].blue = qdbase[unit] + BLUE;	qdmap[unit].green = qdbase[unit] + GREEN;	qdflags[unit].duart_imask = 0;	/* init shadow variables */	/*	 * init the QDSS  	 */	/* 	printf("qdbase[0] = %x, qdmap[0].memcsr = %x\n",		(char *)qdbase[0], qdmap[0].memcsr);	*/	*(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */	cursor[unit].x = 0;	cursor[unit].y = 0;	init_shared(unit);		/* init shared memory */	setup_dragon(unit);		/* init the ADDER/VIPER stuff */	clear_qd_screen(unit);		/* clear the screen */	ldfont(unit);			/* load the console font */	ldcursor(unit, cons_cursor);	/* load default cursor map */	setup_input(unit);		/* init the DUART */	v_putc = qdputc;		/* kernel console output to qdss */#ifdef KADB	v_getc = qdgetc;		/* kernel console input from qdss */	v_poll = qdpoll;		/* kdb hook to disable char intr */#endif	consops = &cdevsw[QDSSMAJOR];	/* virtual console is qdss */	return 1;} /* qdcons_init *//* *  Configure QDSS into Q memory and make it intrpt. * *  side effects: QDSS gets mapped into Qbus memory space at the first *		 vacant 64kb boundary counting back from the top of *		 Qbus memory space (qvmem+4mb) * *  return: QDSS bus request level and vector address returned in *	   registers by UNIX convention. * */qdprobe(reg)	caddr_t reg;	/* character pointer to the QDSS I/O page register */{	register int br, cvec;	register int unit;	struct dga *dga;		/* pointer to gate array structure */	int vector;#ifdef notdef	int *ptep;			/* page table entry pointer */	caddr_t phys_adr;		/* physical QDSS base adrs */	u_int mapix;#endif#ifdef lint	br = 0; cvec = br; br = cvec; nNQD = br; br = nNQD;	qddint(0); qdaint(0); qdiint(0); (void)qdgetc();#endif	/*	 * calculate board unit number from I/O page register address  	 */	unit = (int) (((int)reg >> 1) & 0x0007);	/*	 * QDSS regs must be mapped to Qbus memory space at a 64kb 	 * physical boundary.  The Qbus memory space is mapped into	 * the system memory space at config time.  After config	 * runs, "qvmem[0]" (ubavar.h) holds the system virtual adrs	 * of the start of Qbus memory.   The Qbus memory page table	 * is found via an array of pte ptrs called "QVmap[]" (ubavar.h)	 * which is also loaded at config time.   These are the	 * variables used below to find a vacant 64kb boundary in	 * Qbus memory, and load it's corresponding physical adrs	 * into the QDSS's I/O page CSR.  	 */	/*	 * Only if QD is the graphics device.	 */	/* if this QDSS is NOT the console, then do init here.. */	if (unit != 0) {		printf("qd: can't support two qdss's (yet)\n");#ifdef notdef	/* can't test */		if (v_consputc != qdputc  ||  unit != 0) {			/*			* read QDSS config info 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -