summaryrefslogtreecommitdiff
path: root/bsp/xuantie/xiaohui/c908/board/drv_ramdisk.c
blob: 25f6ac7bd08c1a84959878e6292cfbfddf1517b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * Copyright (C) 2017-2024 Alibaba Group Holding Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <rtthread.h>
#include <rtdevice.h>

#define DBG_TAG "drv.ramdisk"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#define RAMDISK_SECTOR_SIZE 512
#define RAMDISK_SIZE        (8 * 1024 * 1024)
#define RAMDISK_SECTOR_NR   (RAMDISK_SIZE / RAMDISK_SECTOR_SIZE)

static struct rt_device _ramdisk_dev;
static rt_uint8_t *_ramdisk_data;

static rt_ssize_t _ramdisk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    if (pos + size > RAMDISK_SECTOR_NR)
    {
        return 0;
    }
    rt_memcpy(buffer, _ramdisk_data + pos * RAMDISK_SECTOR_SIZE, size * RAMDISK_SECTOR_SIZE);
    return size;
}

static rt_ssize_t _ramdisk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    if (pos + size > RAMDISK_SECTOR_NR)
    {
        return 0;
    }
    rt_memcpy(_ramdisk_data + pos * RAMDISK_SECTOR_SIZE, buffer, size * RAMDISK_SECTOR_SIZE);
    return size;
}

static rt_err_t _ramdisk_control(rt_device_t dev, int cmd, void *args)
{
    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
    {
        struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args;

        if (geometry == RT_NULL)
        {
            return -RT_ERROR;
        }
        geometry->bytes_per_sector = RAMDISK_SECTOR_SIZE;
        geometry->block_size = RAMDISK_SECTOR_SIZE;
        geometry->sector_count = RAMDISK_SECTOR_NR;
    }
    return RT_EOK;
}

#ifdef RT_USING_DEVICE_OPS
static const struct rt_device_ops ramdisk_ops = {
    RT_NULL,
    RT_NULL,
    RT_NULL,
    _ramdisk_read,
    _ramdisk_write,
    _ramdisk_control,
};
#endif

int rt_hw_ramdisk_init(void)
{
    rt_device_t dev = &_ramdisk_dev;

    _ramdisk_data = rt_malloc(RAMDISK_SIZE);
    if (_ramdisk_data == RT_NULL)
    {
        LOG_E("no memory for the ramdisk");
        return -RT_ENOMEM;
    }
    rt_memset(_ramdisk_data, 0, RAMDISK_SIZE);

    dev->type = RT_Device_Class_Block;
#ifdef RT_USING_DEVICE_OPS
    dev->ops = &ramdisk_ops;
#else
    dev->read = _ramdisk_read;
    dev->write = _ramdisk_write;
    dev->control = _ramdisk_control;
#endif

    return rt_device_register(dev, "ramdisk0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
}
INIT_DEVICE_EXPORT(rt_hw_ramdisk_init);