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
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;
}