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