Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2023 On-Line Applications Research (OAR)
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 #include <tmacros.h>
0032 
0033 #include <sys/stat.h>
0034 #include <sys/types.h>
0035 #include <string.h>
0036 
0037 #include <rtems/jffs2.h>
0038 #include <rtems/libio.h>
0039 #include <rtems/libcsupport.h>
0040 
0041 #include "fstest.h"
0042 #include "fstest_support.h"
0043 
0044 #define FLASH_PAGE_SIZE (1024UL)
0045 /* Out of Band/Spare area size is per-page */
0046 #define FLASH_PAGE_OOB_SIZE (32UL)
0047 
0048 #define PAGES_PER_BLOCK (16UL)
0049 #define BLOCKS_PER_DEVICE (8UL)
0050 
0051 #define FLASH_OOB_SIZE (BLOCKS_PER_DEVICE * PAGES_PER_BLOCK * FLASH_PAGE_OOB_SIZE)
0052 #define FLASH_BLOCK_SIZE (PAGES_PER_BLOCK * FLASH_PAGE_SIZE)
0053 #define FLASH_SIZE (BLOCKS_PER_DEVICE * FLASH_BLOCK_SIZE)
0054 
0055 typedef struct {
0056   rtems_jffs2_flash_control super;
0057   unsigned char area[FLASH_SIZE];
0058   unsigned char oob[FLASH_OOB_SIZE];
0059 } flash_control;
0060 
0061 static flash_control *get_flash_control(rtems_jffs2_flash_control *super)
0062 {
0063   return (flash_control *) super;
0064 }
0065 
0066 static int flash_read(
0067   rtems_jffs2_flash_control *super,
0068   uint32_t offset,
0069   unsigned char *buffer,
0070   size_t size_of_buffer
0071 )
0072 {
0073   flash_control *self = get_flash_control(super);
0074   unsigned char *chunk = &self->area[offset];
0075 
0076   memcpy(buffer, chunk, size_of_buffer);
0077 
0078   return 0;
0079 }
0080 
0081 static int flash_write(
0082   rtems_jffs2_flash_control *super,
0083   uint32_t offset,
0084   const unsigned char *buffer,
0085   size_t size_of_buffer
0086 )
0087 {
0088   flash_control *self = get_flash_control(super);
0089   unsigned char *chunk = &self->area[offset];
0090   size_t i;
0091 
0092   for (i = 0; i < size_of_buffer; ++i) {
0093     chunk[i] &= buffer[i];
0094   }
0095 
0096   return 0;
0097 }
0098 
0099 static int flash_erase(
0100   rtems_jffs2_flash_control *super,
0101   uint32_t offset
0102 )
0103 {
0104   flash_control *self = get_flash_control(super);
0105   uint32_t page_index = offset / FLASH_PAGE_SIZE;
0106   uint32_t oob_offset = page_index * FLASH_PAGE_OOB_SIZE;
0107   unsigned char *chunk = &self->area[offset];
0108   unsigned char *oobchunk = &self->oob[oob_offset];
0109 
0110   memset(chunk, 0xff, FLASH_BLOCK_SIZE);
0111   memset(oobchunk, 0xff, PAGES_PER_BLOCK * FLASH_PAGE_OOB_SIZE);
0112 
0113   return 0;
0114 }
0115 
0116 static int flash_read_oob(
0117   rtems_jffs2_flash_control *super,
0118   uint32_t offset,
0119   uint8_t *buffer,
0120   uint32_t size_of_buffer
0121 )
0122 {
0123   flash_control *self = get_flash_control(super);
0124   uint32_t page_index = offset / FLASH_PAGE_SIZE;
0125   uint32_t oob_offset = page_index * FLASH_PAGE_OOB_SIZE;
0126   unsigned char *chunk = &self->oob[oob_offset];
0127 
0128   memcpy(buffer, chunk, size_of_buffer);
0129 
0130   return 0;
0131 }
0132 
0133 static int flash_write_oob(
0134   rtems_jffs2_flash_control *super,
0135   uint32_t offset,
0136   uint8_t *buffer,
0137   uint32_t size_of_buffer
0138 )
0139 {
0140   flash_control *self = get_flash_control(super);
0141   uint32_t page_index = offset / FLASH_PAGE_SIZE;
0142   uint32_t oob_offset = page_index * FLASH_PAGE_OOB_SIZE;
0143   unsigned char *chunk = &self->oob[oob_offset];
0144   size_t i;
0145 
0146   for (i = 0; i < size_of_buffer; ++i) {
0147     chunk[i] &= buffer[i];
0148   }
0149 
0150   return 0;
0151 }
0152 
0153 static int flash_block_is_bad(
0154   rtems_jffs2_flash_control *super,
0155   uint32_t orig_offset,
0156   bool *bad
0157 )
0158 {
0159   *bad = false;
0160   return 0;
0161 }
0162 
0163 static int flash_block_mark_bad(
0164   rtems_jffs2_flash_control *super,
0165   uint32_t orig_offset
0166 )
0167 {
0168   return 0;
0169 }
0170 
0171 static uint32_t flash_get_oob_size(
0172   rtems_jffs2_flash_control *super
0173 )
0174 {
0175   return FLASH_PAGE_OOB_SIZE;
0176 }
0177 
0178 static flash_control flash_instance = {
0179   .super = {
0180     .block_size = FLASH_BLOCK_SIZE,
0181     .flash_size = FLASH_SIZE,
0182     .read = flash_read,
0183     .write = flash_write,
0184     .erase = flash_erase,
0185     .block_is_bad = flash_block_is_bad,
0186     .block_mark_bad = flash_block_mark_bad,
0187     .oob_read = flash_read_oob,
0188     .oob_write = flash_write_oob,
0189     .get_oob_size = flash_get_oob_size,
0190     .write_size = FLASH_PAGE_SIZE
0191   }
0192 };
0193 
0194 static rtems_jffs2_compressor_control compressor_instance = {
0195   .compress = rtems_jffs2_compressor_rtime_compress,
0196   .decompress = rtems_jffs2_compressor_rtime_decompress
0197 };
0198 
0199 static const rtems_jffs2_mount_data mount_data = {
0200   .flash_control = &flash_instance.super,
0201   .compressor_control = &compressor_instance
0202 };
0203 
0204 static void erase_all(void)
0205 {
0206   memset(&flash_instance.area[0], 0xff, FLASH_SIZE);
0207   memset(&flash_instance.oob[0], 0xff, FLASH_OOB_SIZE);
0208 }
0209 
0210 static rtems_resource_snapshot before_mount;
0211 
0212 void test_initialize_filesystem(void)
0213 {
0214   int rv;
0215 
0216   erase_all();
0217 
0218   rv = mkdir(BASE_FOR_TEST, S_IRWXU | S_IRWXG | S_IRWXO);
0219   rtems_test_assert(rv == 0);
0220 
0221   rtems_resource_snapshot_take(&before_mount);
0222 
0223   rv = mount(
0224     NULL,
0225     BASE_FOR_TEST,
0226     RTEMS_FILESYSTEM_TYPE_JFFS2,
0227     RTEMS_FILESYSTEM_READ_WRITE,
0228     &mount_data
0229   );
0230   rtems_test_assert(rv == 0);
0231 }
0232 
0233 void test_shutdown_filesystem(void)
0234 {
0235   int rv = unmount(BASE_FOR_TEST);
0236   rtems_test_assert(rv == 0);
0237   rtems_test_assert(rtems_resource_snapshot_check(&before_mount));
0238 }
0239 
0240 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0241 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0242 
0243 #define CONFIGURE_FILESYSTEM_JFFS2
0244 
0245 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 40
0246 
0247 #define CONFIGURE_MAXIMUM_TASKS 2
0248 
0249 #define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
0250 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
0251 
0252 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0253 
0254 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0255 
0256 #define CONFIGURE_INIT
0257 #include <rtems/confdefs.h>