Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Apr 2020 13:24:05 +0200
From:      Niclas Zeising <zeising@freebsd.org>
To:        Alexey Dokuchaev <danfe@nsu.ru>, x11@freebsd.org
Subject:   Re: GPU firmware naming and problems with loading
Message-ID:  <8990dbd6-65b7-81f4-e0c5-4541e34afee2@freebsd.org>
In-Reply-To: <20200421090909.GB13384@regency.nsu.ru>
References:  <20200421090909.GB13384@regency.nsu.ru>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------55C6910B5155581F623CCC4E
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

On 2020-04-21 11:09, Alexey Dokuchaev via freebsd-x11 wrote:
> Hi there,
> 
> While trying to understand why anything other than `graphics/drm-legacy-kmod'
> port locks my laptop hard on "kldload radeonkms", I've noticed the different
> output during loading of the firmware:
> 
> With graphics/drm-legacy-kmod:
> 
>     info: [drm] Loading ARUBA Microcode
> 2x radeon/ARUBA_pfp.bin: could not load firmware image, error 2
>     drmn0: Successfully loaded firmware image with name (mapped name):
>     radeon/ARUBA_pfp.bin (radeon_ARUBA_pfp_bin)
> 2x radeon/ARUBA_me.bin: could not load firmware image, error 2
>     drmn0: Successfully loaded firmware image with name (mapped name):
>     radeon/ARUBA_me.bin (radeon_ARUBA_me_bin)
> 2x radeon/ARUBA_rlc.bin: could not load firmware image, error 2
>     drmn0: Successfully loaded firmware image with name (mapped name):
>     radeon/ARUBA_rlc.bin (radeon_ARUBA_rlc_bin)
> 
> While graphics/drm-fbsd11.2-kmod:
> 
>     info: [drm] Loading ARUBA Microcode
> 2x radeon/ARUBA_pfp.bin: could not load firmware image, error 2
> 2x radeon/ARUBA_me.bin: could not load firmware image, error 2
> 2x radeon/ARUBA_rlc.bin: could not load firmware image, error 2
>     info: [drm] Internal thermal controller without fan control
>     info: [drm] radeon: dpm initialized
> 2x radeon/TAHITI_uvd.bin: could not load firmware image, error 2
> 2x radeon/TAHITI_vce.bin: could not load firmware image, error 2
> 
> Looks as new DRM code tries to load `/boot/modules/radeon/ARUBA_pfp.bin.ko'
> et al., does not find them, and locks up the system, while the legacy code
> would try to replace the slash with underscore to generate "mapped name",
> which works (since /boot/modules/radeon_ARUBA_pfp_bin.ko does exist).
> 
> Can we please decide on the firmware layout, fix this naming/search bug
> and make it universal across all DRM ports, at the very least?  How does
> this even works for other people? :-/

drm-legacy-kmod and drm-kmod uses the same firmware modules, loaded from 
the same place.  This already works.  drm-legacy-kmod was adapted to 
work with the firmware installed by gpu-firmware-kmod quite some time 
ago, it was one of the last things we did in order to have it replace 
the base kmods.

As you can see in the two prints, the "could not load firmware image", 
comes from ./sys/kern/subr_firmware.c in the base system.
The reason it appears twice, at least for drm-kmod, is that the code 
tries to load the firmware multiple times, guessing where it is.  It 
first tries radeon/TAHITI_pfp.bin twice, then replaces / and . with _ 
and tries again.

IIRC, this was done in order to handle differences between how Linux and 
FreeBSD, and AMD and Intel handles firmware and firmware names.

The relevant code can be seen in request_firmware() here: 
https://github.com/FreeBSDDesktop/kms-drm/blob/drm-v4.11-fbsd11.2/linuxkpi/gplv2/src/linux_firmware.c

I applied a patch done to later drm-kms branches that make the firmware 
loading more verbose, it is attached.  Needs to be applied with -p1, 
easiest is probably to run make extract in graphics/drm-fbsd11.2-kmod, 
then cd into WRKSRC and apply it with `patch -p1 < /path/to/patch`
then go back to graphics/drm-fbsd11.2-kmod and run make install as normal.

Please test the patch and give the output, that way we should be able to 
see how far firmware loading goes.

Regards
-- 
Niclas Zeising

--------------55C6910B5155581F623CCC4E
Content-Type: text/x-patch; charset=UTF-8;
 name="verbose.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="verbose.diff"

commit 91721a9d1071f394da064936209ccc43311ab494
Author: Johannes Lundberg <johalun0@gmail.com>
Date:   Tue Mar 20 11:10:10 2018 +0000

    lkpi: improve firmware load messages
    
    (cherry picked from commit d5e840a1679d975e3762658980a286ae9e05d550)

diff --git a/linuxkpi/gplv2/src/linux_firmware.c b/linuxkpi/gplv2/src/linux_firmware.c
index 68a4196df..e982886bf 100644
--- a/linuxkpi/gplv2/src/linux_firmware.c
+++ b/linuxkpi/gplv2/src/linux_firmware.c
@@ -27,12 +27,17 @@ request_firmware(const struct linux_firmware **lkfwp, const char *name,
 	lkfw = malloc(sizeof(*lkfw), M_LKPI_FW, M_WAITOK);
 
 	retries = 0;
+	device_printf(device->bsddev, "try to load firmware with "
+	    "name: %s\n", name);
 	fw = firmware_get(name);
 	if (fw == NULL) {
 		pause("fwwait", hz/2);
+		device_printf(device->bsddev, "retry to load firmware "
+		    "with name: %s\n", name);
 		fw = firmware_get(name);
 	}
-	if (fw == NULL && ((index(name, '/') != NULL) || (index(name, '.') != NULL))) {
+	if (fw == NULL &&
+	    ((index(name, '/') != NULL) || (index(name, '.') != NULL))) {
 		mapped_name = strdup(name, M_LKPI_FW);
 		if (mapped_name == NULL) {
 			rc = -ENOMEM;
@@ -43,14 +48,22 @@ request_firmware(const struct linux_firmware **lkfwp, const char *name,
 		while ((pindex = index(mapped_name, '.')) != NULL)
 			*pindex = '_';
 		if (linker_reference_module(mapped_name, NULL, &result)) {
-			device_printf(device->bsddev, "failed to load firmware image %s\n", mapped_name);
+			device_printf(device->bsddev, "failed to link firmware "
+			    "module with mapped name: %s\n", mapped_name);
 			rc = -ENOENT;
 			goto fail;
 		}
+		device_printf(device->bsddev, "successfully linked firmware "
+		    "module with mapped name: %s\n", mapped_name);
 	retry:
 		pause("fwwait", hz/4);
+		device_printf(device->bsddev, "try (%d) to load firmware "
+		    "image with name: %s\n", retries, name);
 		fw = firmware_get(name);
 		if (fw == NULL) {
+			device_printf(device->bsddev, "try (%d) to load "
+			    "firmware image with mapped name: %s\n",
+			    retries, name);
 			fw = firmware_get(mapped_name);
 			if (fw == NULL) {
 				if (retries++ < 10)
@@ -64,13 +77,17 @@ request_firmware(const struct linux_firmware **lkfwp, const char *name,
 #endif
 	}
 	if (fw == NULL) {
-		device_printf(device->bsddev, "failed to load firmware image %s\n", name);
+		device_printf(device->bsddev, "failed to load firmware "
+		    "image with name: %s\n", name);
 		if (mapped_name)
-			device_printf(device->bsddev, "failed to load firmware image %s\n", mapped_name);
+			device_printf(device->bsddev, "failed to load firmware "
+			    "image with mapped name: %s\n", mapped_name);
 		rc = -ENOENT;
 		goto fail;
 	}
 
+	device_printf(device->bsddev, "successfully loaded firmware "
+	    "image with name: %s\n", name);
 
 	free(mapped_name, M_LKPI_FW);
 	lkfw->priv = __DECONST(void *, fw);

--------------55C6910B5155581F623CCC4E--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8990dbd6-65b7-81f4-e0c5-4541e34afee2>