PCI: expose BAR sizes
This commit is contained in:
parent
9e4312453d
commit
2488cc6442
|
@ -38,6 +38,7 @@ PRIVATE struct {
|
|||
int hook_id; /* IRQ hook ID */
|
||||
int mode; /* datalink mode */
|
||||
char *base; /* base address of memory-mapped registers */
|
||||
u32_t size; /* size of memory-mapped area */
|
||||
u32_t hwaddr[2]; /* MAC address, in register representation */
|
||||
|
||||
u8_t *txd_base; /* local address of TxD ring buffer base */
|
||||
|
@ -514,7 +515,7 @@ PRIVATE void atl2_init(int devind)
|
|||
/* Initialize the device.
|
||||
*/
|
||||
u32_t bar;
|
||||
int r;
|
||||
int r, flag;
|
||||
|
||||
/* Initialize global state. */
|
||||
state.devind = devind;
|
||||
|
@ -524,12 +525,13 @@ PRIVATE void atl2_init(int devind)
|
|||
|
||||
memset(&state.stat, 0, sizeof(state.stat));
|
||||
|
||||
bar = pci_attr_r32(devind, PCI_BAR) & 0xfffffff0;
|
||||
if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK)
|
||||
panic("unable to retrieve bar: %d", r);
|
||||
|
||||
/* FIXME: hardcoded length, as PCI doesn't expose the size, and it is
|
||||
* not our job to compute the size from the BAR ourselves.
|
||||
*/
|
||||
state.base = vm_map_phys(SELF, (void *) bar, ATL2_MMAP_SIZE);
|
||||
if (state.size < ATL2_MIN_MMAP_SIZE || flag)
|
||||
panic("invalid register bar");
|
||||
|
||||
state.base = vm_map_phys(SELF, (void *) bar, state.size);
|
||||
if (state.base == MAP_FAILED)
|
||||
panic("unable to map in registers");
|
||||
|
||||
|
@ -1214,7 +1216,7 @@ PRIVATE void sef_cb_signal_handler(int signo)
|
|||
free_contig(state.rxd_base_u,
|
||||
state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE);
|
||||
|
||||
vm_unmap_phys(SELF, state.base, ATL2_MMAP_SIZE);
|
||||
vm_unmap_phys(SELF, state.base, state.size);
|
||||
|
||||
/* We cannot free the PCI device at this time. */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Attansic/Atheros L2 FastEthernet driver, by D.C. van Moolenbroek */
|
||||
|
||||
#define ATL2_MMAP_SIZE 0x40000 /* memory-mapped registers */
|
||||
#define ATL2_MIN_MMAP_SIZE 0x1608 /* min. register memory size */
|
||||
|
||||
/* The first three are configurable to a certain extent; the last is not. */
|
||||
#define ATL2_TXD_BUFSIZE 8192 /* TxD ring buffer size */
|
||||
|
|
|
@ -23,6 +23,7 @@ FORWARD _PROTOTYPE( void do_attr_r32, (message *mp) );
|
|||
FORWARD _PROTOTYPE( void do_attr_w8, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_w16, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_attr_w32, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_get_bar, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void do_rescan_bus, (message *mp) );
|
||||
FORWARD _PROTOTYPE( void reply, (message *mp, int result) );
|
||||
FORWARD _PROTOTYPE( struct rs_pci *find_acl, (int endpoint) );
|
||||
|
@ -77,6 +78,7 @@ int main(void)
|
|||
case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
|
||||
case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
|
||||
case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
|
||||
case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
|
||||
default:
|
||||
printf("PCI: got message from %d, type %d\n",
|
||||
m.m_source, m.m_type);
|
||||
|
@ -562,6 +564,32 @@ message *mp;
|
|||
}
|
||||
}
|
||||
|
||||
PRIVATE void do_get_bar(mp)
|
||||
message *mp;
|
||||
{
|
||||
int r, devind, port, ioflag;
|
||||
u32_t base, size;
|
||||
|
||||
devind= mp->BUSC_PGB_DEVIND;
|
||||
port= mp->BUSC_PGB_PORT;
|
||||
|
||||
mp->m_type= pci_get_bar_s(devind, port, &base, &size, &ioflag);
|
||||
|
||||
if (mp->m_type == OK)
|
||||
{
|
||||
mp->BUSC_PGB_BASE= base;
|
||||
mp->BUSC_PGB_SIZE= size;
|
||||
mp->BUSC_PGB_IOFLAG= ioflag;
|
||||
}
|
||||
|
||||
r= send(mp->m_source, mp);
|
||||
if (r != 0)
|
||||
{
|
||||
printf("do_get_bar: unable to send to %d: %d\n",
|
||||
mp->m_source, r);
|
||||
}
|
||||
}
|
||||
|
||||
PRIVATE void do_rescan_bus(mp)
|
||||
message *mp;
|
||||
{
|
||||
|
|
|
@ -516,6 +516,36 @@ PUBLIC char *pci_dev_name(u16_t vid, u16_t did)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* pci_get_bar_s *
|
||||
*===========================================================================*/
|
||||
PUBLIC int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size,
|
||||
int *ioflag)
|
||||
{
|
||||
int i, reg;
|
||||
|
||||
if (devind < 0 || devind >= nr_pcidev)
|
||||
return EINVAL;
|
||||
|
||||
for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
|
||||
{
|
||||
reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
|
||||
|
||||
if (reg == port)
|
||||
{
|
||||
if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
|
||||
return EINVAL;
|
||||
|
||||
*base= pcidev[devind].pd_bar[i].pb_base;
|
||||
*size= pcidev[devind].pd_bar[i].pb_size;
|
||||
*ioflag=
|
||||
!!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* pci_attr_r8_s *
|
||||
*===========================================================================*/
|
||||
|
|
|
@ -105,6 +105,8 @@ _PROTOTYPE( int pci_next_dev_a, (struct rs_pci *aclp, int *devindp,
|
|||
|
||||
_PROTOTYPE( int pci_attr_r8_s, (int devind, int port, u8_t *vp) );
|
||||
_PROTOTYPE( int pci_attr_r32_s, (int devind, int port, u32_t *vp) );
|
||||
_PROTOTYPE( int pci_get_bar_s, (int devind, int port, u32_t *base,
|
||||
u32_t *size, int *ioflag) );
|
||||
_PROTOTYPE( int pci_slot_name_s, (int devind, char **cpp) );
|
||||
_PROTOTYPE( int pci_ids_s, (int devind, u16_t *vidp, u16_t *didp) );
|
||||
|
||||
|
|
|
@ -171,6 +171,14 @@
|
|||
#define BUSC_PCI_DEL_ACL (BUSC_RQ_BASE + 18) /* Delete the ACL of a
|
||||
* driver
|
||||
*/
|
||||
#define BUSC_PCI_GET_BAR (BUSC_RQ_BASE + 19) /* Get Base Address
|
||||
* Register properties
|
||||
*/
|
||||
#define BUSC_PGB_DEVIND m2_i1 /* device index */
|
||||
#define BUSC_PGB_PORT m2_i2 /* port (BAR offset) */
|
||||
#define BUSC_PGB_BASE m2_l1 /* BAR base address */
|
||||
#define BUSC_PGB_SIZE m2_l2 /* BAR size */
|
||||
#define BUSC_PGB_IOFLAG m2_i1 /* I/O space? */
|
||||
#define IOMMU_MAP (BUSC_RQ_BASE + 32) /* Ask IOMMU to map
|
||||
* a segment of memory
|
||||
*/
|
||||
|
|
|
@ -250,6 +250,8 @@ _PROTOTYPE( char *pci_dev_name, (u16_t vid, u16_t did) );
|
|||
_PROTOTYPE( char *pci_slot_name, (int devind) );
|
||||
_PROTOTYPE( int pci_set_acl, (struct rs_pci *rs_pci) );
|
||||
_PROTOTYPE( int pci_del_acl, (endpoint_t proc_ep) );
|
||||
_PROTOTYPE( int pci_get_bar, (int devind, int port, u32_t *base,
|
||||
u32_t *size, int *ioflag) );
|
||||
|
||||
/* Profiling. */
|
||||
_PROTOTYPE( int sys_sprof, (int action, int size, int freq,
|
||||
|
|
|
@ -17,6 +17,7 @@ SRCS= \
|
|||
pci_dev_name.c \
|
||||
pci_find_dev.c \
|
||||
pci_first_dev.c \
|
||||
pci_get_bar.c \
|
||||
pci_ids.c \
|
||||
pci_init.c \
|
||||
pci_init1.c \
|
||||
|
|
38
lib/libsys/pci_get_bar.c
Normal file
38
lib/libsys/pci_get_bar.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
pci_get_bar.c
|
||||
*/
|
||||
|
||||
#include "pci.h"
|
||||
#include "syslib.h"
|
||||
#include <minix/sysutil.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* pci_get_bar *
|
||||
*===========================================================================*/
|
||||
PUBLIC int pci_get_bar(devind, port, base, size, ioflag)
|
||||
int devind;
|
||||
int port;
|
||||
u32_t *base;
|
||||
u32_t *size;
|
||||
int *ioflag;
|
||||
{
|
||||
int r;
|
||||
message m;
|
||||
|
||||
m.m_type= BUSC_PCI_GET_BAR;
|
||||
m.BUSC_PGB_DEVIND= devind;
|
||||
m.BUSC_PGB_PORT= port;
|
||||
|
||||
r= sendrec(pci_procnr, &m);
|
||||
if (r != 0)
|
||||
panic("pci_get_bar: can't talk to PCI: %d", r);
|
||||
|
||||
if (m.m_type == 0)
|
||||
{
|
||||
*base= m.BUSC_PGB_BASE;
|
||||
*size= m.BUSC_PGB_SIZE;
|
||||
*ioflag= m.BUSC_PGB_IOFLAG;
|
||||
}
|
||||
return m.m_type;
|
||||
}
|
||||
|
Loading…
Reference in a new issue