qemu support code added

This commit is contained in:
Grant Mackey 2024-04-22 19:14:14 -07:00
parent fdd2ba3095
commit c55c099bb9
2 changed files with 182 additions and 105 deletions

271
main.c
View File

@ -88,6 +88,9 @@
/* PROTOTYPES ================================================================*/
void cxls_free_ports(struct cxl_switch *s);
void cxls_free_vcss(struct cxl_switch *s);
/* GLOBAL VARIABLES ==========================================================*/
__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
if (d->mlw < p->mlw)
p->nlw = d->mlw << 4;
p->nlw = d->mlw;
else
p->nlw = p->mlw << 4;
p->nlw = p->mlw;
// Pick the lower of the two speeds
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)
{
unsigned i;
struct cxl_port *p;
struct cxl_vcs *v;
int rv;
struct cxl_switch *s;
rv = 0;
// 1: Validate inputs
if (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->sn = 0xa1a2a3a4a5a6a7a8;
s->ingress_port = 1;
s->num_ports = ports;
s->num_vcss = vcss;
s->num_vppbs = vppbs;
s->num_decoders = 42;
// Initialize Mutex
pthread_mutex_init(&s->mtx, NULL);
// 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));
if ( s->ports == NULL )
{
errno = ENOMEM;
goto end_state;
goto end;
}
// Set default port values
@ -384,14 +423,46 @@ struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
p->prsnt = 0;
p->pwrctrl = 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));
if ( s->vcss == NULL )
{
errno = ENOMEM;
goto end_ports;
goto end;
}
// Set default vcs values
@ -401,52 +472,26 @@ struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
v->vcsid = i;
v->state = FMVS_DISABLED;
v->uspid = 0;
v->num = 0;
v->num = vppbs / vcss;
// Set the vcs->vppb[] array to zero
memset(v->vppbs, 0, CXLN_VPPBS_PER_VCS * sizeof(struct cxl_vppb));
}
// Allocate and zero memory for vppb array
v->vppbs = calloc(v->num, sizeof(struct cxl_vppb));
// 5: Initalize PCIe config space register
for ( i = 0 ; i < ports ; i++ )
{
s->ports[i].cfgspace = calloc(1, CXLN_CFG_SPACE);
if(s->vcss == NULL)
// Set the default status and vppbid in each vppb entry in this vcs
for ( int k = 0 ; k < v->num ; k++ )
{
errno = ENOMEM;
goto end_cfgspace;
v->vppbs[k].vppbid = k;
v->vppbs[k].bind_status = FMBS_UNBOUND;
}
}
s->num_vcss = vcss;
s->num_vppbs = vppbs;
goto end;
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;
rv = 0;
end:
return s;
return rv;
}
/**
@ -465,8 +510,8 @@ end:
*/
void cxls_free(struct cxl_switch *s)
{
unsigned i, k;
struct cxl_port *p;
unsigned i;
struct cxl_device *d;
if (s == NULL)
@ -475,6 +520,68 @@ void cxls_free(struct cxl_switch *s)
// 1: Destroy mutex
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
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
if ( s->ports != NULL )
{
free(s->ports);
s->ports = NULL;
s->num_ports = 0;
}
}
// 8: Free devices
if ( s->devices != NULL )
void cxls_free_vcss(struct cxl_switch *s)
{
unsigned i;
if ( s->vcss != 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;
for ( i = 0 ; i < s->num_vcss ; i++)
if (s->vcss[i].vppbs != NULL)
free(s->vcss[i].vppbs);
free(s->vcss);
s->vcss = NULL;
s->num_vcss = 0;
}
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;
}
/**

14
main.h
View File

@ -22,6 +22,8 @@
#include <linux/types.h>
#include <pci/pci.h>
/* MACROS ====================================================================*/
#define CXLN_LD 16
@ -118,9 +120,7 @@ struct cxl_vcs
__u8 state; //!< Virtual CXL switch State [FMVS]
__u8 uspid; //!< USP Physical Port ID
__u8 num; //!< Number of vPPBs
//!< Array of pointers to vPPB objects
struct cxl_vppb vppbs[CXLN_VPPBS_PER_VCS];
struct cxl_vppb *vppbs; //!< Array of vPPB objects
};
/**
@ -153,6 +153,8 @@ struct cxl_port
__u8 *cfgspace; //!< Buffer representing PCIe config space
struct cxl_mld *mld; //!< State for MLD
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
};
/**
@ -215,7 +217,9 @@ struct cxl_switch
__u8 mls; //!< Maximum Link Speed [FMMS]
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 ================================================================*/
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);
int cxls_connect (struct cxl_port *p, struct cxl_device *d, char *dir);