~kris/9p

9hist

592b4dc520f81400bcda74302b84b0a2808f2c17 — David du Colombier 25 years ago 280760c
Plan 9 from Bell Labs 2001-05-05
5 files changed, 524 insertions(+), 81 deletions(-)

M bitsy/etherwavelan.c
M ip/tcp.c
M pc/etherwavelan.c
M pc/vgamach64xx.c
M port/devtls.c
M bitsy/etherwavelan.c => bitsy/etherwavelan.c +1 -1
@@ 29,7 29,7 @@

#define DEBUG	if(1)print

#define SEEKEYS 1
#define SEEKEYS 0

typedef struct Ctlr	Ctlr;
typedef struct Wltv	Wltv;

M ip/tcp.c => ip/tcp.c +1 -1
@@ 1255,7 1255,7 @@ tcpiput(Proto *tcp, uchar*, Block *bp)

	h->Unused = 0;
	hnputs(h->tcplen, length-TCP_PKT);
	if((h->tcpcksum[0] || h->tcpcksum[0]) && 
	if((h->tcpcksum[0] || h->tcpcksum[1]) && 
	    ptclcsum(bp, TCP_IPLEN, length-TCP_IPLEN)) {
		tpriv->stats[CsumErrs]++;
		tpriv->stats[InErrs]++;

M pc/etherwavelan.c => pc/etherwavelan.c +3 -0
@@ 434,7 434,10 @@ ltv_outstr(Ctlr* ctlr, int type, char* val)
	memset(&ltv, 0, sizeof(ltv));
	ltv.len = (sizeof(ltv.type)+sizeof(ltv.slen)+sizeof(ltv.s))/2;
	ltv.type = type;

//	This should be ltv.slen = len; according to Axel Belinfante
	ltv.slen = (len+1) & ~1;

	strncpy(ltv.s, val, len);
	w_outltv(ctlr, &ltv);
}

M pc/vgamach64xx.c => pc/vgamach64xx.c +513 -76
@@ 12,30 12,131 @@
#include <cursor.h>
#include "screen.h"

char Eunsupportedformat[] = "unsupported video format";
char Enotconfigured[] = "device not configured";

#define SCALE_ZERO_EXTEND           	0x0
#define SCALE_DYNAMIC               		0x1
#define SCALE_RED_TEMP_6500K        	0x0
#define SCALE_RED_TEMP_9800K        	0x2
#define SCALE_HORZ_BLEND            	0x0
#define SCALE_HORZ_REP              		0x4
#define SCALE_VERT_BLEND            		0x0
#define SCALE_VERT_REP              		0x8
#define SCALE_BANDWIDTH_NORMAL     0x0
#define SCALE_BANDWIDTH_EXCEEDED  0x4000000
#define SCALE_BANDWIDTH_RESET       	0x4000000
#define SCALE_CLK_ACTIVITY          	0x0
#define SCALE_CLK_CONTINUOUS        	0x20000000
#define OVERLAY_DISABLE             		0x0
#define OVERLAY_ENABLE              		0x40000000
#define SCALE_DISABLE               		0x0
#define SCALE_ENABLE                		0x80000000

#define SCALER_FRAME_READ_MODE_FULL 	0x0
#define SCALER_BUF_MODE_SINGLE      		0x0
#define SCALER_BUF_MODE_DOUBLE      		0x40000
#define SCALER_BUF_NEXT_0           		0x0
#define SCALER_BUF_NEXT_1           		0x80000
#define SCALER_BUF_STATUS_0         		0x0
#define SCALER_BUF_STATUS_1         		0x100000

#define OVERLAY_MIX_G_CMP           		0x0
#define OVERLAY_MIX_ALWAYS_G        		0x100
#define OVERLAY_MIX_ALWAYS_V        		0x200
#define OVERLAY_MIX_NOT_G           		0x300
#define OVERLAY_MIX_NOT_V           		0x400
#define OVERLAY_MIX_G_XOR_V         		0x500
#define OVERLAY_MIX_NOT_G_XOR_V     	0x600
#define OVERLAY_MIX_V_CMP           		0x700
#define OVERLAY_MIX_NOT_G_OR_NOT_V	0x800
#define OVERLAY_MIX_G_OR_NOT_V      	0x900
#define OVERLAY_MIX_NOT_G_OR_V      	0xA00
#define OVERLAY_MIX_G_OR_V          		0xB00
#define OVERLAY_MIX_G_AND_V         		0xC00
#define OVERLAY_MIX_NOT_G_AND_V     	0xD00
#define OVERLAY_MIX_G_AND_NOT_V     	0xE00
#define OVERLAY_MIX_NOT_G_AND_NOT_V 	0xF00
#define OVERLAY_EXCLUSIVE_NORMAL    	0x0
#define OVERLAY_EXCLUSIVE_V_ONLY    	0x80000000

#define VIDEO_IN_8BPP               			0x2
#define VIDEO_IN_16BPP              			0x4
#define VIDEO_IN_32BPP              			0x6
#define VIDEO_IN_VYUY422            			0xB         		/*16 bpp */
#define VIDEO_IN_YVYU422            			0xC         		/* 16 bpp */
#define SCALE_IN_15BPP              			0x30000     	/* aRGB 1555 */
#define SCALE_IN_16BPP              			0x40000     	/* RGB 565 */
#define SCALE_IN_32BPP              			0x60000     	/* aRGB 8888 */
#define SCALE_IN_YUV9               			0x90000     	/* planar */
#define SCALE_IN_YUV12              			0xA0000     	/* planar */
#define SCALE_IN_VYUY422            			0xB0000     	/* 16 bpp */
#define SCALE_IN_YVYU422            			0xC0000     	/* 16 bpp */
#define HOST_YUV_APERTURE_UPPER     		0x0
#define HOST_YUV_APERTURE_LOWER     	0x20000000
#define HOST_MEM_MODE_Y             		0x40000000
#define HOST_MEM_MODE_U             		0x80000000
#define HOST_MEM_MODE_V             		0xC0000000
#define HOST_MEM_MODE_NORMAL     		HOST_YUV_APERTURE_UPPER 

static Chan *ovl_chan;	/* Channel of controlling process */
static int ovl_width;		/* Width of input overlay buffer */
static int ovl_height;		/* Height of input overlay buffer */
static int ovl_format;	/* Overlay format */
static ulong ovl_fib;		/* Frame in bytes */

enum {
	 VTGTB1S1        = 0x01,            //  Asic description for VTB1S1 and GTB1S1.
	 VT4GTIIC        	= 0x3A,            // asic descr for VT4 and RAGE IIC
	 GTB1U1          	= 0x19,            //  Asic description for GTB1U1.
	 GTB1S2          	= 0x41,            //  Asic description for GTB1S2.
	 GTB2U1          	= 0x1A,
	 GTB2U2          	= 0x5A,
	 GTB2U3          	= 0x9A,
	 GTIIIC1U1       	= 0x1B,            // 3D RAGE PRO asic descrp.
	 GTIIIC1U2       	= 0x5B,            // 3D RAGE PRO asic descrp.
	 GTIIIC2U1       	= 0x1C,            // 3D RAGE PRO asic descrp.
	 GTIIIC2U2       	= 0x5C,           // 3D RAGE PRO asic descrp.
	 GTIIIC2U3       	= 0x7C,            // 3D RAGE PRO asic descrp.
	 GTBC            	= 0x3A,            // 3D RAGE IIC asic descrp.
	 LTPRO           	= 0x9C,            // 3D RAGE LT PRO
};

/*
 * ATI Mach64(CT|ET|G*|V*|L*).
 */
static ushort mach64xxdid[] = {
	('C'<<8)|'T',
	('E'<<8)|'T',
	('G'<<8)|'B',
	('G'<<8)|'D',
	('G'<<8)|'I',
	('G'<<8)|'M',
	('G'<<8)|'P',
	('G'<<8)|'Q',
	('G'<<8)|'T',
	('G'<<8)|'U',
	('G'<<8)|'V',
	('G'<<8)|'Z',
	('V'<<8)|'T',
	('V'<<8)|'U',
	('V'<<8)|'V',
	('L'<<8)|'B',
	('L'<<8)|'I',
	('L'<<8)|'M',
	('L'<<8)|'P',
	0,
typedef struct {
	ushort 	m64_id;			/* Chip ID */
	int 		m64_vtgt;		/* Is this a VT or GT chipset? */
	double	m64_ovlclock;		/* Max. overlay clock frequency */
	int		m64_pro;			/* Is this a PRO? */
} mach64types;

static double mach64refclock;
static mach64types *mach64type;
static int mach64revb;			/* Revision B or greater? */
static ulong mach64overlay;		/* Overlay buffer */

static mach64types mach64s[] = {
	('C'<<8)|'T',	0,	0.,		0,	/* 4354: CT */
	('E'<<8)|'T',	0,	0.,		0,	/* 4554: ET */
	('G'<<8)|'B',	1,	125.,		1, 	/* 4742: 264GT PRO */
	('G'<<8)|'D',	1,	125.,		1, 	/* 4744: 264GT PRO */
	('G'<<8)|'I',	1,	125.,		1, 	/* 4749: 264GT PRO */
	('G'<<8)|'M',	0,	135.,		0,	/* 474D: Rage XL */
	('G'<<8)|'P',	1,	125.,		1, 	/* 4750: 264GT PRO */
	('G'<<8)|'Q',	1,	125.,		1,	/* 4751: 264GT PRO */
	('G'<<8)|'T',	1,	80.,		0,	/* 4754: 264GT[B] */
	('G'<<8)|'U',	1,	100.,		0,	/* 4755: 264GT DVD */
	('G'<<8)|'V',	1,	100.,		0,	/* 4756: Rage2C */
	('G'<<8)|'Z',	1,	100.,		0,	/* 475A: Rage2C */
	('V'<<8)|'T',	1,	80.,		0,	/* 5654: 264VT/GT/VTB */
	('V'<<8)|'U',	1,	80.,		0,	/* 5655: 264VT3 */
	('V'<<8)|'V',	1,	100.,		0,	/* 5656: 264VT4 */
	('L'<<8)|'B',	0,	135.,		1,	/* 4C42: Rage LTPro AGP */
	('L'<<8)|'I',		0,	135.,		0,	/* 4C49: Rage LTPro AGP */
	('L'<<8)|'M',	0,	135.,		0,	/* 4C4D: Rage Mobility */
	('L'<<8)|'P',	0,	135.,		1,	/* 4C50: 264LT PRO */
};

static int hwfill(VGAscr*, Rectangle, ulong);


@@ 46,15 147,16 @@ static Pcidev*
mach64xxpci(void)
{
	Pcidev *p;
	ushort *did;
	int i;

	if((p = pcimatch(nil, 0x1002, 0)) == nil)
		return nil;
	for(did = mach64xxdid; *did; did++){
		if(*did == p->did)
			return p;
	}

	for (i = 0; i != nelem(mach64s); i++)
		if (mach64s[i].m64_id == p->did) {
			mach64type = &mach64s[i];
			return p;
		}
	return nil;
}



@@ 70,6 172,7 @@ mach64xxenable(VGAscr* scr)
		return;
	if(p = mach64xxpci()){
		scr->id = p->did;
         	// iprint("mach64xxenable: found x%.4X\n", p->did);

		/*
		 * The CT doesn't always have the I/O base address


@@ 200,6 303,29 @@ enum {
	SrcOffPitch,	
	LcdIndex,
	LcdData,
	ClockCntl,
	OverlayScaleCntl,
	ConfigChipId,
	Buf0Pitch,
	ScalerBuf0Pitch,
	CaptureConfig,
	OverlayKeyCntl,
	ScalerColourCntl,
	ScalerHCoef0,
	ScalerHCoef1,
	ScalerHCoef2,
	ScalerHCoef3,
	ScalerHCoef4,
	VideoFormat,
	Buf0Offset,
	ScalerBuf0Offset,
	CrtcGenCntl,
	OverlayScaleInc,
	OverlayYX,
	OverlayYXEnd,
	ScalerHeightWidth,
	HTotalDisp,
	VTotalDisp,
};

enum {


@@ 216,56 342,83 @@ enum {
	Nlcd,
};

static uchar mmoffset[] = {
	[CrtcOffPitch]	0x05,
	[CurClr0]	0x18,
	[CurClr1]	0x19,
	[CurOffset]	0x1A,
	[CurHVposn]	0x1B,
	[CurHVoff]	0x1C,
	[BusCntl]		0x28,
	[LcdIndex]	0x29,
	[LcdData]	0x2A,
	[GenTestCntl]	0x34,
	[DstOffPitch]	0x40,
	[DstYX]		0x43,
	[DstHeight]	0x45,
#define Bank1			(-0x100)		/* 1KB */

static int mmoffset[] = {
	[HTotalDisp]		0x00,
	[VTotalDisp]		0x02,
	[CrtcOffPitch]		0x05,
	[CrtcGenCntl]		0x07,
	[CurClr0]			0x18,
	[CurClr1]			0x19,
	[CurOffset]		0x1A,
	[CurHVposn]		0x1B,
	[CurHVoff]		0x1C,
	[ClockCntl]		0x24,
	[BusCntl]			0x28,
	[LcdIndex]		0x29,
	[LcdData]			0x2A,
	[GenTestCntl]		0x34,
	[ConfigChipId]		0x38,
	[DstOffPitch]		0x40,
	[DstYX]			0x43,
	[DstHeight]		0x45,
	[DstHeightWidth]	0x46,
	[DstBresErr]	0x49,
	[DstBresInc]	0x4A,
	[DstBresDec]	0x4B,
	[DstCntl]		0x4C,
	[SrcOffPitch]	0x60,
	[SrcYX]	0x63,
	[SrcWidth1]	0x64,
	[SrcYXstart]	0x69,
	[DstBresErr]		0x49,
	[DstBresInc]		0x4A,
	[DstBresDec]		0x4B,
	[DstCntl]			0x4C,
	[SrcOffPitch]		0x60,
	[SrcYX]			0x63,
	[SrcWidth1]		0x64,
	[SrcYXstart]		0x69,
	[SrcHeight1Width1]	0x66,
	[SrcHeight2Width2]	0x6C,
	[SrcCntl]		0x6D,
	[HostCntl]	0x90,
	[PatReg0]	0xA0,
	[PatReg1]	0xA1,
	[PatCntl]	0xA2,
	[ScLeft]	0xA8,
	[ScRight]	0xA9,
	[ScLeftRight]	0xAA,
	[ScTop]	0xAB,
	[ScBottom] 0xAC,
	[ScTopBottom]	0xAD,
	[DpBkgdClr]	0xB0,
	[DpFrgdClr]	0xB1,
	[DpWriteMask]	0xB2,
	[DpChainMask]	0xB3,
	[DpPixWidth]	0xB4,
	[DpMix]		0xB5,
	[DpSrc]		0xB6,
	[ClrCmpClr]	0xC0,
	[ClrCmpMask]	0xC1,
	[ClrCmpCntl]	0xC2,
	[FifoStat]		0xC4,
	[ContextMask]	0xC8,
	[GuiTrajCntl]	0xCC,
	[GuiStat]		0xCE,
	[SrcCntl]			0x6D,
	[HostCntl]			0x90,
	[PatReg0]			0xA0,
	[PatReg1]			0xA1,
	[PatCntl]			0xA2,
	[ScLeft]			0xA8,
	[ScRight]			0xA9,
	[ScLeftRight]		0xAA,
	[ScTop]			0xAB,
	[ScBottom] 		0xAC,
	[ScTopBottom]		0xAD,
	[DpBkgdClr]		0xB0,
	[DpFrgdClr]		0xB1,
	[DpWriteMask]		0xB2,
	[DpChainMask]		0xB3,
	[DpPixWidth]		0xB4,
	[DpMix]			0xB5,
	[DpSrc]			0xB6,
	[ClrCmpClr]		0xC0,
	[ClrCmpMask]		0xC1,
	[ClrCmpCntl]		0xC2,
	[FifoStat]			0xC4,
	[ContextMask]		0xC8,
	[GuiTrajCntl]		0xCC,
	[GuiStat]			0xCE,

	/* Bank1 */
	[OverlayYX]		Bank1 + 0x00,
	[OverlayYXEnd]		Bank1 + 0x01,
	[OverlayKeyCntl]	Bank1 + 0x06,
	[OverlayScaleInc]	Bank1 + 0x08,
	[OverlayScaleCntl]	Bank1 + 0x09,
	[ScalerHeightWidth]	Bank1 + 0x0A,
	[ScalerBuf0Offset]	Bank1 + 0x0D,
	[ScalerBuf0Pitch]	Bank1 + 0x0F,
	[VideoFormat]		Bank1 + 0x12,
	[CaptureConfig]	Bank1 + 0x14,
	[Buf0Offset]		Bank1 + 0x20,
	[Buf0Pitch]		Bank1 + 0x23,
	[ScalerColourCntl]	Bank1 + 0x54,
	[ScalerHCoef0]		Bank1 + 0x55,
	[ScalerHCoef1]		Bank1 + 0x56,
	[ScalerHCoef2]		Bank1 + 0x57,
	[ScalerHCoef3]		Bank1 + 0x58,
	[ScalerHCoef4]		Bank1 + 0x59,
};

static ulong


@@ 545,9 698,46 @@ resetengine(VGAscr *scr)
}

static void
init_overlayclock(VGAscr *scr)
{
	uchar *cc, save, pll_ref_div, pll_vclk_cntl, vclk_post_div, 
			vclk_fb_div, ecp_div;
	int i;
	double dotclock;

	/* Taken from GLX */
	/* Get monitor dotclock, check for Overlay Scaler clock limit */
 	cc = (uchar *)&scr->mmio[mmoffset[ClockCntl]];
  	save = cc[1]; i = cc[0] & 3;
  	cc[1] = 2<<2; pll_ref_div = cc[2];
  	cc[1] = 5<<2; pll_vclk_cntl = cc[2];
  	cc[1] = 6<<2; vclk_post_div = (cc[2]>>(i+i)) & 3;
  	cc[1] = (7+i)<<2; vclk_fb_div = cc[2];

  	dotclock = 2.0 * mach64refclock * vclk_fb_div / 
			(pll_ref_div * (1 << vclk_post_div));
	/* ecp_div: 0=dotclock, 1=dotclock/2, 2=dotclock/4 */
  	ecp_div = dotclock / mach64type->m64_ovlclock;
  	if (ecp_div>2) ecp_div = 2;

  	/* Force a scaler clock factor of 1 if refclock *
   	  * is unknown (VCLK_SRC not PLLVCLK)  */
  	if ((pll_vclk_cntl & 0x03) != 0x03) dotclock = ecp_div = 0;
  	if ((pll_vclk_cntl & 0x30) != ecp_div<<4) {
    		cc[1] = (5<<2)|2;
    		cc[2] = (pll_vclk_cntl&0xCF) | (ecp_div<<4);
	}

  	/* Restore PLL Register Index */
  	cc[1] = save;
}

static void
initengine(VGAscr *scr)
{
	ulong pitch;
	uchar *bios;
	ushort table;

	pitch = Dx(scr->gscreen->r)/8;
	if(scr->gscreen->depth == 24)


@@ 607,7 797,52 @@ initengine(VGAscr *scr)
		break;
	}

	/* Get the base freq from the BIOS */
	bios  = KADDR(0xC000);
	table = *(ushort *)(bios + 0x48);
	table = *(ushort *)(bios + table + 0x10);
	switch (*(ushort *)(bios + table + 0x08)) {
      	case 2700: 
		mach64refclock = 27.0; 
		break;
      	case 2863: 
      	case 2864: 
		mach64refclock = 28.63636; 
		break;
      	case 2950: 
		mach64refclock = 29.498928713; 
		break;
    	case 1432: 
	default:
		mach64refclock = 14.31818; 
		break ;	
	}
	
	/* Figure out which revision this chip is */
	switch ((scr->mmio[mmoffset[ConfigChipId]] >> 24) & 0xFF) {
	case VTGTB1S1:
	case GTB1U1:
	case GTB1S2:
	case GTB2U1:
	case GTB2U2:
	case GTB2U3:
	case GTBC:
	case GTIIIC1U1:
	case GTIIIC1U2:
	case GTIIIC2U1:
	case GTIIIC2U2: 
	case GTIIIC2U3: 
	case LTPRO:
			mach64revb = 1;
			break;
	default: 
			mach64revb = 0;
			break;
	}

	init_overlayclock(scr);
	waitforidle(scr);
	
}

static int


@@ 761,7 996,7 @@ mach64lcdblank(VGAscr *scr, int blank)

static void
mach64xxdrawinit(VGAscr *scr)
{
{ 
	if(scr->io > 0x2FF){
		initengine(scr);
		scr->fill = mach64hwfill;


@@ 780,14 1015,216 @@ mach64xxdrawinit(VGAscr *scr)
	}
}

static void
ovl_configure(VGAscr *scr, Chan *c, int nfields, char **field)
{
	int w, h;
	char *format;

	if (nfields != 4) error(Ebadarg);

	w = (int)strtol(field[1], nil, 0);
	h = (int)strtol(field[2], nil, 0);
	format = field[3];

	if (c != ovl_chan) error(Einuse);
	if (strcmp(format, "YUYV"))
		error(Eunsupportedformat);
	
	ovl_width  = w;
	ovl_height = h;
	ovl_fib       = w * h * sizeof(ushort);

	waitforidle(scr);
	scr->mmio[mmoffset[BusCntl]] |= 0x08000000;	/* Enable regblock 1 */
	scr->mmio[mmoffset[OverlayScaleCntl]] = 
		SCALE_ZERO_EXTEND|SCALE_RED_TEMP_6500K|
		SCALE_HORZ_BLEND|SCALE_VERT_BLEND;
	scr->mmio[mmoffset[!mach64revb? Buf0Pitch: ScalerBuf0Pitch]] = w;
	scr->mmio[mmoffset[CaptureConfig]] = 
		SCALER_FRAME_READ_MODE_FULL|
		SCALER_BUF_MODE_SINGLE|
		SCALER_BUF_NEXT_0;
	scr->mmio[mmoffset[OverlayKeyCntl]] = !mach64revb?
		OVERLAY_MIX_ALWAYS_V|(OVERLAY_EXCLUSIVE_NORMAL << 28): 
		0x011;

	if (mach64type->m64_pro) {
		waitforfifo(scr, 6);

		/* set the scaler co-efficient registers */
		scr->mmio[mmoffset[ScalerColourCntl]] = 
			(0x00) | (0x10 << 8) | (0x10 << 16);
		scr->mmio[mmoffset[ScalerHCoef0]] = 
			(0x00) | (0x20 << 8);
		scr->mmio[mmoffset[ScalerHCoef1]] = 
			(0x0D) | (0x20 << 8) | (0x06 << 16) | (0x0D << 24);
		scr->mmio[mmoffset[ScalerHCoef2]] = 
			(0x0D) | (0x1C << 8) | (0x0A << 16) | (0x0D << 24);
		scr->mmio[mmoffset[ScalerHCoef3]] = 
			(0x0C) | (0x1A << 8) | (0x0E << 16) | (0x0C << 24);
		scr->mmio[mmoffset[ScalerHCoef4]] = 
			(0x0C) | (0x14 << 8) | (0x14 << 16) | (0x0C << 24);
	}
	
	waitforfifo(scr, 3);
	scr->mmio[mmoffset[VideoFormat]] = SCALE_IN_YVYU422 |
		(!mach64revb? 0xC: 0);

	if (mach64overlay == 0)
		mach64overlay = scr->storage + 64 * 64 * sizeof(uchar);
	scr->mmio[mmoffset[!mach64revb? Buf0Offset: ScalerBuf0Offset]] = 
		mach64overlay;
}

static void
ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
{
	int x, y, w, h;
	long h_inc, v_inc;

	if (nfields != 5) error(Ebadarg);

	x = (int)strtol(field[1], nil, 0);
	y = (int)strtol(field[2], nil, 0);
	w = (int)strtol(field[3], nil, 0);
	h = (int)strtol(field[4], nil, 0);

	if (x < 0 || x + w > physgscreenr.max.x ||
	     y < 0 || y + h > physgscreenr.max.y)
		error(Ebadarg);

	if (c != ovl_chan) error(Einuse);
	if (scr->mmio[mmoffset[CrtcGenCntl]] & 1) {	/* double scan enable */
		y *= 2;
		h *= 2;
	}

	waitforfifo(scr, 2);
	scr->mmio[mmoffset[OverlayYX]] = 
			((x & 0xFFFF) << 16) | (y & 0xFFFF);
	scr->mmio[mmoffset[OverlayYXEnd]] = 
			(((x + w) & 0xFFFF) << 16) | ((y + h) & 0xFFFF);

	h_inc = (ovl_width << 12) / (w >> 1);  /* ??? */
	v_inc = (ovl_height << 12) / h;
	waitforfifo(scr, 2);
	scr->mmio[mmoffset[OverlayScaleInc]] = 
			((h_inc & 0xFFFF) << 16) | (v_inc & 0xFFFF);
	scr->mmio[mmoffset[ScalerHeightWidth]] = 
			((ovl_width & 0xFFFF) << 16) | (ovl_height & 0xFFFF);
	waitforidle(scr);
	scr->mmio[mmoffset[OverlayScaleCntl]] |= 
			(SCALE_ENABLE|OVERLAY_ENABLE);
}

static void
ovl_status(VGAscr *scr, Chan *, int nfields, char **field)
{
	if (nfields != 1) error(Ebadarg);

	pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %d\n",
		   scr->dev->name, field[0], mach64type->m64_id,
		   mach64type->m64_vtgt? "yes": "no",
		   mach64type->m64_pro? "yes": "no",
		   (int)(mach64type->m64_ovlclock  * 10000.),
		   mach64revb? "yes": "no",
		   (int)(mach64refclock * 10000.));
	pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
		   scr->dev->name, scr->storage, scr->aperture,
		   mach64overlay);
}
	
static void
ovl_openctl(VGAscr *, Chan *c, int nfields, char **)
{
	if (nfields != 1) error(Ebadarg);
	if (ovl_chan) error(Einuse);
	ovl_chan = c;
}

static void
ovl_closectl(VGAscr *scr, Chan *c, int nfields, char **)
{
	if (c != ovl_chan || nfields != 1) return;

	waitforidle(scr);
	scr->mmio[mmoffset[OverlayScaleCntl]] &=
			~(SCALE_ENABLE|OVERLAY_ENABLE);
	ovl_chan = nil;
	ovl_width = ovl_height = ovl_fib = 0;
}

static struct {
	char *ovl_command;
	void	 (*ovl_f)(VGAscr *, Chan *, int, char **);
} ovl_cmds[] = {
	{	"openctl",		ovl_openctl	},
	{	"configure", 	ovl_configure,	},
	{	"enable",		ovl_enable,	},
	{	"closectl",		ovl_closectl	},
	{	"status",		ovl_status		},
};

static void
mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int)
{
#define MAXARGS	10
	char *field[MAXARGS];
	int nfields, i;

	if (!mach64type->m64_vtgt) error(Enodev);

	nfields = getfields(a, field, nelem(field), 1, "\t\n\r ");
	if (nfields < 1) error(Ebadarg);

	for (i = 0; i != nelem(ovl_cmds); i++)
		if (!strcmp(field[0], ovl_cmds[i].ovl_command))
			break;

	if (i == nelem(ovl_cmds))
		error(Ebadarg);

	ovl_cmds[i].ovl_f(scr, c, nfields, field);
}

static int
mach64xxovlwrite(VGAscr *scr, void *a, int len, vlong offs)
{
	uchar *src;
	int _len;

	if (ovl_chan == nil) return len;	/* Acts as a /dev/null */
	
	/* Calculate the destination address */
	_len = len;
	src   = (uchar *)a;
	while (len > 0) {
		ulong _offs;
		int nb;

		_offs = (ulong)(offs % ovl_fib);
		nb     = (_offs + len > ovl_fib)? ovl_fib - _offs: len;
		memmove((uchar *)KADDR(scr->aperture + mach64overlay + _offs), 
				  src, nb);
		offs += nb;
		src  += nb;
		len  -= nb;
	}
	return _len;
}

VGAdev vgamach64xxdev = {
	"mach64xx",

	mach64xxenable,			/* enable */
	mach64xxenable,	/* enable */
	0,				/* disable */
	0,				/* page */
	mach64xxlinear,			/* linear */
	mach64xxlinear,	/* linear */
	mach64xxdrawinit,	/* drawinit */
	0,
	mach64xxovlctl,	/* overlay control */
	mach64xxovlwrite,	/* write the overlay */
};

VGAcur vgamach64xxcur = {

M port/devtls.c => port/devtls.c +6 -3
@@ 860,9 860,12 @@ tlsrecread(TlsRec *tr)
			b = nil;
			poperror();
			dechandq(tr);
		}else if(tr->verset && tr->version != SSL3Version && !waserror()){
			sendAlert(tr, ENoRenegotiation);
			poperror();
		}else{
			unlock(&tr->hqlock);
			if(tr->verset && tr->version != SSL3Version && !waserror()){
				sendAlert(tr, ENoRenegotiation);
				poperror();
			}
		}
		break;
	case RApplication: