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

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: 
                     25: #include <stdio.h>
                     26: #include <ctype.h>
                     27: #include "hw.h"
1.1.1.2 ! root       28: #include "qemu-char.h"
        !            29: #include "etraxfs.h"
1.1       root       30: 
1.1.1.2 ! root       31: #define D(x)
1.1       root       32: 
1.1.1.2 ! root       33: #define RW_TR_CTRL     0x00
        !            34: #define RW_TR_DMA_EN   0x04
        !            35: #define RW_REC_CTRL    0x08
        !            36: #define RW_DOUT        0x1c
        !            37: #define RS_STAT_DIN    0x20
        !            38: #define R_STAT_DIN     0x24
        !            39: #define RW_INTR_MASK   0x2c
        !            40: #define RW_ACK_INTR    0x30
        !            41: #define R_INTR         0x34
        !            42: #define R_MASKED_INTR  0x38
        !            43: 
        !            44: #define STAT_DAV     16
        !            45: #define STAT_TR_IDLE 22
        !            46: #define STAT_TR_RDY  24
        !            47: 
        !            48: struct etrax_serial_t
        !            49: {
        !            50:        CPUState *env;
        !            51:        CharDriverState *chr;
        !            52:        qemu_irq *irq;
        !            53: 
        !            54:        int pending_tx;
        !            55: 
        !            56:        /* Control registers.  */
        !            57:        uint32_t rw_tr_ctrl;
        !            58:        uint32_t rw_tr_dma_en;
        !            59:        uint32_t rw_rec_ctrl;
        !            60:        uint32_t rs_stat_din;
        !            61:        uint32_t r_stat_din;
        !            62:        uint32_t rw_intr_mask;
        !            63:        uint32_t rw_ack_intr;
        !            64:        uint32_t r_intr;
        !            65:        uint32_t r_masked_intr;
        !            66: };
        !            67: 
        !            68: static void ser_update_irq(struct etrax_serial_t *s)
1.1       root       69: {
1.1.1.2 ! root       70:        uint32_t o_irq = s->r_masked_intr;
        !            71: 
        !            72:        s->r_intr &= ~(s->rw_ack_intr);
        !            73:        s->r_masked_intr = s->r_intr & s->rw_intr_mask;
        !            74: 
        !            75:        if (o_irq != s->r_masked_intr) {
        !            76:                D(printf("irq_mask=%x r_intr=%x rmi=%x airq=%x \n", 
        !            77:                         s->rw_intr_mask, s->r_intr, 
        !            78:                         s->r_masked_intr, s->rw_ack_intr));
        !            79:                if (s->r_masked_intr)
        !            80:                        qemu_irq_raise(s->irq[0]);
        !            81:                else
        !            82:                        qemu_irq_lower(s->irq[0]);
        !            83:        }
        !            84:        s->rw_ack_intr = 0;
1.1       root       85: }
1.1.1.2 ! root       86: 
        !            87: 
        !            88: static uint32_t ser_readb (void *opaque, target_phys_addr_t addr)
1.1       root       89: {
1.1.1.2 ! root       90:        D(CPUState *env = opaque);
        !            91:        D(printf ("%s %x\n", __func__, addr));
        !            92:        return 0;
1.1       root       93: }
                     94: 
                     95: static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
                     96: {
1.1.1.2 ! root       97:        struct etrax_serial_t *s = opaque;
        !            98:        D(CPUState *env = s->env);
1.1       root       99:        uint32_t r = 0;
                    100: 
                    101:        switch (addr)
                    102:        {
1.1.1.2 ! root      103:                case RW_TR_CTRL:
        !           104:                        r = s->rw_tr_ctrl;
        !           105:                        break;
1.1       root      106:                case RW_TR_DMA_EN:
1.1.1.2 ! root      107:                        r = s->rw_tr_dma_en;
        !           108:                        break;
        !           109:                case RS_STAT_DIN:
        !           110:                        r = s->rs_stat_din;
        !           111:                        /* clear dav.  */
        !           112:                        s->rs_stat_din &= ~(1 << STAT_DAV);
1.1       root      113:                        break;
                    114:                case R_STAT_DIN:
1.1.1.2 ! root      115:                        r = s->rs_stat_din;
        !           116:                        break;
        !           117:                case RW_ACK_INTR:
        !           118:                        D(printf("load rw_ack_intr=%x\n", s->rw_ack_intr));
        !           119:                        r = s->rw_ack_intr;
        !           120:                        break;
        !           121:                case RW_INTR_MASK:
        !           122:                        r = s->rw_intr_mask;
        !           123:                        break;
        !           124:                case R_INTR:
        !           125:                        D(printf("load r_intr=%x\n", s->r_intr));
        !           126:                        r = s->r_intr;
        !           127:                        break;
        !           128:                case R_MASKED_INTR:
        !           129:                        D(printf("load r_maked_intr=%x\n", s->r_masked_intr));
        !           130:                        r = s->r_masked_intr;
1.1       root      131:                        break;
                    132: 
                    133:                default:
1.1.1.2 ! root      134:                        D(printf ("%s %x\n", __func__, addr));
1.1       root      135:                        break;
                    136:        }
                    137:        return r;
                    138: }
                    139: 
                    140: static void
                    141: ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
                    142: {
1.1.1.2 ! root      143:        D(struct etrax_serial_t *s = opaque);
        !           144:        D(CPUState *env = s->env);
        !           145:        D(printf ("%s %x %x\n", __func__, addr, value));
1.1       root      146: }
                    147: static void
                    148: ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
                    149: {
1.1.1.2 ! root      150:        struct etrax_serial_t *s = opaque;
        !           151:        unsigned char ch = value;
        !           152:        D(CPUState *env = s->env);
1.1       root      153: 
                    154:        switch (addr)
                    155:        {
1.1.1.2 ! root      156:                case RW_TR_CTRL:
        !           157:                        D(printf("rw_tr_ctrl=%x\n", value));
        !           158:                        s->rw_tr_ctrl = value;
        !           159:                        break;
1.1       root      160:                case RW_TR_DMA_EN:
1.1.1.2 ! root      161:                        D(printf("rw_tr_dma_en=%x\n", value));
        !           162:                        s->rw_tr_dma_en = value;
1.1       root      163:                        break;
                    164:                case RW_DOUT:
1.1.1.2 ! root      165:                        qemu_chr_write(s->chr, &ch, 1);
        !           166:                        s->r_intr |= 1;
        !           167:                        s->pending_tx = 1;
        !           168:                        break;
        !           169:                case RW_ACK_INTR:
        !           170:                        D(printf("rw_ack_intr=%x\n", value));
        !           171:                        s->rw_ack_intr = value;
        !           172:                        if (s->pending_tx && (s->rw_ack_intr & 1)) {
        !           173:                                s->r_intr |= 1;
        !           174:                                s->pending_tx = 0;
        !           175:                                s->rw_ack_intr &= ~1;
        !           176:                        }
        !           177:                        break;
        !           178:                case RW_INTR_MASK:
        !           179:                        D(printf("r_intr_mask=%x\n", value));
        !           180:                        s->rw_intr_mask = value;
1.1       root      181:                        break;
                    182:                default:
1.1.1.2 ! root      183:                        D(printf ("%s %x %x\n",  __func__, addr, value));
1.1       root      184:                        break;
                    185:        }
1.1.1.2 ! root      186:        ser_update_irq(s);
1.1       root      187: }
                    188: 
                    189: static CPUReadMemoryFunc *ser_read[] = {
1.1.1.2 ! root      190:        &ser_readb,
        !           191:        &ser_readb,
        !           192:        &ser_readl,
1.1       root      193: };
                    194: 
                    195: static CPUWriteMemoryFunc *ser_write[] = {
1.1.1.2 ! root      196:        &ser_writeb,
        !           197:        &ser_writeb,
        !           198:        &ser_writel,
1.1       root      199: };
                    200: 
1.1.1.2 ! root      201: static void serial_receive(void *opaque, const uint8_t *buf, int size)
        !           202: {
        !           203:        struct etrax_serial_t *s = opaque;
        !           204: 
        !           205:        s->r_intr |= 8;
        !           206:        s->rs_stat_din &= ~0xff;
        !           207:        s->rs_stat_din |= (buf[0] & 0xff);
        !           208:        s->rs_stat_din |= (1 << STAT_DAV); /* dav.  */
        !           209:        ser_update_irq(s);
        !           210: }
        !           211: 
        !           212: static int serial_can_receive(void *opaque)
1.1       root      213: {
1.1.1.2 ! root      214:        struct etrax_serial_t *s = opaque;
        !           215:        int r;
        !           216: 
        !           217:        /* Is the receiver enabled?  */
        !           218:        r = s->rw_rec_ctrl & 1;
        !           219: 
        !           220:        /* Pending rx data?  */
        !           221:        r |= !(s->r_intr & 8);
        !           222:        return r;
        !           223: }
        !           224: 
        !           225: static void serial_event(void *opaque, int event)
        !           226: {
        !           227: 
        !           228: }
        !           229: 
        !           230: void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
        !           231:                      target_phys_addr_t base)
        !           232: {
        !           233:        struct etrax_serial_t *s;
1.1       root      234:        int ser_regs;
                    235: 
1.1.1.2 ! root      236:        s = qemu_mallocz(sizeof *s);
        !           237: 
        !           238:        s->env = env;
        !           239:        s->irq = irq;
        !           240:        s->chr = chr;
        !           241: 
        !           242:        /* transmitter begins ready and idle.  */
        !           243:        s->rs_stat_din |= (1 << STAT_TR_RDY);
        !           244:        s->rs_stat_din |= (1 << STAT_TR_IDLE);
        !           245: 
        !           246:        qemu_chr_add_handlers(chr, serial_can_receive, serial_receive,
        !           247:                              serial_event, s);
        !           248: 
        !           249:        ser_regs = cpu_register_io_memory(0, ser_read, ser_write, s);
        !           250:        cpu_register_physical_memory (base, 0x3c, ser_regs);
1.1       root      251: }

unix.superglobalmegacorp.com

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