rockchip: block: add rkmtd class and drivers

Add rkmtd class and drivers to create a virtual block device
to transfer Rockchip boot block data to and from NAND with
block orientated tools like "ums" and "rockusb".

Signed-off-by: Johan Jonker <jbx6244@gmail.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
Johan Jonker 2023-10-18 16:00:56 +02:00 committed by Kever Yang
parent 900c303a02
commit 80201eccaa
4 changed files with 1352 additions and 0 deletions

View File

@ -262,3 +262,10 @@ config SYS_64BIT_LBA
help
Make the block subsystem use 64bit sector addresses, rather than the
default of 32bit.
config RKMTD
bool "Rockchip rkmtd virtual block device"
help
Enable "rkmtd" class and driver to create a virtual block device
to transfer Rockchip boot block data to and from NAND with block
orientate tools like "ums" and "rockusb".

View File

@ -11,6 +11,7 @@ endif
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_IDE) += ide.o
obj-$(CONFIG_RKMTD) += rkmtd.o
endif
obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
@ -19,3 +20,4 @@ obj-$(CONFIG_BLKMAP) += blkmap.o
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o

1152
drivers/block/rkmtd.c Normal file

File diff suppressed because it is too large Load Diff

191
include/rkmtd.h Normal file
View File

@ -0,0 +1,191 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Driver interface derived from:
* /include/sandbox_host.h
* Copyright 2022 Google LLC
*
* Copyright 2023 Johan Jonker <jbx6244@gmail.com>
*/
#ifndef __RKMTD__
#define __RKMTD__
#include <part_efi.h>
#include <uuid.h>
#define LBA 64 + 512 + 33
#define RK_TAG 0xFCDC8C3B
#define NFC_SYS_DATA_SIZE 4
#define BLK_SIZE 2048
#define STEP_SIZE 1024
#define BUF_SIZE 512 * 512
struct nand_para_info {
u8 id_bytes;
u8 nand_id[6];
u8 vendor;
u8 die_per_chip;
u8 sec_per_page;
u16 page_per_blk;
u8 cell;
u8 plane_per_die;
u16 blk_per_plane;
u16 operation_opt;
u8 lsb_mode;
u8 read_retry_mode;
u8 ecc_bits;
u8 access_freq;
u8 opt_mode;
u8 die_gap;
u8 bad_block_mode;
u8 multi_plane_mode;
u8 slc_mode;
u8 reserved[5];
};
struct bootblk {
int blk;
int boot_size;
int offset;
};
struct rkmtd_dev {
struct udevice *dev;
struct blk_desc *desc;
char *label;
legacy_mbr *mbr;
gpt_header *gpt_h;
gpt_header *gpt_h2;
gpt_entry *gpt_e;
char *check;
char *idb;
char *str;
char uuid_part_str[UUID_STR_LEN + 1];
char uuid_disk_str[UUID_STR_LEN + 1];
char *datbuf;
char *oobbuf;
struct mtd_info *mtd;
struct nand_para_info *info;
u16 page_table[512];
u32 idb_need_write_back;
struct bootblk idblock[5];
u32 blk_counter;
u32 boot_blks;
u32 offset;
u32 boot_size;
u32 lsb_mode;
};
struct sector0 {
u32 magic;
u8 reserved[4];
u32 rc4_flag;
u16 boot_code1_offset;
u16 boot_code2_offset;
u8 reserved1[490];
u16 flash_data_size;
u16 flash_boot_size;
u8 reserved2[2];
} __packed;
/**
* rkmtd_rc4() - Rockchip specific RC4 Encryption Algorithm
*
* Encrypt Rockchip boot block header version 1 and data
*
* @buf: Pointer to data buffer
* @len: Data buffer size
*/
void rkmtd_rc4(u8 *buf, u32 len);
/**
* struct rkmtd_ops - operations supported by UCLASS_RKMTD
*/
struct rkmtd_ops {
/**
* @attach_mtd: - Attach a new rkmtd driver to the device structure
*
* @attach_mtd.dev: Device to update
* @attach_mtd.Returns: 0 if OK, -EEXIST if a driver is already attached,
* other -ve on other error
*/
int (*attach_mtd)(struct udevice *dev);
/**
* @detach_mtd: - Detach a rkmtd driver from the device structure
*
* @detach_mtd.dev: Device to detach from
* @detach_mtd.Returns: 0 if OK, -ENOENT if no driver is attached,
* other -ve on other error
*/
int (*detach_mtd)(struct udevice *dev);
};
#define rkmtd_get_ops(dev) ((struct rkmtd_ops *)(dev)->driver->ops)
/**
* rkmtd_get_cur_dev() - Get the current device
*
* Returns current device, or NULL if none
*/
struct udevice *rkmtd_get_cur_dev(void);
/**
* rkmtd_set_cur_dev() - Set the current device
*
* Sets the current device, or clears it if @dev is NULL
*
* @dev: Device to set as the current one
*/
void rkmtd_set_cur_dev(struct udevice *dev);
/**
* rkmtd_find_by_label() - Find a rkmtd device by label
*
* Searches all rkmtd devices to find one with the given label
*
* @label: Label to find
* Returns: associated device, or NULL if not found
*/
struct udevice *rkmtd_find_by_label(const char *label);
/**
* rkmtd_attach() - Attach a new rkmtd driver to the device structure
*
* @dev: Device to update
* Returns: 0 if OK, -EEXIST if a file is already attached, other -ve on
* other error
*/
int rkmtd_attach(struct udevice *dev);
/**
* rkmtd_detach() - Detach a rkmtd driver from the device structure
*
* @dev: Device to detach from
* Returns: 0 if OK, -ENOENT if no file is attached, other -ve on other
* error
*/
int rkmtd_detach(struct udevice *dev);
/**
* rkmtd_create_device() - Create a new rkmtd device
*
* Any existing device with the same label is removed and unbound first
*
* @label: Label of the attachment, e.g. "test1"
* @devp: Returns the device created, on success
* Returns: 0 if OK, -ve on error
*/
int rkmtd_create_device(const char *label, struct udevice **devp);
/**
* rkmtd_create_attach_mtd() - Create a new rkmtd device and attach driver
*
* @label: Label of the attachment, e.g. "test1"
* @devp: Returns the device created, on success
* Returns: 0 if OK, -ve on error
*/
int rkmtd_create_attach_mtd(const char *label, struct udevice **devp);
#endif /* __RKMTD__ */