blob: 6b2b3750472355eaa7ab8f8c2f28e4a38206850e [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#ifndef __STORAGE_H__
#define __STORAGE_H__
#include <common.h>
#include <command.h>
#include <console.h>
#include <watchdog.h>
#include <malloc.h>
#include <asm/byteorder.h>
#include <jffs2/jffs2.h>
#define RSV_UNVAIL 140 /* rsv unvail error */
#define DISPROTECT_KEY BIT(0)
#define DISPROTECT_SECURE BIT(1)
#define DISPROTECT_FBBT BIT(2)
#define DISPROTECT_HYNIX BIT(3)
#define PART_PROTECT_FLAG BIT(4)
enum boot_type_e {
BOOT_EMMC = 1,
BOOT_SD = 1 << 1,
BOOT_NAND_NFTL = 1 << 2,
BOOT_NAND_MTD = 1 << 3,
BOOT_SNAND = 1 << 4,/* spi nand */
BOOT_SNOR = 1 << 5,/* spi nor */
BOOT_NONE = 0xFF
};
#define RSV_KEY "key"
#define RSV_ENV "env"
#define RSV_DTB "dtb"
#define RSV_BBT "bbt"
#define RSV_DDR_PARA "ddr_para"
#define DISCRETE_BOOTLOADER 1
#define COMPACT_BOOTLOADER 0
struct nand_startup_parameter {
int page_size;
int block_size;
int layout_reserve_size;
int pages_per_block;
int setup_data;
/* */
int page0_disable;
};
#define BL2E_STORAGE_PARAM_SIZE (0x80)
//#define BOOT_FIRST_BLOB_SIZE (166*1024)
#define BOOT_FILLER_SIZE (4*1024)
#define BOOT_RESERVED_SIZE (4*1024)
#define BOOT_RANDOM_NONCE (16)
#define BOOT_BL2E_SIZE (66672) //74864-8K
#define BOOT_EBL2E_SIZE (BOOT_FILLER_SIZE + BOOT_RESERVED_SIZE + BOOT_BL2E_SIZE)
#define BOOT_BL2X_SIZE (66672)
#define MAX_BOOT_AREA_ENTRIES (8)
/* bl2 core address base */
#define BL2_CORE_BASE_OFFSET_EMMC (0x200)
/* boot area entry index */
#define BOOT_AREA_BB1ST (0)
/* filler and reserved are considered part of the bl2E in storage view */
#define BOOT_AREA_BL2E (1)
#define BOOT_AREA_BL2X (2)
#define BOOT_AREA_DDRFIP (3)
#define BOOT_AREA_DEVFIP (4)
#define BOOT_AREA_INVALID (MAX_BOOT_AREA_ENTRIES)
typedef struct boot_area_entry {
/* name */
char name[11];
/* index */
uint8_t idx;
uint64_t offset;
uint64_t size;
} boot_area_entry_t;
struct boot_layout {
boot_area_entry_t *boot_entry;
};
struct emmc_startup_parameter {
//sd_emmc_setup_t setup;
};
struct spi_nand_startup_parameter {
uint32_t pagesize;
uint32_t pages_per_eraseblock;
uint32_t eraseblocks_per_lun;
uint32_t planes_per_lun;
uint32_t luns_per_target;
uint32_t ntargets;
int layout_reserve_size;
};
struct storage_boot_entry {
uint32_t offset;
uint32_t size;
};
union storage_independent_parameter {
struct nand_startup_parameter nsp;
struct emmc_startup_parameter esp;
struct spi_nand_startup_parameter snasp;
};
struct storage_startup_parameter {
uint8_t boot_device;
uint8_t boot_seq;
uint8_t boot_bakups;
uint8_t reserved;
struct storage_boot_entry boot_entry[MAX_BOOT_AREA_ENTRIES];
union storage_independent_parameter sip;
};
struct storage_info_t {
u8 name[32];
u8 id[8];
u32 read_unit;
u32 write_unit;
u32 erase_unit;
u64 caps;/* total size */
u8 mode;/* bootloader mode, compact or discrete */
};
struct storage_t {
enum boot_type_e type;
struct storage_info_t info;
u32 init_flag;
struct list_head list;
int (*get_part_count)(void);
int (*list_part_name)(int idx, char *part_name);
/* when part_name is null, default to ops in whole chip */
/* int (*block_is_bad)(const char *part_name, loff_t off); */
u64 (*get_part_size)(const char *part_name);
int (*read)(const char *part_name, loff_t off,
size_t size, void *dest);
int (*write)(const char *part_name, loff_t off,
size_t size, void *source);
int (*erase)(const char *part_name, loff_t off,
size_t size, int scrub_flag);
#define BOOT_OPS_ALL 0xFF/* for cpy parameter operates all copies */
u8 (*get_copies)(const char *part_name);
u64 (*get_copy_size)(const char *part_name);
int (*boot_read)(const char *part_name,
u8 cpy, size_t size, void *dest);
int (*boot_write)(const char *part_name,
u8 cpy, size_t size, void *source);
int (*boot_erase)(const char *part_name, u8 cpy);
int (*gpt_read)(void *dest);
int (*gpt_write)(void *source);
int (*gpt_erase)(void);
u32 (*get_rsv_size)(const char *rsv_name);
int (*read_rsv)(const char *rsv_name, size_t size, void *buf);
int (*write_rsv)(const char *rsv_name, size_t size, void *buf);
int (*erase_rsv)(const char *rsv_name);
int (*protect_rsv)(const char *rsv_name,
bool ops);/*true:on false:off*/
};
struct device_node_t {
enum boot_type_e index;
char *type;
int (*pre)(void);
int (*probe)(u32 init_flag);
};
/**
* we use a valid device list to manage the storage devices,
* and every type of device can only exist ONE in this list.
* we will scan and add the valid storage device to the list
* in the init process, and of cause you can register the device
* by you own.
*/
#define NAND_BOOT_NORMAL 0
#define NAND_BOOT_UPGRATE 1
#define NAND_BOOT_ERASE_PROTECT_CACHE 2
#define NAND_BOOT_ERASE_ALL 3
#define NAND_BOOT_SCRUB_ALL 4
#define NAND_SCAN_ID_INIT 5
/**
* @usage: init all the valid storage device
*
* @init_flag: it's only works for MLC/EMMC driver
* 0 NAND_BOOT_NORMAL:normal init, but can't operates the phy data area
* 1 NAND_BOOT_UPGRATE:same as 0, but operation on phy data area is allowed
* 2 NAND_BOOT_ERASE_PROTECT_CACHE:only erase rsv area
* 3 NAND_BOOT_ERASE_ALL:erase whole device
* 4 NAND_BOOT_SCRUB_ALL:erase whole device
* 5 NAND_SCAN_ID_INIT:only read nand id
*
* @return: init result
* 0 = failed
* other = device_index that device probe successfully
*/
int store_init(u32 init_flag);
/**
* @usage: register a storage device to the valid list
*
* @param: the description pointer of your storage device
*
* @return: registration result
* 0 = success
* 1 = fail
*/
int store_register(struct storage_t *store_dev);
/**
* @usage: unregister a storage device from the valid list
*
* @store_dev: the description pointer of your storage device
*/
void store_unregister(struct storage_t *store_dev);
/**
* @usage: check the type of device is valid on this board
*
* @type: the device type that you want to check
*
* @return: is the device valid
* 0 = invalid
* 1 = valid
*/
u8 store_device_valid(enum boot_type_e type);
/**
* @usage: set the 'type' device as current device, and you can operates it
*
* @type: the device type that you want to set
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_set_device(enum boot_type_e type);
/**
* @usage: get the type of current storage device
*
* @return: storage device type
*/
enum boot_type_e store_get_type(void);
/**
* @usage: get information about the current device
*
* @info: the pointer for the information
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_get_device_info(struct storage_info_t *info);
/**
* @usage: read data from storage device
*
* @name: partition name, when it's null the target
* will regards as whole device.
* @off: offset to the 0 address of partition/device
* @size: the amount of bytes to read
* @buf: pointer of target buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_read(const char *name, loff_t off, size_t size, void *buf);
/**
* @usage: write data to storage device
*
* @name: partition name, when it's null the target
* will regards as whole device.
* @off: offset to the 0 address of partition/device
* @size: the amount of bytes to write
* @buf: pointer of source buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_write(const char *name, loff_t off, size_t size, void *buf);
/**
* @usage: erase the storage device
*
* @name: partition name, when it's null the target
* will regards as whole device.
* @off: offset to the 0 address of partition/device
* @size: the amount of bytes to erase
* @scrub: scrub flag(scrub operates will works only when the device support)
* 0 = no scrub, just erase
* 1 = use scrub operates instead of erase
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_erase(const char *name, loff_t off, size_t size, int scrub);
/**
* @usage: get the partition size or capacity of device
*
* @name: partition name, when it's null the target
* will regards as whole device.
*
* @return: the amount of bytes to the partition or device size
*/
u64 store_part_size(const char *name);
/**
* @usage: get the copy number of [name]
*
* @name: only can be "bl2" or "tpl"/"fip" in discrete mode
* be "bootloader" in compact mode
* @return: the copy number of the "bootloader" or "tpl"
*/
u8 store_boot_copy_num(const char *name);
/**
* @usage: get the 1st boot copy nubmer of current device.
* for eMMC: 0 -> user partition; 1 -> boot0; 2 -> boot1
*/
u8 store_boot_copy_start(void);
/**
* @usage: get the bootup index of [name]
*
* @name: do not care discrete mode or compact mode
* "bl2" "spl" could be used as the one romboot loaded
* "fip" "devfip" "tpl" or "bootloader" would be the main u-boot.
* @return: the copy number of the "bootloader" or "tpl"
*/
u8 store_bootup_bootidx(const char *name);
/**
* @usage: restore the bootidx/bootdev etc.
*/
void store_restore_bootidx(void);
/**
* @usage: get the copy size of [name]
*
* @name: name: only can be "bl2" or "tpl"/"fip" in discrete mode
* be "bootloader" in compact mode
*
* @return: the size of every copy
*/
u64 store_boot_copy_size(const char *name);
/**
* @usage: read the [name] data from storage device
*
* @name: only can be "bl2" or "tpl"/"fip" in discrete mode
* be "bootloader" in compact mode
* @copy: which copy you want read
* @size: the amount of bytes to read
* @buf: pointer of the target buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_boot_read(const char *name, u8 copy, size_t size, void *buf);
/**
* @usage: write the [name] data into storage device
*
* @name: only can be "bl2" or "tpl"/"fip" in discrete mode
* be "bootloader" in compact mode
* @copy: which copy you want write,
* it will write to all copies when copy = BOOT_OPS_ALL
* @size: the amount of bytes to write
* @buf: pointer of the source buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_boot_write(const char *name, u8 copy, size_t size, void *buf);
/**
* @usage: erase the [name] data
*
* @name: only can be "bl2" or "tpl"/"fip" in discrete mode
* be "bootloader" in compact mode
* @copy: which copy you want erase,
* it will erase all copies when copy = BOOT_OPS_ALL
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_boot_erase(const char *name, u8 copy);
/**
* @usage: get the rsv info size
*
* @name: rsv info name, please refer to
* RSV_KEY "key"
* RSV_ENV "env"
* RSV_DTB "dtb"
* RSV_BBT "bbt"
*
* @return: the amount bytes of the rsv info
*/
u32 store_rsv_size(const char *name);
/**
* @usage: read the rsv info from storage device
*
* @name: rsv info name, please refer to
* RSV_KEY "key"
* RSV_ENV "env"
* RSV_DTB "dtb"
* RSV_BBT "bbt"
* @size: the amount of bytes to read
* @buf: pointer of the target buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_rsv_read(const char *name, size_t size, void *buf);
/**
* @usage: write the rsv info to the storage device
*
* @name: rsv info name, please refer to
* RSV_KEY "key"
* RSV_ENV "env"
* RSV_DTB "dtb"
* RSV_BBT "bbt"
* @size: the amount of bytes to write
* @buf: pointer of the source buffer
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_rsv_write(const char *name, size_t size, void *buf);
/**
* @usage: erase the rsv info
*
* @name: rsv info name, please refer to
* RSV_KEY "key"
* RSV_ENV "env"
* RSV_DTB "dtb"
* RSV_BBT "bbt"
* it will erase all reserve information
* when name is null
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_rsv_erase(const char *name);
/**
* @usage: turn on/off the protection of rsv info
*
* @name: rsv info name, please refer to
* RSV_KEY "key"
* RSV_ENV "env"
* RSV_DTB "dtb"
* RSV_BBT "bbt"
* it will operates all reserve information
* when name is null
* @ops: turn on/off the rsv info protection
* true = turn on the protection
* flase = turn off the protection
*
* @return: result of the operation
* 0 = success
* other = fail
*/
int store_rsv_protect(const char *name, bool ops);
/**
* @usage: get bootloader mode for current storage
*
* @return: result of the operation
* 0 = COMPACT_BOOTLOADER
* 1 = DISCRETE_BOOTLOADER
*/
int store_get_device_bootloader_mode(void);
int sheader_need(void);
void sheader_load(void *addr);
int store_gpt_read(void *buf);
int store_gpt_write(void *buf);
int store_gpt_erase(void);
#endif/* __STORAGE_H__ */