(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/cs4231.c

    1: /*
    2:  * QEMU Crystal CS4231 audio chip emulation
    3:  *
    4:  * Copyright (c) 2006 Fabrice Bellard
    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: #include "hw.h"
   25: #include "sun4m.h"
   26: 
   27: /* debug CS4231 */
   28: //#define DEBUG_CS
   29: 
   30: /*
   31:  * In addition to Crystal CS4231 there is a DMA controller on Sparc.
   32:  */
   33: #define CS_MAXADDR 0x3f
   34: #define CS_SIZE (CS_MAXADDR + 1)
   35: #define CS_REGS 16
   36: #define CS_DREGS 32
   37: #define CS_MAXDREG (CS_DREGS - 1)
   38: 
   39: typedef struct CSState {
   40:     uint32_t regs[CS_REGS];
   41:     uint8_t dregs[CS_DREGS];
   42:     void *intctl;
   43: } CSState;
   44: 
   45: #define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
   46: #define CS_VER 0xa0
   47: #define CS_CDC_VER 0x8a
   48: 
   49: #ifdef DEBUG_CS
   50: #define DPRINTF(fmt, args...)                           \
   51:     do { printf("CS: " fmt , ##args); } while (0)
   52: #else
   53: #define DPRINTF(fmt, args...)
   54: #endif
   55: 
   56: static void cs_reset(void *opaque)
   57: {
   58:     CSState *s = opaque;
   59: 
   60:     memset(s->regs, 0, CS_REGS * 4);
   61:     memset(s->dregs, 0, CS_DREGS);
   62:     s->dregs[12] = CS_CDC_VER;
   63:     s->dregs[25] = CS_VER;
   64: }
   65: 
   66: static uint32_t cs_mem_readl(void *opaque, target_phys_addr_t addr)
   67: {
   68:     CSState *s = opaque;
   69:     uint32_t saddr, ret;
   70: 
   71:     saddr = (addr & CS_MAXADDR) >> 2;
   72:     switch (saddr) {
   73:     case 1:
   74:         switch (CS_RAP(s)) {
   75:         case 3: // Write only
   76:             ret = 0;
   77:             break;
   78:         default:
   79:             ret = s->dregs[CS_RAP(s)];
   80:             break;
   81:         }
   82:         DPRINTF("read dreg[%d]: 0x%8.8x\n", CS_RAP(s), ret);
   83:         break;
   84:     default:
   85:         ret = s->regs[saddr];
   86:         DPRINTF("read reg[%d]: 0x%8.8x\n", saddr, ret);
   87:         break;
   88:     }
   89:     return ret;
   90: }
   91: 
   92: static void cs_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
   93: {
   94:     CSState *s = opaque;
   95:     uint32_t saddr;
   96: 
   97:     saddr = (addr & CS_MAXADDR) >> 2;
   98:     DPRINTF("write reg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->regs[saddr], val);
   99:     switch (saddr) {
  100:     case 1:
  101:         DPRINTF("write dreg[%d]: 0x%2.2x -> 0x%2.2x\n", CS_RAP(s), s->dregs[CS_RAP(s)], val);
  102:         switch(CS_RAP(s)) {
  103:         case 11:
  104:         case 25: // Read only
  105:             break;
  106:         case 12:
  107:             val &= 0x40;
  108:             val |= CS_CDC_VER; // Codec version
  109:             s->dregs[CS_RAP(s)] = val;
  110:             break;
  111:         default:
  112:             s->dregs[CS_RAP(s)] = val;
  113:             break;
  114:         }
  115:         break;
  116:     case 2: // Read only
  117:         break;
  118:     case 4:
  119:         if (val & 1)
  120:             cs_reset(s);
  121:         val &= 0x7f;
  122:         s->regs[saddr] = val;
  123:         break;
  124:     default:
  125:         s->regs[saddr] = val;
  126:         break;
  127:     }
  128: }
  129: 
  130: static CPUReadMemoryFunc *cs_mem_read[3] = {
  131:     cs_mem_readl,
  132:     cs_mem_readl,
  133:     cs_mem_readl,
  134: };
  135: 
  136: static CPUWriteMemoryFunc *cs_mem_write[3] = {
  137:     cs_mem_writel,
  138:     cs_mem_writel,
  139:     cs_mem_writel,
  140: };
  141: 
  142: static void cs_save(QEMUFile *f, void *opaque)
  143: {
  144:     CSState *s = opaque;
  145:     unsigned int i;
  146: 
  147:     for (i = 0; i < CS_REGS; i++)
  148:         qemu_put_be32s(f, &s->regs[i]);
  149: 
  150:     qemu_put_buffer(f, s->dregs, CS_DREGS);
  151: }
  152: 
  153: static int cs_load(QEMUFile *f, void *opaque, int version_id)
  154: {
  155:     CSState *s = opaque;
  156:     unsigned int i;
  157: 
  158:     if (version_id > 1)
  159:         return -EINVAL;
  160: 
  161:     for (i = 0; i < CS_REGS; i++)
  162:         qemu_get_be32s(f, &s->regs[i]);
  163: 
  164:     qemu_get_buffer(f, s->dregs, CS_DREGS);
  165:     return 0;
  166: }
  167: 
  168: void cs_init(target_phys_addr_t base, int irq, void *intctl)
  169: {
  170:     int cs_io_memory;
  171:     CSState *s;
  172: 
  173:     s = qemu_mallocz(sizeof(CSState));
  174:     if (!s)
  175:         return;
  176: 
  177:     cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
  178:     cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
  179:     register_savevm("cs4231", base, 1, cs_save, cs_load, s);
  180:     qemu_register_reset(cs_reset, s);
  181:     cs_reset(s);
  182: }
Syntax (Markdown)