qemu

Форк
0
/
cfam.c 
168 строк · 4.9 Кб
1
/*
2
 * SPDX-License-Identifier: GPL-2.0-or-later
3
 * Copyright (C) 2024 IBM Corp.
4
 *
5
 * IBM Common FRU Access Macro
6
 */
7

8
#include "qemu/osdep.h"
9
#include "qemu/units.h"
10

11
#include "qapi/error.h"
12
#include "trace.h"
13

14
#include "hw/fsi/cfam.h"
15
#include "hw/fsi/fsi.h"
16

17
#include "hw/qdev-properties.h"
18

19
#define ENGINE_CONFIG_NEXT            BIT(31)
20
#define ENGINE_CONFIG_TYPE_PEEK       (0x02 << 4)
21
#define ENGINE_CONFIG_TYPE_FSI        (0x03 << 4)
22
#define ENGINE_CONFIG_TYPE_SCRATCHPAD (0x06 << 4)
23

24
/* Valid, slots, version, type, crc */
25
#define CFAM_CONFIG_REG(__VER, __TYPE, __CRC)   \
26
    (ENGINE_CONFIG_NEXT       |   \
27
     0x00010000               |   \
28
     (__VER)                  |   \
29
     (__TYPE)                 |   \
30
     (__CRC))
31

32
#define TO_REG(x)                          ((x) >> 2)
33

34
#define CFAM_CONFIG_CHIP_ID                TO_REG(0x00)
35
#define CFAM_CONFIG_PEEK_STATUS            TO_REG(0x04)
36
#define CFAM_CONFIG_CHIP_ID_P9             0xc0022d15
37
#define CFAM_CONFIG_CHIP_ID_BREAK          0xc0de0000
38

39
static uint64_t fsi_cfam_config_read(void *opaque, hwaddr addr, unsigned size)
40
{
41
    trace_fsi_cfam_config_read(addr, size);
42

43
    switch (addr) {
44
    case 0x00:
45
        return CFAM_CONFIG_CHIP_ID_P9;
46
    case 0x04:
47
        return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_PEEK, 0xc);
48
    case 0x08:
49
        return CFAM_CONFIG_REG(0x5000, ENGINE_CONFIG_TYPE_FSI, 0xa);
50
    case 0xc:
51
        return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_SCRATCHPAD, 0x7);
52
    default:
53
        /*
54
         * The config table contains different engines from 0xc onwards.
55
         * The scratch pad is already added at address 0xc. We need to add
56
         * future engines from address 0x10 onwards. Returning 0 as engine
57
         * is not implemented.
58
         */
59
        return 0;
60
    }
61
}
62

63
static void fsi_cfam_config_write(void *opaque, hwaddr addr, uint64_t data,
64
                                  unsigned size)
65
{
66
    FSICFAMState *cfam = FSI_CFAM(opaque);
67

68
    trace_fsi_cfam_config_write(addr, size, data);
69

70
    switch (TO_REG(addr)) {
71
    case CFAM_CONFIG_CHIP_ID:
72
    case CFAM_CONFIG_PEEK_STATUS:
73
        if (data == CFAM_CONFIG_CHIP_ID_BREAK) {
74
            bus_cold_reset(BUS(&cfam->lbus));
75
        }
76
        break;
77
    default:
78
        trace_fsi_cfam_config_write_noaddr(addr, size, data);
79
    }
80
}
81

82
static const struct MemoryRegionOps cfam_config_ops = {
83
    .read = fsi_cfam_config_read,
84
    .write = fsi_cfam_config_write,
85
    .valid.max_access_size = 4,
86
    .valid.min_access_size = 4,
87
    .impl.max_access_size = 4,
88
    .impl.min_access_size = 4,
89
    .endianness = DEVICE_BIG_ENDIAN,
90
};
91

92
static uint64_t fsi_cfam_unimplemented_read(void *opaque, hwaddr addr,
93
                                            unsigned size)
94
{
95
    trace_fsi_cfam_unimplemented_read(addr, size);
96

97
    return 0;
98
}
99

100
static void fsi_cfam_unimplemented_write(void *opaque, hwaddr addr,
101
                                         uint64_t data, unsigned size)
102
{
103
    trace_fsi_cfam_unimplemented_write(addr, size, data);
104
}
105

106
static const struct MemoryRegionOps fsi_cfam_unimplemented_ops = {
107
    .read = fsi_cfam_unimplemented_read,
108
    .write = fsi_cfam_unimplemented_write,
109
    .endianness = DEVICE_BIG_ENDIAN,
110
};
111

112
static void fsi_cfam_instance_init(Object *obj)
113
{
114
    FSICFAMState *s = FSI_CFAM(obj);
115

116
    object_initialize_child(obj, "scratchpad", &s->scratchpad,
117
                            TYPE_FSI_SCRATCHPAD);
118
}
119

120
static void fsi_cfam_realize(DeviceState *dev, Error **errp)
121
{
122
    FSICFAMState *cfam = FSI_CFAM(dev);
123
    FSISlaveState *slave = FSI_SLAVE(dev);
124

125
    /* Each slave has a 2MiB address space */
126
    memory_region_init_io(&cfam->mr, OBJECT(cfam), &fsi_cfam_unimplemented_ops,
127
                          cfam, TYPE_FSI_CFAM, 2 * MiB);
128

129
    qbus_init(&cfam->lbus, sizeof(cfam->lbus), TYPE_FSI_LBUS, DEVICE(cfam),
130
              NULL);
131

132
    memory_region_init_io(&cfam->config_iomem, OBJECT(cfam), &cfam_config_ops,
133
                          cfam, TYPE_FSI_CFAM ".config", 0x400);
134

135
    memory_region_add_subregion(&cfam->mr, 0, &cfam->config_iomem);
136
    memory_region_add_subregion(&cfam->mr, 0x800, &slave->iomem);
137
    memory_region_add_subregion(&cfam->mr, 0xc00, &cfam->lbus.mr);
138

139
    /* Add scratchpad engine */
140
    if (!qdev_realize(DEVICE(&cfam->scratchpad), BUS(&cfam->lbus), errp)) {
141
        return;
142
    }
143

144
    FSILBusDevice *fsi_dev = FSI_LBUS_DEVICE(&cfam->scratchpad);
145
    memory_region_add_subregion(&cfam->lbus.mr, 0, &fsi_dev->iomem);
146
}
147

148
static void fsi_cfam_class_init(ObjectClass *klass, void *data)
149
{
150
    DeviceClass *dc = DEVICE_CLASS(klass);
151
    dc->bus_type = TYPE_FSI_BUS;
152
    dc->realize = fsi_cfam_realize;
153
}
154

155
static const TypeInfo fsi_cfam_info = {
156
    .name = TYPE_FSI_CFAM,
157
    .parent = TYPE_FSI_SLAVE,
158
    .instance_init = fsi_cfam_instance_init,
159
    .instance_size = sizeof(FSICFAMState),
160
    .class_init = fsi_cfam_class_init,
161
};
162

163
static void fsi_cfam_register_types(void)
164
{
165
    type_register_static(&fsi_cfam_info);
166
}
167

168
type_init(fsi_cfam_register_types);
169

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

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

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

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