On Thu, Dec 09, 2021 at 10:01:30PM -0700, Ted Bullock wrote: > On 2021-12-09 6:46 p.m., Ted Bullock wrote: > > On 2021-12-06 4:21 p.m., Ted Bullock wrote: > > I think that there is an bug triggered by endian code here: > > > >> radeondrm0: RV100 > >> BIOS signature incorrect 0 0 > > > > in sys/dev/pci/drm/radeon/radeon_bios.c:840 > > > > if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { > > printk("BIOS signature incorrect %x %x\n", rdev->bios[0], > > rdev->bios[1]); > > goto free_bios; > > } > > > > I'm pretty sure that on sparc those bytes aren't going to be reporting > > the same information as on a little endian machine. Or am I crazy and > > wrong... > > > > Indeed, I'm correct about there being an endian bug here. > > I wrote some testing printfs to determine the code path since I'm still > an uneducated peasant who doesn't understand ddb. At least part of the > problem for this card/system, starts with the following code: > > function: radeon_read_bios in sys/dev/pci/drm/radeon/radeon_bios.c:157 > > I added a test around the memcpy where the cards bios is copied to a > buffer rdev->bios and printed the first 8 bytes. > > printk("radeon bios header: %x %x %x %x %x %x %x %x\n", > bios[0], > bios[1], > bios[2], > bios[3], > bios[4], > bios[5], > bios[6], > bios[7]); > > rdev->bios = kmalloc(size, GFP_KERNEL); > memcpy(rdev->bios, bios, size); > > printk("buffered bios header: %x %x %x %x %x %x %x %x\n", > rdev->bios[0], > rdev->bios[1], > rdev->bios[2], > rdev->bios[3], > rdev->bios[4], > rdev->bios[5], > rdev->bios[6], > rdev->bios[7]); > > On the following boot I see this: > > Rebooting with command: boot > Boot device: disk File and args: > OpenBSD IEEE 1275 Bootblock 2.1 > ..>> OpenBSD BOOT 1.22 > Trying bsd... > > <SNIP> > > radeondrm0: RV100 > radeon bios header: 55 aa 34 0 0 0 0 0 > buffered bios header: 0 0 0 0 0 34 aa 55 > BIOS signature incorrect 0 0 > [drm] *ERROR* radeon: ring test failed (scratch(0x15E4)=0xCAFEDEAD) > [drm] *ERROR* radeon: cp isn't working (-22). > drm:pid0:r100_startup *ERROR* failed initializing CP (-22). > drm:pid0:r100_init *ERROR* Disabling GPU acceleration > [drm] *ERROR* Wait for CP idle timeout, shutting down CP. > Failed to wait GUI idle while programming pipes. Bad things might happen. > radeondrm0: 1280x1024, 8bpp > wsdisplay1 at radeondrm0 mux 1 > wsdisplay1: screen 0 added (std, sun emulation) > Bogus possible_clones: [ENCODER:45:TMDS-45] possible_clones=0x6 (full encoder > mask=0x7) > Bogus possible_clones: [ENCODER:46:TV-46] possible_clones=0x5 (full encoder > mask=0x7) > Bogus possible_clones: [ENCODER:48:DAC-48] possible_clones=0x3 (full encoder > mask=0x7) > > Thoughts folks? This is clearly going to impact all big endian + radeon gear. > > Actually, I bet that the macppc platform has the same problem too.
sparc64 maps pci little endian, I don't think macppc does can you try the following? Index: sys/dev/pci/drm/amd/amdgpu/amdgpu_bios.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_bios.c,v retrieving revision 1.4 diff -u -p -r1.4 amdgpu_bios.c --- sys/dev/pci/drm/amd/amdgpu/amdgpu_bios.c 7 Jul 2021 02:38:22 -0000 1.4 +++ sys/dev/pci/drm/amd/amdgpu/amdgpu_bios.c 10 Dec 2021 07:41:39 -0000 @@ -200,7 +200,6 @@ bool amdgpu_read_bios(struct amdgpu_devi #else bool amdgpu_read_bios(struct amdgpu_device *adev) { - uint8_t __iomem *bios; size_t size; pcireg_t address, mask; bus_space_handle_t romh; @@ -218,25 +217,15 @@ bool amdgpu_read_bios(struct amdgpu_devi size = PCI_ROM_SIZE(mask); if (size == 0) return false; - rc = bus_space_map(adev->memt, PCI_ROM_ADDR(address), size, - BUS_SPACE_MAP_LINEAR, &romh); + rc = bus_space_map(adev->memt, PCI_ROM_ADDR(address), size, 0, &romh); if (rc != 0) { printf(": can't map PCI ROM (%d)\n", rc); return false; } - bios = (uint8_t *)bus_space_vaddr(adev->memt, romh); - if (!bios) { - printf(": bus_space_vaddr failed\n"); - return false; - } adev->bios = kzalloc(size, GFP_KERNEL); - if (adev->bios == NULL) { - bus_space_unmap(adev->memt, romh, size); - return false; - } adev->bios_size = size; - memcpy_fromio(adev->bios, bios, size); + bus_space_read_region_1(adev->memt, romh, 0, adev->bios, size); bus_space_unmap(adev->memt, romh, size); if (!check_atom_bios(adev->bios, size)) { Index: sys/dev/pci/drm/radeon/radeon_bios.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon_bios.c,v retrieving revision 1.18 diff -u -p -r1.18 radeon_bios.c --- sys/dev/pci/drm/radeon/radeon_bios.c 12 Aug 2020 04:58:49 -0000 1.18 +++ sys/dev/pci/drm/radeon/radeon_bios.c 10 Dec 2021 07:41:52 -0000 @@ -89,7 +89,6 @@ static bool igp_read_bios_from_vram(stru #else static bool igp_read_bios_from_vram(struct radeon_device *rdev) { - uint8_t __iomem *bios; bus_size_t size = 256 * 1024; /* ??? */ bus_space_handle_t bsh; bus_space_tag_t bst = rdev->memt; @@ -100,26 +99,19 @@ static bool igp_read_bios_from_vram(stru rdev->bios = NULL; - if (bus_space_map(bst, rdev->fb_aper_offset, size, BUS_SPACE_MAP_LINEAR, &bsh) != 0) + if (bus_space_map(bst, rdev->fb_aper_offset, size, 0, &bsh) != 0) return false; - bios = bus_space_vaddr(rdev->memt, bsh); - if (bios == NULL) { - bus_space_unmap(bst, bsh, size); - return false; - } - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - bus_space_unmap(bst, bsh, size); - return false; - } - rdev->bios = kmalloc(size, GFP_KERNEL); - if (rdev->bios == NULL) { - bus_space_unmap(bst, bsh, size); + bus_space_read_region_1(rdev->memt, bsh, 0, rdev->bios, size); + bus_space_unmap(bst, bsh, size); + + if (size == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { + kfree(rdev->bios); + rdev->bios = NULL; return false; } - memcpy_fromio(rdev->bios, bios, size); - bus_space_unmap(bst, bsh, size); + return true; } #endif @@ -156,7 +148,6 @@ static bool radeon_read_bios(struct rade #else static bool radeon_read_bios(struct radeon_device *rdev) { - uint8_t __iomem *bios; bus_size_t size; pcireg_t address, mask; bus_space_handle_t romh; @@ -174,27 +165,22 @@ static bool radeon_read_bios(struct rade size = PCI_ROM_SIZE(mask); if (size == 0) return false; - rc = bus_space_map(rdev->memt, PCI_ROM_ADDR(address), size, - BUS_SPACE_MAP_LINEAR, &romh); + rc = bus_space_map(rdev->memt, PCI_ROM_ADDR(address), size, 0, &romh); if (rc != 0) { printf(": can't map PCI ROM (%d)\n", rc); return false; } - bios = (uint8_t *)bus_space_vaddr(rdev->memt, romh); - if (!bios) { - printf(": bus_space_vaddr failed\n"); - return false; - } - - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) - goto fail; + rdev->bios = kmalloc(size, GFP_KERNEL); - memcpy(rdev->bios, bios, size); + bus_space_read_region_1(rdev->memt, romh, 0, rdev->bios, size); bus_space_unmap(rdev->memt, romh, size); + + if (size == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { + kfree(rdev->bios); + rdev->bios = NULL; + return false; + } return true; -fail: - bus_space_unmap(rdev->memt, romh, size); - return false; } #endif