OSDev.org
https://forum.osdev.org/

S3 ViRGE 2D driver
https://forum.osdev.org/viewtopic.php?f=1&t=23548
Page 1 of 1

Author:  blackoil [ Thu May 05, 2011 9:27 pm ]
Post subject:  S3 ViRGE 2D driver

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:
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

Author:  Combuster [ Fri May 06, 2011 3:17 am ]
Post subject:  Re: S3 ViRGE 2D driver

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:
/* 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:
/* 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:
/* 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:
/* newmmio.h:48 */
#define S3_NEWMMIO_REGBASE   0x1000000  /* 16MB */
#define S3_NEWMMIO_REGSIZE     0x10000  /* 64KB */

You know the offset:
Code:
/* 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.

Author:  blackoil [ Fri May 06, 2011 4:36 am ]
Post subject:  Re: S3 ViRGE 2D driver

yes, i know how to make a mmio write. but nothing happened.

Code:
/* 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:
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:
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.

Author:  Combuster [ Fri May 06, 2011 5:05 am ]
Post subject:  Re: S3 ViRGE 2D driver

Code:
uint[512]*   mmio;

I get a syntax error on that, and you are apparently doing a double dereference.

Author:  blackoil [ Fri May 06, 2011 5:08 am ]
Post subject:  Re: S3 ViRGE 2D driver

ah sorry , i have my own c-ish compiler, that means uint (*mmio)[512];

Author:  Combuster [ Fri May 06, 2011 5:18 am ]
Post subject:  Re: S3 ViRGE 2D driver

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...

Author:  blackoil [ Fri May 06, 2011 5:46 am ]
Post subject:  Re: S3 ViRGE 2D driver

the statements are ok for my compiler.

Code:
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:
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
}

Author:  blackoil [ Fri May 06, 2011 5:53 am ]
Post subject:  Re: S3 ViRGE 2D driver

I have added the DRAW | DST_24BPP flags in the fillsetup function, but still nothing happened.

I suspect the chip is not ready.

Author:  Combuster [ Fri May 06, 2011 6:01 am ]
Post subject:  Re: S3 ViRGE 2D driver

Still no good copy...
Quote:
OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));


And for the sake of it: I assume plotting pixels manually does work?

Author:  blackoil [ Fri May 06, 2011 6:18 am ]
Post subject:  Re: S3 ViRGE 2D driver

there is a function S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);

It's a little complex.

Author:  blackoil [ Fri May 06, 2011 6:42 am ]
Post subject:  Re: S3 ViRGE 2D driver

oh yeah!!!

something changed on screen.

THANKS! Combuster

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

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/