RC1
This commit is contained in:
parent
e264bdf897
commit
fdd2ba3095
2
LICENSE
2
LICENSE
@ -58,7 +58,7 @@ APPENDIX: How to apply the Apache License to your work.
|
|||||||
|
|
||||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2024 Jackrabbit-Labs-LLC
|
Copyright 2024 Jackrabbit-Founders-LLC
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
16
Makefile
16
Makefile
@ -13,16 +13,16 @@
|
|||||||
# ******************************************************************************
|
# ******************************************************************************
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS= -g3 -O0 -Wall -Wextra
|
CFLAGS?= -g3 -O0 -Wall -Wextra
|
||||||
MACROS=
|
MACROS?=-D CXLS_VERBOSE
|
||||||
INCLUDE_DIR=/usr/local/include
|
INCLUDE_DIR?=/usr/local/include
|
||||||
LIB_DIR=/usr/local/lib
|
LIB_DIR?=/usr/local/lib
|
||||||
INCLUDE_PATH=-I $(INCLUDE_DIR)
|
INCLUDE_PATH=-I $(INCLUDE_DIR)
|
||||||
LIB_PATH=-L $(LIB_DIR)
|
LIB_PATH=-L $(LIB_DIR)
|
||||||
LIBS=-l fmapi -l arrayutils -l pciutils
|
LIBS=-l fmapi -l arrayutils -l pciutils
|
||||||
TARGET=cxlstate
|
TARGET=cxlstate
|
||||||
|
|
||||||
all: testbench lib$(TARGET).a
|
all: lib$(TARGET).a
|
||||||
|
|
||||||
testbench: testbench.c main.o
|
testbench: testbench.c main.o
|
||||||
$(CC) $^ $(CFLAGS) $(MACROS) $(INCLUDE_PATH) $(LIB_PATH) $(LIBS) -o $@
|
$(CC) $^ $(CFLAGS) $(MACROS) $(INCLUDE_PATH) $(LIB_PATH) $(LIBS) -o $@
|
||||||
@ -43,7 +43,11 @@ install: lib$(TARGET).a
|
|||||||
sudo cp lib$(TARGET).a $(LIB_DIR)/
|
sudo cp lib$(TARGET).a $(LIB_DIR)/
|
||||||
sudo cp main.h $(INCLUDE_DIR)/$(TARGET).h
|
sudo cp main.h $(INCLUDE_DIR)/$(TARGET).h
|
||||||
|
|
||||||
.PHONY: all clean doc install
|
uninstall:
|
||||||
|
sudo rm $(LIB_DIR)/lib$(TARGET).a
|
||||||
|
sudo rm $(INCLUDE_DIR)/$(TARGET).h
|
||||||
|
|
||||||
|
.PHONY: all clean doc install uninstall
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
# $^ Will expand to be all the sensitivity list
|
# $^ Will expand to be all the sensitivity list
|
||||||
|
|||||||
53
README.md
53
README.md
@ -1,2 +1,53 @@
|
|||||||
# CXL_state-release
|
# Overview
|
||||||
|
|
||||||
|
This is a C library that provides a software representation of the state of a
|
||||||
|
CXL switch and attached devices.
|
||||||
|
|
||||||
|
# Supported Operating System Versions
|
||||||
|
|
||||||
|
- Ubuntu 23.10
|
||||||
|
- Fedora 38, 39
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
1. Install OS libraries
|
||||||
|
|
||||||
|
Install the following build packages to compile the software on the following
|
||||||
|
operating systems.
|
||||||
|
|
||||||
|
**Ubuntu:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install build-essential libpci-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fedora:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Build Dependencies
|
||||||
|
|
||||||
|
This library is dependent upon the following projects.
|
||||||
|
|
||||||
|
- [array_utils](https://github.com/JackrabbitLabs/array_utils)
|
||||||
|
- [pci_utils](https://github.com/JackrabbitLabs/pci_utils)
|
||||||
|
- [fmapi](https://github.com/JackrabbitLabs/fmapi)
|
||||||
|
|
||||||
|
For each of these repositories, in the order listed, clone and execute:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
This will install a library (.a) and header file to the standard os location
|
||||||
|
(e.g. /usr/local/include, /usr/local/lib)
|
||||||
|
|
||||||
|
3. Build
|
||||||
|
|
||||||
|
After building the required dependencies run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
236
main.c
236
main.c
@ -13,6 +13,12 @@
|
|||||||
|
|
||||||
/* INCLUDES ==================================================================*/
|
/* INCLUDES ==================================================================*/
|
||||||
|
|
||||||
|
/* gettid()
|
||||||
|
*/
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/* printf()
|
/* printf()
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -58,6 +64,24 @@
|
|||||||
|
|
||||||
/* MACROS ====================================================================*/
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
#ifdef CXLS_VERBOSE
|
||||||
|
#define INIT unsigned step = 0;
|
||||||
|
#define ENTER if (cxls_verbosity & CXVB_CALLSTACK) printf("%d:%s Enter\n", gettid(), __FUNCTION__);
|
||||||
|
#define STEP step++; if (cxls_verbosity & CXVB_STEPS) printf("%d:%s STEP: %u\n", gettid(), __FUNCTION__, step);
|
||||||
|
#define HEX32(m, i) if (cxls_verbosity & CXVB_STEPS) printf("%d:%s STEP: %u %s: 0x%x\n", gettid(), __FUNCTION__, step, m, i);
|
||||||
|
#define INT32(m, i) if (cxls_verbosity & CXVB_STEPS) printf("%d:%s STEP: %u %s: %d\n", gettid(), __FUNCTION__, step, m, i);
|
||||||
|
#define EXIT(rc) if (cxls_verbosity & CXVB_CALLSTACK) printf("%d:%s Exit: %d\n", gettid(), __FUNCTION__,rc);
|
||||||
|
#else
|
||||||
|
#define INIT
|
||||||
|
#define ENTER
|
||||||
|
#define STEP
|
||||||
|
#define HEX32(m, i)
|
||||||
|
#define INT32(m, i)
|
||||||
|
#define EXIT(rc)
|
||||||
|
#endif // CSE_VERBOSE
|
||||||
|
|
||||||
|
#define IFV(u) if (cxls_verbosity & u)
|
||||||
|
|
||||||
/* ENUMERATIONS ==============================================================*/
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
/* STRUCTS ===================================================================*/
|
/* STRUCTS ===================================================================*/
|
||||||
@ -66,8 +90,220 @@
|
|||||||
|
|
||||||
/* GLOBAL VARIABLES ==========================================================*/
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
__u64 cxls_verbosity = 0;
|
||||||
|
|
||||||
/* FUNCTIONS =================================================================*/
|
/* FUNCTIONS =================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy data from a device definition to a port
|
||||||
|
*
|
||||||
|
* @param p struct cxl_port* to fill with data
|
||||||
|
* @param d struct cxl_device* to pull the data from
|
||||||
|
* @param dir char* for the directory name for mmaped files
|
||||||
|
*
|
||||||
|
* STEPS:
|
||||||
|
* 1: Copy basic parameters
|
||||||
|
* 2: Copy PCIe config space to the port
|
||||||
|
* 3: Copy MLD information if present
|
||||||
|
* 4: Memory Map a file if requested by the device profile
|
||||||
|
*/
|
||||||
|
int cxls_connect(struct cxl_port *p, struct cxl_device *d, char *dir)
|
||||||
|
{
|
||||||
|
INIT
|
||||||
|
int rv;
|
||||||
|
unsigned i;
|
||||||
|
char filename[CXLN_FILE_NAME];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
ENTER
|
||||||
|
|
||||||
|
// Initialize variables
|
||||||
|
rv = 1;
|
||||||
|
|
||||||
|
// Validate Inputs
|
||||||
|
if (d->name == NULL)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
STEP // 1: Copy basic parameters
|
||||||
|
p->dv = d->dv;
|
||||||
|
p->dt = d->dt;
|
||||||
|
p->cv = d->cv;
|
||||||
|
p->ltssm = FMLS_L0;
|
||||||
|
p->lane = 0;
|
||||||
|
p->lane_rev = 0;
|
||||||
|
p->perst = 0;
|
||||||
|
p->pwrctrl = 0;
|
||||||
|
p->ld = 0;
|
||||||
|
|
||||||
|
// If the device definition says this is a rootport then set as an Upstream Port
|
||||||
|
if( d->rootport == 1 )
|
||||||
|
p->state = FMPS_USP;
|
||||||
|
else
|
||||||
|
p->state = FMPS_DSP;
|
||||||
|
|
||||||
|
// Pick the lower of the two widths
|
||||||
|
if (d->mlw < p->mlw)
|
||||||
|
p->nlw = d->mlw << 4;
|
||||||
|
else
|
||||||
|
p->nlw = p->mlw << 4;
|
||||||
|
|
||||||
|
// Pick the lower of the two speeds
|
||||||
|
if (d->mls < p->mls)
|
||||||
|
p->cls = d->mls;
|
||||||
|
else
|
||||||
|
p->cls = p->mls;
|
||||||
|
|
||||||
|
// Set present bit
|
||||||
|
p->prsnt = 1;
|
||||||
|
|
||||||
|
STEP // 2: Copy PCIe config space to the port
|
||||||
|
memcpy(p->cfgspace, d->cfgspace, CXLN_CFG_SPACE);
|
||||||
|
|
||||||
|
STEP // 3: Copy MLD information if present
|
||||||
|
if (d->mld != NULL)
|
||||||
|
{
|
||||||
|
p->ld = d->mld->num;
|
||||||
|
|
||||||
|
// Allocate memory for MLD object in the port
|
||||||
|
p->mld = malloc(sizeof(struct cxl_mld));
|
||||||
|
|
||||||
|
// Copy MLD from device definition to port
|
||||||
|
memcpy(p->mld, d->mld, sizeof(struct cxl_mld));
|
||||||
|
|
||||||
|
for ( i = 0 ; i < d->mld->num ; i++ )
|
||||||
|
{
|
||||||
|
// Allocate memory for each LD pcie config space
|
||||||
|
p->mld->cfgspace[i] = malloc(CXLN_CFG_SPACE);
|
||||||
|
|
||||||
|
// Copy PCIe config space from device definition to port
|
||||||
|
memcpy(p->mld->cfgspace[i], d->cfgspace, CXLN_CFG_SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STEP // 4: Memory Map a file if requested by the device profile
|
||||||
|
if (d->mld != NULL && d->mld->mmap == 1)
|
||||||
|
{
|
||||||
|
// Prepare filename
|
||||||
|
sprintf(filename, "%s/port%02d", dir, p->ppid);
|
||||||
|
|
||||||
|
// Create file
|
||||||
|
fp = fopen(filename, "w+");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf("Error: Could not open file: %s\n", filename);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate file to desired length
|
||||||
|
rv = ftruncate(fileno(fp), p->mld->memory_size);
|
||||||
|
if (rv != 0) {
|
||||||
|
printf("Error: Could not truncate file. Memory Size: 0x%llx errno: %d\n", p->mld->memory_size, errno);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mmap file
|
||||||
|
p->mld->memspace = mmap(NULL, p->mld->memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(fp), 0);
|
||||||
|
if (p->mld->memspace == NULL) {
|
||||||
|
printf("Error: Could not mmap the file. errno: %d\n", errno);
|
||||||
|
rv = 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the filename to the port mld object
|
||||||
|
p->mld->file = strdup(filename);
|
||||||
|
|
||||||
|
// Close file
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear / Free data from a port device definition
|
||||||
|
*
|
||||||
|
* This function essemtially makes it appear as if the device has been removed from the slot
|
||||||
|
*
|
||||||
|
* @param p struct cxl_port* The port to clear of values
|
||||||
|
*
|
||||||
|
* STEPS:
|
||||||
|
* 1: Clear basic parameters
|
||||||
|
* 2: Clear PCIe config space
|
||||||
|
* 3: Free device name
|
||||||
|
* 4: Unmemmap MLD if present
|
||||||
|
* 5: Free PCIe cfg space for each ld
|
||||||
|
* 6: Free MLD if present
|
||||||
|
*/
|
||||||
|
int cxls_disconnect(struct cxl_port *p)
|
||||||
|
{
|
||||||
|
INIT
|
||||||
|
int rv;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
ENTER
|
||||||
|
|
||||||
|
// Initialize variables
|
||||||
|
rv = 1;
|
||||||
|
|
||||||
|
STEP // 1: Clear basic parameters
|
||||||
|
p->dv = 0;
|
||||||
|
p->dt = 0;
|
||||||
|
p->cv = 0;
|
||||||
|
p->nlw = 0;
|
||||||
|
p->cls = 0;
|
||||||
|
p->ltssm = 0;
|
||||||
|
p->lane = 0;
|
||||||
|
p->lane_rev = 0;
|
||||||
|
p->perst = 0;
|
||||||
|
p->prsnt = 0;
|
||||||
|
p->pwrctrl = 0;
|
||||||
|
p->ld = 0;
|
||||||
|
|
||||||
|
STEP // 2: Clear PCIe config space
|
||||||
|
memset(p->cfgspace, 0, CXLN_CFG_SPACE);
|
||||||
|
|
||||||
|
STEP // 3: Free device name
|
||||||
|
if (p->device_name != NULL)
|
||||||
|
{
|
||||||
|
free(p->device_name);
|
||||||
|
p->device_name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STEP // 4: Unmemmap MLD if present
|
||||||
|
if (p->mld != NULL && p->mld->memspace != NULL)
|
||||||
|
{
|
||||||
|
msync (p->mld->memspace, p->mld->memory_size, MS_SYNC);
|
||||||
|
munmap(p->mld->memspace, p->mld->memory_size);
|
||||||
|
p->mld->memspace = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STEP // 5: Free PCIe cfg space for each ld
|
||||||
|
if (p->mld != NULL)
|
||||||
|
{
|
||||||
|
for ( i = 0 ; i < p->mld->num ; i++ ) {
|
||||||
|
if ( p->mld->cfgspace[i] != NULL ) {
|
||||||
|
free(p->mld->cfgspace[i]);
|
||||||
|
p->mld->cfgspace[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STEP // 6: Free MLD if present
|
||||||
|
if (p->mld != NULL)
|
||||||
|
{
|
||||||
|
free(p->mld);
|
||||||
|
p->mld = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize state object with default values
|
* Initialize state object with default values
|
||||||
*
|
*
|
||||||
|
|||||||
17
main.h
17
main.h
@ -37,6 +37,16 @@
|
|||||||
|
|
||||||
/* ENUMERATIONS ==============================================================*/
|
/* ENUMERATIONS ==============================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CXLS Verbosity Bit Field (VB)
|
||||||
|
*/
|
||||||
|
enum _CXVB
|
||||||
|
{
|
||||||
|
CXVB_GENERAL = (0x01 << 0),
|
||||||
|
CXVB_CALLSTACK = (0x01 << 1),
|
||||||
|
CXVB_STEPS = (0x01 << 2)
|
||||||
|
};
|
||||||
|
|
||||||
/* STRUCTS ===================================================================*/
|
/* STRUCTS ===================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,11 +221,16 @@ struct cxl_switch
|
|||||||
|
|
||||||
/* GLOBAL VARIABLES ==========================================================*/
|
/* GLOBAL VARIABLES ==========================================================*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
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_disconnect (struct cxl_port *p);
|
||||||
|
|
||||||
void cxls_prnt (struct cxl_switch *s);
|
void cxls_prnt (struct cxl_switch *s);
|
||||||
void cxls_prnt_identity (struct cxl_switch *s, unsigned indent);
|
void cxls_prnt_identity (struct cxl_switch *s, unsigned indent);
|
||||||
void cxls_prnt_devices (struct cxl_switch *s);
|
void cxls_prnt_devices (struct cxl_switch *s);
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include "cxlstate.h"
|
#include "main.h"
|
||||||
|
|
||||||
/* MACROS ====================================================================*/
|
/* MACROS ====================================================================*/
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user