Page 1 of 1

S3 ViRGE 2D driver

Posted: Thu May 05, 2011 9:27 pm
by blackoil
hi

I am ready *all day long* to implement it with BitBlt functionality. I got xf86-video-s3virge-1.10.4.zip.
Does anyone have done this before? any hint?

Code: Select all

W3D4(0x38,0x48); //unlock
W3D4(0x39,0xa5); //unlock

W3D4(0x40,R3D4(0x40)|0x1); //enable ext. reg
W3D4(0x53,R3D4(0x53)|0x8); //enable mmio

W3D4(0x59,videoaddr>>24); //linear addr
W3D4(0x5A,videoaddr>>16); //linear addr

W3D4(0x66,0x89); //enabel gfx engine
W3D4(0x63,0x10); //set display fifo
PCICFG bar0 is 0xF8000000

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 3:17 am
by Combuster
If you know where to look, the actual writes are pretty straightforward as they all take a common format: Wait for the device, then pump some commands. Which is not much different from the many other video cards from that period.

As a general tour of reverse engineering basics an example of the reset code:

Code: Select all

/* s3v_accel.c:492 */
    WAITFIFO(5);
    OUTREG(SRC_BASE, 0);
    OUTREG(DEST_BASE, 0);
    OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));
You could have looked up the relevant macros:

Code: Select all

/* s3v.h:91 */
#define OUTREG(addr, val) MMIO_OUT32(ps3v->MapBase, addr, val)
which tells us that the default register is 32 bits and is located at a certain offset from MapBase:

Code: Select all

/* s3v_driverc:2182 */
  ps3v->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, ps3v->PciTag,
				PCI_REGION_BASE(ps3v->PciInfo, 0, REGION_MEM) + S3_NEWMMIO_REGBASE,
				S3_NEWMMIO_REGSIZE);
which maps regsize bytes from BAR + regbase. In essence the MMIO comes directly after the possible video RAM but otherwise shares a base address register.

Code: Select all

/* newmmio.h:48 */
#define S3_NEWMMIO_REGBASE	0x1000000  /* 16MB */
#define S3_NEWMMIO_REGSIZE	  0x10000  /* 64KB */
You know the offset:

Code: Select all

/* s3v_macros.h:73 */
#define SRC_BASE	0xA4D4
#define DEST_BASE	0xA4D8
so altogether a write goes to BAR + REGBASE + (offset). Performing the same strategy with the value part will allow you to replicate the writes an X.org driver would perform, and all I really did so far was just a multi-file search for definitions or the relevant setters.

Now you do the same for the functions in s3v_accel.h that you want to use. You probably want to start with fills or screen-to-screen blits because you can visually inspect the results.

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 4:36 am
by blackoil
yes, i know how to make a mmio write. but nothing happened.

Code: Select all

/* Subsystem Control Register */
#define	GPCTRL_NC	0x0000
#define	GPCTRL_ENAB	0x4000
#define	GPCTRL_RESET	0x8000


/* Command Register */
#define	CMD_OP_MSK	(0xf << 27)
#define	CMD_BITBLT	(0x0 << 27)
#define	CMD_RECT       ((0x2 << 27) | 0x0100)
#define	CMD_LINE	(0x3 << 27)
#define	CMD_POLYFILL	(0x5 << 27)
#define	CMD_NOP		(0xf << 27)

/* Command AutoExecute */
#define CMD_AUTOEXEC	0x01

/* Command Hardware Clipping Enable */
#define CMD_HWCLIP	0x02

/* Destination Color Format */
#define DST_8BPP	0x00
#define DST_16BPP	0x04
#define DST_24BPP	0x08

/* BLT Mix modes */
#define	MIX_BITBLT	0x0000
#define	MIX_MONO_SRC	0x0040
#define	MIX_CPUDATA	0x0080
#define	MIX_MONO_PATT	0x0100
#define MIX_COLOR_PATT  0x0000
#define	MIX_MONO_TRANSP	0x0200

/* Image Transfer Alignments */
#define CMD_ITA_BYTE	0x0000
#define CMD_ITA_WORD	0x0400
#define CMD_ITA_DWORD	0x0800

/* First Doubleword Offset (Image Transfer) */
#define CMD_FDO_BYTE0	0x00000
#define CMD_FDO_BYTE1	0x01000
#define CMD_FDO_BYTE2	0x02000
#define CMD_FDO_BYTE3	0x03000

/* X Positive, Y Positive (Bit BLT) */
#define CMD_XP		0x2000000
#define CMD_YP		0x4000000

Code: Select all

uint[512]*   mmio;

mmio=videoaddr+0x01000000;
                                    //SOLID FILL SETUP
(*mmio) [PAT_FG_CLR/4] = 1235678;
(*mmio) [MONO_PAT_0/4] = ~0;
(*mmio) [MONO_PAT_1/4] = ~0;
(*mmio) [CMD_SET/4] = CMD_AUTOEXEC;

Code: Select all

uint[512]*   mmio;

mmio=videoaddr+0x01000000;
                                      // SOLID FILL
(*mmio) [RWIDTH_HEIGHT/4] = (w<<16)|h;
(*mmio) [RSRC_XY/4] = (srcx<<16)|srcy;
(*mmio) [RDEST_XY/4] = (destx<<16)|desty;
I wonder if I have initialized the chip fully & properly. I have to make the gfx engine ready to work.

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 5:05 am
by Combuster

Code: Select all

uint[512]*   mmio;
I get a syntax error on that, and you are apparently doing a double dereference.

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 5:08 am
by blackoil
ah sorry , i have my own c-ish compiler, that means uint (*mmio)[512];

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 5:18 am
by Combuster
I can't get the right address in there without some serious typecasting work. Have you verified it is correct and not multiplied as the type system would normally demand?

Also, I don't see the reset code anywhere...

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 5:46 am
by blackoil
the statements are ok for my compiler.

Code: Select all

void   S3Reset()
{
uint[512]* mmio;

mmio = videoaddr + 0x01000000;

(*mmio) [SRC_BASE/4] = 0;
(*mmio) [DEST_BASE/4] = 0;
(*mmio) [DEST_SRC_STR/4] = 640*4;
(*mmio) [CLIP_L_R/4] = 0 | 640;
(*mmio) [CLIP_T_B/4] = 0 | 480;
}

Code: Select all

void  S3Init()
{
OutPortB(0x3C3,(UINT)InPortB(0x3C3) | 1); //enable vga
OutPortB(0x3C2,(UINT)InPortB(0x3CC) | 1); //i/o addr select

W3D4(0x38,0x48); //unlock
W3D4(0x39,0xa5); //unlock

W3D4(0x40,R3D4(0x40)|0x1); //enable ext. reg
W3D4(0x53,R3D4(0x53)|0x8); //enable mmio
W3D4(0x58,R3D4(0x58)|0x3|0x10); //linear addr window

W3D4(0x59,videoaddr>>24); //linear addr
W3D4(0x5A,videoaddr>>16); //linear addr

W3D4(0x66,0x89); //enable gfx engine
W3D4(0x63,0x10); //set display fifo
}

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 5:53 am
by blackoil
I have added the DRAW | DST_24BPP flags in the fillsetup function, but still nothing happened.

I suspect the chip is not ready.

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 6:01 am
by Combuster
Still no good copy...
OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));
And for the sake of it: I assume plotting pixels manually does work?

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 6:18 am
by blackoil
there is a function S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);

It's a little complex.

Re: S3 ViRGE 2D driver

Posted: Fri May 06, 2011 6:42 am
by blackoil
oh yeah!!!

something changed on screen.

THANKS! Combuster

Code: Select all

void   S3Reset()
{
uint[512]* mmio;

mmio = videoaddr + 0x01000000;

(*mmio) [SRC_BASE/4] = 0;
(*mmio) [DEST_BASE/4] = 0;
(*mmio) [DEST_SRC_STR/4] = 640*3 | ( (640*3)<<16 );
(*mmio) [CLIP_L_R/4] = 0 | 640;
(*mmio) [CLIP_T_B/4] = 0 | 480;
}