]>
Commit | Line | Data |
---|---|---|
677726ef MC |
1 | /* |
2 | * QEMU simulated pvpanic device. | |
3 | * | |
4 | * Copyright Fujitsu, Corp. 2013 | |
5 | * | |
6 | * Authors: | |
7 | * Wen Congyang <wency@cn.fujitsu.com> | |
8 | * Hu Tao <hutao@cn.fujitsu.com> | |
9 | * | |
10 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
11 | * See the COPYING file in the top-level directory. | |
12 | * | |
13 | */ | |
14 | ||
15 | #include "qemu/osdep.h" | |
677726ef MC |
16 | #include "qemu/module.h" |
17 | #include "sysemu/runstate.h" | |
18 | ||
19 | #include "hw/nvram/fw_cfg.h" | |
20 | #include "hw/qdev-properties.h" | |
21 | #include "hw/misc/pvpanic.h" | |
22 | #include "qom/object.h" | |
23 | #include "hw/isa/isa.h" | |
45d8c052 | 24 | #include "standard-headers/linux/pvpanic.h" |
ff36e90e | 25 | #include "hw/acpi/acpi_aml_interface.h" |
677726ef MC |
26 | |
27 | OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE) | |
28 | ||
29 | /* | |
30 | * PVPanicISAState for ISA device and | |
31 | * use ioport. | |
32 | */ | |
33 | struct PVPanicISAState { | |
34 | ISADevice parent_obj; | |
35 | ||
36 | uint16_t ioport; | |
37 | PVPanicState pvpanic; | |
38 | }; | |
39 | ||
40 | static void pvpanic_isa_initfn(Object *obj) | |
41 | { | |
42 | PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj); | |
43 | ||
44 | pvpanic_setup_io(&s->pvpanic, DEVICE(s), 1); | |
45 | } | |
46 | ||
47 | static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp) | |
48 | { | |
49 | ISADevice *d = ISA_DEVICE(dev); | |
50 | PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev); | |
51 | PVPanicState *ps = &s->pvpanic; | |
52 | FWCfgState *fw_cfg = fw_cfg_find(); | |
53 | uint16_t *pvpanic_port; | |
54 | ||
55 | if (!fw_cfg) { | |
56 | return; | |
57 | } | |
58 | ||
59 | pvpanic_port = g_malloc(sizeof(*pvpanic_port)); | |
60 | *pvpanic_port = cpu_to_le16(s->ioport); | |
61 | fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port, | |
62 | sizeof(*pvpanic_port)); | |
63 | ||
64 | isa_register_ioport(d, &ps->mr, s->ioport); | |
65 | } | |
66 | ||
ff36e90e IM |
67 | static void build_pvpanic_isa_aml(AcpiDevAmlIf *adev, Aml *scope) |
68 | { | |
69 | Aml *crs, *field, *method; | |
70 | PVPanicISAState *s = PVPANIC_ISA_DEVICE(adev); | |
71 | Aml *dev = aml_device("PEVT"); | |
72 | ||
73 | aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001"))); | |
74 | ||
75 | crs = aml_resource_template(); | |
76 | aml_append(crs, | |
77 | aml_io(AML_DECODE16, s->ioport, s->ioport, 1, 1) | |
78 | ); | |
79 | aml_append(dev, aml_name_decl("_CRS", crs)); | |
80 | ||
81 | aml_append(dev, aml_operation_region("PEOR", AML_SYSTEM_IO, | |
82 | aml_int(s->ioport), 1)); | |
83 | field = aml_field("PEOR", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); | |
84 | aml_append(field, aml_named_field("PEPT", 8)); | |
85 | aml_append(dev, field); | |
86 | ||
87 | /* device present, functioning, decoding, shown in UI */ | |
88 | aml_append(dev, aml_name_decl("_STA", aml_int(0xF))); | |
89 | ||
90 | method = aml_method("RDPT", 0, AML_NOTSERIALIZED); | |
91 | aml_append(method, aml_store(aml_name("PEPT"), aml_local(0))); | |
92 | aml_append(method, aml_return(aml_local(0))); | |
93 | aml_append(dev, method); | |
94 | ||
95 | method = aml_method("WRPT", 1, AML_NOTSERIALIZED); | |
96 | aml_append(method, aml_store(aml_arg(0), aml_name("PEPT"))); | |
97 | aml_append(dev, method); | |
98 | ||
99 | aml_append(scope, dev); | |
100 | } | |
101 | ||
677726ef MC |
102 | static Property pvpanic_isa_properties[] = { |
103 | DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505), | |
45d8c052 ZP |
104 | DEFINE_PROP_UINT8("events", PVPanicISAState, pvpanic.events, |
105 | PVPANIC_PANICKED | PVPANIC_CRASH_LOADED), | |
677726ef MC |
106 | DEFINE_PROP_END_OF_LIST(), |
107 | }; | |
108 | ||
109 | static void pvpanic_isa_class_init(ObjectClass *klass, void *data) | |
110 | { | |
111 | DeviceClass *dc = DEVICE_CLASS(klass); | |
ff36e90e | 112 | AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); |
677726ef MC |
113 | |
114 | dc->realize = pvpanic_isa_realizefn; | |
115 | device_class_set_props(dc, pvpanic_isa_properties); | |
116 | set_bit(DEVICE_CATEGORY_MISC, dc->categories); | |
ff36e90e | 117 | adevc->build_dev_aml = build_pvpanic_isa_aml; |
677726ef MC |
118 | } |
119 | ||
5e78c98b | 120 | static const TypeInfo pvpanic_isa_info = { |
677726ef MC |
121 | .name = TYPE_PVPANIC_ISA_DEVICE, |
122 | .parent = TYPE_ISA_DEVICE, | |
123 | .instance_size = sizeof(PVPanicISAState), | |
124 | .instance_init = pvpanic_isa_initfn, | |
125 | .class_init = pvpanic_isa_class_init, | |
ff36e90e IM |
126 | .interfaces = (InterfaceInfo[]) { |
127 | { TYPE_ACPI_DEV_AML_IF }, | |
128 | { }, | |
129 | }, | |
677726ef MC |
130 | }; |
131 | ||
132 | static void pvpanic_register_types(void) | |
133 | { | |
134 | type_register_static(&pvpanic_isa_info); | |
135 | } | |
136 | ||
137 | type_init(pvpanic_register_types) |