1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

the device discovery alg. checks also the PCI subsystem id

This commit is contained in:
Stefan Lankes 2017-06-05 11:12:36 +02:00
parent 7ee56194d3
commit c615fdbf31
5 changed files with 32 additions and 30 deletions

View file

@ -45,10 +45,11 @@ extern "C" {
typedef struct {
uint32_t base[6];
uint32_t size[6];
uint32_t subid;
uint32_t irq;
} pci_info_t;
#define PCI_IGNORE_SUBID (0)
/** @brief Initialize the PCI environment
*/
int pci_init(void);
@ -56,7 +57,8 @@ int pci_init(void);
/** @brief Determine the IObase address and the interrupt number of a specific device
*
* @param vendor_id The device's vendor ID
* @param device_id the device's ID
* @param device_id The device's ID
* @param subystem_id The subsystem DI
* @param info Pointer to the record pci_info_t where among other the IObase address will be stored
* @param enable_bus_master If true, the bus mastering will be enabled.
*
@ -64,7 +66,7 @@ int pci_init(void);
* - 0 on success
* - -EINVAL (-22) on failure
*/
int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, pci_info_t* info, int8_t enble_bus_master);
int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t subsystem_id, pci_info_t* info, int8_t enble_bus_master);
/** @brief Print information of existing pci adapters
*

View file

@ -153,7 +153,7 @@ int pci_init(void)
return 0;
}
int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, pci_info_t* info, int8_t bus_master)
int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, uint32_t subsystem_id, pci_info_t* info, int8_t bus_master)
{
uint32_t slot, bus, i;
@ -167,13 +167,13 @@ int pci_get_device_info(uint32_t vendor_id, uint32_t device_id, pci_info_t* info
for (slot = 0; slot < MAX_SLOTS; slot++) {
if (adapters[bus][slot] != -1) {
if (((adapters[bus][slot] & 0xffff) == vendor_id) &&
(((adapters[bus][slot] & 0xffff0000) >> 16) == device_id)) {
(((adapters[bus][slot] & 0xffff0000) >> 16) == device_id) &&
(((pci_subid(bus, slot) >> 16) & subsystem_id) == subsystem_id)) {
for(i=0; i<6; i++) {
info->base[i] = pci_what_iobase(bus, slot, i);
info->size[i] = (info->base[i]) ? pci_what_size(bus, slot, i) : 0;
}
info->irq = pci_what_irq(bus, slot);
info->subid = pci_subid(bus, slot);
if (bus_master)
pci_bus_master(bus, slot);
return 0;

View file

@ -202,16 +202,16 @@ int uart_init(void)
uint32_t bar = 0;
// Searching for Intel's UART device
if (pci_get_device_info(0x8086, 0x0936, &pci_info, 1) == 0)
if (pci_get_device_info(0x8086, 0x0936, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's UART device
if (pci_get_device_info(0x1b36, 0x0002, &pci_info, 1) == 0)
if (pci_get_device_info(0x1b36, 0x0002, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's 2x UART device (pci-serial-2x)
if (pci_get_device_info(0x1b36, 0x0003, &pci_info, 1) == 0)
if (pci_get_device_info(0x1b36, 0x0003, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's 4x UART device (pci-serial-4x)
if (pci_get_device_info(0x1b36, 0x0004, &pci_info, 1) == 0)
if (pci_get_device_info(0x1b36, 0x0004, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
goto Lsuccess;
// default value of our QEMU configuration

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright 2012 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
@ -58,7 +58,7 @@ typedef struct {
uint32_t device;
} board_t;
static board_t board_tbl[] =
static board_t board_tbl[] =
{
{"Intel", "Intel E1000 (82542)", 0x8086, 0x1000},
{"Intel", "Intel E1000 (82543GC FIBER)", 0x8086, 0x1001},
@ -67,7 +67,7 @@ static board_t board_tbl[] =
{"Intel", "Intel E1000 (82544EI FIBER)", 0x8086, 0x1009},
{"Intel", "Intel E1000 (82544GC COPPER)", 0x8086, 0x100C},
{"Intel", "Intel E1000 (82544GC LOM)", 0x8086, 0x100D},
{"Intel", "Intel E1000 (82540EM)", 0x8086, 0x100E},
{"Intel", "Intel E1000 (82540EM)", 0x8086, 0x100E},
{"Intel", "Intel E1000 (82540EM LOM)", 0x8086, 0x1015},
{"Intel", "Intel E1000 (82540EP LOM)", 0x8086, 0x1016},
{"Intel", "Intel E1000 (82540EP)", 0x8086, 0x1017},
@ -132,7 +132,7 @@ static uint16_t eeprom_read(volatile uint8_t* base, uint8_t addr)
e1000_write(base, E1000_EERD, 1 | ((uint32_t)(addr) << 8));
while(!((tmp = e1000_read(base, E1000_EERD)) & (1 << 4)))
while(!((tmp = e1000_read(base, E1000_EERD)) & (1 << 4)))
udelay(1);
data = (uint16_t)((tmp >> 16) & 0xFFFF);
@ -148,7 +148,7 @@ static uint16_t eeprom_read(uint8_t* base, uint8_t addr)
e1000_write(base, E1000_EERD, 1 | ((uint32_t)(addr) << 2));
while(!((tmp = e1000_read(base, E1000_EERD)) & (1 << 1)))
while(!((tmp = e1000_read(base, E1000_EERD)) & (1 << 1)))
udelay(1);
data = (uint16_t)((tmp >> 16) & 0xFFFF);
@ -198,7 +198,7 @@ static err_t e1000if_output(struct netif* netif, struct pbuf* p)
// update the tail so the hardware knows it's ready
e1000if->tx_tail = (e1000if->tx_tail + 1) % NUM_TX_DESCRIPTORS;
e1000_write(e1000if->bar0, E1000_TDT, e1000if->tx_tail);
e1000_write(e1000if->bar0, E1000_TDT, e1000if->tx_tail);
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
@ -256,7 +256,7 @@ static void e1000_rx_inthandler(struct netif* netif)
LINK_STATS_INC(link.drop);
}
no_eop:
no_eop:
e1000if->rx_desc[e1000if->rx_tail].status = 0;
// update tail and write the value to the device
@ -333,12 +333,12 @@ err_t e1000if_init(struct netif* netif)
uint16_t tmp16, speed, cold = 0x40;
uint8_t tmp8, is64bit, mem_type, prefetch;
static uint8_t num = 0;
LWIP_ASSERT("netif != NULL", (netif != NULL));
tmp8 = 0;
while (board_tbl[tmp8].vendor_str) {
if (pci_get_device_info(board_tbl[tmp8].vendor, board_tbl[tmp8].device, &pci_info, 1) == 0)
if (pci_get_device_info(board_tbl[tmp8].vendor, board_tbl[tmp8].device, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
break;
tmp8++;
}
@ -394,7 +394,7 @@ err_t e1000if_init(struct netif* netif)
goto oom;
memset((void*) e1000if->tx_desc, 0x00, NUM_TX_DESCRIPTORS*sizeof(tx_desc_t));
LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: Found %s at mmio 0x%x (size 0x%x), irq %u\n", board_tbl[tmp8].device_str,
LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: Found %s at mmio 0x%x (size 0x%x), irq %u\n", board_tbl[tmp8].device_str,
pci_info.base[0] & ~0xF, pci_info.size[0], e1000if->irq));
//LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: Map iobase to %p\n", e1000if->bar0));
LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: is64bit %u, prefetch %u\n", is64bit, prefetch));
@ -439,7 +439,7 @@ err_t e1000if_init(struct netif* netif)
// transmit buffer length; NUM_TX_DESCRIPTORS 16-byte descriptors
e1000_write(e1000if->bar0, E1000_TDLEN , (uint32_t)(NUM_TX_DESCRIPTORS * sizeof(tx_desc_t)));
// setup head and tail pointers
e1000_write(e1000if->bar0, E1000_TDH, 0);
e1000_write(e1000if->bar0, E1000_TDT, 0);
@ -472,7 +472,7 @@ err_t e1000if_init(struct netif* netif)
tmp32 = 0;
for(tmp8=0; tmp8<2; tmp8++)
((uint8_t*) &tmp32)[tmp8] = netif->hwaddr[tmp8+4];
e1000_write(e1000if->bar0, E1000_RA+4, tmp32 | (1 << 31)); // set also AV bit to check incoming packets
e1000_write(e1000if->bar0, E1000_RA+4, tmp32 | (1 << 31)); // set also AV bit to check incoming packets
/* Zero out the other receive addresses. */
for (tmp8=1; tmp8<16; tmp8++) {

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
* RWTH Aachen University
*
@ -68,7 +68,7 @@ typedef struct {
uint32_t device;
} board_t;
static board_t board_tbl[] =
static board_t board_tbl[] =
{
{"RealTek", "RealTek RTL8139", 0x10ec, 0x8139},
{"RealTek", "RealTek RTL8129 Fast Ethernet", 0x10ec, 0x8129},
@ -307,7 +307,7 @@ err_t rtl8139if_init(struct netif* netif)
tmp8 = 0;
while (board_tbl[tmp8].vendor_str) {
if (pci_get_device_info(board_tbl[tmp8].vendor, board_tbl[tmp8].device, &pci_info, 1) == 0)
if (pci_get_device_info(board_tbl[tmp8].vendor, board_tbl[tmp8].device, PCI_IGNORE_SUBID, &pci_info, 1) == 0)
break;
tmp8++;
}
@ -388,8 +388,8 @@ err_t rtl8139if_init(struct netif* netif)
outportb(rtl8139if->iobase + CR, CR_RST);
/*
* The RST bit must be checked to make sure that the chip has finished the reset.
* If the RST bit is high (1), then the reset is still in operation.
* The RST bit must be checked to make sure that the chip has finished the reset.
* If the RST bit is high (1), then the reset is still in operation.
*/
udelay(10000);
tmp16 = 10000;
@ -419,7 +419,7 @@ err_t rtl8139if_init(struct netif* netif)
outportb(rtl8139if->iobase + CONFIG1, 0);
// disable driver loaded and lanwake bits, turn driver loaded bit back on
outportb(rtl8139if->iobase + CONFIG1,
outportb(rtl8139if->iobase + CONFIG1,
(inportb(rtl8139if->iobase + CONFIG1) & ~(CONFIG1_DVRLOAD | CONFIG1_LWACT)) | CONFIG1_DVRLOAD);
// unlock config register
@ -430,7 +430,7 @@ err_t rtl8139if_init(struct netif* netif)
* AB - Accept Broadcast: Accept broadcast packets sent to mac ff:ff:ff:ff:ff:ff
* AM - Accept Multicast: Accept multicast packets.
* APM - Accept Physical Match: Accept packets send to NIC's MAC address.
* AAP - Accept All Packets. Accept all packets (run in promiscuous mode).
* AAP - Accept All Packets. Accept all packets (run in promiscuous mode).
*/
outportl(rtl8139if->iobase + RCR, RCR_MXDMA2|RCR_MXDMA1|RCR_MXDMA0|RCR_AB|RCR_AM|RCR_APM|RCR_AAP); // The WRAP bit isn't set!
@ -456,7 +456,7 @@ err_t rtl8139if_init(struct netif* netif)
if (tmp16 & BMCR_SPD1000)
speed = 1000;
else if (tmp16 & BMCR_SPD100)
speed = 100;
speed = 100;
else
speed = 10;
// Enable Receive and Transmitter