amdgpu: fix ASIC detection, quirk stubs, firmware store, connector descriptors, register offsets

- Fix ASIC detection: use PCI device_id instead of broken MMIO offset-0 read.
  Add proper device_id->ASIC family lookup table covering Navi10-Navi33 (RDNA1/RDNA2/RDNA3).
  Add per-family properties (DCN revision, firmware name, OTG/HUBP base offsets, HPD register).

- Wire quirk flags from Rust to C: replace pci_get_quirk_flags/pci_has_quirk stubs
  (previously always returned 0/false) with stored quirk_flags set via new FFI
  redox_pci_set_quirk_flags(). Quirk-aware IRQ policy now actually works.

- Store firmware blobs from Rust to C: add redox_firmware_store() FFI to pass
  firmware blobs from AmdDriver.firmware HashMap into C-side storage. C side
  can now fall back to scheme:firmware if blobs not pre-stored.

- Fix connector descriptors: replace hardcoded 600x340mm fake dimensions with
  per-ASIC-family connector tables (desktop dGPU vs APU layout). Set mm_width/
  mm_height to 0 (unprobed — needs DC hardware detection). HPD register offset
  now comes from per-family asic_props table.

- Fix register offsets: replace hardcoded OTG base 0x4800 / HUBP base 0x5800
  (Navi23-specific) with per-DCN-revision dispatch from asic_props table
  (DCN2.0=0x4000/0x5000, DCN3.0=0x4800/0x5800, DCN3.2=0x5000/0x6000).
This commit is contained in:
2026-05-31 22:46:47 +03:00
parent 934ff65e2b
commit 0a3e1fa7db
5 changed files with 330 additions and 76 deletions
@@ -10,19 +10,143 @@ static u64 g_fb_phys;
static size_t g_fb_size;
static int g_asic_family = -1;
/* ASIC family definitions based on device IDs */
#define ASIC_FAMILY_NAVI10 0x7310
#define ASIC_FAMILY_NAVI14 0x7340
#define ASIC_FAMILY_NAVI21 0x73A0
#define ASIC_FAMILY_NAVI22 0x73C0
#define ASIC_FAMILY_NAVI23 0x73E0
#define ASIC_FAMILY_NAVI24 0x7420
#define ASIC_FAMILY_NAVI31 0x7440
#define ASIC_FAMILY_NAVI32 0x7480
#define ASIC_FAMILY_NAVI33 0x74A0
enum {
ASIC_NAVI10 = 1,
ASIC_NAVI14,
ASIC_NAVI12,
ASIC_NAVI21,
ASIC_NAVI22,
ASIC_NAVI23,
ASIC_NAVI24,
ASIC_NAVI31,
ASIC_NAVI32,
ASIC_NAVI33,
ASIC_MAX,
};
struct asic_props {
int family;
const char *name;
const char *dmcub_firmware;
u32 otg_base[4];
u32 hubp_base[4];
u32 hpd_status_reg;
int max_connectors;
int max_crtcs;
};
static const struct asic_props g_asic_table[] = {
[ASIC_NAVI10] = {
.family = ASIC_NAVI10, .name = "Navi10 (RDNA1)",
.dmcub_firmware = "dmcub_dcn20.bin",
.otg_base = {0x4000, 0x4800, 0x5000, 0x5800},
.hubp_base = {0x5000, 0x5400, 0x5800, 0x5c00},
.hpd_status_reg = 0x1e74, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI14] = {
.family = ASIC_NAVI14, .name = "Navi14 (RDNA1)",
.dmcub_firmware = "dmcub_dcn20.bin",
.otg_base = {0x4000, 0x4800, 0x5000, 0x5800},
.hubp_base = {0x5000, 0x5400, 0x5800, 0x5c00},
.hpd_status_reg = 0x1e74, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI12] = {
.family = ASIC_NAVI12, .name = "Navi12 (RDNA1)",
.dmcub_firmware = "dmcub_dcn20.bin",
.otg_base = {0x4000, 0x4800, 0x5000, 0x5800},
.hubp_base = {0x5000, 0x5400, 0x5800, 0x5c00},
.hpd_status_reg = 0x1e74, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI21] = {
.family = ASIC_NAVI21, .name = "Navi21 / Sienna Cichlid (RDNA2)",
.dmcub_firmware = "dmcub_dcn31.bin",
.otg_base = {0x4800, 0x5000, 0x5800, 0x6000},
.hubp_base = {0x5800, 0x5c00, 0x6000, 0x6400},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI22] = {
.family = ASIC_NAVI22, .name = "Navi22 / Navy Flounder (RDNA2)",
.dmcub_firmware = "dmcub_dcn31.bin",
.otg_base = {0x4800, 0x5000, 0x5800, 0x6000},
.hubp_base = {0x5800, 0x5c00, 0x6000, 0x6400},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI23] = {
.family = ASIC_NAVI23, .name = "Navi23 / Dimgrey Cavefish (RDNA2)",
.dmcub_firmware = "dmcub_dcn31.bin",
.otg_base = {0x4800, 0x5000, 0x5800, 0x6000},
.hubp_base = {0x5800, 0x5c00, 0x6000, 0x6400},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI24] = {
.family = ASIC_NAVI24, .name = "Navi24 / Beige Goby (RDNA2)",
.dmcub_firmware = "dmcub_dcn31.bin",
.otg_base = {0x4800, 0x5000, 0x5800, 0x6000},
.hubp_base = {0x5800, 0x5c00, 0x6000, 0x6400},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI31] = {
.family = ASIC_NAVI31, .name = "Navi31 / Plum Bonito (RDNA3)",
.dmcub_firmware = "dmcub_dcn32.bin",
.otg_base = {0x5000, 0x5800, 0x6000, 0x6800},
.hubp_base = {0x6000, 0x6400, 0x6800, 0x6c00},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI32] = {
.family = ASIC_NAVI32, .name = "Navi32 / Wheat Nas (RDNA3)",
.dmcub_firmware = "dmcub_dcn32.bin",
.otg_base = {0x5000, 0x5800, 0x6000, 0x6800},
.hubp_base = {0x6000, 0x6400, 0x6800, 0x6c00},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
[ASIC_NAVI33] = {
.family = ASIC_NAVI33, .name = "Navi33 / Hotpink Bonefish (RDNA3)",
.dmcub_firmware = "dmcub_dcn32.bin",
.otg_base = {0x5000, 0x5800, 0x6000, 0x6800},
.hubp_base = {0x6000, 0x6400, 0x6800, 0x6c00},
.hpd_status_reg = 0x4A00, .max_connectors = 4, .max_crtcs = 4,
},
};
static int asic_from_device_id(u16 device_id)
{
switch (device_id & 0xFFF0) {
case 0x7310: return ASIC_NAVI10;
case 0x7340: return ASIC_NAVI14;
case 0x7360: return ASIC_NAVI12;
case 0x73A0: return ASIC_NAVI21;
case 0x73C0: return ASIC_NAVI22;
case 0x73E0: return ASIC_NAVI23;
case 0x7420: return ASIC_NAVI24;
case 0x7440: return ASIC_NAVI31;
case 0x7480: return ASIC_NAVI32;
case 0x74A0: return ASIC_NAVI33;
default: break;
}
/* Wider ranges for variant device IDs within each family */
if (device_id >= 0x7300 && device_id < 0x7320) return ASIC_NAVI10;
if (device_id >= 0x7340 && device_id < 0x7360) return ASIC_NAVI14;
if (device_id >= 0x7360 && device_id < 0x7380) return ASIC_NAVI12;
if (device_id >= 0x73A0 && device_id < 0x73C0) return ASIC_NAVI21;
if (device_id >= 0x73C0 && device_id < 0x73E0) return ASIC_NAVI22;
if (device_id >= 0x73E0 && device_id < 0x7400) return ASIC_NAVI23;
if (device_id >= 0x7420 && device_id < 0x7440) return ASIC_NAVI24;
if (device_id >= 0x7440 && device_id < 0x7480) return ASIC_NAVI31;
if (device_id >= 0x7480 && device_id < 0x74A0) return ASIC_NAVI32;
if (device_id >= 0x74A0 && device_id < 0x74C0) return ASIC_NAVI33;
return -1;
}
static const struct asic_props *asic_props(void)
{
if (g_asic_family > 0 && g_asic_family < ASIC_MAX) {
return &g_asic_table[g_asic_family];
}
return NULL;
}
#define AMDGPU_DC_HPD_STATUS_REG 0x4A00
#define AMDGPU_DC_MAX_CONNECTORS 4
#define AMDGPU_DC_BYTES_PER_PIXEL 4U
#define AMDGPU_DC_PIXEL_FORMAT_ARGB8888 3U
@@ -63,11 +187,24 @@ struct amdgpu_redox_connector_desc {
int mm_height;
};
static const struct amdgpu_redox_connector_desc g_connector_descs[AMDGPU_DC_MAX_CONNECTORS] = {
{ .id = 1, .hpd_mask = 0x01, .connector_type = 10, .connector_type_id = 1, .encoder_id = 1, .mm_width = 600, .mm_height = 340 },
{ .id = 2, .hpd_mask = 0x02, .connector_type = 10, .connector_type_id = 2, .encoder_id = 2, .mm_width = 600, .mm_height = 340 },
{ .id = 3, .hpd_mask = 0x04, .connector_type = 11, .connector_type_id = 3, .encoder_id = 3, .mm_width = 600, .mm_height = 340 },
{ .id = 4, .hpd_mask = 0x08, .connector_type = 11, .connector_type_id = 4, .encoder_id = 4, .mm_width = 600, .mm_height = 340 },
static const struct amdgpu_redox_connector_desc g_connector_descs_desktop_dgpu[] = {
{ .id = 1, .hpd_mask = 0x01, .connector_type = 10, .connector_type_id = 1,
.encoder_id = 1, .mm_width = 0, .mm_height = 0 },
{ .id = 2, .hpd_mask = 0x02, .connector_type = 10, .connector_type_id = 2,
.encoder_id = 2, .mm_width = 0, .mm_height = 0 },
{ .id = 3, .hpd_mask = 0x04, .connector_type = 10, .connector_type_id = 3,
.encoder_id = 3, .mm_width = 0, .mm_height = 0 },
{ .id = 4, .hpd_mask = 0x08, .connector_type = 11, .connector_type_id = 4,
.encoder_id = 4, .mm_width = 0, .mm_height = 0 },
};
static const struct amdgpu_redox_connector_desc g_connector_descs_apu[] = {
{ .id = 1, .hpd_mask = 0x01, .connector_type = 11, .connector_type_id = 1,
.encoder_id = 1, .mm_width = 0, .mm_height = 0 },
{ .id = 2, .hpd_mask = 0x02, .connector_type = 10, .connector_type_id = 2,
.encoder_id = 2, .mm_width = 0, .mm_height = 0 },
{ .id = 3, .hpd_mask = 0x04, .connector_type = 14, .connector_type_id = 3,
.encoder_id = 3, .mm_width = 0, .mm_height = 0 },
};
static inline void __iomem *amdgpu_dc_reg_ptr(u32 base, u32 offset)
@@ -110,10 +247,27 @@ static inline u32 amdgpu_dc_read_reg(u32 base, u32 offset)
static inline u32 amdgpu_dc_hpd_status(void)
{
if (amdgpu_dc_validate_mmio_access(0, AMDGPU_DC_HPD_STATUS_REG) != 0) {
u32 hpd_reg;
const struct asic_props *props = asic_props();
if (!props) {
return 0;
}
return readl((u8 __iomem *)g_mmio_base + AMDGPU_DC_HPD_STATUS_REG);
hpd_reg = props->hpd_status_reg;
if (amdgpu_dc_validate_mmio_access(0, hpd_reg) != 0) {
return 0;
}
return readl((u8 __iomem *)g_mmio_base + hpd_reg);
}
static const struct amdgpu_redox_connector_desc *connector_table(int *count)
{
if (g_asic_family == ASIC_NAVI14 || g_asic_family == ASIC_NAVI33) {
*count = (int)ARRAY_SIZE(g_connector_descs_apu);
return g_connector_descs_apu;
}
*count = (int)ARRAY_SIZE(g_connector_descs_desktop_dgpu);
return g_connector_descs_desktop_dgpu;
}
static void amdgpu_redox_log_irq_expectation(u64 quirk_flags)
@@ -137,7 +291,7 @@ static void amdgpu_redox_log_irq_expectation(u64 quirk_flags)
int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
{
int ret = 0;
u32 gpu_id = 0;
u16 device_id;
const char *firmware_name = NULL;
u64 quirk_flags = 0;
@@ -148,10 +302,18 @@ int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
return -EINVAL;
}
gpu_id = readl(mmio_base);
printk("amdgpu_redox: GPU ID = %#010x\n", gpu_id);
if (!g_pci_dev) {
pr_err("amdgpu_redox: no PCI device info; call redox_pci_set_device_info first\n");
return -ENODEV;
}
if (g_pci_dev) {
device_id = g_pci_dev->device;
printk("amdgpu_redox: PCI device_id = %#06x\n", device_id);
printk("amdgpu_redox: MMIO identity register = %#010x (not used for ASIC detection)\n",
readl(mmio_base));
{
quirk_flags = pci_get_quirk_flags(g_pci_dev);
printk("amdgpu_redox: PCI %02x:%02x.%u quirk flags = %#llx\n",
g_pci_dev->bus_number,
@@ -173,51 +335,23 @@ int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
amdgpu_redox_log_irq_expectation(quirk_flags);
}
switch (gpu_id) {
case ASIC_FAMILY_NAVI10:
g_asic_family = ASIC_FAMILY_NAVI10;
firmware_name = "dmcub_dcn20.bin";
break;
case ASIC_FAMILY_NAVI14:
g_asic_family = ASIC_FAMILY_NAVI14;
firmware_name = "dmcub_dcn20.bin";
break;
case ASIC_FAMILY_NAVI21:
g_asic_family = ASIC_FAMILY_NAVI21;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI22:
g_asic_family = ASIC_FAMILY_NAVI22;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI23:
g_asic_family = ASIC_FAMILY_NAVI23;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI24:
g_asic_family = ASIC_FAMILY_NAVI24;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI31:
g_asic_family = ASIC_FAMILY_NAVI31;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI32:
g_asic_family = ASIC_FAMILY_NAVI32;
firmware_name = "dmcub_dcn31.bin";
break;
case ASIC_FAMILY_NAVI33:
g_asic_family = ASIC_FAMILY_NAVI33;
firmware_name = "dmcub_dcn31.bin";
break;
default:
pr_warn("amdgpu_redox: unknown ASIC %#010x, using DCN31 firmware\n", gpu_id);
g_asic_family = gpu_id;
firmware_name = "dmcub_dcn31.bin";
break;
g_asic_family = asic_from_device_id(device_id);
if (g_asic_family < 0) {
pr_err("amdgpu_redox: unknown AMD GPU device_id %#06x — cannot identify ASIC family\n",
device_id);
return -ENODEV;
}
printk("amdgpu_redox: ASIC family identified, loading firmware: %s\n", firmware_name);
{
const struct asic_props *props = asic_props();
if (!props) {
pr_err("amdgpu_redox: no properties for ASIC family %d\n", g_asic_family);
return -ENODEV;
}
firmware_name = props->dmcub_firmware;
printk("amdgpu_redox: identified %s, loading firmware: %s\n",
props->name, firmware_name);
}
{
const struct firmware *fw = NULL;
@@ -308,15 +442,18 @@ int amdgpu_dc_detect_connectors(void)
#ifdef __redox__
u32 hpd_status = amdgpu_dc_hpd_status();
int table_count;
const struct amdgpu_redox_connector_desc *table = connector_table(&table_count);
int i;
for (i = 0; i < AMDGPU_DC_MAX_CONNECTORS; ++i) {
if (hpd_status & g_connector_descs[i].hpd_mask) {
for (i = 0; i < table_count; ++i) {
if (hpd_status & table[i].hpd_mask) {
num_connectors++;
}
}
printk("amdgpu_redox: detected %d connector(s)\n", num_connectors);
printk("amdgpu_redox: detected %d connector(s) via HPD status %#010x\n",
num_connectors, hpd_status);
#else
printk("amdgpu_redox: running on Linux, using AMD DC detection\n");
#endif
@@ -341,11 +478,13 @@ int amdgpu_dc_get_connector_info(int idx, void *info)
#ifdef __redox__
{
u32 hpd_status = amdgpu_dc_hpd_status();
int table_count;
const struct amdgpu_redox_connector_desc *table = connector_table(&table_count);
int active_index = 0;
int i;
for (i = 0; i < AMDGPU_DC_MAX_CONNECTORS; ++i) {
const struct amdgpu_redox_connector_desc *desc = &g_connector_descs[i];
for (i = 0; i < table_count; ++i) {
const struct amdgpu_redox_connector_desc *desc = &table[i];
if (!(hpd_status & desc->hpd_mask)) {
continue;
@@ -425,10 +564,21 @@ int amdgpu_dc_set_crtc(int crtc_id, uint64_t fb_addr, uint32_t width, uint32_t h
return -EINVAL;
}
u32 otg_base = 0x4800 + (crtc_id * 0x800);
u32 hubp_base = 0x5800 + (crtc_id * 0x400);
u32 otg_base;
u32 hubp_base;
u32 otg_control;
{
const struct asic_props *props = asic_props();
if (!props || crtc_id >= props->max_crtcs) {
pr_err("amdgpu_redox: no register layout for ASIC family %d crtc %d\n",
g_asic_family, crtc_id);
return -EINVAL;
}
otg_base = props->otg_base[crtc_id];
hubp_base = props->hubp_base[crtc_id];
}
if (amdgpu_dc_validate_mmio_access(otg_base, AMDGPU_DC_OTG_VSTARTUP) != 0 ||
amdgpu_dc_validate_mmio_access(hubp_base, AMDGPU_DC_HUBP_FLIP_ADDR_HIGH) != 0) {
return -EINVAL;
@@ -244,6 +244,7 @@ extern void redox_pci_set_device_info(u16 vendor, u16 device,
u8 func_number, u8 revision, u32 irq,
u64 bar0_addr, u64 bar0_size,
u64 bar2_addr, u64 bar2_size);
extern void redox_pci_set_quirk_flags(u64 quirk_flags);
extern void redox_pci_dev_put(struct pci_dev *pdev);
extern int redox_pci_enable_device(struct pci_dev *pdev);
extern void redox_pci_set_master(struct pci_dev *pdev);
@@ -288,9 +289,11 @@ struct firmware {
extern int redox_request_firmware(const struct firmware **fw, const char *name, void *dev);
extern void redox_release_firmware(const struct firmware *fw);
extern void redox_firmware_store(const char *name, const u8 *data, size_t size);
#define request_firmware(fw, name, dev) redox_request_firmware((fw), (name), (dev))
#define release_firmware(fw) redox_release_firmware((fw))
#define firmware_store(name, data, size) redox_firmware_store((name), (data), (size))
#define dev_get_drvdata(dev) ((dev)->driver_data)
#define dev_set_drvdata(dev, data) ((dev)->driver_data = (data))
+76 -3
View File
@@ -221,8 +221,20 @@ void redox_dma_free_coherent(size_t size, void *vaddr, dma_addr_t dma_handle)
*/
static struct pci_dev g_pci_dev;
static int g_pci_dev_populated;
static u64 g_pci_quirk_flags;
#define REDOX_MAX_FIRMWARE_BYTES (64U * 1024U * 1024U)
#define REDOX_MAX_STORED_FIRMWARES 32
struct redox_stored_firmware {
char name[128];
u8 *data;
size_t size;
};
static struct redox_stored_firmware g_stored_firmware[REDOX_MAX_STORED_FIRMWARES];
static int g_stored_firmware_count;
static pthread_mutex_t g_firmware_store_lock = PTHREAD_MUTEX_INITIALIZER;
void redox_pci_set_device_info(u16 vendor, u16 device,
u8 bus_number, u8 dev_number,
@@ -299,14 +311,75 @@ void redox_pci_release_regions(struct pci_dev *pdev)
u64 pci_get_quirk_flags(struct pci_dev *pdev)
{
(void)pdev;
return 0;
return g_pci_quirk_flags;
}
bool pci_has_quirk(struct pci_dev *pdev, u64 flag)
{
(void)pdev;
(void)flag;
return false;
return (g_pci_quirk_flags & flag) != 0;
}
void redox_pci_set_quirk_flags(u64 quirk_flags)
{
g_pci_quirk_flags = quirk_flags;
printk("PCI quirk flags stored: %#llx\n", (unsigned long long)quirk_flags);
}
void redox_firmware_store(const char *name, const u8 *data, size_t size)
{
int i;
if (!name || !data || size == 0) {
return;
}
if (size > REDOX_MAX_FIRMWARE_BYTES) {
pr_err("firmware_store: blob %s too large (%zu bytes, max %u)\n",
name, size, REDOX_MAX_FIRMWARE_BYTES);
return;
}
pthread_mutex_lock(&g_firmware_store_lock);
for (i = 0; i < g_stored_firmware_count; ++i) {
if (strcmp(g_stored_firmware[i].name, name) == 0) {
free(g_stored_firmware[i].data);
g_stored_firmware[i].data = malloc(size);
if (!g_stored_firmware[i].data) {
g_stored_firmware[i].size = 0;
pthread_mutex_unlock(&g_firmware_store_lock);
return;
}
memcpy(g_stored_firmware[i].data, data, size);
g_stored_firmware[i].size = size;
pthread_mutex_unlock(&g_firmware_store_lock);
printk("firmware_store: replaced %s (%zu bytes)\n", name, size);
return;
}
}
if (g_stored_firmware_count >= REDOX_MAX_STORED_FIRMWARES) {
pr_err("firmware_store: store full (%d entries), cannot store %s\n",
g_stored_firmware_count, name);
pthread_mutex_unlock(&g_firmware_store_lock);
return;
}
i = g_stored_firmware_count;
strncpy(g_stored_firmware[i].name, name, sizeof(g_stored_firmware[i].name) - 1);
g_stored_firmware[i].name[sizeof(g_stored_firmware[i].name) - 1] = '\0';
g_stored_firmware[i].data = malloc(size);
if (!g_stored_firmware[i].data) {
g_stored_firmware[i].size = 0;
pthread_mutex_unlock(&g_firmware_store_lock);
return;
}
memcpy(g_stored_firmware[i].data, data, size);
g_stored_firmware[i].size = size;
g_stored_firmware_count++;
pthread_mutex_unlock(&g_firmware_store_lock);
printk("firmware_store: stored %s (%zu bytes)\n", name, size);
}
int redox_request_firmware(const struct firmware **fw, const char *name, void *dev)
@@ -1,4 +1,5 @@
use log::{info, warn};
use std::ffi::CString;
use std::ptr;
#[cfg(no_amdgpu_c)]
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -54,6 +55,12 @@ unsafe extern "C" {
bar2_addr: u64,
bar2_size: u64,
);
#[link_name = "redox_pci_set_quirk_flags"]
fn ffi_redox_pci_set_quirk_flags(quirk_flags: u64);
#[link_name = "redox_firmware_store"]
fn ffi_redox_firmware_store(name: *const libc::c_char, data: *const u8, size: usize);
}
#[cfg(no_amdgpu_c)]
@@ -117,6 +124,7 @@ pub fn set_pci_device_info(
bar0_size: u64,
bar2_addr: u64,
bar2_size: u64,
quirk_flags: u64,
) {
#[cfg(not(no_amdgpu_c))]
unsafe {
@@ -133,6 +141,7 @@ pub fn set_pci_device_info(
bar2_addr,
bar2_size,
);
ffi_redox_pci_set_quirk_flags(quirk_flags);
}
let _ = (
vendor,
@@ -146,9 +155,22 @@ pub fn set_pci_device_info(
bar0_size,
bar2_addr,
bar2_size,
quirk_flags,
);
}
pub fn store_firmware_blobs(firmware: &std::collections::HashMap<String, Vec<u8>>) {
#[cfg(not(no_amdgpu_c))]
for (name, data) in firmware {
if let Ok(c_name) = CString::new(name.as_str()) {
unsafe {
ffi_redox_firmware_store(c_name.as_ptr(), data.as_ptr(), data.len());
}
}
}
let _ = firmware;
}
#[cfg(not(no_amdgpu_c))]
fn amdgpu_dc_init(mmio_base: *const u8, mmio_size: usize) -> i32 {
unsafe { ffi_amdgpu_redox_init(mmio_base, mmio_size, 0, 0) }
@@ -92,6 +92,9 @@ impl AmdDriver {
}
};
let quirks = info.quirks();
let quirk_flags: u64 = quirks.bits();
display::set_pci_device_info(
info.vendor_id,
info.device_id,
@@ -104,8 +107,11 @@ impl AmdDriver {
bar0.size,
bar2.as_ref().map(|b| b.addr).unwrap_or(0),
bar2.as_ref().map(|b| b.size).unwrap_or(0),
quirk_flags,
);
display::store_firmware_blobs(&firmware);
let irq_handle = Some(InterruptHandle::setup(&info, &mut device).map_err(|e| {
DriverError::Io(format!(
"failed to setup interrupt for {}: {e}",