Release candidate
This commit is contained in:
parent
9ca25b553b
commit
88623508dc
52
Makefile
Normal file
52
Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# ******************************************************************************
|
||||
#
|
||||
# @file Makefile
|
||||
#
|
||||
# @brief Makefile for CXL State library
|
||||
#
|
||||
# @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
#
|
||||
# @date Mar 2024
|
||||
# @author Barrett Edwards <code@jrlabs.io>
|
||||
#
|
||||
# ******************************************************************************
|
||||
|
||||
CC=gcc
|
||||
CFLAGS= -g3 -O0 -Wall -Wextra
|
||||
MACROS=
|
||||
INCLUDE_DIR=/usr/local/include
|
||||
LIB_DIR=/usr/local/lib
|
||||
INCLUDE_PATH=-I $(INCLUDE_DIR)
|
||||
LIB_PATH=-L $(LIB_DIR)
|
||||
LIBS=-l fmapi -l arrayutils -l pciutils
|
||||
TARGET=cxlstate
|
||||
|
||||
all: testbench lib$(TARGET).a
|
||||
|
||||
testbench: testbench.c main.o
|
||||
$(CC) $^ $(CFLAGS) $(MACROS) $(INCLUDE_PATH) $(LIB_PATH) $(LIBS) -o $@
|
||||
|
||||
lib$(TARGET).a: main.o
|
||||
ar rcs $@ $^
|
||||
|
||||
main.o: main.c main.h
|
||||
$(CC) -c $< $(CFLAGS) $(MACROS) $(INCLUDE_PATH) -o $@
|
||||
|
||||
clean:
|
||||
rm -rf ./*.o ./*.a testbench
|
||||
|
||||
doc:
|
||||
doxygen
|
||||
|
||||
install: lib$(TARGET).a
|
||||
sudo cp lib$(TARGET).a $(LIB_DIR)/
|
||||
sudo cp main.h $(INCLUDE_DIR)/$(TARGET).h
|
||||
|
||||
.PHONY: all clean doc install
|
||||
|
||||
# Variables
|
||||
# $^ Will expand to be all the sensitivity list
|
||||
# $< Will expand to be the frist file in sensitivity list
|
||||
# $@ Will expand to be the target name (the left side of the ":" )
|
||||
# -c gcc will compile but not try and link
|
||||
611
main.c
Normal file
611
main.c
Normal file
@ -0,0 +1,611 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file cxlstate.c
|
||||
*
|
||||
* @brief Code file for CXL State library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
/* printf()
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
/* malloc()
|
||||
* free()
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
/* errno
|
||||
*/
|
||||
#include <errno.h>
|
||||
|
||||
/* pthread_mutex_t
|
||||
*/
|
||||
#include <pthread.h>
|
||||
|
||||
/* memset()
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
/* mmap()
|
||||
*/
|
||||
#include <sys/mman.h>
|
||||
|
||||
/*
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
/* fmdt()
|
||||
* fmdv()
|
||||
* fmvc()
|
||||
*/
|
||||
#include <fmapi.h>
|
||||
|
||||
#include <arrayutils.h>
|
||||
|
||||
/* pcie_prnt_cfgspace()
|
||||
*/
|
||||
#include <pciutils.h>
|
||||
|
||||
#include "cxlstate.h"
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* FUNCTIONS =================================================================*/
|
||||
|
||||
/**
|
||||
* Initialize state object with default values
|
||||
*
|
||||
* @return struct state. Returns 0 upon error and sets errno
|
||||
*
|
||||
* STEPS
|
||||
* 1: Validate inputs
|
||||
* 2: Initalize State Identity
|
||||
* 3: Initalize Ports
|
||||
* 4: Initalize VCSs
|
||||
* 5: Initalize PCIe config space register
|
||||
*/
|
||||
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs)
|
||||
{
|
||||
unsigned i;
|
||||
struct cxl_port *p;
|
||||
struct cxl_vcs *v;
|
||||
struct cxl_switch *s;
|
||||
|
||||
// 1: Validate inputs
|
||||
if (ports > CXLN_PORTS)
|
||||
ports = CXLN_PORTS;
|
||||
if (vcss > CXLN_VCSS)
|
||||
vcss = CXLN_VCSS;
|
||||
if (vppbs > CXLN_VPPBS)
|
||||
vppbs = CXLN_VPPBS;
|
||||
|
||||
// 2: Initalize State Identity
|
||||
s = calloc(1, sizeof(struct cxl_switch));
|
||||
if ( s == NULL )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Initialize Identity information
|
||||
s->version = 1;
|
||||
s->vid = 0xb1b2;
|
||||
s->did = 0xc1c2;
|
||||
s->svid = 0xd1d2;
|
||||
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
|
||||
s->ports = calloc(ports, sizeof(struct cxl_port));
|
||||
if ( s->ports == NULL )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
goto end_state;
|
||||
}
|
||||
|
||||
// Set default port values
|
||||
for ( i = 0 ; i < ports ; i++ )
|
||||
{
|
||||
p = &s->ports[i];
|
||||
p->ppid = i;
|
||||
p->state = FMPS_DISABLED;
|
||||
p->dv = FMDV_NOT_CXL;
|
||||
p->dt = FMDT_NONE;
|
||||
p->cv = 0;
|
||||
p->mlw = 16;
|
||||
p->nlw = 0;
|
||||
p->speeds = FMSS_PCIE5 | FMSS_PCIE4 | FMSS_PCIE3 | FMSS_PCIE2 | FMSS_PCIE1;
|
||||
p->mls = FMMS_PCIE5;
|
||||
p->cls = 0;
|
||||
p->ltssm = FMLS_DISABLED;
|
||||
p->lane = 0;
|
||||
p->lane_rev = 0;
|
||||
p->perst = 0;
|
||||
p->prsnt = 0;
|
||||
p->pwrctrl = 0;
|
||||
p->ld = 0;
|
||||
}
|
||||
|
||||
// 4: Initalize VCSs
|
||||
s->vcss = calloc(vcss, sizeof(struct cxl_vcs));
|
||||
if ( s->vcss == NULL )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
goto end_ports;
|
||||
}
|
||||
|
||||
// Set default vcs values
|
||||
for ( i = 0 ; i < vcss ; i++)
|
||||
{
|
||||
v = &s->vcss[i];
|
||||
v->vcsid = i;
|
||||
v->state = FMVS_DISABLED;
|
||||
v->uspid = 0;
|
||||
v->num = 0;
|
||||
|
||||
// Set the vcs->vppb[] array to zero
|
||||
memset(v->vppbs, 0, CXLN_VPPBS_PER_VCS * 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)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
goto end_cfgspace;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
end:
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free memory allocated by the CXL Switch State
|
||||
*
|
||||
* STEPS:
|
||||
* 1: Destroy Mutex
|
||||
* 2: Free pci config space memory
|
||||
* 3: Free Port MLD config space
|
||||
* 4: unmap memory space if present
|
||||
* 5: Free Port MLD
|
||||
* 6: Free VCSs
|
||||
* 7: Free ports
|
||||
* 8: Free devices
|
||||
* 9: Free Switch State
|
||||
*/
|
||||
void cxls_free(struct cxl_switch *s)
|
||||
{
|
||||
unsigned i, k;
|
||||
struct cxl_port *p;
|
||||
struct cxl_device *d;
|
||||
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
// 1: Destroy mutex
|
||||
pthread_mutex_destroy(&s->mtx);
|
||||
|
||||
// 2: Free pci config space memory
|
||||
for ( i = 0 ; i < s->num_ports ; i++ )
|
||||
{
|
||||
p = &s->ports[i];
|
||||
if ( p->cfgspace != NULL )
|
||||
{
|
||||
free(p->cfgspace);
|
||||
p->cfgspace = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 3: Free Port MLD config space
|
||||
for ( i = 0 ; i < s->num_ports ; i++ )
|
||||
{
|
||||
p = &s->ports[i];
|
||||
if ( p->mld != NULL )
|
||||
{
|
||||
for ( k = 0 ; k < CXLN_LD ; k++ )
|
||||
{
|
||||
if ( p->mld->cfgspace[k] != NULL )
|
||||
{
|
||||
free(p->mld->cfgspace[k]);
|
||||
p->mld->cfgspace[k] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4: unmap memory space if present
|
||||
for ( i = 0 ; i < s->num_ports ; i++ )
|
||||
{
|
||||
p = &s->ports[i];
|
||||
if ( p->mld != NULL )
|
||||
{
|
||||
if ( p->mld->memspace != NULL )
|
||||
{
|
||||
munmap(p->mld->memspace, p->mld->memory_size);
|
||||
p->mld->memspace = NULL;
|
||||
}
|
||||
|
||||
if ( p->mld->file != NULL )
|
||||
{
|
||||
free(p->mld->file);
|
||||
p->mld->file = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5: Free Port MLD
|
||||
for ( i = 0 ; i < s->num_ports ; i++ )
|
||||
{
|
||||
p = &s->ports[i];
|
||||
if ( p->mld != NULL )
|
||||
{
|
||||
free(p->mld);
|
||||
p->mld = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
free(s);
|
||||
s = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the CXL Switch State
|
||||
*/
|
||||
void cxls_prnt(struct cxl_switch *s)
|
||||
{
|
||||
cxls_prnt_identity(s, 0);
|
||||
cxls_prnt_ports(s, 0);
|
||||
cxls_prnt_vcss(s, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the Device List
|
||||
*/
|
||||
void cxls_prnt_devices(struct cxl_switch *s)
|
||||
{
|
||||
unsigned i;
|
||||
struct cxl_device *d;
|
||||
|
||||
if (s->devices == NULL)
|
||||
return;
|
||||
|
||||
for ( i = 0 ; i < s->num_devices ; i++ )
|
||||
{
|
||||
d = &s->devices[i];
|
||||
|
||||
printf("%s:\n", d->name);
|
||||
printf(" Port:\n");
|
||||
printf(" dt: %2d - %s\n", d->dt, fmdt(d->dt));
|
||||
printf(" dv: %2d - %s\n", d->dv, fmdv(d->dv));
|
||||
printf(" cv: %2d - %s\n", d->cv, fmvc(d->cv));
|
||||
printf(" mlw: %2d\n", d->mlw);
|
||||
|
||||
pcie_prnt_cfgspace(d->cfgspace, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the CXL Switch Idenfity Information
|
||||
*
|
||||
* @param struct cxl_switch_state* to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_identity(struct cxl_switch *s, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields
|
||||
printf("%singress_port: %u\n", space, s->ingress_port);
|
||||
printf("%snum_ports: %u\n", space, s->num_ports);
|
||||
printf("%snum_vcss: %u\n", space, s->num_vcss);
|
||||
printf("%snum_vppbs: %u\n", space, s->num_vppbs);
|
||||
printf("%snum_decoders: %u\n", space, s->num_decoders);
|
||||
printf("%sdir: %s\n", space, s->dir);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Print CXL MLD Info
|
||||
*
|
||||
* @param mld struct mld* to use to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_mld(struct cxl_mld *m, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
int i;
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
printf("%sMulti-Logical Device:\n", space);
|
||||
|
||||
space[indent] = ' ';
|
||||
space[indent+2] = 0;
|
||||
|
||||
printf("%sMemory Size 0x%016llx\n", space, m->memory_size);
|
||||
printf("%sNum LD %d\n", space, m->num);
|
||||
printf("%sEgress Port Congestion Supported %d\n", space, m->epc);
|
||||
printf("%sTemporary Throughput Reduction Supported %d\n", space, m->ttr);
|
||||
printf("%sGranularity %d - %s\n", space, m->granularity, fmmg(m->granularity));
|
||||
printf("%sEgress Port Congestion Enabled %d\n", space, m->epc_en);
|
||||
printf("%sTemporary Throughput Reduction Enabled %d\n", space, m->ttr_en);
|
||||
printf("%sEgress Moderate Percentage %d\n", space, m->egress_mod_pcnt);
|
||||
printf("%sEgress Severe Percentage %d\n", space, m->egress_sev_pcnt);
|
||||
printf("%sBackpressure Sample Interval %d\n", space, m->sample_interval);
|
||||
printf("%sReqCmpBasis %d\n", space, m->rcb);
|
||||
printf("%sCompletion Collection Interval %d\n", space, m->comp_interval);
|
||||
printf("%sBackpressure Average Percentage %d\n", space, m->bp_avg_pcnt);
|
||||
printf("%smmap %d\n", space, m->mmap);
|
||||
printf("%smmap file %s\n", space, m->file);
|
||||
printf("\n");
|
||||
printf("%sLDID Range 1 Range 2 Alloc BW BW Limit\n", space);
|
||||
printf("%s---- ------------------ ------------------ -------- --------\n", space);
|
||||
for ( i = 0 ; i < m->num ; i++ )
|
||||
printf("%s%4d: 0x%016llx 0x%016llx %8d %8d\n", space, i, m->rng1[i], m->rng2[i], m->alloc_bw[i], m->bw_limit[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print CXL Ports
|
||||
*
|
||||
* @param struct cxl_switch_stat* to use to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_ports(struct cxl_switch *s, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
int i;
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields
|
||||
printf("%sports:\n", space);
|
||||
|
||||
for ( i = 0 ; i < s->num_ports ; i++)
|
||||
{
|
||||
printf("%s %02u:\n", space,i);
|
||||
cxls_prnt_port(&s->ports[i], indent + 2 + CXLN_INDENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the CXL Port Information
|
||||
*
|
||||
* @param struct port* to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_port(struct cxl_port *p, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields
|
||||
printf("%sstate: %u\t\t%s\n", space, p->state, fmps(p->state));
|
||||
printf("%sdv: %u\t\t%s\n", space, p->dv, fmdv(p->dv));
|
||||
printf("%sdt: %u\t\t%s\n", space, p->dt, fmdt(p->dt));
|
||||
printf("%scv: 0x%02x\n", space, p->cv);
|
||||
printf("%smax_link_width: %u\n", space, p->mlw);
|
||||
printf("%sneg_link_width: %u\n", space, p->nlw);
|
||||
printf("%sspeeds: 0x%02x\n", space, p->speeds);
|
||||
printf("%smax_link_speed: %u\t\t%s\n", space, p->mls, fmms(p->mls));
|
||||
printf("%scur_link_speed: %u\t\t%s\n", space, p->cls, fmms(p->cls));
|
||||
printf("%sltssm: %u\t\t%s\n", space, p->ltssm, fmls(p->ltssm));
|
||||
printf("%sfirst_lane: %u\n", space, p->lane);
|
||||
printf("%sLane Reversal State %d\n", space, p->lane_rev);
|
||||
printf("%sPCIe Reset State %d\n", space, p->perst);
|
||||
printf("%sPort Presence pin state %d\n", space, p->prsnt);
|
||||
printf("%sPower Control State %d\n", space, p->pwrctrl);
|
||||
printf("%sld: %u\n", space, p->ld);
|
||||
printf("%sDevice Name %s\n", space, p->device_name);
|
||||
|
||||
if (p->cfgspace != NULL)
|
||||
{
|
||||
pcie_prnt_cfgspace(p->cfgspace, indent);
|
||||
autl_prnt_buf(p->cfgspace, 1024, 16, 1);
|
||||
}
|
||||
|
||||
if (p->mld != NULL)
|
||||
cxls_prnt_mld(p->mld, indent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the CXL VCS List
|
||||
*
|
||||
* @param struct cxl_switch_state* to print from
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_vcss(struct cxl_switch *s, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
int i;
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields
|
||||
printf("%svcss:\n", space);
|
||||
|
||||
for ( i = 0 ; i < s->num_vcss ; i++)
|
||||
{
|
||||
printf("%s %02u:\n", space, i);
|
||||
cxls_prnt_vcs(&s->vcss[i], indent + 2 + CXLN_INDENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print information for a single CXL VCS
|
||||
*
|
||||
* @param struct vcs* to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_vcs(struct cxl_vcs *v, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
int i;
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields of the VCS
|
||||
printf("%sstate: %u\t\t%s\n", space, v->state, fmvs(v->state));
|
||||
printf("%suspid: %u\n", space, v->uspid);
|
||||
printf("%snum_vppb: %u\n", space, v->num);
|
||||
printf("%svppbs:\n", space);
|
||||
|
||||
// Print the vPPBs of the VCS
|
||||
for ( i = 0 ; i < v->num ; i++)
|
||||
{
|
||||
printf("%s %u:\n", space, i);
|
||||
cxls_prnt_vppb(&v->vppbs[i], indent + 2 + CXLN_INDENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print information for a single CXL vPPB
|
||||
*
|
||||
* @param struct vppb* to print
|
||||
* @param indent The number of spaces to indent the printed text
|
||||
*/
|
||||
void cxls_prnt_vppb(struct cxl_vppb *b, unsigned indent)
|
||||
{
|
||||
char space[CXLN_MAX_INDENT] = " ";
|
||||
|
||||
// Handle indent
|
||||
if ( indent >= CXLN_MAX_INDENT )
|
||||
indent = CXLN_MAX_INDENT;
|
||||
space[indent] = 0;
|
||||
|
||||
// Print fields of the VCS
|
||||
printf("%sldid: %u\n", space, b->ldid);
|
||||
printf("%sppid: %u\n", space, b->ppid);
|
||||
printf("%sbind_status: %u\t\t%s\n", space, b->bind_status, fmbs(b->bind_status));
|
||||
}
|
||||
|
||||
229
main.h
Normal file
229
main.h
Normal file
@ -0,0 +1,229 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file cxlstate.h
|
||||
*
|
||||
* @brief Header file for CXL State library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CXLSTATE_H
|
||||
#define _CXLSTATE_H
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
/* pthread_mutex_t
|
||||
*/
|
||||
#include <pthread.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
#define CXLN_LD 16
|
||||
#define CXLN_PORTS 256
|
||||
#define CXLN_VCSS 256
|
||||
#define CXLN_VPPBS_PER_VCS 256
|
||||
#define CXLN_VPPBS (CXLN_PORTS * CXLN_LD)
|
||||
#define CXLN_DEVICES 128
|
||||
#define CXLN_MAX_INDENT 32
|
||||
#define CXLN_INDENT 2
|
||||
#define CXLN_CFG_SPACE 4096
|
||||
#define CXLN_FILE_NAME 256
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/**
|
||||
* Multi Logical Device Object*
|
||||
*
|
||||
* This device aggregates all the descriptors for a CXL MLD Logical Device
|
||||
*
|
||||
* CXL 2.0 v1.0 Table 111,112,113,116,117,118,119
|
||||
*/
|
||||
struct cxl_mld
|
||||
{
|
||||
/* LD Info: Table 111*/
|
||||
__u64 memory_size; //!< Total device memory capacity
|
||||
__u16 num; //!< Number of Logical Devices supported
|
||||
__u8 epc; //!< Egress Port Congestion Supported
|
||||
__u8 ttr; //!< Temporary Throughput Reduction Supported
|
||||
|
||||
/* LD Allocations: Table 112,113 */
|
||||
__u8 granularity; //!< Memory Granularity [FMMG]
|
||||
__u64 rng1[CXLN_LD]; //!< Range 1 Allocation Multiplier
|
||||
__u64 rng2[CXLN_LD]; //!< Range 2 Allocation Multiplier
|
||||
|
||||
/* LD QoS Control parameters: Table 116*/
|
||||
__u8 epc_en; //!< QoS Telem: Egress Port Congestion Enable. Bitfield [FMQT]
|
||||
__u8 ttr_en; //!< QoS Telem: Temporary Throuhput Reduction Enable. Bitfield [FMQT]
|
||||
__u8 egress_mod_pcnt; //!< Egress Moderate Percentage: Valid range 1-100. Default 10
|
||||
__u8 egress_sev_pcnt; //!< Egress Severe Percentage: Valid range 1-100. Default 25
|
||||
__u8 sample_interval; //!< Backpressure Sample Interval: Valid range is 0-15. Default 8 (800 ns of history). 0 disables
|
||||
__u16 rcb; //!< ReqCmpBasis. Valid range is 0-65,535. 0 disables. Default 0.
|
||||
__u8 comp_interval; //!< Completion Collection Interval: Valid range 0-255. Default 64
|
||||
|
||||
/* LD QoS Status: Table 117*/
|
||||
__u8 bp_avg_pcnt; //!< Backpressure Average Percentage
|
||||
|
||||
/* LD QoS Allocated BW Fractions: Table 118 */
|
||||
__u8 alloc_bw[CXLN_LD];
|
||||
|
||||
/* LD QoS BW Limit Fractions: Table 119 */
|
||||
__u8 bw_limit[CXLN_LD];
|
||||
|
||||
__u8 *cfgspace[CXLN_LD]; //!< Buffers representing PCIe config space for each logical device
|
||||
|
||||
__u8 mmap; //!< Direction to mmap a file for the memory space
|
||||
char *file; //!< Filename for mmaped file
|
||||
__u8 *memspace; //!< Buffer representing memory space for entire logical device
|
||||
};
|
||||
|
||||
/**
|
||||
* Virtual PCIe-to-PCIe Bridge Object
|
||||
*
|
||||
* CXL 2.0 v1.0 Table 99
|
||||
*/
|
||||
struct cxl_vppb
|
||||
{
|
||||
__u16 vppbid; //!< Index of this vPPB in the state->vppbs[] array
|
||||
__u8 bind_status; //!< PBB Binding Status [FMBS]
|
||||
__u8 ppid; //!< Physical port number of bound port
|
||||
__u16 ldid; //!< ID of LD bound to port from MLD on associated physical port
|
||||
};
|
||||
|
||||
/**
|
||||
* Virtual CXL Switch Object
|
||||
*
|
||||
* CXL 2.0 v1.0 Table 99
|
||||
*/
|
||||
struct cxl_vcs
|
||||
{
|
||||
__u8 vcsid; //!< VCS ID - Index of this vcs in the state->vcss[] array
|
||||
__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];
|
||||
};
|
||||
|
||||
/**
|
||||
* CXL Switch Port Object
|
||||
*
|
||||
* CXL 2.0 v1.0 Table 92
|
||||
*/
|
||||
struct cxl_port
|
||||
{
|
||||
__u8 ppid; //!< Port ID - Index of this port in the state->ports[] array
|
||||
__u8 state; //!< Current Port Configuration State [FMPS]
|
||||
__u8 dv; //!< Connected Device CXL version [FMDV]
|
||||
__u8 dt; //!< Connected device type [FMDT]
|
||||
__u8 cv; //!< Connected CXL version bitmask [FMVC]
|
||||
__u8 mlw; //!< Max Link Width. Integer number of lanes (1,2,4,8,16)
|
||||
__u8 nlw; //!< Negotiated Link Width [FMNW]
|
||||
__u8 speeds; //!< Supported Link Speeds Vector [FMSS]
|
||||
__u8 mls; //!< Maximum Link Speed [FMMS]
|
||||
__u8 cls; //!< Current Link Speed [FMMS]
|
||||
__u8 ltssm; //!< LTSSM State [FMLS]
|
||||
__u8 lane; //!< First negotiated lane number (Integer lane number)
|
||||
|
||||
/** Link State Flags [FMLF] [FMLO] */
|
||||
__u8 lane_rev; //!< Lane reversal state. 0=standard, 1=rev [FMLO]
|
||||
__u8 perst; //!< PCIe Reset State PERST#
|
||||
__u8 prsnt; //!< Port Presence pin state PRSNT#
|
||||
__u8 pwrctrl; //!< Power Control State (PWR_CTRL)
|
||||
|
||||
__u8 ld; //!< Additional supported LD Count (beyond 1)
|
||||
__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
|
||||
};
|
||||
|
||||
/**
|
||||
* CXL Device Profile
|
||||
*/
|
||||
struct cxl_device
|
||||
{
|
||||
char *name; //!< Name of device
|
||||
__u8 rootport; //!< Root Port Device. 1=root, 2=endpoint
|
||||
__u8 dv; //!< Connected Device CXL version [FMDV]
|
||||
__u8 dt; //!< Connected device type [FMDT]
|
||||
__u8 cv; //!< Connected CXL version bitmask [FMVC]
|
||||
__u8 mlw; //!< Maximum Link Width. Integer number of lanes (1,2,4,8,16)
|
||||
__u8 mls; //!< Maximum Link Speed [FMMS]
|
||||
__u8 *cfgspace; //!< Buffer representing PCIe config space
|
||||
struct cxl_mld *mld; //!< MLD info if this is an MLD
|
||||
};
|
||||
|
||||
/**
|
||||
* CXL Switch State Identify Information
|
||||
*
|
||||
* CXL 2.0 v1 Table 89
|
||||
*/
|
||||
struct cxl_switch
|
||||
{
|
||||
__u8 version; //!< Device Management Version
|
||||
|
||||
__u16 vid; //!< PCIe Vendor ID
|
||||
__u16 did; //!< PCIe Device ID
|
||||
__u16 svid; //!< PCIe Subsystem Vendor ID
|
||||
__u16 ssid; //!< PCIe Subsystem ID
|
||||
__u64 sn; //!< Device Serial Number
|
||||
__u8 max_msg_size_n; //!< Max fmapi msg size. 2^n
|
||||
|
||||
__u8 msg_rsp_limit_n; //!< Message Response Limit n of 2^n
|
||||
|
||||
__u8 bos_running; //!< Background operation status 0=none, 1=running
|
||||
__u8 bos_pcnt; //!< Background operation percent complete [0-100]
|
||||
__u16 bos_opcode; //!< Background operation opcode
|
||||
__u16 bos_rc; //!< Background operation return code
|
||||
__u16 bos_ext; //!< Background operation Extended Vendor Status
|
||||
|
||||
__u8 ingress_port; //!< Ingress Port ID
|
||||
__u8 num_ports; //!< Total number of physical ports
|
||||
__u8 num_vcss; //!< Max number of VCSs
|
||||
__u16 num_vppbs; //!< Max number of vPPBs
|
||||
__u16 active_vppbs; //!< Number of active vPPBs
|
||||
__u8 num_decoders; //!< Number of HDM decoders available per USP
|
||||
|
||||
struct cxl_port *ports; //!< array of Port objects
|
||||
struct cxl_vcs *vcss; //!< array of VCS objects
|
||||
|
||||
struct cxl_device *devices; //!< array of device definitions
|
||||
__u16 len_devices; //!< Number of entries supported in devices array
|
||||
__u16 num_devices; //!< Number of entries in devices array
|
||||
|
||||
/* Port defaults */
|
||||
__u8 mlw; //!< Max Link Width. Integer number of lanes (1,2,4,8,16)
|
||||
__u8 speeds; //!< Supported Link Speeds Vector [FMSS]
|
||||
__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
|
||||
};
|
||||
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
struct cxl_switch *cxls_init(unsigned ports, unsigned vcss, unsigned vppbs);
|
||||
|
||||
void cxls_free (struct cxl_switch *s);
|
||||
void cxls_prnt (struct cxl_switch *s);
|
||||
void cxls_prnt_identity (struct cxl_switch *s, unsigned indent);
|
||||
void cxls_prnt_devices (struct cxl_switch *s);
|
||||
void cxls_prnt_ports (struct cxl_switch *s, unsigned indent);
|
||||
void cxls_prnt_port (struct cxl_port *p, unsigned indent);
|
||||
void cxls_prnt_vcss (struct cxl_switch *s, unsigned indent);
|
||||
void cxls_prnt_vcs (struct cxl_vcs *v, unsigned indent);
|
||||
void cxls_prnt_vppb (struct cxl_vppb *b, unsigned indent);
|
||||
void cxls_prnt_mld (struct cxl_mld *m, unsigned indent);
|
||||
|
||||
#endif /* ifndef _CXLSTATE_H */
|
||||
39
testbench.c
Normal file
39
testbench.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/**
|
||||
* @file testbench.c
|
||||
*
|
||||
* @brief Testbench code file for CXL State library
|
||||
*
|
||||
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
|
||||
*
|
||||
* @date Mar 2024
|
||||
* @author Barrett Edwards <code@jrlabs.io>
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ==================================================================*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "cxlstate.h"
|
||||
|
||||
/* MACROS ====================================================================*/
|
||||
|
||||
/* ENUMERATIONS ==============================================================*/
|
||||
|
||||
/* STRUCTS ===================================================================*/
|
||||
|
||||
/* GLOBAL VARIABLES ==========================================================*/
|
||||
|
||||
/* PROTOTYPES ================================================================*/
|
||||
|
||||
int main()
|
||||
{
|
||||
struct cxl_switch *s = cxls_init(32, 32, 256);
|
||||
|
||||
cxls_prnt(s);
|
||||
|
||||
cxls_free(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user