Statistics
| Branch: | Revision:

root / hw / arm_l2x0.c @ 4e4fa398

History | View | Annotate | Download (4.6 kB)

1 b2123a48 Rob Herring
/*
2 b2123a48 Rob Herring
 * ARM dummy L210, L220, PL310 cache controller.
3 b2123a48 Rob Herring
 *
4 b2123a48 Rob Herring
 * Copyright (c) 2010-2012 Calxeda
5 b2123a48 Rob Herring
 *
6 b2123a48 Rob Herring
 * This program is free software; you can redistribute it and/or modify it
7 b2123a48 Rob Herring
 * under the terms and conditions of the GNU General Public License,
8 b2123a48 Rob Herring
 * version 2 or any later version, as published by the Free Software
9 b2123a48 Rob Herring
 * Foundation.
10 b2123a48 Rob Herring
 *
11 b2123a48 Rob Herring
 * This program is distributed in the hope it will be useful, but WITHOUT
12 b2123a48 Rob Herring
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 b2123a48 Rob Herring
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14 b2123a48 Rob Herring
 * more details.
15 b2123a48 Rob Herring
 *
16 b2123a48 Rob Herring
 * You should have received a copy of the GNU General Public License along with
17 b2123a48 Rob Herring
 * this program.  If not, see <http://www.gnu.org/licenses/>.
18 b2123a48 Rob Herring
 *
19 b2123a48 Rob Herring
 */
20 b2123a48 Rob Herring
21 b2123a48 Rob Herring
#include "sysbus.h"
22 b2123a48 Rob Herring
23 b2123a48 Rob Herring
/* L2C-310 r3p2 */
24 b2123a48 Rob Herring
#define CACHE_ID 0x410000c8
25 b2123a48 Rob Herring
26 b2123a48 Rob Herring
typedef struct l2x0_state {
27 b2123a48 Rob Herring
    SysBusDevice busdev;
28 b2123a48 Rob Herring
    MemoryRegion iomem;
29 b2123a48 Rob Herring
    uint32_t cache_type;
30 b2123a48 Rob Herring
    uint32_t ctrl;
31 b2123a48 Rob Herring
    uint32_t aux_ctrl;
32 b2123a48 Rob Herring
    uint32_t data_ctrl;
33 b2123a48 Rob Herring
    uint32_t tag_ctrl;
34 b2123a48 Rob Herring
    uint32_t filter_start;
35 b2123a48 Rob Herring
    uint32_t filter_end;
36 b2123a48 Rob Herring
} l2x0_state;
37 b2123a48 Rob Herring
38 b2123a48 Rob Herring
static const VMStateDescription vmstate_l2x0 = {
39 b2123a48 Rob Herring
    .name = "l2x0",
40 b2123a48 Rob Herring
    .version_id = 1,
41 b2123a48 Rob Herring
    .minimum_version_id = 1,
42 b2123a48 Rob Herring
    .fields = (VMStateField[]) {
43 b2123a48 Rob Herring
        VMSTATE_UINT32(ctrl, l2x0_state),
44 b2123a48 Rob Herring
        VMSTATE_UINT32(aux_ctrl, l2x0_state),
45 b2123a48 Rob Herring
        VMSTATE_UINT32(data_ctrl, l2x0_state),
46 b2123a48 Rob Herring
        VMSTATE_UINT32(tag_ctrl, l2x0_state),
47 b2123a48 Rob Herring
        VMSTATE_UINT32(filter_start, l2x0_state),
48 b2123a48 Rob Herring
        VMSTATE_UINT32(filter_end, l2x0_state),
49 b2123a48 Rob Herring
        VMSTATE_END_OF_LIST()
50 b2123a48 Rob Herring
    }
51 b2123a48 Rob Herring
};
52 b2123a48 Rob Herring
53 b2123a48 Rob Herring
54 b2123a48 Rob Herring
static uint64_t l2x0_priv_read(void *opaque, target_phys_addr_t offset,
55 b2123a48 Rob Herring
                               unsigned size)
56 b2123a48 Rob Herring
{
57 b2123a48 Rob Herring
    uint32_t cache_data;
58 b2123a48 Rob Herring
    l2x0_state *s = (l2x0_state *)opaque;
59 b2123a48 Rob Herring
    offset &= 0xfff;
60 b2123a48 Rob Herring
    if (offset >= 0x730 && offset < 0x800) {
61 b2123a48 Rob Herring
        return 0; /* cache ops complete */
62 b2123a48 Rob Herring
    }
63 b2123a48 Rob Herring
    switch (offset) {
64 b2123a48 Rob Herring
    case 0:
65 b2123a48 Rob Herring
        return CACHE_ID;
66 b2123a48 Rob Herring
    case 0x4:
67 b2123a48 Rob Herring
        /* aux_ctrl values affect cache_type values */
68 b2123a48 Rob Herring
        cache_data = (s->aux_ctrl & (7 << 17)) >> 15;
69 b2123a48 Rob Herring
        cache_data |= (s->aux_ctrl & (1 << 16)) >> 16;
70 b2123a48 Rob Herring
        return s->cache_type |= (cache_data << 18) | (cache_data << 6);
71 b2123a48 Rob Herring
    case 0x100:
72 b2123a48 Rob Herring
        return s->ctrl;
73 b2123a48 Rob Herring
    case 0x104:
74 b2123a48 Rob Herring
        return s->aux_ctrl;
75 b2123a48 Rob Herring
    case 0x108:
76 b2123a48 Rob Herring
        return s->tag_ctrl;
77 b2123a48 Rob Herring
    case 0x10C:
78 b2123a48 Rob Herring
        return s->data_ctrl;
79 b2123a48 Rob Herring
    case 0xC00:
80 b2123a48 Rob Herring
        return s->filter_start;
81 b2123a48 Rob Herring
    case 0xC04:
82 b2123a48 Rob Herring
        return s->filter_end;
83 b2123a48 Rob Herring
    case 0xF40:
84 b2123a48 Rob Herring
        return 0;
85 b2123a48 Rob Herring
    case 0xF60:
86 b2123a48 Rob Herring
        return 0;
87 b2123a48 Rob Herring
    case 0xF80:
88 b2123a48 Rob Herring
        return 0;
89 b2123a48 Rob Herring
    default:
90 b2123a48 Rob Herring
        fprintf(stderr, "l2x0_priv_read: Bad offset %x\n", (int)offset);
91 b2123a48 Rob Herring
        break;
92 b2123a48 Rob Herring
    }
93 b2123a48 Rob Herring
    return 0;
94 b2123a48 Rob Herring
}
95 b2123a48 Rob Herring
96 b2123a48 Rob Herring
static void l2x0_priv_write(void *opaque, target_phys_addr_t offset,
97 b2123a48 Rob Herring
                            uint64_t value, unsigned size)
98 b2123a48 Rob Herring
{
99 b2123a48 Rob Herring
    l2x0_state *s = (l2x0_state *)opaque;
100 b2123a48 Rob Herring
    offset &= 0xfff;
101 b2123a48 Rob Herring
    if (offset >= 0x730 && offset < 0x800) {
102 b2123a48 Rob Herring
        /* ignore */
103 b2123a48 Rob Herring
        return;
104 b2123a48 Rob Herring
    }
105 b2123a48 Rob Herring
    switch (offset) {
106 b2123a48 Rob Herring
    case 0x100:
107 b2123a48 Rob Herring
        s->ctrl = value & 1;
108 b2123a48 Rob Herring
        break;
109 b2123a48 Rob Herring
    case 0x104:
110 b2123a48 Rob Herring
        s->aux_ctrl = value;
111 b2123a48 Rob Herring
        break;
112 b2123a48 Rob Herring
    case 0x108:
113 b2123a48 Rob Herring
        s->tag_ctrl = value;
114 b2123a48 Rob Herring
        break;
115 b2123a48 Rob Herring
    case 0x10C:
116 b2123a48 Rob Herring
        s->data_ctrl = value;
117 b2123a48 Rob Herring
        break;
118 b2123a48 Rob Herring
    case 0xC00:
119 b2123a48 Rob Herring
        s->filter_start = value;
120 b2123a48 Rob Herring
        break;
121 b2123a48 Rob Herring
    case 0xC04:
122 b2123a48 Rob Herring
        s->filter_end = value;
123 b2123a48 Rob Herring
        break;
124 b2123a48 Rob Herring
    case 0xF40:
125 b2123a48 Rob Herring
        return;
126 b2123a48 Rob Herring
    case 0xF60:
127 b2123a48 Rob Herring
        return;
128 b2123a48 Rob Herring
    case 0xF80:
129 b2123a48 Rob Herring
        return;
130 b2123a48 Rob Herring
    default:
131 b2123a48 Rob Herring
        fprintf(stderr, "l2x0_priv_write: Bad offset %x\n", (int)offset);
132 b2123a48 Rob Herring
        break;
133 b2123a48 Rob Herring
    }
134 b2123a48 Rob Herring
}
135 b2123a48 Rob Herring
136 b2123a48 Rob Herring
static void l2x0_priv_reset(DeviceState *dev)
137 b2123a48 Rob Herring
{
138 b2123a48 Rob Herring
    l2x0_state *s = DO_UPCAST(l2x0_state, busdev.qdev, dev);
139 b2123a48 Rob Herring
140 b2123a48 Rob Herring
    s->ctrl = 0;
141 b2123a48 Rob Herring
    s->aux_ctrl = 0x02020000;
142 b2123a48 Rob Herring
    s->tag_ctrl = 0;
143 b2123a48 Rob Herring
    s->data_ctrl = 0;
144 b2123a48 Rob Herring
    s->filter_start = 0;
145 b2123a48 Rob Herring
    s->filter_end = 0;
146 b2123a48 Rob Herring
}
147 b2123a48 Rob Herring
148 b2123a48 Rob Herring
static const MemoryRegionOps l2x0_mem_ops = {
149 b2123a48 Rob Herring
    .read = l2x0_priv_read,
150 b2123a48 Rob Herring
    .write = l2x0_priv_write,
151 b2123a48 Rob Herring
    .endianness = DEVICE_NATIVE_ENDIAN,
152 b2123a48 Rob Herring
 };
153 b2123a48 Rob Herring
154 b2123a48 Rob Herring
static int l2x0_priv_init(SysBusDevice *dev)
155 b2123a48 Rob Herring
{
156 b2123a48 Rob Herring
    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);
157 b2123a48 Rob Herring
158 b2123a48 Rob Herring
    memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
159 b2123a48 Rob Herring
    sysbus_init_mmio(dev, &s->iomem);
160 b2123a48 Rob Herring
    return 0;
161 b2123a48 Rob Herring
}
162 b2123a48 Rob Herring
163 999e12bb Anthony Liguori
static void l2x0_class_init(ObjectClass *klass, void *data)
164 999e12bb Anthony Liguori
{
165 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
166 999e12bb Anthony Liguori
167 999e12bb Anthony Liguori
    k->init = l2x0_priv_init;
168 999e12bb Anthony Liguori
}
169 999e12bb Anthony Liguori
170 999e12bb Anthony Liguori
static DeviceInfo l2x0_info = {
171 999e12bb Anthony Liguori
    .name = "l2x0",
172 999e12bb Anthony Liguori
    .size = sizeof(l2x0_state),
173 999e12bb Anthony Liguori
    .vmsd = &vmstate_l2x0,
174 999e12bb Anthony Liguori
    .no_user = 1,
175 999e12bb Anthony Liguori
    .props = (Property[]) {
176 b2123a48 Rob Herring
        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
177 b2123a48 Rob Herring
        DEFINE_PROP_END_OF_LIST(),
178 b2123a48 Rob Herring
    },
179 999e12bb Anthony Liguori
    .reset = l2x0_priv_reset,
180 999e12bb Anthony Liguori
    .class_init = l2x0_class_init,
181 b2123a48 Rob Herring
};
182 b2123a48 Rob Herring
183 b2123a48 Rob Herring
static void l2x0_register_device(void)
184 b2123a48 Rob Herring
{
185 999e12bb Anthony Liguori
    sysbus_qdev_register(&l2x0_info);
186 b2123a48 Rob Herring
}
187 b2123a48 Rob Herring
188 b2123a48 Rob Herring
device_init(l2x0_register_device)