Compare commits

...

2 Commits

Author SHA1 Message Date
3183117718 PCI_BAR_IOBASE() macro for bit extraction 2025-11-29 00:19:02 +01:00
436f29bec9 Get rid of PCI register size map 2025-11-29 00:08:31 +01:00
5 changed files with 56 additions and 62 deletions

View File

@@ -31,10 +31,10 @@ void pci_ata_init(void) {
uint16_t iobase, ctrlbase; uint16_t iobase, ctrlbase;
uint64_t ps; uint64_t ps;
uint32_t bar0 = pci_read(dev, PCI_BAR0); uint32_t bar0 = pci_read32(dev, PCI_BAR0);
uint32_t bar1 = pci_read(dev, PCI_BAR1); uint32_t bar1 = pci_read32(dev, PCI_BAR1);
uint32_t bar2 = pci_read(dev, PCI_BAR2); uint32_t bar2 = pci_read32(dev, PCI_BAR2);
uint32_t bar3 = pci_read(dev, PCI_BAR3); uint32_t bar3 = pci_read32(dev, PCI_BAR3);
LOG("pci", "ATA bar0=0x%x, bar1=0x%x, bar2=0x%x, bar3=0x%x\n", bar0, bar1, bar2, bar3); LOG("pci", "ATA bar0=0x%x, bar1=0x%x, bar2=0x%x, bar3=0x%x\n", bar0, bar1, bar2, bar3);

View File

@@ -9,49 +9,64 @@
#include "kprintf.h" #include "kprintf.h"
static PciDev PCI_DEV_ZERO = {0}; static PciDev PCI_DEV_ZERO = {0};
uint32_t PCI_SIZE_MAP[100] = {0};
uint32_t pci_read(PciDev dev, uint32_t field) { uint32_t pci_read32(PciDev dev, uint32_t field) {
dev.fieldnum = (field & 0xFC) >> 2; dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1; dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits); io_out32(PCI_CFG_ADDR, dev.bits);
uint32_t size = PCI_SIZE_MAP[field]; return io_in32(PCI_CFG_DATA);
uint8_t u8; uint16_t u16; uint32_t u32;
switch (size) {
case 1:
u8 = io_in8(PCI_CFG_DATA + (field & 0x3));
return (uint32_t)u8;
case 2:
u16 = io_in16(PCI_CFG_DATA + (field & 0x2));
return (uint32_t)u16;
case 4:
u32 = io_in32(PCI_CFG_DATA);
return u32;
default:
return 0xFFFF;
}
} }
void pci_write(PciDev dev, uint32_t field, uint32_t v) { uint16_t pci_read16(PciDev dev, uint32_t field) {
dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits);
return io_in16(PCI_CFG_DATA + (field & 0x2));
}
uint8_t pci_read8(PciDev dev, uint32_t field) {
dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits);
return io_in8(PCI_CFG_DATA + (field & 0x3));
}
void pci_write32(PciDev dev, uint32_t field, uint32_t v) {
dev.fieldnum = (field & 0xFC) >> 2; dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1; dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits); io_out32(PCI_CFG_ADDR, dev.bits);
io_out32(PCI_CFG_DATA, v); io_out32(PCI_CFG_DATA, v);
} }
void pci_write16(PciDev dev, uint32_t field, uint16_t v) {
dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits);
io_out16(PCI_CFG_DATA, v);
}
void pci_write8(PciDev dev, uint32_t field, uint8_t v) {
dev.fieldnum = (field & 0xFC) >> 2;
dev.enable = 1;
io_out32(PCI_CFG_ADDR, dev.bits);
io_out8(PCI_CFG_DATA, v);
}
uint32_t pci_devtype(PciDev dev) { uint32_t pci_devtype(PciDev dev) {
uint32_t a = pci_read(dev, PCI_CLASS) << 8; uint32_t a = pci_read8(dev, PCI_CLASS) << 8;
uint32_t b = pci_read(dev, PCI_SUBCLASS); uint32_t b = pci_read8(dev, PCI_SUBCLASS);
return a | b; return a | b;
} }
uint32_t pci_scndrybus(PciDev dev) { uint32_t pci_scndrybus(PciDev dev) {
return pci_read(dev, PCI_SCNDRY_BUS); return pci_read8(dev, PCI_SCNDRY_BUS);
} }
uint32_t pci_isend(PciDev dev) { uint32_t pci_isend(PciDev dev) {
return !(pci_read(dev, PCI_HDRTYPE)); return !(pci_read8(dev, PCI_HDRTYPE));
} }
PciDev pci_scanfn(uint16_t vendorid, uint16_t deviceid, uint32_t bus, PciDev pci_scanfn(uint16_t vendorid, uint16_t deviceid, uint32_t bus,
@@ -66,8 +81,8 @@ PciDev pci_scanfn(uint16_t vendorid, uint16_t deviceid, uint32_t bus,
pci_scanbus(vendorid, deviceid, pci_scndrybus(dev), devtype); pci_scanbus(vendorid, deviceid, pci_scndrybus(dev), devtype);
} }
if (devtype == -1 || (uint32_t)devtype == pci_devtype(dev)) { if (devtype == -1 || (uint32_t)devtype == pci_devtype(dev)) {
uint32_t venid = pci_read(dev, PCI_VENDORID); uint32_t venid = pci_read16(dev, PCI_VENDORID);
uint32_t devid = pci_read(dev, PCI_DEVICEID); uint32_t devid = pci_read16(dev, PCI_DEVICEID);
if (devid == deviceid && venid == vendorid) { if (devid == deviceid && venid == vendorid) {
return dev; return dev;
@@ -93,7 +108,7 @@ PciDev pci_scandev(uint16_t vendorid, uint16_t deviceid,
dev.busnum = bus; dev.busnum = bus;
dev.devnum = device; dev.devnum = device;
if (pci_read(dev, PCI_VENDORID) == 0xFFFF) { if (pci_read16(dev, PCI_VENDORID) == 0xFFFF) {
return PCI_DEV_ZERO; return PCI_DEV_ZERO;
} }
@@ -107,7 +122,7 @@ PciDev pci_scandev(uint16_t vendorid, uint16_t deviceid,
} }
for (uint32_t fn = 1; fn < PCI_FN_PER_DEV; fn++) { for (uint32_t fn = 1; fn < PCI_FN_PER_DEV; fn++) {
if (pci_read(dev, PCI_VENDORID) != 0xFFFF) { if (pci_read16(dev, PCI_VENDORID) != 0xFFFF) {
d = pci_scanfn(vendorid, deviceid, bus, device, fn, devtype); d = pci_scanfn(vendorid, deviceid, bus, device, fn, devtype);
if (d.bits) { if (d.bits) {
return d; return d;
@@ -132,7 +147,7 @@ PciDev pci_getdev(uint16_t vendorid, uint16_t deviceid, int devtype) {
PciDev d2; memset(&d2, 0, sizeof(d2)); PciDev d2; memset(&d2, 0, sizeof(d2));
d2.fnnum = fn; d2.fnnum = fn;
if (pci_read(d2, PCI_VENDORID) == 0xFFFF) { if (pci_read16(d2, PCI_VENDORID) == 0xFFFF) {
break; break;
} }
@@ -145,28 +160,6 @@ PciDev pci_getdev(uint16_t vendorid, uint16_t deviceid, int devtype) {
return PCI_DEV_ZERO; return PCI_DEV_ZERO;
} }
void pci_init_size_map(void) {
PCI_SIZE_MAP[PCI_VENDORID] = 2;
PCI_SIZE_MAP[PCI_DEVICEID] = 2;
PCI_SIZE_MAP[PCI_CMD] = 2;
PCI_SIZE_MAP[PCI_STATUS] = 2;
PCI_SIZE_MAP[PCI_SUBCLASS] = 1;
PCI_SIZE_MAP[PCI_CLASS] = 1;
PCI_SIZE_MAP[PCI_CACHELINESZ] = 1;
PCI_SIZE_MAP[PCI_LTNCY_TIMER] = 1;
PCI_SIZE_MAP[PCI_HDRTYPE] = 1;
PCI_SIZE_MAP[PCI_BIST] = 1;
PCI_SIZE_MAP[PCI_BAR0] = 4;
PCI_SIZE_MAP[PCI_BAR1] = 4;
PCI_SIZE_MAP[PCI_BAR2] = 4;
PCI_SIZE_MAP[PCI_BAR3] = 4;
PCI_SIZE_MAP[PCI_BAR4] = 4;
PCI_SIZE_MAP[PCI_BAR5] = 4;
PCI_SIZE_MAP[PCI_INTRLINE] = 1;
PCI_SIZE_MAP[PCI_SCNDRY_BUS] = 1;
}
PciInitFn PCI_INIT_ARRAY[PCI_INIT_ARRAY_MAX] = { PciInitFn PCI_INIT_ARRAY[PCI_INIT_ARRAY_MAX] = {
&pci_ata_init, &pci_ata_init,
&pci_qemu_pci_serial_init, &pci_qemu_pci_serial_init,
@@ -180,6 +173,5 @@ void pci_init_devs(void) {
} }
void pci_init(void) { void pci_init(void) {
pci_init_size_map();
pci_init_devs(); pci_init_devs();
} }

View File

@@ -48,8 +48,14 @@ typedef union {
#define PCI_DEV_PER_BUS 32 #define PCI_DEV_PER_BUS 32
#define PCI_FN_PER_DEV 32 #define PCI_FN_PER_DEV 32
uint32_t pci_read(PciDev dev, uint32_t field); #define PCI_BAR_IOBASE(bar) ((bar) & 0xFFFFFFFC)
void pci_write(PciDev dev, uint32_t field, uint32_t v);
uint32_t pci_read32(PciDev dev, uint32_t field);
uint16_t pci_read16(PciDev dev, uint32_t field);
uint8_t pci_read8(PciDev dev, uint32_t field);
void pci_write32(PciDev dev, uint32_t field, uint32_t v);
void pci_write16(PciDev dev, uint32_t field, uint16_t v);
void pci_write8(PciDev dev, uint32_t field, uint8_t v);
uint32_t pci_devtype(PciDev dev); uint32_t pci_devtype(PciDev dev);
uint32_t pci_scndrybus(PciDev dev); uint32_t pci_scndrybus(PciDev dev);
uint32_t pci_isend(PciDev dev); uint32_t pci_isend(PciDev dev);

View File

@@ -158,14 +158,13 @@ void pci_qemu_pci_serial_init(void) {
return; return;
} }
uint32_t bar0 = pci_read(dev, PCI_BAR0); uint32_t bar0 = pci_read32(dev, PCI_BAR0);
LOG("pci", "QEMU_PCI_SERIAL bar0=0x%x\n", bar0); LOG("pci", "QEMU_PCI_SERIAL bar0=0x%x\n", bar0);
uint16_t iobase = bar0 & 0xFFFFFFFC; uint16_t iobase = PCI_BAR_IOBASE(bar0);
LOG("pci", "QEMU_PCI_SERIAL iobase=0x%x\n", iobase); LOG("pci", "QEMU_PCI_SERIAL iobase=0x%x\n", iobase);
QEMU_PCI_SERIAL_DEV._magic = QEMU_PCI_SERIAL_MAGIC;
QEMU_PCI_SERIAL_DEV.iobase = iobase; QEMU_PCI_SERIAL_DEV.iobase = iobase;
QEMU_PCI_SERIAL_DEV.lockstate = -1; QEMU_PCI_SERIAL_DEV.lockstate = -1;

View File

@@ -4,10 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#define QEMU_PCI_SERIAL_MAGIC 0x1234
typedef struct { typedef struct {
uint32_t _magic;
uint16_t iobase; uint16_t iobase;
int lockstate; int lockstate;
} QemuPciSerialDev; } QemuPciSerialDev;