Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
system_data.h 6.96 KiB

#ifndef _SYSTEMDATA_H_
#define _SYSTEMDATA_H_


/* Note: use USE_HOSTCC to determinate if we are compiling
 * for u-boot or for external tool (in this case these is present) 
 */

#ifndef USE_HOSTCC
#include <linux/kconfig.h>
#include <common.h>
#else
#include <sys/types.h>
#include <stdint.h>
#include <ctype.h>
#endif


#define VERSION_MAJOR                       1
#define VERSION_MINOR                       0

#define SYSDATA_DEV_NAME_LEN                20
#define SYSDATA_VERSION_LEN                 7


#define SYSDATA_MAX_SLOTS                   2

#define SYSDATA_MAX_FAIL_BOOT               3

#define SLOT_NULL                           0

#define SYSDATA_GLOBAL_BOOT_COUNT_ENABLE    0

#define FAIL_BOOT_COUNT_ENABLE_SHIFT        0
#define GLOBAL_BOOT_COUNT_ENABLE_SHIFT      1

#define FAIL_BOOT_COUNT_ENABLE_MASK         0x1
#define GLOBAL_BOOT_COUNT_ENABLE_MASK       0x2

#define GET_FAIL_BOOT_COUNT_ENABLE(x)       \
						(((x) & FAIL_BOOT_COUNT_ENABLE_MASK) >> FAIL_BOOT_COUNT_ENABLE_SHIFT)
#define GET_GLOBAL_BOOT_COUNT_ENABLE(x)     \
						(((x) & GLOBAL_BOOT_COUNT_ENABLE_MASK) >> GLOBAL_BOOT_COUNT_ENABLE_SHIFT)

#define ENV_SYSDATA_GROUP_PART     "slot_partition"

#define SLOT_NUM2ID(x)             ((x) != 0 ? (char)((x) + 64) : '/')  // x=1 -> A, x=2 -> B
#define SLOT_ID2NUM(x)             ((int)((char)(x) - 64))
#define SLOT_IS_VALID(x)           ((x) > 0 && (x) <= SYSDATA_MAX_SLOTS ? 1 : 0)

typedef enum switch_group_alg {
	SWITCH_SLOT_ROUND_WAY,
	SWITCH_SLOT_LAST_USED,
} switch_group_alg_t;


typedef struct systemdata_header  {
	uint32_t	      crc;		/* CRC32 over data bytes	*/
	uint32_t          version_major;
    uint32_t          version_minor;
} sysdata_header_t;


typedef struct switching_table {

    uint32_t          boot_slot_counter[SYSDATA_MAX_SLOTS];
	uint8_t           boot_fail_counter[SYSDATA_MAX_SLOTS];
	uint8_t           boot_slot_order[SYSDATA_MAX_SLOTS];
    uint8_t           current_boot_slot;
	uint8_t           previous_boot_slot;
    
	uint8_t           enable_flags;
} switching_table_t;


typedef struct systemdata_data {
	switching_table_t   switch_table;
} sysdata_data_t;


typedef struct systemdata {
	sysdata_header_t    header;
	sysdata_data_t      data;	
} sysdata_t;


#define SYSTEMDATA_SIZE           (unsigned long)(sizeof(sysdata_t))
#define SYSTEMDATA_CONTENT_SIZE   (unsigned long)(sizeof(sysdata_data_t))



struct sysdata_driver {
	const char        *name;
	//enum env_location location;

	int (*load)( sysdata_t *rd_data );
	int (*save)( sysdata_t *new_data );
	const char *(*get_device_name)( void );
};


extern int sysdata_init( void );
extern int sysdata_integration_check( void );

extern const char *get_sysdata_device_name( void );
extern int get_sysdata_version( char **version );
/* switchpart functions */
extern int get_switchslot_data( switching_table_t *switch_data );
extern int sysdata_switchslot_init( void );
extern int get_switchslot_max_fail_boot( void );
/** 
 * sysdata_switchslot_set_enable_global_counter( ) - set the enable for the global boot counter
 *
 * This set the global boot counter enable
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_set_enable_global_counter( int en );
/** 
 * sysdata_switchslot_set_enable_fail_counter( ) - set the enable for the fail boot counter
 *
 * This set the fail boot counter enable
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_set_enable_fail_counter( int en );
/** 
 * sysdata_switchslot_get_primary_slot( ) - get primary slot
 * 
 * This read the first element in boot order array
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_get_primary_slot( int *primary );
/** 
 * sysdata_switchslot_get_valid_slot( ) - get id of first valid bootable slot
 *
 * This get first valid bootable slot based on present boot order
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_get_valid_slot( int *curr_slot );
/** 
 * sysdata_swtchslot_update_current( ) - update the current slot to use
 *
 * This evaluate and eventually update the current slot to use
 * 
 * @return updated current slot if ok, error number otherwise
*/
int sysdata_swtchslot_update_current_slot( void );
/** 
 * sysdata_switchslot_get_current_slot( ) - get current slot
 * 
 * This get the current slot stored in media storage
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_get_current_slot( int *current );
/** 
 * sysdata_switchslot_get_previous_slot( ) - get previous slot
 * 
 * This get the previous slot stored in media storage
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_get_previous_slot( int *previous );

#ifndef USE_HOSTCC
/** 
 * sysdata_switchslot_current_env( ) - create a environment variable for valid slot
 *
 * This creates a environment variable for valid slot
 * 
 * @return void
*/
extern void sysdata_switchslot_current_env( void );
#else
void sysdata_switchslot_current_env( void );
#endif
/** 
 * sysdata_switchslot_boot_counter_update( ) - increment the number of boot for current slot
 *
 * This increments the number of boot for current slot
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_boot_counter_update( void );
/** 
 * sysdata_switchslot_boot_ok( ) - initialize the fail boot counter
 *
 * This initializes the fail boot counter in order to sign a valid boot.
 * There is also an updade of the previous_boot_slot field
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_boot_ok( void );
/** 
 * sysdata_switchslot_set_primary( ) - set the primary slot with the passed slot ID
 *
 * This set the primary slot with the passed slot ID. The passed slot is placed into
 * the head of boot order list and the other positions are filled with the previous
 * order.
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_set_primary( char slot_id );
/** 
 * sysdata_switchslot_remote_from_boot_order( ) - remove slot from boot order list
 *
 * This remove slot from boot order list.
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_remote_from_boot_order( char slot_id );
/** 
 * sysdata_switchslot_invalidate_slot( ) - invalidate slot
 *
 * This invalidate slot:
 * - remote it from the boot order list
 * - set its fail boot counter as maximum allowed plus 1
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_invalidate_slot( char slot_id );
/** 
 * sysdata_switchslot_reset_fail_counter( ) - reset fail boot counter for passed slot ID
 *
 * This reset fail boot counter for passed slot ID
 * 
 * @return 0 if ok, error number otherwise
*/
extern int sysdata_switchslot_reset_fail_counter( char slot_id );

#define U_BOOT_SYSDATA_LOCATION(__name)					\
	ll_entry_declare(struct sysdata_driver, __name, sysdata_driver)

	

/* the I/O basic functions will be implemeted by the external
 * tool
 */

#ifdef USE_HOSTCC
extern int _sysdata_rd( sysdata_t *table );
extern int _sysdata_wr( sysdata_t *table );
#endif

#endif     /*  _SYSTEMDATA_H_  */