meta-facebook/meta-fbtp/recipes-fbtp/plat-libs/files/pal/machine_config.c (179 lines of code) (raw):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "pal.h"
#include <openbmc/kv.h>
enum {
SINGLE_SIDE = 0,
DOUBLE_SIDE = 1
};
enum {
RISER_ABSENT = 0,
RISER_2SLOT = 1,
RISER_3SLOT = 2
};
enum {
CARD_ABSENT = 0,
CARD_1AVA = 1,
CARD_2AVA = 2,
CARD_3AVA = 3,
CARD_4AVA = 4,
CARD_RETIMER = 5,
CARD_HBA = 6,
CARD_OTHER_FLASH = 7,
CARD_UNKNOWN = 0x80,
// Custom to ease computation. Not
// sent by BIOS.
CARD_NIC = 0xff,
CARD_AVA = 0xfe
};
typedef struct
{
uint8_t chassis_type; // 00 - ORv1, 01 - ORv2 (FBTP)
uint8_t MB_type; // 00 - SS, 01 - DS, 02 - Type3
uint8_t processor_count;
uint8_t memory_count;
uint8_t hdd35_count; // 0/1 in FBTP, ff - unknown
uint8_t hdd25_count; // 0 for FBTP
uint8_t riser_type; // 00 - not installed, 01 - 2 slot, 02 - 3 slot
uint8_t pcie_card_loc; // Bit0 - Slot1 Present/Absent, Bit1 - Slot 2 Present/Absent etc.
uint8_t slot1_pciecard_type; // Always NIC for FBTP
uint8_t slot2_pciecard_type; // 2-4: 00 - Absent, 01 - AVA 2 x m.2, 02 - AVA 3x m.2,
uint8_t slot3_pciecard_type; // 03 - AVA 4 x m.2, 04 - Re-timer, 05 - HBA
uint8_t slot4_pciecard_type; // 06 - Other flash cards (Intel, HGST), 80 - Unknown
uint8_t AEP_mem_count;
} machine_config_info;
#define NUM_CONFIGURATIONS (sizeof(configurations)/sizeof(configurations[0]))
#define SS_IDX 0
#define DS_IDX 1
#define CONF_START 2
struct conf_s {
const char *name;
const char *desc;
machine_config_info info;
};
static struct conf_s configurations[] = {
{"SS_D", "Single Side, default", {0}},
{"DS_D", "Double Side, default", {0}},
{"SS_0", "Type 8 Head Node", {0, SINGLE_SIDE, 2, 4, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_RETIMER, CARD_ABSENT, 0}},
{"SS_1", "Type 6/8 compute (no-flash)", {0, SINGLE_SIDE, 2, 8, 1, 0, RISER_ABSENT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 0}},
{"SS_2", "Custom 3 Ava cards, no boot-drive", {0, SINGLE_SIDE, 2, 8, 0, 0, RISER_3SLOT, 0, CARD_NIC, CARD_AVA, CARD_AVA, CARD_AVA, 0}},
{"SS_3", "Type 6 with Ava, no boot-drive", {0, SINGLE_SIDE, 2, 8, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_AVA, CARD_ABSENT, CARD_ABSENT, 0}},
{"SS_4", "Type 6 with Ava", {0, SINGLE_SIDE, 2, 8, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_AVA, CARD_ABSENT, CARD_ABSENT, 0}},
{"SS_5", "Type 6 with Ava (alt)", {0, SINGLE_SIDE, 2, 8, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_AVA, CARD_ABSENT, 0}},
{"SS_6", "JBOG", {0, SINGLE_SIDE, 2, 8, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_RETIMER, CARD_RETIMER, CARD_ABSENT, 0}},
{"SS_7", "Type 3 with Ava", {0, SINGLE_SIDE, 2, 8, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_AVA, CARD_AVA, CARD_ABSENT, 0}},
{"SS_8", "Type 9 with HBA", {0, SINGLE_SIDE, 2, 8, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_HBA, CARD_HBA, CARD_ABSENT, 0}},
{"SS_9", "Type 6 with Ava (top slot)", {0, SINGLE_SIDE, 2, 8, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_AVA, CARD_ABSENT, 0}},
{"DS_0", "DS compute", {0, DOUBLE_SIDE, 2, 12, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 0}},
{"DS_1", "DS compute with boot drive", {0, DOUBLE_SIDE, 2, 12, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 0}},
{"DS_2", "DS memory without boot-drive", {0, DOUBLE_SIDE, 2, 24, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 0}},
{"DS_3", "DS memory with boot-drive", {0, DOUBLE_SIDE, 2, 24, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 0}},
{"DS_4", "DS AEP without boot-drive", {0, DOUBLE_SIDE, 2, 12, 0, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 12}},
{"DS_5", "DS AEP with boot-drive", {0, DOUBLE_SIDE, 2, 12, 1, 0, RISER_2SLOT, 0, CARD_NIC, CARD_ABSENT, CARD_ABSENT, CARD_ABSENT, 12}}
};
static const char *default_machine_config_name(void)
{
uint8_t plat_id;
if (pal_get_platform_id(&plat_id)) {
/* Default to SS */
return "SS_D";
}
if (plat_id & PLAT_ID_SKU_MASK) {
return "DS_D";
}
return "SS_D";
}
static uint8_t pcie_card_resolve(uint8_t type)
{
switch(type) {
case CARD_ABSENT:
case CARD_RETIMER:
case CARD_HBA:
case CARD_OTHER_FLASH:
break;
case CARD_1AVA:
case CARD_2AVA:
case CARD_3AVA:
case CARD_4AVA:
type = CARD_AVA;
break;
case CARD_UNKNOWN:
default:
type = CARD_UNKNOWN;
break;
}
return type;
}
// Sets to known values of knobs we do not care
// about. So, the lookup logic can be easier.
static void set_defaults(machine_config_info *mc)
{
mc->chassis_type = 0;
mc->processor_count = 2;
mc->hdd25_count = 0;
mc->pcie_card_loc = 0;
mc->slot1_pciecard_type = CARD_NIC; // NIC always exists
mc->slot2_pciecard_type = pcie_card_resolve(mc->slot2_pciecard_type);
mc->slot3_pciecard_type = pcie_card_resolve(mc->slot3_pciecard_type);
mc->slot4_pciecard_type = pcie_card_resolve(mc->slot4_pciecard_type);
}
static bool config_equal(machine_config_info *m1, machine_config_info *m2)
{
return memcmp(m1, m2, sizeof(machine_config_info)) == 0;
}
static struct conf_s *machine_config(machine_config_info *mc)
{
int i;
set_defaults(mc);
for(i = CONF_START; i < NUM_CONFIGURATIONS; i++) {
if (config_equal(mc, &configurations[i].info)) {
return &configurations[i];
}
}
if (mc->MB_type == SINGLE_SIDE) {
return &configurations[SS_IDX];
}
if (mc->MB_type == DOUBLE_SIDE) {
return &configurations[DS_IDX];
}
return NULL;
}
int
pal_set_machine_configuration(uint8_t slot, uint8_t *req_data, uint8_t req_len, uint8_t *res_data, uint8_t *res_len)
{
char key[MAX_KEY_LEN];
char value[MAX_VALUE_LEN] = {0};
machine_config_info mc;
struct conf_s *conf;
if (req_len < sizeof(machine_config_info)) {
syslog(LOG_CRIT, "Invalid machine configuration received");
return -1;
}
sprintf(key, "mb_machine_config");
kv_set(key, (char *)req_data, sizeof(machine_config_info), KV_FPERSIST);
memcpy(&mc, &req_data[0], sizeof(machine_config_info));
conf = machine_config(&mc);
if (!conf) {
strcpy(value, default_machine_config_name());
kv_set("mb_system_conf", value, 0, KV_FPERSIST);
kv_set("mb_system_conf_desc", value, 0, KV_FPERSIST);
return 0;
}
strcpy(value, conf->name);
kv_set("mb_system_conf", value, 0, KV_FPERSIST);
memset(value, 0, sizeof(value));
strcpy(value, conf->desc);
kv_set("mb_system_conf_desc", value, 0, KV_FPERSIST);
return 0;
}
int pal_get_machine_configuration(char *conf)
{
char key[MAX_KEY_LEN];
char value[MAX_VALUE_LEN] = {0};
int ret;
sprintf(key, "mb_system_conf");
ret = kv_get(key, value, NULL, KV_FPERSIST);
if (ret < 0) {
strcpy(value, default_machine_config_name());
kv_set(key, value, 0, KV_FPERSIST | KV_FCREATE);
}
strcpy(conf, value);
return 0;
}