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#include "qemu/osdep.h"
28#include "qemu/log.h"
29#include "qapi/error.h"
30#include "hw/i2c/i2c.h"
31#include "hw/block/m24cxx.h"
32#include "migration/vmstate.h"
33#include "hw/qdev-properties.h"
34
35#define TYPE_SODIMM_SPD "sodimm-spd"
36#define DEBUG_SODIMM_SPD 0
37#define DPRINT(fmt, args...) \
38 if (DEBUG_SODIMM_SPD) { \
39 qemu_log("%s: " fmt, __func__, ## args); \
40 }
41
42#define SODIMM_SPD(obj) \
43 OBJECT_CHECK(SodimmSPD, (obj), TYPE_SODIMM_SPD)
44
45#define SODIMM_SPD_CLASS(obj) \
46 OBJECT_CLASS_CHECK(SodimmSPDClass, (obj), TYPE_SODIMM_SPD)
47
48#define SODIMM_SPD_GET_CLASS(obj) \
49 OBJECT_GET_CLASS(SodimmSPDClass, (obj), TYPE_SODIMM_SPD)
50
51
52#define SPD_MANF_ID_INDEX 73
53
54
55typedef struct SodimmSPD {
56 M24CXXState parent_obj;
57
58} SodimmSPD;
59
60typedef struct SodimmSPDClass {
61 I2CSlaveClass parent_class;
62
63 char manf_id[32];
64} SodimmSPDClass;
65
66
67static void sodimm_spd_reset(DeviceState *dev)
68{
69 M24CXXState *p = M24CXX(dev);
70 SodimmSPDClass *sc = SODIMM_SPD_GET_CLASS(dev);
71
72 strcpy((char *)&p->storage[SPD_MANF_ID_INDEX], sc->manf_id);
73}
74
75static void sodimm_spd_init(Object *obj)
76{
77
78 qdev_prop_set_uint16(DEVICE(obj), "size", 128);
79}
80
81static void sodimm_spd_class_init(ObjectClass *klass, void *data)
82{
83 DeviceClass *dc = DEVICE_CLASS(klass);
84 SodimmSPDClass *sc = SODIMM_SPD_CLASS(klass);
85
86 strcpy(sc->manf_id, (char *) data);
87 dc->reset = sodimm_spd_reset;
88}
89
90static const char *dev_info[] = {
91 "4ATF51264HZ-2G6E1",
92};
93
94static const TypeInfo sodimm_spd_info = {
95 .name = TYPE_SODIMM_SPD,
96 .parent = TYPE_M24CXX,
97 .instance_size = sizeof(SodimmSPD),
98 .class_init = sodimm_spd_class_init,
99 .instance_init = sodimm_spd_init,
100 .class_size = sizeof(SodimmSPDClass),
101 .class_data = &dev_info[0],
102};
103
104static void sodimm_spd_register_type(void)
105{
106 type_register_static(&sodimm_spd_info);
107}
108
109type_init(sodimm_spd_register_type)
110