4 * Copyright (c) 2021 Vijai Kumar K <vijai@behindbytes.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "qemu/osdep.h"
26 #include "hw/char/shakti_uart.h"
27 #include "hw/qdev-properties.h"
28 #include "hw/qdev-properties-system.h"
31 static uint64_t shakti_uart_read(void *opaque
, hwaddr addr
, unsigned size
)
33 ShaktiUartState
*s
= opaque
;
36 case SHAKTI_UART_BAUD
:
39 qemu_chr_fe_accept_input(&s
->chr
);
40 s
->uart_status
&= ~SHAKTI_UART_STATUS_RX_NOT_EMPTY
;
42 case SHAKTI_UART_STATUS
:
43 return s
->uart_status
;
44 case SHAKTI_UART_DELAY
:
46 case SHAKTI_UART_CONTROL
:
47 return s
->uart_control
;
48 case SHAKTI_UART_INT_EN
:
49 return s
->uart_interrupt
;
50 case SHAKTI_UART_IQ_CYCLES
:
51 return s
->uart_iq_cycles
;
52 case SHAKTI_UART_RX_THRES
:
53 return s
->uart_rx_threshold
;
55 /* Also handles TX REG which is write only */
56 qemu_log_mask(LOG_GUEST_ERROR
,
57 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
63 static void shakti_uart_write(void *opaque
, hwaddr addr
,
64 uint64_t data
, unsigned size
)
66 ShaktiUartState
*s
= opaque
;
67 uint32_t value
= data
;
71 case SHAKTI_UART_BAUD
:
76 qemu_chr_fe_write_all(&s
->chr
, &ch
, 1);
77 s
->uart_status
&= ~SHAKTI_UART_STATUS_TX_FULL
;
79 case SHAKTI_UART_STATUS
:
80 s
->uart_status
= value
;
82 case SHAKTI_UART_DELAY
:
83 s
->uart_delay
= value
;
85 case SHAKTI_UART_CONTROL
:
86 s
->uart_control
= value
;
88 case SHAKTI_UART_INT_EN
:
89 s
->uart_interrupt
= value
;
91 case SHAKTI_UART_IQ_CYCLES
:
92 s
->uart_iq_cycles
= value
;
94 case SHAKTI_UART_RX_THRES
:
95 s
->uart_rx_threshold
= value
;
98 qemu_log_mask(LOG_GUEST_ERROR
,
99 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
103 static const MemoryRegionOps shakti_uart_ops
= {
104 .read
= shakti_uart_read
,
105 .write
= shakti_uart_write
,
106 .endianness
= DEVICE_NATIVE_ENDIAN
,
107 .impl
= {.min_access_size
= 1, .max_access_size
= 4},
108 .valid
= {.min_access_size
= 1, .max_access_size
= 4},
111 static void shakti_uart_reset(DeviceState
*dev
)
113 ShaktiUartState
*s
= SHAKTI_UART(dev
);
115 s
->uart_baud
= SHAKTI_UART_BAUD_DEFAULT
;
118 s
->uart_status
= 0x0000;
119 s
->uart_delay
= 0x0000;
120 s
->uart_control
= SHAKTI_UART_CONTROL_DEFAULT
;
121 s
->uart_interrupt
= 0x0000;
122 s
->uart_iq_cycles
= 0x00;
123 s
->uart_rx_threshold
= 0x00;
126 static int shakti_uart_can_receive(void *opaque
)
128 ShaktiUartState
*s
= opaque
;
130 return !(s
->uart_status
& SHAKTI_UART_STATUS_RX_NOT_EMPTY
);
133 static void shakti_uart_receive(void *opaque
, const uint8_t *buf
, int size
)
135 ShaktiUartState
*s
= opaque
;
138 s
->uart_status
|= SHAKTI_UART_STATUS_RX_NOT_EMPTY
;
141 static void shakti_uart_realize(DeviceState
*dev
, Error
**errp
)
143 ShaktiUartState
*sus
= SHAKTI_UART(dev
);
144 qemu_chr_fe_set_handlers(&sus
->chr
, shakti_uart_can_receive
,
145 shakti_uart_receive
, NULL
, NULL
, sus
, NULL
, true);
148 static void shakti_uart_instance_init(Object
*obj
)
150 ShaktiUartState
*sus
= SHAKTI_UART(obj
);
151 memory_region_init_io(&sus
->mmio
,
157 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &sus
->mmio
);
160 static Property shakti_uart_properties
[] = {
161 DEFINE_PROP_CHR("chardev", ShaktiUartState
, chr
),
162 DEFINE_PROP_END_OF_LIST(),
165 static void shakti_uart_class_init(ObjectClass
*klass
, void *data
)
167 DeviceClass
*dc
= DEVICE_CLASS(klass
);
168 dc
->reset
= shakti_uart_reset
;
169 dc
->realize
= shakti_uart_realize
;
170 device_class_set_props(dc
, shakti_uart_properties
);
173 static const TypeInfo shakti_uart_info
= {
174 .name
= TYPE_SHAKTI_UART
,
175 .parent
= TYPE_SYS_BUS_DEVICE
,
176 .instance_size
= sizeof(ShaktiUartState
),
177 .class_init
= shakti_uart_class_init
,
178 .instance_init
= shakti_uart_instance_init
,
181 static void shakti_uart_register_types(void)
183 type_register_static(&shakti_uart_info
);
185 type_init(shakti_uart_register_types
)