qemu support code added
This commit is contained in:
parent
fdd2ba3095
commit
c55c099bb9
271
main.c
271
main.c
@ -88,6 +88,9 @@
|
|||||||
|
|
||||||
/* PROTOTYPES ================================================================*/
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
|
void cxls_free_ports(struct cxl_switch *s);
|
||||||
|
void cxls_free_vcss(struct cxl_switch *s);
|
||||||
|
|
||||||
/* GLOBAL VARIABLES ==========================================================*/
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
__u64 cxls_verbosity = 0;
|
__u64 cxls_verbosity = 0;
|
||||||
@ -143,9 +146,9 @@ int cxls_connect(struct cxl_port *p, struct cxl_device *d, char *dir)
|
|||||||
|
|
||||||
// Pick the lower of the two widths
|
// Pick the lower of the two widths
|
||||||
if (d->mlw < p->mlw)
|
if (d->mlw < p->mlw)
|
||||||
p->nlw = d->mlw << 4;
|
p->nlw = d->mlw;
|
||||||
else
|
else
|
||||||
p->nlw = p->mlw << 4;
|
p->nlw = p->mlw;
|
||||||
|
|
||||||
// Pick the lower of the two speeds
|
// Pick the lower of the two speeds
|
||||||
if (d->mls < p->mls)
|
if (d->mls < p->mls)
|
||||||
@ -318,11 +321,11 @@ int cxls_disconnect(struct cxl_port *p)
|
|||||||
*/
|
*/
|
||||||
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
||||||
{
|
{
|
||||||
unsigned i;
|
int rv;
|
||||||
struct cxl_port *p;
|
|
||||||
struct cxl_vcs *v;
|
|
||||||
struct cxl_switch *s;
|
struct cxl_switch *s;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
// 1: Validate inputs
|
// 1: Validate inputs
|
||||||
if (ports > CXLN_PORTS)
|
if (ports > CXLN_PORTS)
|
||||||
ports = CXLN_PORTS;
|
ports = CXLN_PORTS;
|
||||||
@ -347,20 +350,56 @@ struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
|||||||
s->ssid = 0xe1e2;
|
s->ssid = 0xe1e2;
|
||||||
s->sn = 0xa1a2a3a4a5a6a7a8;
|
s->sn = 0xa1a2a3a4a5a6a7a8;
|
||||||
s->ingress_port = 1;
|
s->ingress_port = 1;
|
||||||
s->num_ports = ports;
|
|
||||||
s->num_vcss = vcss;
|
|
||||||
s->num_vppbs = vppbs;
|
|
||||||
s->num_decoders = 42;
|
s->num_decoders = 42;
|
||||||
|
|
||||||
// Initialize Mutex
|
// Initialize Mutex
|
||||||
pthread_mutex_init(&s->mtx, NULL);
|
pthread_mutex_init(&s->mtx, NULL);
|
||||||
|
|
||||||
// 3: Initalize Ports
|
// 3: Initalize Ports
|
||||||
|
rv = cxls_init_ports(s, ports);
|
||||||
|
if ( rv != 0 )
|
||||||
|
goto end_state;
|
||||||
|
|
||||||
|
// 4: Initalize VCSs
|
||||||
|
rv = cxls_init_vcss(s, vcss, vppbs / vcss);
|
||||||
|
if ( rv != 0 )
|
||||||
|
goto end_ports;
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
end_ports:
|
||||||
|
|
||||||
|
free(s->ports);
|
||||||
|
s->ports = NULL;
|
||||||
|
|
||||||
|
end_state:
|
||||||
|
|
||||||
|
free(s);
|
||||||
|
s = NULL;
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cxls_init_ports(struct cxl_switch *s, unsigned ports)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
int rv;
|
||||||
|
struct cxl_port *p;
|
||||||
|
|
||||||
|
// Initialize variables
|
||||||
|
rv = 1;
|
||||||
|
|
||||||
|
// Free existing array if present
|
||||||
|
cxls_free_ports(s);
|
||||||
|
|
||||||
|
// Allocate memory for new array
|
||||||
s->ports = calloc(ports, sizeof(struct cxl_port));
|
s->ports = calloc(ports, sizeof(struct cxl_port));
|
||||||
if ( s->ports == NULL )
|
if ( s->ports == NULL )
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto end_state;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default port values
|
// Set default port values
|
||||||
@ -384,14 +423,46 @@ struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
|||||||
p->prsnt = 0;
|
p->prsnt = 0;
|
||||||
p->pwrctrl = 0;
|
p->pwrctrl = 0;
|
||||||
p->ld = 0;
|
p->ld = 0;
|
||||||
}
|
p->cfgspace = calloc(1, CXLN_CFG_SPACE);
|
||||||
|
|
||||||
// 4: Initalize VCSs
|
if ( p->cfgspace == NULL )
|
||||||
|
{
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto end_cfgspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s->num_ports = ports;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
end_cfgspace:
|
||||||
|
|
||||||
|
cxls_free_ports(s);
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cxls_init_vcss(struct cxl_switch *s, unsigned vcss, unsigned vppbs)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
int rv;
|
||||||
|
struct cxl_vcs *v;
|
||||||
|
|
||||||
|
rv = 1;
|
||||||
|
|
||||||
|
// Free existing array if present
|
||||||
|
cxls_free_vcss(s);
|
||||||
|
|
||||||
|
// Allocate memory for new array
|
||||||
s->vcss = calloc(vcss, sizeof(struct cxl_vcs));
|
s->vcss = calloc(vcss, sizeof(struct cxl_vcs));
|
||||||
if ( s->vcss == NULL )
|
if ( s->vcss == NULL )
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto end_ports;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default vcs values
|
// Set default vcs values
|
||||||
@ -401,52 +472,26 @@ struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
|||||||
v->vcsid = i;
|
v->vcsid = i;
|
||||||
v->state = FMVS_DISABLED;
|
v->state = FMVS_DISABLED;
|
||||||
v->uspid = 0;
|
v->uspid = 0;
|
||||||
v->num = 0;
|
v->num = vppbs / vcss;
|
||||||
|
|
||||||
// Set the vcs->vppb[] array to zero
|
// Allocate and zero memory for vppb array
|
||||||
memset(v->vppbs, 0, CXLN_VPPBS_PER_VCS * sizeof(struct cxl_vppb));
|
v->vppbs = calloc(v->num, sizeof(struct cxl_vppb));
|
||||||
}
|
|
||||||
|
|
||||||
// 5: Initalize PCIe config space register
|
// Set the default status and vppbid in each vppb entry in this vcs
|
||||||
for ( i = 0 ; i < ports ; i++ )
|
for ( int k = 0 ; k < v->num ; k++ )
|
||||||
{
|
{
|
||||||
s->ports[i].cfgspace = calloc(1, CXLN_CFG_SPACE);
|
v->vppbs[k].vppbid = k;
|
||||||
if(s->vcss == NULL)
|
v->vppbs[k].bind_status = FMBS_UNBOUND;
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto end_cfgspace;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s->num_vcss = vcss;
|
||||||
|
s->num_vppbs = vppbs;
|
||||||
|
|
||||||
goto end;
|
rv = 0;
|
||||||
|
|
||||||
end_cfgspace:
|
|
||||||
|
|
||||||
for ( i = 0 ; i < ports ; i++ )
|
|
||||||
{
|
|
||||||
if( s->ports[i].cfgspace != NULL )
|
|
||||||
{
|
|
||||||
free(s->ports[i].cfgspace);
|
|
||||||
s->ports[i].cfgspace = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(s->vcss);
|
|
||||||
s->vcss = NULL;
|
|
||||||
|
|
||||||
end_ports:
|
|
||||||
|
|
||||||
free(s->ports);
|
|
||||||
s->ports = NULL;
|
|
||||||
|
|
||||||
end_state:
|
|
||||||
|
|
||||||
free(s);
|
|
||||||
s = NULL;
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
return s;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -465,8 +510,8 @@ end:
|
|||||||
*/
|
*/
|
||||||
void cxls_free(struct cxl_switch *s)
|
void cxls_free(struct cxl_switch *s)
|
||||||
{
|
{
|
||||||
unsigned i, k;
|
unsigned i;
|
||||||
struct cxl_port *p;
|
|
||||||
struct cxl_device *d;
|
struct cxl_device *d;
|
||||||
|
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
@ -475,6 +520,68 @@ void cxls_free(struct cxl_switch *s)
|
|||||||
// 1: Destroy mutex
|
// 1: Destroy mutex
|
||||||
pthread_mutex_destroy(&s->mtx);
|
pthread_mutex_destroy(&s->mtx);
|
||||||
|
|
||||||
|
cxls_free_ports(s);
|
||||||
|
|
||||||
|
// 6: Free VCSs & vppbs
|
||||||
|
cxls_free_vcss(s);
|
||||||
|
|
||||||
|
// 8: Free devices
|
||||||
|
if ( s->devices != NULL )
|
||||||
|
{
|
||||||
|
for ( i = 0 ; i < s->len_devices ; i++ )
|
||||||
|
{
|
||||||
|
d = &s->devices[i];
|
||||||
|
|
||||||
|
// Free device name string if present
|
||||||
|
if ( d->name != NULL )
|
||||||
|
{
|
||||||
|
free(d->name);
|
||||||
|
d->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free device pcie config space if present
|
||||||
|
if ( d->cfgspace != NULL )
|
||||||
|
{
|
||||||
|
free(d->cfgspace);
|
||||||
|
d->cfgspace = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free device MLD if present
|
||||||
|
if ( d->mld != NULL)
|
||||||
|
{
|
||||||
|
free(d->mld);
|
||||||
|
d->mld = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s->devices);
|
||||||
|
s->devices = NULL;
|
||||||
|
}
|
||||||
|
s->len_devices = 0;
|
||||||
|
s->num_devices = 0;
|
||||||
|
|
||||||
|
// 9: Free Switch State
|
||||||
|
if ( s->dir != NULL )
|
||||||
|
{
|
||||||
|
free(s->dir);
|
||||||
|
s->dir = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->pacc != NULL)
|
||||||
|
pci_cleanup(s->pacc);
|
||||||
|
|
||||||
|
free(s);
|
||||||
|
s = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cxls_free_ports(struct cxl_switch *s)
|
||||||
|
{
|
||||||
|
unsigned i, k;
|
||||||
|
struct cxl_port *p;
|
||||||
|
|
||||||
|
if (s->ports == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
// 2: Free pci config space memory
|
// 2: Free pci config space memory
|
||||||
for ( i = 0 ; i < s->num_ports ; i++ )
|
for ( i = 0 ; i < s->num_ports ; i++ )
|
||||||
{
|
{
|
||||||
@ -534,64 +641,28 @@ void cxls_free(struct cxl_switch *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6: Free VCSs
|
|
||||||
if ( s->vcss != NULL )
|
|
||||||
{
|
|
||||||
free(s->vcss);
|
|
||||||
s->vcss = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7: Free Ports
|
// 7: Free Ports
|
||||||
if ( s->ports != NULL )
|
if ( s->ports != NULL )
|
||||||
{
|
{
|
||||||
free(s->ports);
|
free(s->ports);
|
||||||
s->ports = NULL;
|
s->ports = NULL;
|
||||||
|
s->num_ports = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 8: Free devices
|
void cxls_free_vcss(struct cxl_switch *s)
|
||||||
if ( s->devices != NULL )
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if ( s->vcss != NULL )
|
||||||
{
|
{
|
||||||
for ( i = 0 ; i < s->len_devices ; i++ )
|
for ( i = 0 ; i < s->num_vcss ; i++)
|
||||||
{
|
if (s->vcss[i].vppbs != NULL)
|
||||||
d = &s->devices[i];
|
free(s->vcss[i].vppbs);
|
||||||
|
free(s->vcss);
|
||||||
// Free device name string if present
|
s->vcss = NULL;
|
||||||
if ( d->name != NULL )
|
s->num_vcss = 0;
|
||||||
{
|
|
||||||
free(d->name);
|
|
||||||
d->name = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free device pcie config space if present
|
|
||||||
if ( d->cfgspace != NULL )
|
|
||||||
{
|
|
||||||
free(d->cfgspace);
|
|
||||||
d->cfgspace = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free device MLD if present
|
|
||||||
if ( d->mld != NULL)
|
|
||||||
{
|
|
||||||
free(d->mld);
|
|
||||||
d->mld = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(s->devices);
|
|
||||||
s->devices = NULL;
|
|
||||||
}
|
|
||||||
s->len_devices = 0;
|
|
||||||
s->num_devices = 0;
|
|
||||||
|
|
||||||
// 9: Free Switch State
|
|
||||||
if ( s->dir != NULL )
|
|
||||||
{
|
|
||||||
free(s->dir);
|
|
||||||
s->dir = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(s);
|
|
||||||
s = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
12
main.h
12
main.h
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include <pci/pci.h>
|
||||||
|
|
||||||
/* MACROS ====================================================================*/
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
#define CXLN_LD 16
|
#define CXLN_LD 16
|
||||||
@ -118,9 +120,7 @@ struct cxl_vcs
|
|||||||
__u8 state; //!< Virtual CXL switch State [FMVS]
|
__u8 state; //!< Virtual CXL switch State [FMVS]
|
||||||
__u8 uspid; //!< USP Physical Port ID
|
__u8 uspid; //!< USP Physical Port ID
|
||||||
__u8 num; //!< Number of vPPBs
|
__u8 num; //!< Number of vPPBs
|
||||||
|
struct cxl_vppb *vppbs; //!< Array of vPPB objects
|
||||||
//!< Array of pointers to vPPB objects
|
|
||||||
struct cxl_vppb vppbs[CXLN_VPPBS_PER_VCS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,6 +153,8 @@ struct cxl_port
|
|||||||
__u8 *cfgspace; //!< Buffer representing PCIe config space
|
__u8 *cfgspace; //!< Buffer representing PCIe config space
|
||||||
struct cxl_mld *mld; //!< State for MLD
|
struct cxl_mld *mld; //!< State for MLD
|
||||||
char *device_name; //!< Name of device used to populate this port
|
char *device_name; //!< Name of device used to populate this port
|
||||||
|
|
||||||
|
struct pci_dev *dev; //!< Pointer to Physical PCI device, if running in QEMU mode
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,6 +218,8 @@ struct cxl_switch
|
|||||||
char *dir; //!< Filepath to directory for instantiated memory
|
char *dir; //!< Filepath to directory for instantiated memory
|
||||||
|
|
||||||
pthread_mutex_t mtx; //!< Mutex to control access to this object
|
pthread_mutex_t mtx; //!< Mutex to control access to this object
|
||||||
|
|
||||||
|
struct pci_access *pacc; //!< Kept so this can be cleaned up at exit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -226,6 +230,8 @@ extern __u64 cxls_verbosity;
|
|||||||
/* PROTOTYPES ================================================================*/
|
/* PROTOTYPES ================================================================*/
|
||||||
|
|
||||||
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs);
|
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs);
|
||||||
|
int cxls_init_ports(struct cxl_switch *s, unsigned ports);
|
||||||
|
int cxls_init_vcss(struct cxl_switch *s, unsigned vcss, unsigned vppbs);
|
||||||
void cxls_free (struct cxl_switch *s);
|
void cxls_free (struct cxl_switch *s);
|
||||||
|
|
||||||
int cxls_connect (struct cxl_port *p, struct cxl_device *d, char *dir);
|
int cxls_connect (struct cxl_port *p, struct cxl_device *d, char *dir);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user