Skip to content
Snippets Groups Projects
Commit dbb19b87 authored by Tobias Kahlki's avatar Tobias Kahlki
Browse files

sysdata: Updated to current version

Pulled the changes to sysdata from https://git.seco.com/arm/nxp/imx/develop/
yocto/5.x/u-boot-seco-imx/-/commit/c2d100148f4f50dc977891a580fe5980b399ecce

BCS 746-001143
parent 23d5a499
No related branches found
No related tags found
1 merge request!115cmd: Activated the boot mode command for TANARO
#include <asm/byteorder.h>
#include <asm/io.h>
#include <common.h>
#include <cli.h>
#include <command.h>
#include <common.h>
#include <console.h>
#include <env.h>
#include <search.h>
#include <errno.h>
#include <linux/stddef.h>
#include <malloc.h>
#include <mapmem.h>
#include <search.h>
#include <watchdog.h>
#include <linux/stddef.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include "sysdata.h"
#include <sysdata.h>
static int do_sysdata(struct cmd_tbl* cmdtp, int flag, int argc, char* const argv[])
static int do_sysdata( struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[] )
{
int ret = 0;
if (argc == 2) {
if (strcmp(argv[1], "version") == 0) {
const char* version = get_sysdata_version();
if (version)
printf("SysData version: %s\n", version);
else
printf("Error on retrieving data\n");
} else if (strcmp(argv[1], "dev") == 0) {
const char* device = get_sysdata_device_name();
if (device) {
char device_id[32];
printf("%s\n", device);
if (strcmp(device, "MMC0") == 0)
sprintf(device_id, "mmcblk0");
else if (strcmp(device, "MMC1") == 0)
sprintf(device_id, "mmcblk1");
else if (strcmp(device, "MMC2") == 0)
sprintf(device_id, "mmcblk2");
else
sprintf(device_id, "none");
env_set("sysdata_device", device_id);
} else
printf("Error on retrieving data\n");
} else if (strcmp(argv[1], "initialize") == 0) {
ret = sysdata_init();
if (ret)
printf("Error (%d), table not initialized\n", ret);
else
printf("Table initialized\n");
}
} else if (argc >= 3) {
if (strcmp(argv[1], "switchslot") == 0) {
int i;
switching_table_t switch_data;
if (strcmp(argv[2], "status") == 0) {
ret = get_switchslot_data(&switch_data);
if (ret)
printf("Error (%d) on retrieving data\n", ret);
else {
for (i = 1; i <= SYSDATA_MAX_SLOTS; i++) {
printf("Boot on slot %c: %05d\n", SLOT_NUM2ID(i),
switch_data.boot_slot_counter[i - 1]);
}
printf("Current boot slot: %c\n", SLOT_NUM2ID(switch_data.current_boot_slot));
printf("Previous boot slot: %c\n", SLOT_NUM2ID(switch_data.previous_boot_slot));
printf("Consecutive fail boot: %01d\n", switch_data.boot_fail_counter);
printf("Boot fail counter state: %s\n",
switch_data.enable_counter ? "enabled" : "disabled");
char slot_partition[2];
slot_partition[0] = SLOT_NUM2ID(switch_data.current_boot_slot);
slot_partition[1] = '\0';
env_set("slot_partition", slot_partition);
}
}
if (strcmp(argv[2], "switch") == 0) {
if (argc >= 4) {
if (strcmp(argv[3], "round") == 0) {
ret = switch_slot(SWITCH_SLOT_ROUND_WAY);
} else if (strcmp(argv[3], "last") == 0) {
ret = switch_slot(SWITCH_SLOT_LAST_USED);
} else
ret = -EINVAL;
} else
ret = -EINVAL;
if (ret > 0) {
sysdata_switchslot_current_env();
printf("Switch to group: %d\n", ret);
} else
printf("Error (%d) on switching or invalid parameters.\n", ret);
}
if (strcmp(argv[2], "counter") == 0) {
if (argc == 4) {
if (strcmp(argv[3], "enable") == 0) {
if (sysdata_switchslot_enable_counter(1) == 0)
printf("Boot fail counter enable\n");
else
printf("Error: invalid operation\n");
} else if (strcmp(argv[3], "disable") == 0) {
if (sysdata_switchslot_enable_counter(0) == 0)
printf("Boot fail counter disable\n");
else
printf("Error: invalid operation\n");
} else
printf("Error: invalid parameters.\n");
}
}
if (strcmp(argv[2], "slot") == 0) {
ret = get_switchslot_data(&switch_data);
if (ret)
printf("0\n");
else {
printf("%c\n", SLOT_NUM2ID(switch_data.current_boot_slot));
}
}
}
}
return 4;
int ret = 0;
if ( argc == 2 ) {
if ( strcmp( argv[1], "version" ) == 0 ) {
char *version = NULL;
ret = get_sysdata_version( &version );
if ( ret == 0 ) {
if ( version )
printf( "SysData version: %s\n", version );
else
printf( "Error on retrieving data.\n" );
} else
printf( "Error on retrieving data.\n" );
} else if ( strcmp( argv[1], "dev" ) == 0 ) {
const char *device = get_sysdata_device_name( );
if ( device ) {
char device_id[32];
printf( "%s\n", device );
if ( strcmp( device, "MMC0" ) == 0 )
sprintf( device_id, "mmcblk0" );
else if ( strcmp( device, "MMC1" ) == 0 )
sprintf( device_id, "mmcblk1" );
else if ( strcmp( device, "MMC2" ) == 0 )
sprintf( device_id, "mmcblk2" );
else
sprintf( device_id, "none" );
env_set( "sysdata_device", device_id );
} else
printf( "Error on retrieving data.\n" );
} else if ( strcmp( argv[1], "initialize" ) == 0 ) {
ret = sysdata_init( );
if ( ret )
printf( "Error (%d), table not initialized.\n", ret );
else
printf( "Table initialized.\n" );
}
} else if ( argc >= 3 ) {
if ( strcmp( argv[1], "switchslot" ) == 0 ) {
int i;
switching_table_t switch_data;
if ( strcmp( argv[2], "status" ) == 0 ) {
ret = get_switchslot_data( &switch_data );
if ( ret )
printf( "Error (%d) on retrieving data.\n", ret );
else {
for ( i = 1 ; i <= SYSDATA_MAX_SLOTS ; i++ ) {
printf( "Boot on slot %c: %05d\n", SLOT_NUM2ID(i), switch_data.boot_slot_counter[i-1] );
printf( "Consecutive fail boot on slot %c: %01d\n", SLOT_NUM2ID(i), switch_data.boot_fail_counter[i-1]);
}
printf( "---------------\n" );
printf( "Boot order: " );
for ( i = 1 ; i <= SYSDATA_MAX_SLOTS ; i++ ) {
printf( " %c ", SLOT_NUM2ID(switch_data.boot_slot_order[i-1]) );
}
printf( "\n---------------\n" );
printf( "Current boot slot: %c\n", SLOT_NUM2ID(switch_data.current_boot_slot) );
printf( "Previous boot slot: %c\n", SLOT_NUM2ID(switch_data.previous_boot_slot) );
printf( "Fail Boot counter state: %s\n",
GET_FAIL_BOOT_COUNT_ENABLE(switch_data.enable_flags) ? "enabled" : "disabled" );
printf( "Global Boot counter state: %s\n",
GET_GLOBAL_BOOT_COUNT_ENABLE(switch_data.enable_flags) ? "enabled" : "disabled" );
}
}
if ( strcmp( argv[2], "global_counter" ) == 0 ) {
if ( argc == 4 ) {
if ( strcmp( argv[3], "enable" ) == 0 ) {
if ( sysdata_switchslot_set_enable_global_counter( 1 ) == 0 )
printf( "Global Boot counter enabled.\n" );
else
printf( "Error: invalid operation.\n" );
} else if ( strcmp( argv[3], "disable" ) == 0 ) {
if ( sysdata_switchslot_set_enable_global_counter( 0 ) == 0 )
printf( "Global Boot counter disabled.\n" );
else
printf( "Error: invalid operation.\n" );
} else
printf( "Error: invalid parameters.\n" );
}
}
if ( strcmp( argv[2], "fail_counter" ) == 0 ) {
if ( argc == 4 ) {
if ( strcmp( argv[3], "enable" ) == 0 ) {
if ( sysdata_switchslot_set_enable_fail_counter( 1 ) == 0 )
printf( "Fail Boot counter enabled.\n" );
else
printf( "Error: invalid operation.\n" );
} else if ( strcmp( argv[3], "disable" ) == 0 ) {
if ( sysdata_switchslot_set_enable_fail_counter( 0 ) == 0 )
printf( "Fail Boot counter disabled.\n" );
else
printf( "Error: invalid operation.\n" );
} else
printf( "Error: invalid parameters.\n" );
}
}
if ( strcmp( argv[2], "set_primary" ) == 0 ) {
if ( argc == 4 ) {
char slot = (char)argv[3][0];
if ( SLOT_IS_VALID(SLOT_ID2NUM(slot)) ) {
if ( sysdata_switchslot_set_primary( slot ) == 0 )
printf( "Slot %c set as primary.\n", slot );
else
printf( "Error: invalid operation.\n" );
} else {
printf( "Error: %c is not a valid slot.\n", slot );
}
}
}
if ( strcmp( argv[2], "remove_slot" ) == 0 ) {
if ( argc == 4 ) {
char slot = (char)argv[3][0];
if ( SLOT_IS_VALID(SLOT_ID2NUM(slot)) ) {
if ( sysdata_switchslot_remote_from_boot_order( slot ) == 0 )
printf( "Slot %c has been removed from boot order list.\n", slot );
else
printf( "Error: invalid operation.\n" );
} else {
printf( "Error: %c is not a valid slot.\n", slot );
}
}
}
if ( strcmp( argv[2], "invalidate_slot" ) == 0 ) {
if ( argc == 4 ) {
char slot = (char)argv[3][0];
if ( SLOT_IS_VALID(SLOT_ID2NUM(slot)) ) {
if ( sysdata_switchslot_invalidate_slot( slot ) == 0 )
printf( "Slot %c has been invalidated.\n", slot );
else
printf( "Error: invalid operation.\n" );
} else {
printf( "Error: %c is not a valid slot.\n", slot );
}
}
}
}
}
return 4;
}
U_BOOT_CMD_COMPLETE(sysdata, CONFIG_SYS_MAXARGS, 1, do_sysdata, "SECO system data manager",
"sysdata [main command] [options]\n"
"main command:\n"
"- version - shows sysdata version\n"
"- dev - shows current device used to read/write sysdata\n"
" (sets env sysdata_device with reference to kernel space device id)\n"
"- initialize - reset all memory reserved of sysdata with factory data\n"
"- switchslot <command>\n"
" command:\n"
" - status - shows current state switching slot system\n"
" - switch [algorithm] - performs selected switching algorithm:\n"
" round - cicle selection\n"
" last (default) - select latest used inactive slot\n"
" note: for 2 slot system, roud and last have the same behavior\n"
" - counter [enable | disable] - enable/disable the counter of fail boots\n",
var_complete);
U_BOOT_CMD_COMPLETE(
sysdata, CONFIG_SYS_MAXARGS, 1, do_sysdata,
"SECO system data manager",
"sysdata [command] [options]\n"
" command:\n"
" - version - shows sysdata version.\n"
" - dev - shows current device used to read/write sysdata.\n"
" (sets env sysdata_device with reference to kernel space device id).\n"
" - initialize - reset all memory reserved to SysData with factory data.\n"
" - switchslot <subcommand>\n"
" subcommand:\n"
" - status - shows current state switching slot system.\n"
" - global_counter [enable | disable] - enable/disable the global boot counter.\n"
" - fail_counter [enable | disable] - enable/disable the fail boot counter.\n"
" - set_primary [slot ID] - set a slot as primary in boot order list.\n"
" - remove_slot [slot ID] - remove a slot from boot order list.\n"
" - invalidate_slot [slot ID] - invalidate a slot.\n",
var_complete
);
#ifndef _SYSTEMDATA_H_
#define _SYSTEMDATA_H_
/*
* Note: Use USE_HOSTCC to determine if we're compiling for U-Boot or
* for an external tool (in which case, we need additional includes).
/* 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 <common.h>
#include <linux/kconfig.h>
#include <common.h>
#else
#include <ctype.h>
#include <stdint.h>
#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 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 SYSDATA_MAX_SLOTS 2
#define SLOT_NULL 0
#define SYSDATA_MAX_FAIL_BOOT 3
#define SYSDATA_GLOBAL_BOOT_COUNT_ENABLE 0
#define ENV_SYSDATA_GROUP_PART "slot_partition"
#define FAIL_BOOT_COUNT_ENABLE_SHIFT 0
#define GLOBAL_BOOT_COUNT_ENABLE_SHIFT 1
#define SLOT_NUM2ID(x) ((char)((x) + 64)) // x=1 -> A, x=2 -> B
#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;
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];
uint32_t current_boot_slot;
uint32_t previous_boot_slot;
uint32_t boot_fail_counter;
uint8_t enable_counter;
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;
switching_table_t switch_table;
} sysdata_data_t;
typedef struct systemdata {
sysdata_header_t header;
sysdata_data_t data;
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))
#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;
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);
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 const char* get_sysdata_version(void);
/* switchpart functions */
extern int get_switchslot_data(switching_table_t* switch_data);
extern int get_switchslot_max_fail_boot(void);
extern int sysdata_init( void );
extern int sysdata_integration_check( void );
/**
* switchslot_group_round_way( ) - switch partitions slot in round way
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 switches partitions slot to the next one. If the current group is
* the last one (tail), the selected group will be ne first one (head)
* 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
*
* @return the current partitions slot
*/
extern int switch_slot(switch_group_alg_t alg);
/**
* sysdata_switchslot_check( ) - check if the max number of fail boot was reached
* 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 switches partitions slot with round way algorithm if the maximum number
* of fail boot was reached
* 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
*
* @return 0 if ok, number of current partitions slot in case of switching
*/
extern int sysdata_switchslot_check(void);
* 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 );
/**
* sysdata_switchslot_boot_inc( ) - increment the number of boot
#ifndef USE_HOSTCC
/**
* sysdata_switchslot_current_env( ) - create a environment variable for valid slot
*
* This increments the number of boot
* 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_inc(void);
/**
*/
extern int sysdata_switchslot_boot_counter_update( void );
/**
* sysdata_switchslot_boot_ok( ) - initialize the fail boot counter
*
* This inizializes the fail boot counter in order to sign a valid boot
* 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_boot_ok(void);
/**
* sysdata_switchslot_enable_counter( ) - set the enable for the fail boot counter
*/
extern int sysdata_switchslot_set_primary( char slot_id );
/**
* sysdata_switchslot_remote_from_boot_order( ) - remove slot from boot order list
*
* This set the fail boot counter enable
* 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_enable_counter(int en);
*/
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) \
#define U_BOOT_SYSDATA_LOCATION(__name) \
ll_entry_declare(struct sysdata_driver, __name, sysdata_driver)
void sysdata_switchslot_current_env(void);
/* 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);
extern int _sysdata_rd( sysdata_t *table );
extern int _sysdata_wr( sysdata_t *table );
#endif
#endif /* _SYSTEMDATA_H_ */
#endif /* _SYSTEMDATA_H_ */
......@@ -3,17 +3,13 @@
# (C) Copyright 2004-2006
# Davide Cardillo, SECO SpA, seco.com
menuconfig SECO_SYSTEM_DATA
bool "SECO System Data Manager"
default n
bool "Seco System Data"
help
The SECO System Data Manager creates an additional environment
alongside the U-Boot default environment. This additional env-
ironment stores mostly boot related parameters/information (e.g.
active boot partition, boot failures, etc.).
SECO System Data Manager
config SECO_SYSDATA_IN_MMC
bool "Place System Data Environment on MMC"
default y
bool "System Data is placed in MMC"
depends on SECO_SYSTEM_DATA
......@@ -3,6 +3,8 @@
# (C) Copyright 2004-2006
# Davide Cardillo, SECO SpA, seco.com
ifndef CONFIG_SPL_BUILD
ifeq ($(CONFIG_SECO_SYSTEM_DATA),y)
......
#include <common.h>
#include <command.h>
#include <errno.h>
#include <sysdata.h>
#include <fdtdec.h>
#include <linux/stddef.h>
#include <malloc.h>
#include <memalign.h>
#include <part.h>
#include <search.h>
#include <sysdata.h>
#include <errno.h>
#include <mmc.h>
#define CONFIG_SYSDATA_MMC_DEV 1
#define CONFIG_SYSDATA_OFFSET CONFIG_ENV_OFFSET - SZ_2K
#define CONFIG_SYSDATA_MMC_DEV 1
#define CONFIG_SYSDATA_OFFSET CONFIG_ENV_OFFSET - SZ_2K
static unsigned char env_mmc_orig_hwpart;
static int mmc_set_sysdata_part(struct mmc* mmc)
{
/* uint part = mmc_get_env_part( mmc ); */
uint part = 0;
int dev = mmc_get_env_dev();
static int mmc_set_sysdata_part( struct mmc *mmc ) {
uint part = mmc_get_env_part( mmc );
int dev = mmc_get_env_dev( );
int ret = 0;
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
env_mmc_orig_hwpart = mmc_get_blk_desc( mmc )->hwpart;
ret = blk_select_hwpart_devnum( IF_TYPE_MMC, dev, part );
return ret;
}
static void mmc_clean_setting(struct mmc* mmc)
{
static void mmc_clean_setting( struct mmc *mmc ) {
#ifdef CONFIG_SYS_MMC_ENV_PART
int dev = mmc_get_env_dev();
int dev = mmc_get_env_dev( );
blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart);
blk_select_hwpart_devnum( IF_TYPE_MMC, dev, env_mmc_orig_hwpart );
#endif
}
__weak int mmc_get_sysdata_addr(struct mmc* mmc, int copy, u32* sysdata_addr)
{
__weak int mmc_get_sysdata_addr( struct mmc *mmc, int copy, u32 *sysdata_addr ) {
s64 offset = CONFIG_SYSDATA_OFFSET;
if (offset < 0)
if ( offset < 0 )
offset += mmc->capacity;
*sysdata_addr = offset;
......@@ -51,146 +52,152 @@ __weak int mmc_get_sysdata_addr(struct mmc* mmc, int copy, u32* sysdata_addr)
return 0;
}
static inline ulong write_sysdata(struct mmc* mmc, unsigned long size, unsigned long offset,
const void* buffer)
static inline ulong write_sysdata( struct mmc *mmc, unsigned long size,
unsigned long offset, const void *buffer )
{
ulong blk_start, blk_cnt, n;
struct blk_desc* desc = mmc_get_blk_desc(mmc);
ulong blk_start, blk_cnt, n;
struct blk_desc *desc = mmc_get_blk_desc( mmc );
blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len;
blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len;
blk_start = ALIGN( offset, mmc->write_bl_len ) / mmc->write_bl_len;
blk_cnt = ALIGN( size, mmc->write_bl_len ) / mmc->write_bl_len;
n = blk_dwrite(desc, blk_start, blk_cnt, (u_char*)buffer);
n = blk_dwrite( desc, blk_start, blk_cnt, (u_char *)buffer );
return (n == blk_cnt) ? 0 : -1;
return ( n == blk_cnt ) ? 0 : -1;
}
static inline ulong read_sysdata(struct mmc* mmc, unsigned long size, unsigned long offset,
void* buffer)
static inline ulong read_sysdata( struct mmc *mmc, unsigned long size,
unsigned long offset, void *buffer )
{
ulong blk_start, blk_cnt, n;
struct blk_desc* desc = mmc_get_blk_desc(mmc);
ulong blk_start, blk_cnt, n;
struct blk_desc *desc = mmc_get_blk_desc(mmc);
blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
blk_start = ALIGN( offset, mmc->read_bl_len ) / mmc->read_bl_len;
blk_cnt = ALIGN( size, mmc->read_bl_len ) / mmc->read_bl_len;
n = blk_dread(desc, blk_start, blk_cnt, (u_char*)buffer);
n = blk_dread( desc, blk_start, blk_cnt, (u_char *)buffer );
return (n == blk_cnt) ? 0 : -1;
}
static int init_device(struct mmc** mmc)
{
int dev = mmc_get_env_dev();
*mmc = find_mmc_device(dev);
static int init_device( struct mmc **mmc ) {
int dev = mmc_get_env_dev( );
*mmc = find_mmc_device( dev );
if (!(*mmc))
return -ENODEV;
if ( !(*mmc) )
return -ENODEV;
#if CONFIG_IS_ENABLED(BLK)
struct udevice* udev;
struct udevice *udev;
if (blk_get_from_parent((*mmc)->dev, &udev))
return -EINVAL;
if ( blk_get_from_parent( (*mmc)->dev, &udev ) )
return -EINVAL;
#else
if (mmc_init(*mmc))
if ( mmc_init( *mmc ) )
return -ENOMEM;
#endif
mmc_set_sysdata_part(*mmc);
return 0;
mmc_set_sysdata_part( *mmc );
return 0;
}
static int sysdata_mmc_load(sysdata_t* rd_data)
{
int dev = mmc_get_env_dev();
struct mmc* mmc = find_mmc_device(dev);
int ret = 0;
u32 offset = 0;
ret = init_device(&mmc);
if (ret) {
// error
return ret;
}
static int sysdata_mmc_load( sysdata_t *rd_data ) {
int dev = mmc_get_env_dev( );
struct mmc *mmc = find_mmc_device(dev);
int ret = 0;
u32 offset = 0;
ALLOC_CACHE_ALIGN_BUFFER(
u_char, buf, mmc->write_bl_len > sizeof(sysdata_t) ? mmc->write_bl_len : sizeof(sysdata_t));
ret = init_device( &mmc );
if ( ret ) {
// error
return ret;
}
if (mmc_get_sysdata_addr(mmc, 0, &offset)) {
// error
return -EINVAL;
}
ALLOC_CACHE_ALIGN_BUFFER( u_char, buf,
mmc->write_bl_len > sizeof(sysdata_t) ? mmc->write_bl_len : sizeof(sysdata_t) );
if (read_sysdata(mmc, SYSTEMDATA_SIZE, offset, (u_char*)buf)) {
// error
return -ENOMEM;
}
if ( mmc_get_sysdata_addr( mmc, 0, &offset ) ) {
// error
return -EINVAL;
}
mmc_clean_setting(mmc);
if ( read_sysdata( mmc, SYSTEMDATA_SIZE, offset, (u_char *)buf ) ) {
// error
return -ENOMEM;
}
memcpy(rd_data, buf, sizeof(sysdata_t));
mmc_clean_setting( mmc );
return ret;
memcpy( rd_data, buf, sizeof(sysdata_t) );
return ret;
}
static int sysdata_mmc_save(sysdata_t* new_data)
{
int dev = mmc_get_env_dev();
struct mmc* mmc = find_mmc_device(dev);
int ret = 0;
u32 offset = 0;
ret = init_device(&mmc);
if (ret) {
// error
return ret;
}
static int sysdata_mmc_save( sysdata_t *new_data ) {
int dev = mmc_get_env_dev( );
struct mmc *mmc = find_mmc_device(dev);
int ret = 0;
u32 offset = 0;
ALLOC_CACHE_ALIGN_BUFFER(
u_char, buf, mmc->write_bl_len > sizeof(sysdata_t) ? mmc->write_bl_len : sizeof(sysdata_t));
if (mmc_get_sysdata_addr(mmc, 0, &offset)) {
// error
return -EINVAL;
}
ret = init_device( &mmc );
if ( ret ) {
// error
return ret;
}
/* the write block size may be bigger then the data size we are writing, so
* a read of the whole block is need. */
if (read_sysdata(mmc, SYSTEMDATA_SIZE, offset, (u_char*)buf)) {
// error
return -ENOMEM;
}
memcpy(buf, new_data, sizeof(sysdata_t));
ALLOC_CACHE_ALIGN_BUFFER( u_char, buf,
mmc->write_bl_len > sizeof(sysdata_t) ? mmc->write_bl_len : sizeof(sysdata_t) );
if (write_sysdata(mmc, SYSTEMDATA_SIZE, offset, (u_char*)buf)) {
// error
return -ENOMEM;
}
if ( mmc_get_sysdata_addr( mmc, 0, &offset ) ) {
// error
return -EINVAL;
}
mmc_clean_setting(mmc);
return ret;
/* the write block size may be bigger then the data size we are writing, so
a read of the whole block is need.
*/
if ( read_sysdata( mmc, SYSTEMDATA_SIZE, offset, (u_char *)buf ) ) {
// error
return -ENOMEM;
}
memcpy( buf, new_data, sizeof(sysdata_t) );
if ( write_sysdata( mmc, SYSTEMDATA_SIZE, offset, (u_char *)buf ) ) {
// error
return -ENOMEM;
}
mmc_clean_setting( mmc );
return ret;
}
static const char* get_device_name(void)
{
int dev = mmc_get_env_dev();
char* name;
name = malloc(sizeof(char) * SYSDATA_DEV_NAME_LEN);
if (!name)
static const char *get_device_name( void ) {
int dev = mmc_get_env_dev( );
char *name;
name = malloc( sizeof(char) * SYSDATA_DEV_NAME_LEN );
if ( !name )
return NULL;
sprintf(name, "MMC%d", dev);
return (const char*)name;
sprintf( name, "MMC%d", dev );
return (const char *)name;
}
U_BOOT_SYSDATA_LOCATION(mmc) = {
//.location = 0,
.name = "MMC",
.load = sysdata_mmc_load,
.save = sysdata_mmc_save,
.name = "MMC",
.load = sysdata_mmc_load,
.save = sysdata_mmc_save,
.get_device_name = get_device_name,
};
This diff is collapsed.
This diff is collapsed.
#ifndef _FW_SYSTEMDATA_H_
#define _FW_SYSTEMDATA_H_
#ifdef MTD_OLD
#include <linux/mtd/mtd.h>
#include <stdint.h>
# include <stdint.h>
# include <linux/mtd/mtd.h>
#else
#define __user /* nothing */
#include <mtd/mtd-user.h>
# define __user /* nothing */
# include <mtd/mtd-user.h>
#endif
#include <sysdata.h>
typedef struct sysdev {
const char* devname; /* Device name */
long long devoff; /* Device offset */
ulong env_size; /* environment size */
ulong erase_size; /* device erase size */
ulong env_sectors; /* number of environment sectors */
uint8_t mtd_type; /* type of the MTD device */
int is_ubi; /* set if we use UBI volume */
const char *devname; /* Device name */
long long devoff; /* Device offset */
ulong env_size; /* environment size */
ulong erase_size; /* device erase size */
ulong env_sectors; /* number of environment sectors */
uint8_t mtd_type; /* type of the MTD device */
int is_ubi; /* set if we use UBI volume */
} sysdev_t;
#define SZ_2K 0x00000800
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
#define SZ_2K 0x00000800
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define min(x, y) \
({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void)(&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; \
})
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
extern int dev_current;
static sysdev_t sysdevice[3] = {
{
.devname = "/dev/mmcblk0",
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.env_size = SYSTEMDATA_SIZE,
.erase_size = 0,
.env_sectors = 0,
.mtd_type = MTD_ABSENT,
.is_ubi = 0,
},
{
}, {
.devname = "/dev/mmcblk1",
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.env_size = SYSTEMDATA_SIZE,
.erase_size = 0,
.env_sectors = 0,
.mtd_type = MTD_ABSENT,
.is_ubi = 0,
},
{
}, {
.devname = "/dev/mmcblk2",
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.devoff = CONFIG_ENV_OFFSET - SZ_2K,
.env_size = SYSTEMDATA_SIZE,
.erase_size = 0,
.env_sectors = 0,
......@@ -64,23 +59,23 @@ static sysdev_t sysdevice[3] = {
},
};
#define DEVNAME(i) sysdevice[(i)].devname
#define DEVOFFSET(i) sysdevice[(i)].devoff
#define DATASIZE(i) sysdevice[(i)].env_size
#define DEVESIZE(i) sysdevice[(i)].erase_size
#define DEVNAME(i) sysdevice[(i)].devname
#define DEVOFFSET(i) sysdevice[(i)].devoff
#define DATASIZE(i) sysdevice[(i)].env_size
#define DEVESIZE(i) sysdevice[(i)].erase_size
#define DATASECTORS(i) sysdevice[(i)].env_sectors
#define DEVTYPE(i) sysdevice[(i)].mtd_type
#define IS_UBI(i) sysdevice[(i)].is_ubi
#define DEVTYPE(i) sysdevice[(i)].mtd_type
#define IS_UBI(i) sysdevice[(i)].is_ubi
#define CUR_SYSDATASIZE DATASIZE(dev_current)
static int is_device_valid(const char* device_name)
{
int num = sizeof(sysdevice) / sizeof(sysdev_t);
static int is_device_valid( const char * device_name ) {
int num = sizeof( sysdevice ) / sizeof ( sysdev_t );
int device_id = -1;
int i;
for (i = 0; i < num; i++) {
if (strcmp(device_name, DEVNAME(i)) == 0) {
for ( i = 0 ; i < num ; i++ ) {
if ( strcmp( device_name, DEVNAME(i) ) == 0 ) {
device_id = i;
break;
}
......@@ -88,4 +83,5 @@ static int is_device_valid(const char* device_name)
return device_id;
}
#endif /* _FW_SYSTEMDATA_H_ */
#endif /* _FW_SYSTEMDATA_H_ */
#include "../../sysdata/sysdata.c"
#include "../../sysdata/sysdata.c"
\ No newline at end of file
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment