tech-x11 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: s3 doesn't work on non i386/amd64



On Thu, 17 Nov 2022 10:48:50 -0500, Michael wrote:

> Hello,
> 
> On Tue, 15 Nov 2022 17:21:34 -0000 (UTC)
> T <bobs%thelibertytree.org@localhost> wrote:
> 
>> > Xorg stopped working for me after upgrading from NetBSD 8.x to 9.x
>> > and hasn't worked since, it always segfaults. There is the Xorg log
>> > output posted on the port-prep mailing list, although it does not
>> > really provide any specific clues to the root cause. I've recently
>> > used GDB on Xorg with debug sets and believe the problem was
>> > introduced when some changes were made to the s3 driver and a few
>> > related files. The backtrace output is also on the port-prep mailing
>> > list.
>> > 
>> > The flow is:
>> > vgaHWSetStdFuncs(hwp) ->
>> > ci_legacy_open_io(hwp->dev, 0, 64 * 1024) ->
>> > !pci_sys->methods->open_legacy_io(ret, dev, base, size) -> resolves
>> > to:
>> > pci_device_netbsd_open_legacy_io(...)
>> > 
>> > ...
> 
> Hmm, the driver unconditionally calls vgaHWSetStdFuncs(). On non-x86 it
> should really use vgaHWSetMmioFuncs(hwp, ioBase, 0), assuming the
> earlier call to xf86EnableIO() succeeded. You should see something like
> this in your Xorg.0.log:
> 
> [   152.103] (--) using VT number 5 [   152.111] (WW) xf86EnableIO 9 [  
> 152.111] (II) xf86EnableIO: 0xfca00000 [   152.111] (EE) xf86BusConfig:
> hwaccess 1 [   152.111] (WW) xf86EnableIO 9 [   152.112] (EE)
> xf86BusConfig: 1 drivers [   152.112] (EE) trying nv
> 
There are two areas in the Xorg log file that look similar to that, 
although that one looks similar to the second one here:
---...---
[   567.681] (II) Loader magic: 0x1ac2e5c
[   567.681] (II) Module ABI versions:
[   567.682] 	X.Org ANSI C Emulation: 0.4
[   567.682] 	X.Org Video Driver: 24.0
[   567.682] 	X.Org XInput driver : 24.1
[   567.683] 	X.Org Server Extension : 10.0
[   567.694] (WW) xf86EnableIO -1
[   567.695] (II) xf86EnableIO: 0xffffffff
[   567.696] (WW) Can't map IO space! (9)
[   567.698] (--) PCI:*(0@0:14:0) 5333:88c1:0000:0000 rev 0, Mem @ 
0x00000000/8388608, BIOS @ 0x????????/65536
[   567.701] (II) LoadModule: "glx"
---...---
[   567.805] (II) S3: driver (version 0.6.3 for S3 chipset: 864-0, 864-1, 
964-0, 964-1,
	968, Trio32/64, Aurora64V+, Trio64UV+, Trio64V2/DX/GX
[   567.812] (--) Using wscons driver
[   567.812] (WW) xf86EnableIO 7
[   567.813] (II) xf86EnableIO: 0xfca30000
[   567.813] (WW) Falling back to old probe method for s3
[   567.817] (--) Assigning device section with no busID to primary device
[   567.818] (--) Chipset 864-1 found
---...---

The first one looks like it might be of concern when comparing it to Xorg 
log output from when the original effort was made to get s3 working on 
prep.
https://mail-index.netbsd.org/port-prep/2009/01/09/msg000035.html

(--) PCI:*(0:0:0) S3 Inc. 86c864 [Vision 864 DRAM] vers 1 rev 0, Mem @ 
0x08000000/23, BIOS @ 0x08810000/16

There's mention of a "NewMIMO" in the driver, but the chipset I have 
isn't supported by it yet, so I suspect it is (was?) using an old method 
for access.

>> 
=========================================================================
>> > 
>> > This always returns a NULL handle because the system I'm using is not
>> > i386 or amd64. This causes this to segfault:
>> > vgaHWGetIOBase(hwp) ->
>> > hwp->readMiscOut(hwp) -> resolves to:
>> > stdReadMiscOut(vgaHWPtr hwp) -> which calls:
>> > pci_io_read8(hwp->io, VGA_MISC_OUT_R) ->
>> > segfault, as hwp->io is 0x0
>> > 
>> > ...
>> 
=========================================================================
>> > 
>> > It would seem that pci_device_netbsd_open_legacy_io(...) would need
>> > to be modified to allow for non x86 systems to use the s3 driver.
> 
> Hmm, we have several non-x86 ports that access PCI IO space in Xorg,
> although none that I have access to use the S3 driver. Basically, we map
> the IO space through the console fd, that way we get the IO space the
> console lives in. I never got around to implement proper per-domain PIO
> access but in about 99.9% of all cases that's what you need. See
> hw/xfree86/os-support/bsd.ppc_video.c. That file name is a bit of a
> misnomer, it's used on a few decidedly non-ppc ports.
> 
>> I received some feedback in IRC:
>> 
>> "That function is for getting a port IO handle. Port IO itself is x86
>> centric. On archs other than x86 there generally is not a concept of
>> port IO at all, the function returns NULL if it can't get access to
>> port IO, and that can only happen via an IOPL call so when on a non-x86
>> arch it should fail. Well, there's probably other ways to access the
>> PCI I/O address space. I think it's usually mappable, and netbsd
>> probably uses it for something. I'm not sure what options userspace
>> would have for accessing it in that case though."
>> 
>> "vgaHW.c is missing error branches in the event pci_legacy_open_io
>> fails"
> 
> It should probably not fail on ports that have PCI_MAGIC_IO_RANGE since
> there we can map PCI IO automatically.
> It's defined on prep, so that part should Just Work(tm).
> 
> have fun Michael
Based on the changes shown here, and if I understand them, the s3 driver 
used to do that, but it was updated to use functions in libpciaccess
http://cvsweb.netbsd.org/bsdweb.cgi/xsrc/external/mit/xorg-server/dist/hw/
xfree86/vgahw/vgaHW.c.diff?r1=1.1.1.3&r2=1.1.1.4&f=h

I was curious to see what one of the other BSD OS do there and they 
include an IF_DEF for PCI_MAGIC_IO_RANGE, but we do not.

static struct pci_io_handle *
pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
    struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
#if defined(__i386__)
	struct i386_iopl_args ia;

	ia.iopl = 1;
	if (sysarch(I386_IOPL, &ia))
		return NULL;

	ret->base = base;
	ret->size = size;
	ret->is_legacy = 1;
	return ret;
#elif defined(__amd64__)
	struct amd64_iopl_args ia;

	ia.iopl = 1;
	if (sysarch(AMD64_IOPL, &ia))
		return NULL;

	ret->base = base;
	ret->size = size;
	ret->is_legacy = 1;
	return ret;
#elif defined(PCI_MAGIC_IO_RANGE)
	ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
	    aperturefd, PCI_MAGIC_IO_RANGE + base);
	if (ret->memory == MAP_FAILED)
		return NULL;

	ret->base = base;
	ret->size = size;
	ret->is_legacy = 1;
	return ret;
#else
	return NULL;
#endif
}



Home | Main Index | Thread Index | Old Index