xref: /openbmc/qemu/hw/misc/avr_power.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
1dc288de0SMichael Rolnik /*
2dc288de0SMichael Rolnik  * AVR Power Reduction Management
3dc288de0SMichael Rolnik  *
4dc288de0SMichael Rolnik  * Copyright (c) 2019-2020 Michael Rolnik
5dc288de0SMichael Rolnik  *
6dc288de0SMichael Rolnik  * Permission is hereby granted, free of charge, to any person obtaining a copy
7dc288de0SMichael Rolnik  * of this software and associated documentation files (the "Software"), to deal
8dc288de0SMichael Rolnik  * in the Software without restriction, including without limitation the rights
9dc288de0SMichael Rolnik  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10dc288de0SMichael Rolnik  * copies of the Software, and to permit persons to whom the Software is
11dc288de0SMichael Rolnik  * furnished to do so, subject to the following conditions:
12dc288de0SMichael Rolnik  *
13dc288de0SMichael Rolnik  * The above copyright notice and this permission notice shall be included in
14dc288de0SMichael Rolnik  * all copies or substantial portions of the Software.
15dc288de0SMichael Rolnik  *
16dc288de0SMichael Rolnik  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17dc288de0SMichael Rolnik  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18dc288de0SMichael Rolnik  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19dc288de0SMichael Rolnik  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20dc288de0SMichael Rolnik  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21dc288de0SMichael Rolnik  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22dc288de0SMichael Rolnik  * THE SOFTWARE.
23dc288de0SMichael Rolnik  */
24dc288de0SMichael Rolnik 
25dc288de0SMichael Rolnik #include "qemu/osdep.h"
26dc288de0SMichael Rolnik #include "hw/misc/avr_power.h"
27dc288de0SMichael Rolnik #include "qemu/log.h"
28dc288de0SMichael Rolnik #include "hw/qdev-properties.h"
29dc288de0SMichael Rolnik #include "hw/irq.h"
30dc288de0SMichael Rolnik #include "trace.h"
31dc288de0SMichael Rolnik 
avr_mask_reset(DeviceState * dev)32dc288de0SMichael Rolnik static void avr_mask_reset(DeviceState *dev)
33dc288de0SMichael Rolnik {
34dc288de0SMichael Rolnik     AVRMaskState *s = AVR_MASK(dev);
35dc288de0SMichael Rolnik 
36dc288de0SMichael Rolnik     s->val = 0x00;
37dc288de0SMichael Rolnik 
38dc288de0SMichael Rolnik     for (int i = 0; i < 8; i++) {
39dc288de0SMichael Rolnik         qemu_set_irq(s->irq[i], 0);
40dc288de0SMichael Rolnik     }
41dc288de0SMichael Rolnik }
42dc288de0SMichael Rolnik 
avr_mask_read(void * opaque,hwaddr offset,unsigned size)43dc288de0SMichael Rolnik static uint64_t avr_mask_read(void *opaque, hwaddr offset, unsigned size)
44dc288de0SMichael Rolnik {
45dc288de0SMichael Rolnik     assert(size == 1);
46dc288de0SMichael Rolnik     assert(offset == 0);
47dc288de0SMichael Rolnik     AVRMaskState *s = opaque;
48dc288de0SMichael Rolnik 
49dc288de0SMichael Rolnik     trace_avr_power_read(s->val);
50dc288de0SMichael Rolnik 
51dc288de0SMichael Rolnik     return (uint64_t)s->val;
52dc288de0SMichael Rolnik }
53dc288de0SMichael Rolnik 
avr_mask_write(void * opaque,hwaddr offset,uint64_t val64,unsigned size)54dc288de0SMichael Rolnik static void avr_mask_write(void *opaque, hwaddr offset,
55dc288de0SMichael Rolnik                            uint64_t val64, unsigned size)
56dc288de0SMichael Rolnik {
57dc288de0SMichael Rolnik     assert(size == 1);
58dc288de0SMichael Rolnik     assert(offset == 0);
59dc288de0SMichael Rolnik     AVRMaskState *s = opaque;
60dc288de0SMichael Rolnik     uint8_t val8 = val64;
61dc288de0SMichael Rolnik 
62dc288de0SMichael Rolnik     trace_avr_power_write(val8);
63dc288de0SMichael Rolnik     s->val = val8;
64dc288de0SMichael Rolnik     for (int i = 0; i < 8; i++) {
65dc288de0SMichael Rolnik         qemu_set_irq(s->irq[i], (val8 & (1 << i)) != 0);
66dc288de0SMichael Rolnik     }
67dc288de0SMichael Rolnik }
68dc288de0SMichael Rolnik 
69dc288de0SMichael Rolnik static const MemoryRegionOps avr_mask_ops = {
70dc288de0SMichael Rolnik     .read = avr_mask_read,
71dc288de0SMichael Rolnik     .write = avr_mask_write,
72dc288de0SMichael Rolnik     .endianness = DEVICE_NATIVE_ENDIAN,
73dc288de0SMichael Rolnik     .impl = {
74dc288de0SMichael Rolnik         .max_access_size = 1,
75dc288de0SMichael Rolnik     },
76dc288de0SMichael Rolnik };
77dc288de0SMichael Rolnik 
avr_mask_init(Object * dev)78dc288de0SMichael Rolnik static void avr_mask_init(Object *dev)
79dc288de0SMichael Rolnik {
80dc288de0SMichael Rolnik     AVRMaskState *s = AVR_MASK(dev);
81dc288de0SMichael Rolnik     SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
82dc288de0SMichael Rolnik 
83dc288de0SMichael Rolnik     memory_region_init_io(&s->iomem, dev, &avr_mask_ops, s, TYPE_AVR_MASK,
84dc288de0SMichael Rolnik                           0x01);
85dc288de0SMichael Rolnik     sysbus_init_mmio(busdev, &s->iomem);
86dc288de0SMichael Rolnik 
87dc288de0SMichael Rolnik     for (int i = 0; i < 8; i++) {
88dc288de0SMichael Rolnik         sysbus_init_irq(busdev, &s->irq[i]);
89dc288de0SMichael Rolnik     }
90dc288de0SMichael Rolnik     s->val = 0x00;
91dc288de0SMichael Rolnik }
92dc288de0SMichael Rolnik 
avr_mask_class_init(ObjectClass * klass,void * data)93dc288de0SMichael Rolnik static void avr_mask_class_init(ObjectClass *klass, void *data)
94dc288de0SMichael Rolnik {
95dc288de0SMichael Rolnik     DeviceClass *dc = DEVICE_CLASS(klass);
96dc288de0SMichael Rolnik 
97*e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, avr_mask_reset);
98dc288de0SMichael Rolnik }
99dc288de0SMichael Rolnik 
100dc288de0SMichael Rolnik static const TypeInfo avr_mask_info = {
101dc288de0SMichael Rolnik     .name          = TYPE_AVR_MASK,
102dc288de0SMichael Rolnik     .parent        = TYPE_SYS_BUS_DEVICE,
103dc288de0SMichael Rolnik     .instance_size = sizeof(AVRMaskState),
104dc288de0SMichael Rolnik     .class_init    = avr_mask_class_init,
105dc288de0SMichael Rolnik     .instance_init = avr_mask_init,
106dc288de0SMichael Rolnik };
107dc288de0SMichael Rolnik 
avr_mask_register_types(void)108dc288de0SMichael Rolnik static void avr_mask_register_types(void)
109dc288de0SMichael Rolnik {
110dc288de0SMichael Rolnik     type_register_static(&avr_mask_info);
111dc288de0SMichael Rolnik }
112dc288de0SMichael Rolnik 
113dc288de0SMichael Rolnik type_init(avr_mask_register_types)
114