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

Reply via email to