Annotation of qemu/hw/etraxfs_ser.c, revision 1.1.1.7

1.1       root        1: /*
                      2:  * QEMU ETRAX System Emulator
                      3:  *
                      4:  * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
                      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: 
1.1.1.3   root       25: #include "sysbus.h"
1.1.1.2   root       26: #include "qemu-char.h"
1.1       root       27: 
1.1.1.2   root       28: #define D(x)
1.1       root       29: 
1.1.1.3   root       30: #define RW_TR_CTRL     (0x00 / 4)
                     31: #define RW_TR_DMA_EN   (0x04 / 4)
                     32: #define RW_REC_CTRL    (0x08 / 4)
                     33: #define RW_DOUT        (0x1c / 4)
                     34: #define RS_STAT_DIN    (0x20 / 4)
                     35: #define R_STAT_DIN     (0x24 / 4)
                     36: #define RW_INTR_MASK   (0x2c / 4)
                     37: #define RW_ACK_INTR    (0x30 / 4)
                     38: #define R_INTR         (0x34 / 4)
                     39: #define R_MASKED_INTR  (0x38 / 4)
                     40: #define R_MAX          (0x3c / 4)
1.1.1.2   root       41: 
                     42: #define STAT_DAV     16
                     43: #define STAT_TR_IDLE 22
                     44: #define STAT_TR_RDY  24
                     45: 
1.1.1.3   root       46: struct etrax_serial
1.1.1.2   root       47: {
1.1.1.3   root       48:     SysBusDevice busdev;
                     49:     CharDriverState *chr;
                     50:     qemu_irq irq;
1.1.1.2   root       51: 
1.1.1.3   root       52:     int pending_tx;
1.1.1.2   root       53: 
1.1.1.5   root       54:     uint8_t rx_fifo[16];
                     55:     unsigned int rx_fifo_pos;
                     56:     unsigned int rx_fifo_len;
                     57: 
1.1.1.3   root       58:     /* Control registers.  */
                     59:     uint32_t regs[R_MAX];
                     60: };
1.1.1.2   root       61: 
1.1.1.3   root       62: static void ser_update_irq(struct etrax_serial *s)
1.1       root       63: {
1.1.1.3   root       64: 
1.1.1.5   root       65:     if (s->rx_fifo_len) {
                     66:         s->regs[R_INTR] |= 8;
                     67:     } else {
                     68:         s->regs[R_INTR] &= ~8;
                     69:     }
                     70: 
                     71:     s->regs[R_MASKED_INTR] = s->regs[R_INTR] & s->regs[RW_INTR_MASK];
1.1.1.3   root       72:     qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]);
1.1       root       73: }
                     74: 
                     75: static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
                     76: {
1.1.1.3   root       77:     struct etrax_serial *s = opaque;
                     78:     D(CPUState *env = s->env);
                     79:     uint32_t r = 0;
                     80: 
                     81:     addr >>= 2;
                     82:     switch (addr)
                     83:     {
                     84:         case R_STAT_DIN:
1.1.1.5   root       85:             r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
                     86:             if (s->rx_fifo_len) {
                     87:                 r |= 1 << STAT_DAV;
                     88:             }
                     89:             r |= 1 << STAT_TR_RDY;
                     90:             r |= 1 << STAT_TR_IDLE;
1.1.1.3   root       91:             break;
                     92:         case RS_STAT_DIN:
1.1.1.5   root       93:             r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 15];
                     94:             if (s->rx_fifo_len) {
                     95:                 r |= 1 << STAT_DAV;
                     96:                 s->rx_fifo_len--;
                     97:             }
                     98:             r |= 1 << STAT_TR_RDY;
                     99:             r |= 1 << STAT_TR_IDLE;
1.1.1.3   root      100:             break;
                    101:         default:
                    102:             r = s->regs[addr];
1.1.1.5   root      103:             D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
1.1.1.3   root      104:             break;
                    105:     }
                    106:     return r;
1.1       root      107: }
                    108: 
                    109: static void
                    110: ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
                    111: {
1.1.1.3   root      112:     struct etrax_serial *s = opaque;
                    113:     unsigned char ch = value;
                    114:     D(CPUState *env = s->env);
                    115: 
1.1.1.5   root      116:     D(printf ("%s " TARGET_FMT_plx "=%x\n",  __func__, addr, value));
1.1.1.3   root      117:     addr >>= 2;
                    118:     switch (addr)
                    119:     {
                    120:         case RW_DOUT:
                    121:             qemu_chr_write(s->chr, &ch, 1);
1.1.1.5   root      122:             s->regs[R_INTR] |= 3;
1.1.1.3   root      123:             s->pending_tx = 1;
                    124:             s->regs[addr] = value;
                    125:             break;
                    126:         case RW_ACK_INTR:
1.1.1.5   root      127:             if (s->pending_tx) {
                    128:                 value &= ~1;
1.1.1.3   root      129:                 s->pending_tx = 0;
1.1.1.5   root      130:                 D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR]));
1.1.1.3   root      131:             }
1.1.1.5   root      132:             s->regs[addr] = value;
                    133:             s->regs[R_INTR] &= ~value;
                    134:             D(printf("r_intr=%x\n", s->regs[R_INTR]));
1.1.1.3   root      135:             break;
                    136:         default:
                    137:             s->regs[addr] = value;
                    138:             break;
                    139:     }
                    140:     ser_update_irq(s);
1.1       root      141: }
                    142: 
1.1.1.4   root      143: static CPUReadMemoryFunc * const ser_read[] = {
1.1.1.3   root      144:     NULL, NULL,
                    145:     &ser_readl,
1.1       root      146: };
                    147: 
1.1.1.4   root      148: static CPUWriteMemoryFunc * const ser_write[] = {
1.1.1.3   root      149:     NULL, NULL,
                    150:     &ser_writel,
1.1       root      151: };
                    152: 
1.1.1.2   root      153: static void serial_receive(void *opaque, const uint8_t *buf, int size)
                    154: {
1.1.1.3   root      155:     struct etrax_serial *s = opaque;
1.1.1.5   root      156:     int i;
                    157: 
                    158:     /* Got a byte.  */
                    159:     if (s->rx_fifo_len >= 16) {
                    160:         printf("WARNING: UART dropped char.\n");
                    161:         return;
                    162:     }
                    163: 
                    164:     for (i = 0; i < size; i++) { 
                    165:         s->rx_fifo[s->rx_fifo_pos] = buf[i];
                    166:         s->rx_fifo_pos++;
                    167:         s->rx_fifo_pos &= 15;
                    168:         s->rx_fifo_len++;
                    169:     }
1.1.1.2   root      170: 
1.1.1.3   root      171:     ser_update_irq(s);
1.1.1.2   root      172: }
                    173: 
                    174: static int serial_can_receive(void *opaque)
1.1       root      175: {
1.1.1.3   root      176:     struct etrax_serial *s = opaque;
                    177:     int r;
1.1.1.2   root      178: 
1.1.1.3   root      179:     /* Is the receiver enabled?  */
1.1.1.5   root      180:     if (!(s->regs[RW_REC_CTRL] & (1 << 3))) {
                    181:         return 0;
                    182:     }
1.1.1.2   root      183: 
1.1.1.5   root      184:     r = sizeof(s->rx_fifo) - s->rx_fifo_len;
1.1.1.3   root      185:     return r;
1.1.1.2   root      186: }
                    187: 
                    188: static void serial_event(void *opaque, int event)
                    189: {
                    190: 
                    191: }
                    192: 
1.1.1.7 ! root      193: static void etraxfs_ser_reset(DeviceState *d)
1.1.1.2   root      194: {
1.1.1.7 ! root      195:     struct etrax_serial *s = container_of(d, typeof(*s), busdev.qdev);
1.1.1.2   root      196: 
1.1.1.3   root      197:     /* transmitter begins ready and idle.  */
                    198:     s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
                    199:     s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE);
1.1.1.2   root      200: 
1.1.1.7 ! root      201:     s->regs[RW_REC_CTRL] = 0x10000;
        !           202: 
        !           203: }
        !           204: 
        !           205: static int etraxfs_ser_init(SysBusDevice *dev)
        !           206: {
        !           207:     struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
        !           208:     int ser_regs;
        !           209: 
1.1.1.3   root      210:     sysbus_init_irq(dev, &s->irq);
1.1.1.6   root      211:     ser_regs = cpu_register_io_memory(ser_read, ser_write, s,
                    212:                                       DEVICE_NATIVE_ENDIAN);
1.1.1.3   root      213:     sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
                    214:     s->chr = qdev_init_chardev(&dev->qdev);
                    215:     if (s->chr)
                    216:         qemu_chr_add_handlers(s->chr,
                    217:                       serial_can_receive, serial_receive,
                    218:                       serial_event, s);
1.1.1.4   root      219:     return 0;
1.1.1.3   root      220: }
1.1.1.2   root      221: 
1.1.1.7 ! root      222: static SysBusDeviceInfo etraxfs_ser_info = {
        !           223:     .init = etraxfs_ser_init,
        !           224:     .qdev.name  = "etraxfs,serial",
        !           225:     .qdev.size  = sizeof(struct etrax_serial),
        !           226:     .qdev.reset = etraxfs_ser_reset,
        !           227: };
        !           228: 
1.1.1.3   root      229: static void etraxfs_serial_register(void)
                    230: {
1.1.1.7 ! root      231:     sysbus_register_withprop(&etraxfs_ser_info);
1.1       root      232: }
1.1.1.3   root      233: 
                    234: device_init(etraxfs_serial_register)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.