summaryrefslogtreecommitdiff
path: root/components/drivers/hwcache/hwcache.c
blob: 65029bf66ec98d96efb92de88fa6224431ee87e6 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-02-25     GuEe-GUI     the first version
 */

#include <drivers/hwcache.h>

#define DBG_TAG "rtdm.hwcache"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

struct rt_hwcache_ops *rt_dm_cpu_dcache_ops = RT_NULL;
struct rt_hwcache_ops *rt_dm_cpu_icache_ops = RT_NULL;

static void hwcache_enable(struct rt_hwcache_ops *ops)
{
    if (ops && ops->enable)
    {
        ops->enable();
    }
}

static void hwcache_disable(struct rt_hwcache_ops *ops)
{
    if (ops && ops->enable)
    {
        ops->enable();
    }
}

static rt_base_t hwcache_status(struct rt_hwcache_ops *ops)
{
    if (ops && ops->status)
    {
        return ops->status();
    }

    return 0;
}

static void hwcache_ops(struct rt_hwcache_ops *ops, int op, void *addr, int size)
{
    if (ops)
    {
        if (op == RT_HW_CACHE_FLUSH)
        {
            if (ops->flush)
            {
                ops->flush(addr, size);
            }
        }
        else if (op == RT_HW_CACHE_INVALIDATE)
        {
            if (ops->invalidate)
            {
                ops->invalidate(addr, size);
            }
        }
    }
}

void rt_hwcache_icache_enable(void)
{
    hwcache_enable(rt_dm_cpu_icache_ops);
}

void rt_hwcache_icache_disable(void)
{
    hwcache_disable(rt_dm_cpu_icache_ops);
}

rt_base_t rt_hwcache_icache_status(void)
{
    return hwcache_status(rt_dm_cpu_icache_ops);
}

void rt_hwcache_icache_ops(int ops, void *addr, int size)
{
    hwcache_ops(rt_dm_cpu_icache_ops, ops, addr, size);
}

void rt_hwcache_dcache_enable(void)
{
    hwcache_enable(rt_dm_cpu_dcache_ops);
}

void rt_hwcache_dcache_disable(void)
{
    hwcache_disable(rt_dm_cpu_dcache_ops);
}

rt_base_t rt_hwcache_dcache_status(void)
{
    return hwcache_status(rt_dm_cpu_dcache_ops);
}

void rt_hwcache_dcache_ops(int ops, void *addr, int size)
{
    hwcache_ops(rt_dm_cpu_dcache_ops, ops, addr, size);
}

#ifdef RT_USING_OFW
RT_OFW_STUB_RANGE_EXPORT(hwcache, _hwcache_ofw_start, _hwcache_ofw_end);

static rt_err_t ofw_hwcache_init(void)
{
    struct rt_ofw_node *cache_np;

    rt_ofw_foreach_allnodes(cache_np)
    {
        rt_ofw_stub_probe_range(cache_np, &_hwcache_ofw_start, &_hwcache_ofw_end);
    }

    return RT_EOK;
}
#else
static rt_err_t ofw_hwcache_init(void)
{
    return RT_EOK;
}
#endif /* !RT_USING_OFW */

rt_err_t rt_hwcache_init(void)
{
    rt_err_t err;

    LOG_D("init start");

    err = ofw_hwcache_init();

    LOG_D("init end");

    return err;
}