SiS driver: Fix compilation with -fPIC; implement sane OS check for SSE

support.
This commit is contained in:
Thomas Winischhofer
2004-10-29 10:35:16 +00:00
parent 64bfe79b6a
commit 43f68e100d
3 changed files with 95 additions and 62 deletions

View File

@@ -153,6 +153,10 @@
#endif
#endif
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(6,8,2,0,0)
#define SISCHECKOSSSE /* Check OS for SSE; requires SigIll facility */
#endif
#undef SIS315DRI /* define this if dri is adapted for 315/330 series */
/* For SiS315/550/650/740/330/660 - these should be moved elsewhere! */
@@ -1026,6 +1030,9 @@ typedef struct {
Bool OverruleRanges;
Bool BenchMemCpy;
vidCopyFunc SiSFastVidCopy;
#ifndef SISCHECKOSSSE
Bool XvSSEMemcpy;
#endif
#ifdef SIS_NEED_MAP_IOP
CARD32 IOPAddress; /* I/O port physical address */
unsigned char * IOPBase; /* I/O port linear address */

View File

@@ -498,11 +498,13 @@ static unsigned int taketime(void) /* get current time (for benchmarking) */
unsigned int eax;
__asm__ volatile (
" pushl %%ebx\n"
" cpuid\n"
" .byte 0x0f, 0x31\n"
" rdtsc\n"
" popl %%ebx\n"
: "=a" (eax)
: "0"(0)
: "ebx", "ecx", "edx", "cc");
: "0" (0)
: "ecx", "edx", "cc");
return(eax);
}
@@ -519,11 +521,13 @@ static unsigned int taketime(void) /* get current time (for benchmarking) */
unsigned int eax;
__asm__ volatile (
" pushq %%rbx\n"
" cpuid\n"
" rdtsc\n"
" popq %%rbx\n"
: "=a" (eax)
: "0" (0)
: "rbx", "rcx", "rdx", "cc");
: "rcx", "rdx", "cc");
return(eax);
}
@@ -747,6 +751,62 @@ static unsigned int SiS_ParseCPUFlags(char *cpuinfo, SISMCFuncData *MCFunctions)
/* Arch-specific routines */
/**********************************************************************/
#if defined(__i386__) || defined (__AMD64__) /* Common i386, AMD64 */
#ifdef SISCHECKOSSSE
static jmp_buf sigill_return;
static void sigill_handler(void)
{
longjmp(sigill_return, 1);
}
#endif
static Bool CheckOSforSSE(ScrnInfoPtr pScrn)
{
#ifdef SISCHECKOSSSE
int signo = -1;
#ifdef SISDGBMC
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking OS SSE support\n");
#endif
xf86InterceptSigIll(&sigill_handler);
if(setjmp(sigill_return)) {
signo = 4;
} else {
__asm__ __volatile__ (" xorps %xmm0, %xmm0\n");
/* __asm__ __volatile__ (" .byte 0xff\n"); */ /* For test */
}
xf86InterceptSigIll(NULL);
#ifdef SISDGBMC
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OS SSE support signal %d\n", signo);
#endif
if(signo != -1) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"OS does not support SSE instructions\n");
}
return (signo >= 0) ? FALSE : TRUE;
#else
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Checking OS for SSE support is supported in X.org 6.8.2 and later.\n");
if(pSiS->XvSSEMemcpy) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"If you get a signal 4 here, set the option \"XvSSEMemcpy\" to \"off\".\n");
return TRUE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"If your OS supports SSE, you can set the option \"XvSSEMemcpy\" to \"on\".\n");
return FALSE;
}
#endif
}
#endif /* i386, AMD64 */
#ifdef __i386__ /* i386 *************************************/
PREFETCH_FUNC(SiS_sse,SSE,SSE,,FENCE,small_memcpy_i386)
@@ -852,42 +912,6 @@ static int SiS_GetCpuFeatures(void)
return flags;
}
static Bool CheckOSforSSE(ScrnInfoPtr pScrn)
{
int signo;
#ifdef SISDGBMC
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking OS SSE support\n");
#endif
/* The following does not work yet: If sig 4 is catched, that
* idiotic signal handler just "return"s, and causes an immediate
* second sig 4 since the "return" returns to the beginning of the
* illegal instruction. Need to find a way to install my own signal
* handler here, and use a setjmp/longjmp method...
*/
xf86InterceptSignals(&signo);
__asm__ __volatile__ (" xorps %xmm0, %xmm0\n");
xf86InterceptSignals(NULL);
#ifdef SISDGBMC
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "OS SSE support signal %d\n", signo);
#endif
if(signo == 4) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"OS does not support SSE instructions\n");
} else if(signo >= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Checking SSE instructions caused signal %d - this should not happen!\n",
signo);
}
return (signo >= 0) ? FALSE : TRUE;
}
#elif defined(__AMD64__) /* AMD64 ************************* */
PREFETCH_FUNC(SiS_sse,SSE,SSE,,FENCE,small_memcpy_amd64)
@@ -907,28 +931,6 @@ static int SiS_GetCpuFeatures(void)
return((int)(FL_SSE));
}
static Bool CheckOSforSSE(ScrnInfoPtr pScrn)
{
int signo;
xf86InterceptSignals(&signo);
__asm__ __volatile__ (" xorps %xmm0, %xmm0\n");
xf86InterceptSignals(NULL);
if(signo == 4) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"OS does not support SSE/MMXEXT instructions\n");
} else if(signo >= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Checking SSE/MMXEXT instructions caused signal %d - this should not happen!\n",
signo);
}
return (signo >= 0) ? FALSE : TRUE;
}
#else /* Other archs ************************************* */
/* Fill in here */

View File

@@ -116,6 +116,9 @@ typedef enum {
OPTION_XVDEFDISABLEGFXLR,
OPTION_XVMEMCPY,
OPTION_XVBENCHCPY,
#ifndef SISCHECKOSSSE
OPTION_XVSSECOPY,
#endif
OPTION_XVUSECHROMAKEY,
OPTION_XVCHROMAMIN,
OPTION_XVCHROMAMAX,
@@ -240,6 +243,9 @@ static const OptionInfoRec SISOptions[] = {
{ OPTION_XVDISABLECOLORKEY, "XvDisableColorKey", OPTV_BOOLEAN, {0}, -1 },
{ OPTION_XVMEMCPY, "XvUseMemcpy", OPTV_BOOLEAN, {0}, -1 },
{ OPTION_XVBENCHCPY, "XvBenchmarkMemcpy", OPTV_BOOLEAN, {0}, -1 },
#ifndef SISCHECKOSSSE
{ OPTION_XVSSECOPY, "XvSSEMemcpy", OPTV_BOOLEAN, {0}, -1 },
#endif
{ OPTION_XVDEFAULTADAPTOR, "XvDefaultAdaptor", OPTV_STRING, {0}, -1 },
{ OPTION_SCALELCD, "ScaleLCD", OPTV_BOOLEAN, {0}, -1 },
{ OPTION_CENTERLCD, "CenterLCD", OPTV_BOOLEAN, {0}, -1 },
@@ -392,6 +398,9 @@ SiSOptions(ScrnInfoPtr pScrn)
pSiS->HWCursorIsVisible = FALSE;
pSiS->OverruleRanges = TRUE;
pSiS->BenchMemCpy = TRUE;
#ifndef SISCHECKOSSSE
pSiS->XvSSEMemcpy = FALSE;
#endif
#ifdef SISMERGED
pSiS->MergedFB = pSiS->MergedFBAuto = FALSE;
pSiS->CRT2Position = sisRightOf;
@@ -858,6 +867,11 @@ SiSOptions(ScrnInfoPtr pScrn)
if(xf86GetOptValBool(pSiS->Options, OPTION_XVBENCHCPY, &val)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "XvBenchmarkMemcpy");
}
#ifndef SISCHECKOSSSE
if(xf86GetOptValBool(pSiS->Options, OPTION_XVSSECOPY, &val)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mystring, "XvSSEMemcpy");
}
#endif
#ifdef SIS_CP
SIS_CP_OPT_DH_WARN
#endif
@@ -1582,6 +1596,16 @@ SiSOptions(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Xv: Will %sbenchmark memcpy() methods\n",
val ? "" : "not ");
#ifndef SISCHECKOSSSE
if(val) {
if(xf86GetOptValBool(pSiS->Options, OPTION_XVSSECOPY, &val)) {
pSiS->XvSSEMemcpy = val ? TRUE : FALSE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Xv: Will %scheck SSE memcpy()\n",
val ? "" : "not ");
}
}
#endif
}
} else pSiS->BenchMemCpy = FALSE;
}