~vcs-imports/qemu/maemo

« back to all changes in this revision

Viewing changes to hw/etraxfs_ser.c

  • Committer: Riku Voipio
  • Date: 2009-06-08 15:31:58 UTC
  • mfrom: (6281.2.366)
  • mto: This revision was merged to the branch mainline in revision 6452.
  • Revision ID: git-v1:759b334a9739814df2883aa4c41b1c0f5670e90a
Merge commit 'gnu/master' into test

Epic merge

Conflicts:
        Makefile
        block.c
        block.h
        configure
        hw/boards.h
        hw/flash.h
        hw/integratorcp.c
        hw/nand.c
        hw/omap2.c
        hw/omap_i2c.c
        hw/sd.c
        hw/smc91c111.c
        hw/tsc2005.c
        hw/tusb6010.c
        hw/usb-musb.c
        linux-user/syscall.c
        target-arm/machine.c
        target-arm/translate.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 * THE SOFTWARE.
23
23
 */
24
24
 
25
 
#include <stdio.h>
26
 
#include <ctype.h>
27
 
#include "hw.h"
 
25
#include "sysbus.h"
28
26
#include "qemu-char.h"
29
 
#include "etraxfs.h"
30
27
 
31
28
#define D(x)
32
29
 
48
45
 
49
46
struct etrax_serial
50
47
{
51
 
        CPUState *env;
52
 
        CharDriverState *chr;
53
 
        qemu_irq *irq;
54
 
 
55
 
        /* This pending thing is a hack.  */
56
 
        int pending_tx;
57
 
 
58
 
        /* Control registers.  */
59
 
        uint32_t regs[R_MAX];
 
48
    SysBusDevice busdev;
 
49
    CharDriverState *chr;
 
50
    qemu_irq irq;
 
51
 
 
52
    /* This pending thing is a hack.  */
 
53
    int pending_tx;
 
54
 
 
55
    /* Control registers.  */
 
56
    uint32_t regs[R_MAX];
60
57
};
61
58
 
62
59
static void ser_update_irq(struct etrax_serial *s)
63
60
{
64
 
        s->regs[R_INTR] &= ~(s->regs[RW_ACK_INTR]);
65
 
        s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
 
61
    s->regs[R_INTR] &= ~(s->regs[RW_ACK_INTR]);
 
62
    s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
66
63
 
67
 
        qemu_set_irq(s->irq[0], !!s->regs[R_MASKED_INTR]);
68
 
        s->regs[RW_ACK_INTR] = 0;
 
64
    qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]);
 
65
    s->regs[RW_ACK_INTR] = 0;
69
66
}
70
67
 
71
68
static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
72
69
{
73
 
        struct etrax_serial *s = opaque;
74
 
        D(CPUState *env = s->env);
75
 
        uint32_t r = 0;
 
70
    struct etrax_serial *s = opaque;
 
71
    D(CPUState *env = s->env);
 
72
    uint32_t r = 0;
76
73
 
77
 
        addr >>= 2;
78
 
        switch (addr)
79
 
        {
80
 
                case R_STAT_DIN:
81
 
                        r = s->regs[RS_STAT_DIN];
82
 
                        break;
83
 
                case RS_STAT_DIN:
84
 
                        r = s->regs[addr];
85
 
                        /* Read side-effect: clear dav.  */
86
 
                        s->regs[addr] &= ~(1 << STAT_DAV);
87
 
                        break;
88
 
                default:
89
 
                        r = s->regs[addr];
90
 
                        D(printf ("%s %x=%x\n", __func__, addr, r));
91
 
                        break;
92
 
        }
93
 
        return r;
 
74
    addr >>= 2;
 
75
    switch (addr)
 
76
    {
 
77
        case R_STAT_DIN:
 
78
            r = s->regs[RS_STAT_DIN];
 
79
            break;
 
80
        case RS_STAT_DIN:
 
81
            r = s->regs[addr];
 
82
            /* Read side-effect: clear dav.  */
 
83
            s->regs[addr] &= ~(1 << STAT_DAV);
 
84
            break;
 
85
        default:
 
86
            r = s->regs[addr];
 
87
            D(printf ("%s %x=%x\n", __func__, addr, r));
 
88
            break;
 
89
    }
 
90
    return r;
94
91
}
95
92
 
96
93
static void
97
94
ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
98
95
{
99
 
        struct etrax_serial *s = opaque;
100
 
        unsigned char ch = value;
101
 
        D(CPUState *env = s->env);
 
96
    struct etrax_serial *s = opaque;
 
97
    unsigned char ch = value;
 
98
    D(CPUState *env = s->env);
102
99
 
103
 
        D(printf ("%s %x %x\n",  __func__, addr, value));
104
 
        addr >>= 2;
105
 
        switch (addr)
106
 
        {
107
 
                case RW_DOUT:
108
 
                        qemu_chr_write(s->chr, &ch, 1);
109
 
                        s->regs[R_INTR] |= 1;
110
 
                        s->pending_tx = 1;
111
 
                        s->regs[addr] = value;
112
 
                        break;
113
 
                case RW_ACK_INTR:
114
 
                        s->regs[addr] = value;
115
 
                        if (s->pending_tx && (s->regs[addr] & 1)) {
116
 
                                s->regs[R_INTR] |= 1;
117
 
                                s->pending_tx = 0;
118
 
                                s->regs[addr] &= ~1;
119
 
                        }
120
 
                        break;
121
 
                default:
122
 
                        s->regs[addr] = value;
123
 
                        break;
124
 
        }
125
 
        ser_update_irq(s);
 
100
    D(printf ("%s %x %x\n",  __func__, addr, value));
 
101
    addr >>= 2;
 
102
    switch (addr)
 
103
    {
 
104
        case RW_DOUT:
 
105
            qemu_chr_write(s->chr, &ch, 1);
 
106
            s->regs[R_INTR] |= 1;
 
107
            s->pending_tx = 1;
 
108
            s->regs[addr] = value;
 
109
            break;
 
110
        case RW_ACK_INTR:
 
111
            s->regs[addr] = value;
 
112
            if (s->pending_tx && (s->regs[addr] & 1)) {
 
113
                s->regs[R_INTR] |= 1;
 
114
                s->pending_tx = 0;
 
115
                s->regs[addr] &= ~1;
 
116
            }
 
117
            break;
 
118
        default:
 
119
            s->regs[addr] = value;
 
120
            break;
 
121
    }
 
122
    ser_update_irq(s);
126
123
}
127
124
 
128
125
static CPUReadMemoryFunc *ser_read[] = {
129
 
        NULL, NULL,
130
 
        &ser_readl,
 
126
    NULL, NULL,
 
127
    &ser_readl,
131
128
};
132
129
 
133
130
static CPUWriteMemoryFunc *ser_write[] = {
134
 
        NULL, NULL,
135
 
        &ser_writel,
 
131
    NULL, NULL,
 
132
    &ser_writel,
136
133
};
137
134
 
138
135
static void serial_receive(void *opaque, const uint8_t *buf, int size)
139
136
{
140
 
        struct etrax_serial *s = opaque;
 
137
    struct etrax_serial *s = opaque;
141
138
 
142
 
        s->regs[R_INTR] |= 8;
143
 
        s->regs[RS_STAT_DIN] &= ~0xff;
144
 
        s->regs[RS_STAT_DIN] |= (buf[0] & 0xff);
145
 
        s->regs[RS_STAT_DIN] |= (1 << STAT_DAV); /* dav.  */
146
 
        ser_update_irq(s);
 
139
    s->regs[R_INTR] |= 8;
 
140
    s->regs[RS_STAT_DIN] &= ~0xff;
 
141
    s->regs[RS_STAT_DIN] |= (buf[0] & 0xff);
 
142
    s->regs[RS_STAT_DIN] |= (1 << STAT_DAV); /* dav.  */
 
143
    ser_update_irq(s);
147
144
}
148
145
 
149
146
static int serial_can_receive(void *opaque)
150
147
{
151
 
        struct etrax_serial *s = opaque;
152
 
        int r;
153
 
 
154
 
        /* Is the receiver enabled?  */
155
 
        r = s->regs[RW_REC_CTRL] & 1;
156
 
 
157
 
        /* Pending rx data?  */
158
 
        r |= !(s->regs[R_INTR] & 8);
159
 
        return r;
 
148
    struct etrax_serial *s = opaque;
 
149
    int r;
 
150
 
 
151
    /* Is the receiver enabled?  */
 
152
    r = s->regs[RW_REC_CTRL] & 1;
 
153
 
 
154
    /* Pending rx data?  */
 
155
    r |= !(s->regs[R_INTR] & 8);
 
156
    return r;
160
157
}
161
158
 
162
159
static void serial_event(void *opaque, int event)
164
161
 
165
162
}
166
163
 
167
 
void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
168
 
                      target_phys_addr_t base)
169
 
{
170
 
        struct etrax_serial *s;
171
 
        int ser_regs;
172
 
 
173
 
        s = qemu_mallocz(sizeof *s);
174
 
 
175
 
        s->env = env;
176
 
        s->irq = irq;
177
 
        s->chr = chr;
178
 
 
179
 
        /* transmitter begins ready and idle.  */
180
 
        s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
181
 
        s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
182
 
 
183
 
        qemu_chr_add_handlers(chr, serial_can_receive, serial_receive,
184
 
                              serial_event, s);
185
 
 
186
 
        ser_regs = cpu_register_io_memory(0, ser_read, ser_write, s);
187
 
        cpu_register_physical_memory (base, R_MAX * 4, ser_regs);
188
 
}
 
164
static void etraxfs_ser_init(SysBusDevice *dev)
 
165
{
 
166
    struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
 
167
    int ser_regs;
 
168
 
 
169
    /* transmitter begins ready and idle.  */
 
170
    s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
 
171
    s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
 
172
 
 
173
    sysbus_init_irq(dev, &s->irq);
 
174
    ser_regs = cpu_register_io_memory(0, ser_read, ser_write, s);
 
175
    sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
 
176
    s->chr = qdev_init_chardev(&dev->qdev);
 
177
    if (s->chr)
 
178
        qemu_chr_add_handlers(s->chr,
 
179
                      serial_can_receive, serial_receive,
 
180
                      serial_event, s);
 
181
}
 
182
 
 
183
static void etraxfs_serial_register(void)
 
184
{
 
185
    sysbus_register_dev("etraxfs,serial", sizeof (struct etrax_serial),
 
186
                etraxfs_ser_init);
 
187
}
 
188
 
 
189
device_init(etraxfs_serial_register)