qemu

Форк
0
/
allwinner-sramc.c 
185 строк · 5.3 Кб
1
/*
2
 * Allwinner R40 SRAM controller emulation
3
 *
4
 * Copyright (C) 2023 qianfan Zhao <qianfanguijin@163.com>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
#include "qemu/osdep.h"
21
#include "qemu/units.h"
22
#include "hw/sysbus.h"
23
#include "migration/vmstate.h"
24
#include "qemu/log.h"
25
#include "qemu/module.h"
26
#include "qapi/error.h"
27
#include "hw/qdev-properties.h"
28
#include "hw/qdev-properties-system.h"
29
#include "hw/misc/allwinner-sramc.h"
30
#include "trace.h"
31

32
/*
33
 * register offsets
34
 * https://linux-sunxi.org/SRAM_Controller_Register_Guide
35
 */
36
enum {
37
    REG_SRAM_CTL1_CFG               = 0x04, /* SRAM Control register 1 */
38
    REG_SRAM_VER                    = 0x24, /* SRAM Version register */
39
    REG_SRAM_R40_SOFT_ENTRY_REG0    = 0xbc,
40
};
41

42
/* REG_SRAMC_VERSION bit defines */
43
#define SRAM_VER_READ_ENABLE            (1 << 15)
44
#define SRAM_VER_VERSION_SHIFT          16
45
#define SRAM_VERSION_SUN8I_R40          0x1701
46

47
static uint64_t allwinner_sramc_read(void *opaque, hwaddr offset,
48
                                     unsigned size)
49
{
50
    AwSRAMCState *s = AW_SRAMC(opaque);
51
    AwSRAMCClass *sc = AW_SRAMC_GET_CLASS(s);
52
    uint64_t val = 0;
53

54
    switch (offset) {
55
    case REG_SRAM_CTL1_CFG:
56
        val = s->sram_ctl1;
57
        break;
58
    case REG_SRAM_VER:
59
        /* bit15: lock bit, set this bit before reading this register */
60
        if (s->sram_ver & SRAM_VER_READ_ENABLE) {
61
            val = SRAM_VER_READ_ENABLE |
62
                    (sc->sram_version_code << SRAM_VER_VERSION_SHIFT);
63
        }
64
        break;
65
    case REG_SRAM_R40_SOFT_ENTRY_REG0:
66
        val = s->sram_soft_entry_reg0;
67
        break;
68
    default:
69
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
70
                      __func__, (uint32_t)offset);
71
        return 0;
72
    }
73

74
    trace_allwinner_sramc_read(offset, val);
75

76
    return val;
77
}
78

79
static void allwinner_sramc_write(void *opaque, hwaddr offset,
80
                                  uint64_t val, unsigned size)
81
{
82
    AwSRAMCState *s = AW_SRAMC(opaque);
83

84
    trace_allwinner_sramc_write(offset, val);
85

86
    switch (offset) {
87
    case REG_SRAM_CTL1_CFG:
88
        s->sram_ctl1 = val;
89
        break;
90
    case REG_SRAM_VER:
91
        /* Only the READ_ENABLE bit is writeable */
92
        s->sram_ver = val & SRAM_VER_READ_ENABLE;
93
        break;
94
    case REG_SRAM_R40_SOFT_ENTRY_REG0:
95
        s->sram_soft_entry_reg0 = val;
96
        break;
97
    default:
98
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
99
                      __func__, (uint32_t)offset);
100
        break;
101
    }
102
}
103

104
static const MemoryRegionOps allwinner_sramc_ops = {
105
    .read = allwinner_sramc_read,
106
    .write = allwinner_sramc_write,
107
    .endianness = DEVICE_NATIVE_ENDIAN,
108
    .valid = {
109
        .min_access_size = 4,
110
        .max_access_size = 4,
111
    },
112
    .impl.min_access_size = 4,
113
};
114

115
static const VMStateDescription allwinner_sramc_vmstate = {
116
    .name = "allwinner-sramc",
117
    .version_id = 1,
118
    .minimum_version_id = 1,
119
    .fields = (const VMStateField[]) {
120
        VMSTATE_UINT32(sram_ver, AwSRAMCState),
121
        VMSTATE_UINT32(sram_soft_entry_reg0, AwSRAMCState),
122
        VMSTATE_END_OF_LIST()
123
    }
124
};
125

126
static void allwinner_sramc_reset(DeviceState *dev)
127
{
128
    AwSRAMCState *s = AW_SRAMC(dev);
129
    AwSRAMCClass *sc = AW_SRAMC_GET_CLASS(s);
130

131
    switch (sc->sram_version_code) {
132
    case SRAM_VERSION_SUN8I_R40:
133
        s->sram_ctl1 = 0x1300;
134
        break;
135
    }
136
}
137

138
static void allwinner_sramc_class_init(ObjectClass *klass, void *data)
139
{
140
    DeviceClass *dc = DEVICE_CLASS(klass);
141

142
    dc->reset = allwinner_sramc_reset;
143
    dc->vmsd = &allwinner_sramc_vmstate;
144
}
145

146
static void allwinner_sramc_init(Object *obj)
147
{
148
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
149
    AwSRAMCState *s = AW_SRAMC(obj);
150

151
    /* Memory mapping */
152
    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_sramc_ops, s,
153
                           TYPE_AW_SRAMC, 1 * KiB);
154
    sysbus_init_mmio(sbd, &s->iomem);
155
}
156

157
static const TypeInfo allwinner_sramc_info = {
158
    .name          = TYPE_AW_SRAMC,
159
    .parent        = TYPE_SYS_BUS_DEVICE,
160
    .instance_init = allwinner_sramc_init,
161
    .instance_size = sizeof(AwSRAMCState),
162
    .class_size    = sizeof(AwSRAMCClass),
163
    .class_init    = allwinner_sramc_class_init,
164
};
165

166
static void allwinner_r40_sramc_class_init(ObjectClass *klass, void *data)
167
{
168
    AwSRAMCClass *sc = AW_SRAMC_CLASS(klass);
169

170
    sc->sram_version_code = SRAM_VERSION_SUN8I_R40;
171
}
172

173
static const TypeInfo allwinner_r40_sramc_info = {
174
    .name          = TYPE_AW_SRAMC_SUN8I_R40,
175
    .parent        = TYPE_AW_SRAMC,
176
    .class_init    = allwinner_r40_sramc_class_init,
177
};
178

179
static void allwinner_sramc_register(void)
180
{
181
    type_register_static(&allwinner_sramc_info);
182
    type_register_static(&allwinner_r40_sramc_info);
183
}
184

185
type_init(allwinner_sramc_register)
186

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.