Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:33

0001 /*
0002  * Copyright (C) 2023 Aaron Nyholm
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0014  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0016  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0017  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0018  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0019  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0020  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0021  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0022  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0023  * POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include "test_flashdev.h"
0027 
0028 #include <stdlib.h>
0029 #include <string.h>
0030 
0031 #include <rtems/seterr.h>
0032 
0033 #define TEST_DATA_SIZE (PAGE_SIZE * PAGE_COUNT)
0034 #define PAGE_COUNT 16
0035 #define PAGE_SIZE 128
0036 #define SECTOR_COUNT 4
0037 #define SECTOR_SIZE (TEST_DATA_SIZE / SECTOR_COUNT)
0038 #define WB_SIZE 1
0039 #define MAX_NUM_REGIONS 48
0040 #define BITALLOC_SIZE 32
0041 #define NUM_BITALLOC ((MAX_NUM_REGIONS + BITALLOC_SIZE - 1) / BITALLOC_SIZE)
0042 
0043 /**
0044  * This flash device driver is for testing flashdev
0045  * API calls.
0046  */
0047 typedef struct test_flashdev {
0048   char* data;
0049   uint32_t jedec_id;
0050   uint32_t bit_allocator[NUM_BITALLOC];
0051   rtems_flashdev_region regions[MAX_NUM_REGIONS];
0052 } test_flashdev;
0053 
0054 int test_flashdev_page_by_off(
0055   rtems_flashdev *flash,
0056   off_t search_offset,
0057   off_t *page_offset,
0058   size_t *page_size
0059 );
0060 
0061 int test_flashdev_page_by_index(
0062   rtems_flashdev *flash,
0063   off_t search_index,
0064   off_t *page_offset,
0065   size_t *page_size
0066 );
0067 
0068 int test_flashdev_page_count(
0069   rtems_flashdev *flash,
0070   int *page_count
0071 );
0072 
0073 int test_flashdev_wb_size(
0074   rtems_flashdev *flash,
0075   size_t *write_block_size
0076 );
0077 
0078 int test_flashdev_sector_by_off(
0079   rtems_flashdev *flash,
0080   off_t search_offset,
0081   off_t *sector_offset,
0082   size_t *sector_size
0083 );
0084 
0085 int test_flashdev_sector_count(
0086   rtems_flashdev *flash,
0087   int *sector_count
0088 );
0089 
0090 uint32_t test_flashdev_jedec_id(
0091   rtems_flashdev* flash
0092 );
0093 
0094 int test_flashdev_type(
0095   rtems_flashdev* flash,
0096   rtems_flashdev_flash_type* type
0097 );
0098 
0099 int test_flashdev_read(
0100   rtems_flashdev* flash,
0101   uintptr_t offset,
0102   size_t count,
0103   void* buffer
0104 );
0105 
0106 int test_flashdev_write(
0107   rtems_flashdev* flash,
0108   uintptr_t offset,
0109   size_t count,
0110   const void* buffer
0111 );
0112 
0113 int test_flashdev_erase(
0114   rtems_flashdev* flash,
0115   uintptr_t offset,
0116   size_t count
0117 );
0118 
0119 /* Find page info by offset handler */
0120 int test_flashdev_page_by_off(
0121   rtems_flashdev *flash,
0122   off_t search_offset,
0123   off_t *page_offset,
0124   size_t *page_size
0125 )
0126 {
0127   *page_offset = search_offset - (search_offset%PAGE_SIZE);
0128   *page_size = PAGE_SIZE;
0129   return 0;
0130 }
0131 
0132 /* Find page by index handler */
0133 int test_flashdev_page_by_index(
0134   rtems_flashdev *flash,
0135   off_t search_index,
0136   off_t *page_offset,
0137   size_t *page_size
0138 )
0139 {
0140   *page_offset = search_index * PAGE_SIZE;
0141   *page_size = PAGE_SIZE;
0142   return 0;
0143 }
0144 
0145 /* Page count handler */
0146 int test_flashdev_page_count(
0147   rtems_flashdev *flash,
0148   int *page_count
0149 )
0150 {
0151   *page_count = PAGE_COUNT;
0152   return 0;
0153 }
0154 
0155 /* Write block size handler */
0156 int test_flashdev_wb_size(
0157   rtems_flashdev *flash,
0158   size_t *write_block_size
0159 )
0160 {
0161   *write_block_size = WB_SIZE;
0162   return 0;
0163 }
0164 
0165 int test_flashdev_sector_by_off(
0166   rtems_flashdev *flash,
0167   off_t search_offset,
0168   off_t *sector_offset,
0169   size_t *sector_size
0170 ) {
0171   *sector_offset = search_offset - (search_offset%SECTOR_SIZE);
0172   *sector_size = SECTOR_SIZE;
0173   return 0;
0174 }
0175 
0176 int test_flashdev_sector_count(
0177   rtems_flashdev *flash,
0178   int *sector_count
0179 ) {
0180   *sector_count = SECTOR_COUNT;
0181   return 0;
0182 }
0183 
0184 /* JEDEC ID handler, this would normally require a READID
0185  * call to the physical flash device.
0186  */
0187 uint32_t test_flashdev_jedec_id(
0188   rtems_flashdev* flash
0189 )
0190 {
0191   test_flashdev* driver = flash->driver;
0192   return driver->jedec_id;
0193 }
0194 
0195 /* Function to identify what kind of flash is attached. */
0196 int test_flashdev_type(
0197   rtems_flashdev *flash,
0198   rtems_flashdev_flash_type *type
0199 )
0200 {
0201   *type = RTEMS_FLASHDEV_NOR;
0202   return 0;
0203 }
0204 
0205 /* Read flash call. Any offset or count protections are
0206  * required to be done in the driver function. */
0207 int test_flashdev_read(
0208   rtems_flashdev* flash,
0209   uintptr_t offset,
0210   size_t count,
0211   void* buffer
0212 )
0213 {
0214   test_flashdev* driver = flash->driver;
0215 
0216   if (offset + count > TEST_DATA_SIZE) {
0217     rtems_set_errno_and_return_minus_one( EINVAL );
0218   }
0219 
0220   memcpy(buffer, &driver->data[offset], count);
0221   return 0;
0222 }
0223 
0224 /* Write Flash call. Any offset or count protections are
0225  * required to be done in the driver function. */
0226 int test_flashdev_write(
0227   rtems_flashdev* flash,
0228   uintptr_t offset,
0229   size_t count,
0230   const void* buffer
0231 )
0232 {
0233   test_flashdev* driver = flash->driver;
0234 
0235   if (offset + count > TEST_DATA_SIZE) {
0236     rtems_set_errno_and_return_minus_one( EINVAL );
0237   }
0238 
0239   memcpy(&driver->data[offset], buffer, count);
0240   return 0;
0241 }
0242 
0243 /* Erase Flash call. Any offset or count protections are
0244  * required to be done in the driver function. */
0245 int test_flashdev_erase(
0246   rtems_flashdev* flash,
0247   uintptr_t offset,
0248   size_t count
0249 )
0250 {
0251   test_flashdev* driver = flash->driver;
0252 
0253   if (offset + count > TEST_DATA_SIZE) {
0254     rtems_set_errno_and_return_minus_one( EINVAL );
0255   }
0256 
0257   if (offset%PAGE_SIZE || count%PAGE_SIZE) {
0258     rtems_set_errno_and_return_minus_one( EINVAL );
0259   }
0260 
0261   memset(&driver->data[offset], 0, count);
0262   return 0;
0263 }
0264 
0265 /* Initialize Flashdev and underlying driver. */
0266 rtems_flashdev* test_flashdev_init(void)
0267 {
0268   rtems_flashdev *flash = rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));
0269 
0270   if (flash == NULL) {
0271     return NULL;
0272   }
0273 
0274   test_flashdev* flash_driver = calloc(1, sizeof(test_flashdev));
0275 
0276   if (flash_driver == NULL) {
0277     rtems_flashdev_destroy_and_free(flash);
0278     return NULL;
0279   }
0280 
0281   flash_driver->data = calloc(1, TEST_DATA_SIZE);
0282   if (flash_driver->data == NULL) {
0283     free(flash_driver);
0284     rtems_flashdev_destroy_and_free(flash);
0285     return NULL;
0286   }
0287 
0288   flash_driver->jedec_id = 0x00ABCDEF;
0289 
0290   rtems_flashdev_region_table *ftable = calloc(1, sizeof(rtems_flashdev_region_table));
0291   ftable->max_regions = MAX_NUM_REGIONS;
0292   ftable->regions = flash_driver->regions;
0293   ftable->bit_allocator = flash_driver->bit_allocator;
0294 
0295   flash->driver = flash_driver;
0296   flash->read = &test_flashdev_read;
0297   flash->write = &test_flashdev_write;
0298   flash->erase = &test_flashdev_erase;
0299   flash->jedec_id = &test_flashdev_jedec_id;
0300   flash->flash_type = &test_flashdev_type;
0301   flash->page_info_by_offset = &test_flashdev_page_by_off;
0302   flash->page_info_by_index = &test_flashdev_page_by_index;
0303   flash->page_count = &test_flashdev_page_count;
0304   flash->write_block_size = &test_flashdev_wb_size;
0305   flash->sector_info_by_offset = &test_flashdev_sector_by_off;
0306   flash->sector_count = &test_flashdev_sector_count;
0307   flash->region_table = ftable;
0308 
0309   return flash;
0310 }