From 101dc7a4d51fd3696f53cd83e1e649076c85ddff Mon Sep 17 00:00:00 2001 From: laokz Date: Sun, 7 Mar 2021 17:44:13 +0800 Subject: [PATCH] update CFI flash driver: replace vm region mapping with I/O space addressing; implement erase method; modify erase-block size for correct erase Change-Id: I64d2126b485d0bbd5cefcc6a41b4eaac1cb687e1 --- arm/virt/README.en.md | 3 +- arm/virt/README.md | 3 +- arm/virt/config/cfiflash/cfi_config.hcs | 2 -- arm/virt/config/cfiflash/cfiflash.c | 24 +++++++++++--- arm/virt/config/cfiflash/cfiflash.h | 6 ++-- arm/virt/config/cfiflash/hdf_cfi.c | 43 +++++-------------------- 6 files changed, 34 insertions(+), 47 deletions(-) diff --git a/arm/virt/README.en.md b/arm/virt/README.en.md index 62e11f9..be93ef5 100644 --- a/arm/virt/README.en.md +++ b/arm/virt/README.en.md @@ -46,7 +46,7 @@ Note: The introduced functionality was tested on virt-5.1 target machine. It is b) Prepare flash image file. Now its capacity was hard-coded 64M with 3 partitions, 1st 10M for kernel image, 2nd 27M for rootfs, 3rd 27M for userfs. Linux host can reference following commands: ``` -sudo modprobe mtdram total_size=65536 erase_size=128 writebuf_size=2048 +sudo modprobe mtdram total_size=65536 erase_size=256 sudo mtdpart add /dev/mtd0 kernel 0 10485760 sudo mtdpart add /dev/mtd0 root 10485760 28311552 sudo mtdpart add /dev/mtd0 user 38797312 28311552 @@ -55,6 +55,7 @@ sudo nandwrite -p /dev/mtd2 out/qemu_arm_virt_ca7/rootfs.img sudo nandwrite -p /dev/mtd3 out/qemu_arm_virt_ca7/userfs.img sudo dd if=/dev/mtd0 of=flash.img sudo chown USERNAME flash.img +sudo rmmod mtdram ``` c) Run `qemu-system-arm`, enter user-space command line. diff --git a/arm/virt/README.md b/arm/virt/README.md index fe2d4dd..d94f556 100644 --- a/arm/virt/README.md +++ b/arm/virt/README.md @@ -40,7 +40,7 @@ a) 如果没有安装 `qemu-system-arm` ,安装请参考链接 [Qemu installat b) 准备flash映像文件。目前系统硬编码flash容量64M,分三个分区:分区一10M用于内核映像,分区二27M用于rootfs,分区三27M用于userfs。Linux系统可参考如下命令: ``` -sudo modprobe mtdram total_size=65536 erase_size=128 writebuf_size=2048 +sudo modprobe mtdram total_size=65536 erase_size=256 sudo mtdpart add /dev/mtd0 kernel 0 10485760 sudo mtdpart add /dev/mtd0 root 10485760 28311552 sudo mtdpart add /dev/mtd0 user 38797312 28311552 @@ -49,6 +49,7 @@ sudo nandwrite -p /dev/mtd2 out/qemu_arm_virt_ca7/rootfs.img sudo nandwrite -p /dev/mtd3 out/qemu_arm_virt_ca7/userfs.img sudo dd if=/dev/mtd0 of=flash.img sudo chown USERNAME flash.img +sudo rmmod mtdram ``` c) 运行`qemu-system-arm`,进入用户态命令行。 diff --git a/arm/virt/config/cfiflash/cfi_config.hcs b/arm/virt/config/cfiflash/cfi_config.hcs index 6ed7bea..1e0b30c 100644 --- a/arm/virt/config/cfiflash/cfi_config.hcs +++ b/arm/virt/config/cfiflash/cfi_config.hcs @@ -3,8 +3,6 @@ root { template cfi_flash_attr { match_attr = ""; pbase = 0x00000000; // slot0 - size = 0x04000000; // 64M - vbase = 0x70000000; } cfiflash0 :: cfi_flash_attr { match_attr = "qemu_virt_cfi_0"; diff --git a/arm/virt/config/cfiflash/cfiflash.c b/arm/virt/config/cfiflash/cfiflash.c index e7d1286..be3df7e 100644 --- a/arm/virt/config/cfiflash/cfiflash.c +++ b/arm/virt/config/cfiflash/cfiflash.c @@ -1,7 +1,7 @@ /* simple CFI flash driver for QEMU arm 'virt' machine, with: - * 64M = 2 bank * 1 region * 256 Erase Blocks * 128K(64 pages * 2048B) + * 64M = 1 region * 256 Erase Blocks * 256K(2 banks: 64 pages * 4096B) * 32 bits, Intel command set */ @@ -33,7 +33,6 @@ volatile uint32_t *g_cfiFlashBase; goto ERR_OUT; \ } \ } while(0) -/* TODO: let QEMU response one-64M-bank other than two-32M-bank */ #define CFIFLASH_QUERY_SIZE(p) do { \ if (p[0x27<<2] != CFIFLASH_ONE_BANK_BITS) { \ dprintf("[CFIFLASH_QUERY]0x27: %#02x\n", p[0x27<<2]); \ @@ -83,9 +82,11 @@ volatile uint32_t *g_cfiFlashBase; #define CFIFLASH_CLEAR_STATUS() do { *g_cfiFlashBase = 0x50; } while(0) #define CFIFLASH_CMD_BUFWRITE_BEGIN(blk) do { CFIFLASH_WRITE_WORD(blk, 0xE8); } while(0) -#define CFIFLASH_CMD_BUFWRITE_CONFIRM(blk) do { CFIFLASH_WRITE_WORD(blk, 0xD0); } while(0) +#define CFIFLASH_CMD_CONFIRM(blk) do { CFIFLASH_WRITE_WORD(blk, 0xD0); } while(0) #define CFIFLASH_CMD_BUFWRITE_COUNT(blk, cnt) do { CFIFLASH_WRITE_WORD(blk, (cnt)-1); } while(0) /* 0-based */ +#define CFIFLASH_CMD_ERASE_BEGIN(blk) do { CFIFLASH_WRITE_WORD(blk, 0x20); } while(0) + /* all in word(4 bytes) measure */ static void CfiFlashWriteBuf(int offset, uint32_t *buffer, size_t buflen) { @@ -109,7 +110,7 @@ static void CfiFlashWriteBuf(int offset, uint32_t *buffer, size_t buflen) } /* command buffer-write end to Erase Block address */ - CFIFLASH_CMD_BUFWRITE_CONFIRM(blkaddr); + CFIFLASH_CMD_CONFIRM(blkaddr); while (!CFIFLASH_STATUS_IS_READY(blkaddr)); buflen -= wordcount; @@ -117,7 +118,6 @@ static void CfiFlashWriteBuf(int offset, uint32_t *buffer, size_t buflen) } CFIFLASH_CLEAR_STATUS(); - CFIFLASH_RESET(offset); } static int CfiFlashQuery(void) @@ -278,6 +278,20 @@ int CfiBlkGeometry(struct inode *inode, struct geometry *geometry) int CfiMtdErase(struct MtdDev *mtd, UINT64 start, UINT64 len, UINT64 *failAddr) { + uint32_t blkaddr, count, i; + + blkaddr = CFIFLASH_ERASEBLK_WORDADDR(start >> 2); + count = (CFIFLASH_ERASEBLK_WORDADDR((start + len - 1) >> 2) - blkaddr) / CFIFLASH_ERASEBLK_WORDS + 1; + + for (i = 0; i < count; i++) { + CFIFLASH_CMD_ERASE_BEGIN(blkaddr); + CFIFLASH_CMD_CONFIRM(blkaddr); + while (!CFIFLASH_STATUS_IS_READY(blkaddr)); + + blkaddr += CFIFLASH_ERASEBLK_WORDS; + } + + CFIFLASH_CLEAR_STATUS(); return 0; } diff --git a/arm/virt/config/cfiflash/cfiflash.h b/arm/virt/config/cfiflash/cfiflash.h index 38ed219..e1937ec 100644 --- a/arm/virt/config/cfiflash/cfiflash.h +++ b/arm/virt/config/cfiflash/cfiflash.h @@ -14,18 +14,18 @@ extern "C" { #define CFI_DRIVER "/dev/cfiflash" #define CFIFLASH_CAPACITY (64 * 1024 * 1024) -#define CFIFLASH_ONE_BANK_BITS 25 /* 32M */ +#define CFIFLASH_ONE_BANK_BITS 25 #define CFIFLASH_SEC_SIZE 512 #define CFIFLASH_SEC_SIZE_BITS 9 #define CFIFLASH_SECTORS (CFIFLASH_CAPACITY / CFIFLASH_SEC_SIZE) #define CFIFLASH_SEC_TO_BYTES(sector) ({ sector << CFIFLASH_SEC_SIZE_BITS; }) -#define CFIFLASH_PAGE_SIZE 2048 +#define CFIFLASH_PAGE_SIZE (2048 * 2) /* fit QEMU of 2 banks */ #define CFIFLASH_PAGE_WORDS (CFIFLASH_PAGE_SIZE / sizeof(uint32_t)) #define CFIFLASH_PAGE_WORDS_MASK (CFIFLASH_PAGE_WORDS - 1) #define CFIFLASH_PAGE_WORDOFFSET(addr) ({ (addr) & CFIFLASH_PAGE_WORDS_MASK; }) -#define CFIFLASH_ERASEBLK_SIZE (128 * 1024) +#define CFIFLASH_ERASEBLK_SIZE (128 * 1024 * 2) /* fit QEMU of 2 banks */ #define CFIFLASH_ERASEBLK_WORDS (CFIFLASH_ERASEBLK_SIZE / sizeof(uint32_t)) #define CFIFLASH_ERASEBLK_WORDMASK (~(CFIFLASH_ERASEBLK_WORDS - 1)) #define CFIFLASH_ERASEBLK_WORDADDR(addr) ({ (addr) & CFIFLASH_ERASEBLK_WORDMASK; }) diff --git a/arm/virt/config/cfiflash/hdf_cfi.c b/arm/virt/config/cfiflash/hdf_cfi.c index 0fc5646..72e8930 100644 --- a/arm/virt/config/cfiflash/hdf_cfi.c +++ b/arm/virt/config/cfiflash/hdf_cfi.c @@ -2,8 +2,7 @@ #include "hdf_base.h" #include "hdf_device_desc.h" #include "device_resource_if.h" -#include "los_vm_map.h" -#include "los_mmu_descriptor_v6.h" +#include "los_vm_zone.h" #include "cfiflash.h" #ifdef __cplusplus @@ -27,60 +26,34 @@ struct block_operations *GetCfiBlkOps() return &g_cfiBlkops; } -static LosVmMapRegion *HdfCfiMapInit(const struct DeviceResourceNode *node) +static int HdfCfiMapInit(const struct DeviceResourceNode *node) { - int ret, count; - uint32_t pbase, len; + int ret; + uint32_t pbase; struct DeviceResourceIface *p = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); if ((ret = p->GetUint32(node, "pbase", &pbase, 0))) { HDF_LOGE("[%s]GetUint32 error:%d", __func__, ret); - return NULL; - } - if ((ret = p->GetUint32(node, "vbase", (uint32_t *)&g_cfiFlashBase, 0))) { - HDF_LOGE("[%s]GetUint32 error:%d", __func__, ret); - return NULL; - } - if ((ret = p->GetUint32(node, "size", &len, 0))) { - HDF_LOGE("[%s]GetUint32 error:%d", __func__, ret); - return NULL; + return HDF_FAILURE; } - count = (len + MMU_DESCRIPTOR_L2_SMALL_SIZE - 1) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT; - ret = LOS_ArchMmuMap(&LOS_GetKVmSpace()->archMmu, (VADDR_T)g_cfiFlashBase, pbase, count, - VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE); - if (ret != count) { - HDF_LOGE("[%s]LOS_ArchMmuMap error:%d", __func__, ret); - return NULL; - } - LosVmMapRegion *r; - r = LOS_RegionAlloc(LOS_GetKVmSpace(), (VADDR_T)g_cfiFlashBase, len, VM_MAP_REGION_FLAG_PERM_READ | - VM_MAP_REGION_FLAG_PERM_WRITE | VM_MAP_REGION_TYPE_DEV, 0); - if (r == NULL) { - HDF_LOGE("[%s]LOS_RegionAlloc error", __func__); - LOS_ArchMmuUnmap(&LOS_GetKVmSpace()->archMmu, (VADDR_T)g_cfiFlashBase, count); - return NULL; - } + g_cfiFlashBase = (uint32_t *)IO_DEVICE_ADDR(pbase); - return r; + return HDF_SUCCESS; } int HdfCfiDriverInit(struct HdfDeviceObject *deviceObject) { - LosVmMapRegion *r; - if (deviceObject == NULL || deviceObject->property == NULL) { HDF_LOGE("[%s]deviceObject or property is null", __func__); return HDF_ERR_INVALID_PARAM; } - r = HdfCfiMapInit(deviceObject->property); - if (r == NULL) { + if (HdfCfiMapInit(deviceObject->property) != HDF_SUCCESS) { return HDF_FAILURE; } if(CfiFlashInit()) { - LOS_RegionFree(LOS_GetKVmSpace(), r); return HDF_ERR_NOT_SUPPORT; } -- Gitee