intel/dev: Support INTEL_FORCE_PROBE env-var
This environment variable allows some Intel devices that are unsupported to be forced to run. These devices have incomplete support, and therefore might not work at all. Reworks: * José: Simplify scan_for_force_probe() with strtok() Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: José Roberto de Souza <jose.souza@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29273>
This commit is contained in:
@@ -1333,6 +1333,69 @@ intel_device_info_update_cs_workgroup_threads(struct intel_device_info *devinfo)
|
||||
MIN2(devinfo->max_cs_threads, 64);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_force_probe_entry(int pci_id, const char *entry, bool *force_on,
|
||||
bool *force_off)
|
||||
{
|
||||
const char *cp = entry;
|
||||
|
||||
bool negated = *cp == '!';
|
||||
if (negated)
|
||||
cp++;
|
||||
|
||||
if (*cp == '\0')
|
||||
return false;
|
||||
|
||||
bool wildcard = *cp == '*';
|
||||
long val = 0;
|
||||
|
||||
if (wildcard) {
|
||||
cp++;
|
||||
} else {
|
||||
char *end;
|
||||
val = strtol(cp, &end, 16);
|
||||
if (end == cp)
|
||||
return false;
|
||||
cp = end;
|
||||
}
|
||||
|
||||
if (*cp != '\0')
|
||||
return false;
|
||||
|
||||
bool matched = wildcard || (long)pci_id == val;
|
||||
if (matched) {
|
||||
*force_on = !negated;
|
||||
*force_off = negated;
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
static void
|
||||
scan_for_force_probe(int pci_id, bool *force_on, bool *force_off)
|
||||
{
|
||||
*force_on = false;
|
||||
*force_off = false;
|
||||
|
||||
const char *env = getenv("INTEL_FORCE_PROBE");
|
||||
if (env == NULL)
|
||||
return;
|
||||
|
||||
size_t len = strlen(env);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
char *dup = strndup(env, len);
|
||||
if (dup == NULL)
|
||||
return;
|
||||
|
||||
for (char *entry = strtok(dup, ","); entry; entry = strtok(NULL, ","))
|
||||
parse_force_probe_entry(pci_id, entry, force_on, force_off);
|
||||
|
||||
free(dup);
|
||||
assert(!*force_on || !*force_off);
|
||||
}
|
||||
|
||||
struct device_init_config {
|
||||
bool require_force_probe;
|
||||
};
|
||||
@@ -1383,8 +1446,23 @@ intel_device_info_init_common(int pci_id,
|
||||
strncpy(devinfo->name, "Intel Unknown", sizeof(devinfo->name));
|
||||
}
|
||||
|
||||
if (device_config.require_force_probe)
|
||||
bool force_on = false;
|
||||
bool force_off = false;
|
||||
scan_for_force_probe(pci_id, &force_on, &force_off);
|
||||
if (force_off) {
|
||||
mesa_logw("%s (0x%x) disabled with INTEL_FORCE_PROBE", devinfo->name,
|
||||
pci_id);
|
||||
return false;
|
||||
} else if (device_config.require_force_probe) {
|
||||
if (force_on) {
|
||||
mesa_logw("Forcing probe of unsupported: %s (0x%x)", devinfo->name,
|
||||
pci_id);
|
||||
} else {
|
||||
mesa_loge("%s (0x%x) requires INTEL_FORCE_PROBE", devinfo->name,
|
||||
pci_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
devinfo->pci_device_id = pci_id;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#undef NDEBUG
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "intel_device_info.h"
|
||||
@@ -21,7 +22,12 @@ main(int argc, char *argv[])
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(chipsets); i++) {
|
||||
struct intel_device_info devinfo = { 0, };
|
||||
char force_probe[10];
|
||||
int len = snprintf(force_probe, sizeof force_probe, "%x",
|
||||
chipsets[i].pci_id);
|
||||
assert(len < sizeof force_probe);
|
||||
|
||||
setenv("INTEL_FORCE_PROBE", force_probe, 1);
|
||||
assert(intel_get_device_info_from_pci_id(chipsets[i].pci_id, &devinfo));
|
||||
|
||||
verify_device_info(&devinfo);
|
||||
|
||||
Reference in New Issue
Block a user