~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to hw/grlib_apbuart.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU GRLIB APB UART Emulator
 
3
 *
 
4
 * Copyright (c) 2010-2011 AdaCore
 
5
 *
 
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:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
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
 
22
 * THE SOFTWARE.
 
23
 */
 
24
 
 
25
#include "sysbus.h"
 
26
#include "qemu-char.h"
 
27
 
 
28
#include "trace.h"
 
29
 
 
30
#define UART_REG_SIZE 20     /* Size of memory mapped registers */
 
31
 
 
32
/* UART status register fields */
 
33
#define UART_DATA_READY           (1 <<  0)
 
34
#define UART_TRANSMIT_SHIFT_EMPTY (1 <<  1)
 
35
#define UART_TRANSMIT_FIFO_EMPTY  (1 <<  2)
 
36
#define UART_BREAK_RECEIVED       (1 <<  3)
 
37
#define UART_OVERRUN              (1 <<  4)
 
38
#define UART_PARITY_ERROR         (1 <<  5)
 
39
#define UART_FRAMING_ERROR        (1 <<  6)
 
40
#define UART_TRANSMIT_FIFO_HALF   (1 <<  7)
 
41
#define UART_RECEIVE_FIFO_HALF    (1 <<  8)
 
42
#define UART_TRANSMIT_FIFO_FULL   (1 <<  9)
 
43
#define UART_RECEIVE_FIFO_FULL    (1 << 10)
 
44
 
 
45
/* UART control register fields */
 
46
#define UART_RECEIVE_ENABLE          (1 <<  0)
 
47
#define UART_TRANSMIT_ENABLE         (1 <<  1)
 
48
#define UART_RECEIVE_INTERRUPT       (1 <<  2)
 
49
#define UART_TRANSMIT_INTERRUPT      (1 <<  3)
 
50
#define UART_PARITY_SELECT           (1 <<  4)
 
51
#define UART_PARITY_ENABLE           (1 <<  5)
 
52
#define UART_FLOW_CONTROL            (1 <<  6)
 
53
#define UART_LOOPBACK                (1 <<  7)
 
54
#define UART_EXTERNAL_CLOCK          (1 <<  8)
 
55
#define UART_RECEIVE_FIFO_INTERRUPT  (1 <<  9)
 
56
#define UART_TRANSMIT_FIFO_INTERRUPT (1 << 10)
 
57
#define UART_FIFO_DEBUG_MODE         (1 << 11)
 
58
#define UART_OUTPUT_ENABLE           (1 << 12)
 
59
#define UART_FIFO_AVAILABLE          (1 << 31)
 
60
 
 
61
/* Memory mapped register offsets */
 
62
#define DATA_OFFSET       0x00
 
63
#define STATUS_OFFSET     0x04
 
64
#define CONTROL_OFFSET    0x08
 
65
#define SCALER_OFFSET     0x0C  /* not supported */
 
66
#define FIFO_DEBUG_OFFSET 0x10  /* not supported */
 
67
 
 
68
typedef struct UART {
 
69
    SysBusDevice busdev;
 
70
 
 
71
    qemu_irq irq;
 
72
 
 
73
    CharDriverState *chr;
 
74
 
 
75
    /* registers */
 
76
    uint32_t receive;
 
77
    uint32_t status;
 
78
    uint32_t control;
 
79
} UART;
 
80
 
 
81
static int grlib_apbuart_can_receive(void *opaque)
 
82
{
 
83
    UART *uart = opaque;
 
84
 
 
85
    return !!(uart->status & UART_DATA_READY);
 
86
}
 
87
 
 
88
static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, int size)
 
89
{
 
90
    UART *uart = opaque;
 
91
 
 
92
    uart->receive  = *buf;
 
93
    uart->status  |= UART_DATA_READY;
 
94
 
 
95
    if (uart->control & UART_RECEIVE_INTERRUPT) {
 
96
        qemu_irq_pulse(uart->irq);
 
97
    }
 
98
}
 
99
 
 
100
static void grlib_apbuart_event(void *opaque, int event)
 
101
{
 
102
    trace_grlib_apbuart_event(event);
 
103
}
 
104
 
 
105
static void
 
106
grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
 
107
{
 
108
    UART          *uart = opaque;
 
109
    unsigned char  c    = 0;
 
110
 
 
111
    addr &= 0xff;
 
112
 
 
113
    /* Unit registers */
 
114
    switch (addr) {
 
115
    case DATA_OFFSET:
 
116
        c = value & 0xFF;
 
117
        qemu_chr_write(uart->chr, &c, 1);
 
118
        return;
 
119
 
 
120
    case STATUS_OFFSET:
 
121
        /* Read Only */
 
122
        return;
 
123
 
 
124
    case CONTROL_OFFSET:
 
125
        /* Not supported */
 
126
        return;
 
127
 
 
128
    case SCALER_OFFSET:
 
129
        /* Not supported */
 
130
        return;
 
131
 
 
132
    default:
 
133
        break;
 
134
    }
 
135
 
 
136
    trace_grlib_apbuart_writel_unknown(addr, value);
 
137
}
 
138
 
 
139
static CPUReadMemoryFunc * const grlib_apbuart_read[] = {
 
140
    NULL, NULL, NULL,
 
141
};
 
142
 
 
143
static CPUWriteMemoryFunc * const grlib_apbuart_write[] = {
 
144
    NULL, NULL, grlib_apbuart_writel,
 
145
};
 
146
 
 
147
static int grlib_apbuart_init(SysBusDevice *dev)
 
148
{
 
149
    UART *uart      = FROM_SYSBUS(typeof(*uart), dev);
 
150
    int   uart_regs = 0;
 
151
 
 
152
    qemu_chr_add_handlers(uart->chr,
 
153
                          grlib_apbuart_can_receive,
 
154
                          grlib_apbuart_receive,
 
155
                          grlib_apbuart_event,
 
156
                          uart);
 
157
 
 
158
    sysbus_init_irq(dev, &uart->irq);
 
159
 
 
160
    uart_regs = cpu_register_io_memory(grlib_apbuart_read,
 
161
                                       grlib_apbuart_write,
 
162
                                       uart, DEVICE_NATIVE_ENDIAN);
 
163
    if (uart_regs < 0) {
 
164
        return -1;
 
165
    }
 
166
 
 
167
    sysbus_init_mmio(dev, UART_REG_SIZE, uart_regs);
 
168
 
 
169
    return 0;
 
170
}
 
171
 
 
172
static SysBusDeviceInfo grlib_gptimer_info = {
 
173
    .init       = grlib_apbuart_init,
 
174
    .qdev.name  = "grlib,apbuart",
 
175
    .qdev.size  = sizeof(UART),
 
176
    .qdev.props = (Property[]) {
 
177
        DEFINE_PROP_CHR("chrdev", UART, chr),
 
178
        DEFINE_PROP_END_OF_LIST()
 
179
    }
 
180
};
 
181
 
 
182
static void grlib_gptimer_register(void)
 
183
{
 
184
    sysbus_register_withprop(&grlib_gptimer_info);
 
185
}
 
186
 
 
187
device_init(grlib_gptimer_register)