359 lines
7.4 KiB
C
359 lines
7.4 KiB
C
/******************************************************************************
|
|
* (c) COPYRIGHT 2010-2019 by NetModule AG, Switzerland.
|
|
*
|
|
* The program(s) may only be used and/or copied with the written permission
|
|
* from NetModule AG or in accordance with the terms and conditions stipulated
|
|
* in the agreement contract under which the program(s) have been supplied.
|
|
*
|
|
* PACKAGE : NetModule Common Hardware Abstraction
|
|
*
|
|
* ABSTRACT:
|
|
* Board descriptor library
|
|
*
|
|
* HISTORY:
|
|
* Date Author Description
|
|
* 20100421 SMA created
|
|
* 20100903 rs reading carrier board descriptor from EEPROM at 54.
|
|
* code cleanup (tabs/indentation)
|
|
* 20110211 rs partition table handling
|
|
* 20190330 rs cleanup after years of chaotic development
|
|
* 20200615 rs added bd_get_hw_type()
|
|
*
|
|
*****************************************************************************/
|
|
#include <common.h>
|
|
#include <i2c.h>
|
|
#include <malloc.h>
|
|
|
|
#include "board_descriptor.h" /* own header file */
|
|
|
|
|
|
#define MAX_PARTITION_ENTRIES 4
|
|
|
|
|
|
static const BD_Context *bdctx_list;
|
|
static size_t bdctx_count = 0;
|
|
|
|
|
|
static bd_bool_t _get_string(bd_uint16_t tag, bd_uint_t index, char* pResult, bd_size_t bufLen)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetString(&bdctx_list[i], tag, index, pResult, bufLen)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static bd_bool_t _get_mac(bd_uint16_t tag, bd_uint_t index, bd_uint8_t pResult[6])
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetMAC(&bdctx_list[i], tag, index, pResult)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static bd_bool_t _get_uint8(bd_uint16_t tag, bd_uint_t index, bd_uint8_t* pResult)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetUInt8(&bdctx_list[i], tag, index, pResult)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static bd_bool_t _get_uint16(bd_uint16_t tag, bd_uint_t index, bd_uint16_t* pResult)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetUInt16(&bdctx_list[i], tag, index, pResult)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static bd_bool_t _get_uint32(bd_uint16_t tag, bd_uint_t index, bd_uint32_t* pResult)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetUInt32(&bdctx_list[i], tag, index, pResult)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static bd_bool_t _get_partition64(bd_uint16_t tag, bd_uint_t index, BD_PartitionEntry64 *pResult)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < bdctx_count; i++) {
|
|
if (BD_GetPartition64(&bdctx_list[i], tag, index, pResult)) {
|
|
return BD_TRUE;
|
|
}
|
|
}
|
|
|
|
return BD_FALSE;
|
|
}
|
|
|
|
static uint8_t _try_partition_read(void)
|
|
{
|
|
BD_PartitionEntry64 partition;
|
|
int i;
|
|
int rc;
|
|
int partition_count = 0;
|
|
int boot_partition = 0;
|
|
|
|
for (i = 0; i < MAX_PARTITION_ENTRIES; i++)
|
|
{
|
|
rc = _get_partition64(BD_Partition64, i, &partition);
|
|
if (rc) {
|
|
partition_count++;
|
|
if (((partition.flags & BD_Partition_Flags_Active) != 0) &&
|
|
(i > 0)) {
|
|
boot_partition = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (partition_count < 1) {
|
|
printf("ERROR: Too few partitions defined, taking default 0\n");
|
|
}
|
|
|
|
return boot_partition;
|
|
}
|
|
|
|
|
|
void bd_register_context_list(const BD_Context *list, size_t count)
|
|
{
|
|
bdctx_list = list;
|
|
bdctx_count = count;
|
|
}
|
|
|
|
int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset)
|
|
{
|
|
bd_bool_t rc;
|
|
uint8_t bdHeader[8];
|
|
void* pBdData = NULL;
|
|
|
|
/* Read header bytes from beginning of EEPROM */
|
|
if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) {
|
|
debug("%s() Can't read BD header from EEPROM\n", __func__);
|
|
goto exit1;
|
|
}
|
|
|
|
/* Check whether this is a valid board descriptor (or empty EEPROM) */
|
|
rc = BD_CheckHeader( bdctx, bdHeader );
|
|
if (!rc) {
|
|
debug("%s() No valid board descriptor found\n", __func__);
|
|
goto exit1;
|
|
}
|
|
|
|
/* Allocate memory for descriptor data and .. */
|
|
pBdData = malloc( bdctx->size );
|
|
if ( pBdData == NULL ) {
|
|
debug("%s() Can't allocate %d bytes\n", __func__, bdctx->size);
|
|
goto exit1;
|
|
}
|
|
|
|
/* .. read data from EEPROM */
|
|
if (i2c_read(i2caddress, offset+BD_HEADER_LENGTH, 2, pBdData, bdctx->size)) {
|
|
debug("%s() Can't read data from EEPROM\n", __func__);
|
|
goto exit1;
|
|
}
|
|
|
|
/*
|
|
* Import data into board descriptor context
|
|
*/
|
|
rc = BD_ImportData( bdctx, pBdData );
|
|
if (!rc) {
|
|
debug("%s() Invalid board descriptor data\n", __func__);
|
|
goto exit1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
exit1:
|
|
if (pBdData != NULL) {
|
|
free(pBdData);
|
|
pBdData = NULL;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int bd_get_prodname(char *prodname, size_t len)
|
|
{
|
|
if ( !_get_string( BD_Prod_Name, 0, prodname, len) ) {
|
|
debug("%s() Product name not found\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_variantname(char *variantname, size_t len)
|
|
{
|
|
if ( !_get_string( BD_Prod_Variant_Name, 0, variantname, len) ) {
|
|
debug("%s() Variant name not found\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void bd_get_hw_type(int* type)
|
|
{
|
|
uint16_t hwtype = 0;
|
|
|
|
if ( !_get_uint16( BD_Hw_Type, 0, &hwtype) )
|
|
debug("%s() no Hw Type found\n", __func__);
|
|
|
|
*type = hwtype;
|
|
}
|
|
|
|
void bd_get_hw_version(int* ver, int* rev)
|
|
{
|
|
uint8_t hwver = 0;
|
|
uint8_t hwrev = 0;
|
|
|
|
if ( !_get_uint8( BD_Hw_Ver, 0, &hwver) )
|
|
debug("%s() no Hw Version found\n", __func__);
|
|
|
|
if ( !_get_uint8( BD_Hw_Rel, 0, &hwrev) )
|
|
debug("%s() no Hw Release found\n", __func__);
|
|
|
|
*ver = hwver;
|
|
*rev = hwrev;
|
|
}
|
|
|
|
void bd_get_hw_patch(int* patch)
|
|
{
|
|
uint8_t hwpatch = 0;
|
|
|
|
if ( !_get_uint8( BD_BOM_Patch, 0, &hwpatch) )
|
|
debug("%s() no Hw Patch found\n", __func__);
|
|
|
|
*patch = hwpatch;
|
|
}
|
|
|
|
int bd_get_mac(int index, uint8_t *macaddr, size_t len)
|
|
{
|
|
if ( len != 6 ) {
|
|
debug("macaddr size must be 6 (is %d)", len);
|
|
return -1;
|
|
}
|
|
|
|
/* MAC address */
|
|
if ( !_get_mac( BD_Eth_Mac, index, macaddr) ) {
|
|
debug("%s() MAC addresss %d not found\n", __func__, index);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t bd_get_fpgainfo(void)
|
|
{
|
|
uint32_t fpgainfo = 0xFFFFFFFF;
|
|
|
|
if ( !_get_uint32( BD_Fpga_Info, 0, &fpgainfo) )
|
|
debug("%s() no FGPA Info found\n", __func__);
|
|
|
|
return fpgainfo;
|
|
}
|
|
|
|
int bd_get_pd_dio(char *config, size_t len)
|
|
{
|
|
if ( !_get_string(BD_Pd_DIO, 0, config, len) ) {
|
|
debug("%s() no DIO info\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_pd_serial(char *config, size_t len)
|
|
{
|
|
if ( !_get_string(BD_Pd_Serial, 0, config, len) ) {
|
|
debug("%s() no serial port info\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_pd_module(uint32_t slot, char *config, size_t len)
|
|
{
|
|
if ( !_get_string(BD_Pd_Module0 + slot, 0, config, len) ) {
|
|
debug("%s() could not read module configuration on slot %d\n",
|
|
__func__, slot);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_sim_config(char* simconfig, size_t len)
|
|
{
|
|
if (!_get_string(BD_Pd_Sim, 0, simconfig, len)) {
|
|
debug("%s() no valid SIM config found\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_devicetree(char* devicetreename, size_t len)
|
|
{
|
|
if (!_get_string(PD_Dev_Tree, 0, devicetreename, len)) {
|
|
debug("%s() no valid devicetree name found\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bd_get_shield(uint32_t shieldnr)
|
|
{
|
|
bd_uint16_t shield = 0;
|
|
|
|
if (!_get_uint16(PD_Shield, shieldnr, &shield) ) {
|
|
debug("%s() no shield populated\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
return shield;
|
|
}
|
|
|
|
uint8_t bd_get_boot_partition(void)
|
|
{
|
|
uint8_t boot_part;
|
|
|
|
/* If we have a Bootpartition entry take this as boot part */
|
|
if (_get_uint8( BD_BootPart, 0, &boot_part) ) {
|
|
if (boot_part >= 0 && boot_part <= 1) {
|
|
return boot_part;
|
|
}
|
|
}
|
|
|
|
/* If we don't have a Bootpartition entry, perhaps we have a partition table */
|
|
return _try_partition_read();
|
|
}
|