Annotation of qemu/hw/slavio_misc.c, revision 1.1.1.8

1.1       root        1: /*
                      2:  * QEMU Sparc SLAVIO aux io port emulation
1.1.1.4   root        3:  *
1.1       root        4:  * Copyright (c) 2005 Fabrice Bellard
1.1.1.4   root        5:  *
1.1       root        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:  */
1.1.1.6   root       24: 
1.1.1.4   root       25: #include "sysemu.h"
1.1.1.6   root       26: #include "sysbus.h"
1.1.1.8 ! root       27: #include "trace.h"
1.1       root       28: 
                     29: /*
                     30:  * This is the auxio port, chip control and system control part of
                     31:  * chip STP2001 (Slave I/O), also produced as NCR89C105. See
                     32:  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
                     33:  *
                     34:  * This also includes the PMC CPU idle controller.
                     35:  */
                     36: 
                     37: typedef struct MiscState {
1.1.1.6   root       38:     SysBusDevice busdev;
1.1.1.4   root       39:     qemu_irq irq;
1.1.1.7   root       40:     uint32_t dummy;
1.1       root       41:     uint8_t config;
                     42:     uint8_t aux1, aux2;
1.1.1.4   root       43:     uint8_t diag, mctrl;
1.1.1.7   root       44:     uint8_t sysctrl;
1.1.1.4   root       45:     uint16_t leds;
1.1.1.5   root       46:     qemu_irq fdc_tc;
1.1       root       47: } MiscState;
                     48: 
1.1.1.6   root       49: typedef struct APCState {
                     50:     SysBusDevice busdev;
                     51:     qemu_irq cpu_halt;
                     52: } APCState;
                     53: 
1.1.1.4   root       54: #define MISC_SIZE 1
1.1.1.5   root       55: #define SYSCTRL_SIZE 4
1.1.1.4   root       56: 
1.1.1.5   root       57: #define AUX1_TC        0x02
                     58: 
1.1.1.4   root       59: #define AUX2_PWROFF    0x01
                     60: #define AUX2_PWRINTCLR 0x02
                     61: #define AUX2_PWRFAIL   0x20
                     62: 
                     63: #define CFG_PWRINTEN   0x08
                     64: 
                     65: #define SYS_RESET      0x01
                     66: #define SYS_RESETSTAT  0x02
1.1       root       67: 
                     68: static void slavio_misc_update_irq(void *opaque)
                     69: {
                     70:     MiscState *s = opaque;
                     71: 
1.1.1.4   root       72:     if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) {
1.1.1.8 ! root       73:         trace_slavio_misc_update_irq_raise();
1.1.1.4   root       74:         qemu_irq_raise(s->irq);
1.1       root       75:     } else {
1.1.1.8 ! root       76:         trace_slavio_misc_update_irq_lower();
1.1.1.4   root       77:         qemu_irq_lower(s->irq);
1.1       root       78:     }
                     79: }
                     80: 
1.1.1.7   root       81: static void slavio_misc_reset(DeviceState *d)
1.1       root       82: {
1.1.1.7   root       83:     MiscState *s = container_of(d, MiscState, busdev.qdev);
1.1       root       84: 
1.1.1.2   root       85:     // Diagnostic and system control registers not cleared in reset
1.1       root       86:     s->config = s->aux1 = s->aux2 = s->mctrl = 0;
                     87: }
                     88: 
1.1.1.7   root       89: static void slavio_set_power_fail(void *opaque, int irq, int power_failing)
1.1       root       90: {
                     91:     MiscState *s = opaque;
                     92: 
1.1.1.8 ! root       93:     trace_slavio_set_power_fail(power_failing, s->config);
1.1.1.4   root       94:     if (power_failing && (s->config & CFG_PWRINTEN)) {
                     95:         s->aux2 |= AUX2_PWRFAIL;
1.1       root       96:     } else {
1.1.1.4   root       97:         s->aux2 &= ~AUX2_PWRFAIL;
1.1       root       98:     }
                     99:     slavio_misc_update_irq(s);
                    100: }
                    101: 
1.1.1.5   root      102: static void slavio_cfg_mem_writeb(void *opaque, target_phys_addr_t addr,
                    103:                                   uint32_t val)
                    104: {
                    105:     MiscState *s = opaque;
                    106: 
1.1.1.8 ! root      107:     trace_slavio_cfg_mem_writeb(val & 0xff);
1.1.1.5   root      108:     s->config = val & 0xff;
                    109:     slavio_misc_update_irq(s);
                    110: }
                    111: 
                    112: static uint32_t slavio_cfg_mem_readb(void *opaque, target_phys_addr_t addr)
                    113: {
                    114:     MiscState *s = opaque;
                    115:     uint32_t ret = 0;
                    116: 
                    117:     ret = s->config;
1.1.1.8 ! root      118:     trace_slavio_cfg_mem_readb(ret);
1.1.1.5   root      119:     return ret;
                    120: }
                    121: 
1.1.1.7   root      122: static CPUReadMemoryFunc * const slavio_cfg_mem_read[3] = {
1.1.1.5   root      123:     slavio_cfg_mem_readb,
                    124:     NULL,
                    125:     NULL,
                    126: };
                    127: 
1.1.1.7   root      128: static CPUWriteMemoryFunc * const slavio_cfg_mem_write[3] = {
1.1.1.5   root      129:     slavio_cfg_mem_writeb,
                    130:     NULL,
                    131:     NULL,
                    132: };
                    133: 
                    134: static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
1.1.1.4   root      135:                                    uint32_t val)
1.1       root      136: {
                    137:     MiscState *s = opaque;
                    138: 
1.1.1.8 ! root      139:     trace_slavio_diag_mem_writeb(val & 0xff);
1.1.1.5   root      140:     s->diag = val & 0xff;
1.1       root      141: }
                    142: 
1.1.1.5   root      143: static uint32_t slavio_diag_mem_readb(void *opaque, target_phys_addr_t addr)
1.1       root      144: {
                    145:     MiscState *s = opaque;
                    146:     uint32_t ret = 0;
                    147: 
1.1.1.5   root      148:     ret = s->diag;
1.1.1.8 ! root      149:     trace_slavio_diag_mem_readb(ret);
1.1.1.5   root      150:     return ret;
                    151: }
                    152: 
1.1.1.7   root      153: static CPUReadMemoryFunc * const slavio_diag_mem_read[3] = {
1.1.1.5   root      154:     slavio_diag_mem_readb,
                    155:     NULL,
                    156:     NULL,
                    157: };
                    158: 
1.1.1.7   root      159: static CPUWriteMemoryFunc * const slavio_diag_mem_write[3] = {
1.1.1.5   root      160:     slavio_diag_mem_writeb,
                    161:     NULL,
                    162:     NULL,
                    163: };
                    164: 
                    165: static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr,
                    166:                                   uint32_t val)
                    167: {
                    168:     MiscState *s = opaque;
                    169: 
1.1.1.8 ! root      170:     trace_slavio_mdm_mem_writeb(val & 0xff);
1.1.1.5   root      171:     s->mctrl = val & 0xff;
                    172: }
                    173: 
                    174: static uint32_t slavio_mdm_mem_readb(void *opaque, target_phys_addr_t addr)
                    175: {
                    176:     MiscState *s = opaque;
                    177:     uint32_t ret = 0;
                    178: 
                    179:     ret = s->mctrl;
1.1.1.8 ! root      180:     trace_slavio_mdm_mem_readb(ret);
1.1.1.5   root      181:     return ret;
                    182: }
                    183: 
1.1.1.7   root      184: static CPUReadMemoryFunc * const slavio_mdm_mem_read[3] = {
1.1.1.5   root      185:     slavio_mdm_mem_readb,
                    186:     NULL,
                    187:     NULL,
                    188: };
                    189: 
1.1.1.7   root      190: static CPUWriteMemoryFunc * const slavio_mdm_mem_write[3] = {
1.1.1.5   root      191:     slavio_mdm_mem_writeb,
                    192:     NULL,
                    193:     NULL,
                    194: };
                    195: 
                    196: static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr,
                    197:                                    uint32_t val)
                    198: {
                    199:     MiscState *s = opaque;
                    200: 
1.1.1.8 ! root      201:     trace_slavio_aux1_mem_writeb(val & 0xff);
1.1.1.5   root      202:     if (val & AUX1_TC) {
                    203:         // Send a pulse to floppy terminal count line
                    204:         if (s->fdc_tc) {
                    205:             qemu_irq_raise(s->fdc_tc);
                    206:             qemu_irq_lower(s->fdc_tc);
1.1.1.4   root      207:         }
1.1.1.5   root      208:         val &= ~AUX1_TC;
1.1       root      209:     }
1.1.1.5   root      210:     s->aux1 = val & 0xff;
                    211: }
                    212: 
                    213: static uint32_t slavio_aux1_mem_readb(void *opaque, target_phys_addr_t addr)
                    214: {
                    215:     MiscState *s = opaque;
                    216:     uint32_t ret = 0;
                    217: 
                    218:     ret = s->aux1;
1.1.1.8 ! root      219:     trace_slavio_aux1_mem_readb(ret);
1.1       root      220:     return ret;
                    221: }
                    222: 
1.1.1.7   root      223: static CPUReadMemoryFunc * const slavio_aux1_mem_read[3] = {
1.1.1.5   root      224:     slavio_aux1_mem_readb,
                    225:     NULL,
                    226:     NULL,
                    227: };
                    228: 
1.1.1.7   root      229: static CPUWriteMemoryFunc * const slavio_aux1_mem_write[3] = {
1.1.1.5   root      230:     slavio_aux1_mem_writeb,
1.1.1.4   root      231:     NULL,
                    232:     NULL,
1.1       root      233: };
                    234: 
1.1.1.5   root      235: static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr,
                    236:                                    uint32_t val)
                    237: {
                    238:     MiscState *s = opaque;
                    239: 
                    240:     val &= AUX2_PWRINTCLR | AUX2_PWROFF;
1.1.1.8 ! root      241:     trace_slavio_aux2_mem_writeb(val & 0xff);
1.1.1.5   root      242:     val |= s->aux2 & AUX2_PWRFAIL;
                    243:     if (val & AUX2_PWRINTCLR) // Clear Power Fail int
                    244:         val &= AUX2_PWROFF;
                    245:     s->aux2 = val;
                    246:     if (val & AUX2_PWROFF)
                    247:         qemu_system_shutdown_request();
                    248:     slavio_misc_update_irq(s);
                    249: }
                    250: 
                    251: static uint32_t slavio_aux2_mem_readb(void *opaque, target_phys_addr_t addr)
                    252: {
                    253:     MiscState *s = opaque;
                    254:     uint32_t ret = 0;
                    255: 
                    256:     ret = s->aux2;
1.1.1.8 ! root      257:     trace_slavio_aux2_mem_readb(ret);
1.1.1.5   root      258:     return ret;
                    259: }
                    260: 
1.1.1.7   root      261: static CPUReadMemoryFunc * const slavio_aux2_mem_read[3] = {
1.1.1.5   root      262:     slavio_aux2_mem_readb,
                    263:     NULL,
                    264:     NULL,
                    265: };
                    266: 
1.1.1.7   root      267: static CPUWriteMemoryFunc * const slavio_aux2_mem_write[3] = {
1.1.1.5   root      268:     slavio_aux2_mem_writeb,
                    269:     NULL,
                    270:     NULL,
                    271: };
                    272: 
                    273: static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
                    274: {
1.1.1.6   root      275:     APCState *s = opaque;
1.1.1.5   root      276: 
1.1.1.8 ! root      277:     trace_apc_mem_writeb(val & 0xff);
1.1.1.5   root      278:     qemu_irq_raise(s->cpu_halt);
                    279: }
                    280: 
                    281: static uint32_t apc_mem_readb(void *opaque, target_phys_addr_t addr)
                    282: {
                    283:     uint32_t ret = 0;
                    284: 
1.1.1.8 ! root      285:     trace_apc_mem_readb(ret);
1.1.1.5   root      286:     return ret;
                    287: }
                    288: 
1.1.1.7   root      289: static CPUReadMemoryFunc * const apc_mem_read[3] = {
1.1.1.5   root      290:     apc_mem_readb,
                    291:     NULL,
                    292:     NULL,
                    293: };
                    294: 
1.1.1.7   root      295: static CPUWriteMemoryFunc * const apc_mem_write[3] = {
1.1.1.5   root      296:     apc_mem_writeb,
1.1.1.4   root      297:     NULL,
                    298:     NULL,
                    299: };
                    300: 
                    301: static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
                    302: {
                    303:     MiscState *s = opaque;
1.1.1.5   root      304:     uint32_t ret = 0;
1.1.1.4   root      305: 
1.1.1.5   root      306:     switch (addr) {
1.1.1.4   root      307:     case 0:
                    308:         ret = s->sysctrl;
                    309:         break;
                    310:     default:
                    311:         break;
                    312:     }
1.1.1.8 ! root      313:     trace_slavio_sysctrl_mem_readl(ret);
1.1.1.4   root      314:     return ret;
                    315: }
                    316: 
                    317: static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr,
                    318:                                       uint32_t val)
                    319: {
                    320:     MiscState *s = opaque;
                    321: 
1.1.1.8 ! root      322:     trace_slavio_sysctrl_mem_writel(val);
1.1.1.5   root      323:     switch (addr) {
1.1.1.4   root      324:     case 0:
                    325:         if (val & SYS_RESET) {
                    326:             s->sysctrl = SYS_RESETSTAT;
                    327:             qemu_system_reset_request();
                    328:         }
                    329:         break;
                    330:     default:
                    331:         break;
                    332:     }
                    333: }
                    334: 
1.1.1.7   root      335: static CPUReadMemoryFunc * const slavio_sysctrl_mem_read[3] = {
1.1.1.4   root      336:     NULL,
                    337:     NULL,
                    338:     slavio_sysctrl_mem_readl,
                    339: };
                    340: 
1.1.1.7   root      341: static CPUWriteMemoryFunc * const slavio_sysctrl_mem_write[3] = {
1.1.1.4   root      342:     NULL,
                    343:     NULL,
                    344:     slavio_sysctrl_mem_writel,
                    345: };
                    346: 
                    347: static uint32_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr)
                    348: {
                    349:     MiscState *s = opaque;
1.1.1.5   root      350:     uint32_t ret = 0;
1.1.1.4   root      351: 
1.1.1.5   root      352:     switch (addr) {
1.1.1.4   root      353:     case 0:
                    354:         ret = s->leds;
                    355:         break;
                    356:     default:
                    357:         break;
                    358:     }
1.1.1.8 ! root      359:     trace_slavio_led_mem_readw(ret);
1.1.1.4   root      360:     return ret;
                    361: }
                    362: 
                    363: static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr,
                    364:                                   uint32_t val)
                    365: {
                    366:     MiscState *s = opaque;
                    367: 
1.1.1.8 ! root      368:     trace_slavio_led_mem_readw(val & 0xffff);
1.1.1.5   root      369:     switch (addr) {
1.1.1.4   root      370:     case 0:
                    371:         s->leds = val;
                    372:         break;
                    373:     default:
                    374:         break;
                    375:     }
                    376: }
                    377: 
1.1.1.7   root      378: static CPUReadMemoryFunc * const slavio_led_mem_read[3] = {
1.1.1.4   root      379:     NULL,
                    380:     slavio_led_mem_readw,
                    381:     NULL,
                    382: };
                    383: 
1.1.1.7   root      384: static CPUWriteMemoryFunc * const slavio_led_mem_write[3] = {
1.1.1.4   root      385:     NULL,
                    386:     slavio_led_mem_writew,
                    387:     NULL,
1.1       root      388: };
                    389: 
1.1.1.7   root      390: static const VMStateDescription vmstate_misc = {
                    391:     .name ="slavio_misc",
                    392:     .version_id = 1,
                    393:     .minimum_version_id = 1,
                    394:     .minimum_version_id_old = 1,
                    395:     .fields      = (VMStateField []) {
                    396:         VMSTATE_UINT32(dummy, MiscState),
                    397:         VMSTATE_UINT8(config, MiscState),
                    398:         VMSTATE_UINT8(aux1, MiscState),
                    399:         VMSTATE_UINT8(aux2, MiscState),
                    400:         VMSTATE_UINT8(diag, MiscState),
                    401:         VMSTATE_UINT8(mctrl, MiscState),
                    402:         VMSTATE_UINT8(sysctrl, MiscState),
                    403:         VMSTATE_END_OF_LIST()
1.1.1.5   root      404:     }
1.1.1.7   root      405: };
1.1.1.6   root      406: 
1.1.1.7   root      407: static int apc_init1(SysBusDevice *dev)
1.1.1.6   root      408: {
                    409:     APCState *s = FROM_SYSBUS(APCState, dev);
                    410:     int io;
1.1       root      411: 
1.1.1.6   root      412:     sysbus_init_irq(dev, &s->cpu_halt);
1.1       root      413: 
1.1.1.6   root      414:     /* Power management (APC) XXX: not a Slavio device */
1.1.1.8 ! root      415:     io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s,
        !           416:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      417:     sysbus_init_mmio(dev, MISC_SIZE, io);
1.1.1.7   root      418:     return 0;
1.1.1.6   root      419: }
                    420: 
1.1.1.7   root      421: static int slavio_misc_init1(SysBusDevice *dev)
1.1.1.6   root      422: {
                    423:     MiscState *s = FROM_SYSBUS(MiscState, dev);
                    424:     int io;
                    425: 
                    426:     sysbus_init_irq(dev, &s->irq);
                    427:     sysbus_init_irq(dev, &s->fdc_tc);
                    428: 
                    429:     /* 8 bit registers */
                    430:     /* Slavio control */
                    431:     io = cpu_register_io_memory(slavio_cfg_mem_read,
1.1.1.8 ! root      432:                                 slavio_cfg_mem_write, s,
        !           433:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      434:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    435: 
                    436:     /* Diagnostics */
                    437:     io = cpu_register_io_memory(slavio_diag_mem_read,
1.1.1.8 ! root      438:                                 slavio_diag_mem_write, s,
        !           439:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      440:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    441: 
                    442:     /* Modem control */
                    443:     io = cpu_register_io_memory(slavio_mdm_mem_read,
1.1.1.8 ! root      444:                                 slavio_mdm_mem_write, s,
        !           445:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      446:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    447: 
                    448:     /* 16 bit registers */
                    449:     /* ss600mp diag LEDs */
                    450:     io = cpu_register_io_memory(slavio_led_mem_read,
1.1.1.8 ! root      451:                                 slavio_led_mem_write, s,
        !           452:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      453:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    454: 
                    455:     /* 32 bit registers */
                    456:     /* System control */
                    457:     io = cpu_register_io_memory(slavio_sysctrl_mem_read,
1.1.1.8 ! root      458:                                 slavio_sysctrl_mem_write, s,
        !           459:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      460:     sysbus_init_mmio(dev, SYSCTRL_SIZE, io);
                    461: 
                    462:     /* AUX 1 (Misc System Functions) */
                    463:     io = cpu_register_io_memory(slavio_aux1_mem_read,
1.1.1.8 ! root      464:                                 slavio_aux1_mem_write, s,
        !           465:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      466:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    467: 
                    468:     /* AUX 2 (Software Powerdown Control) */
                    469:     io = cpu_register_io_memory(slavio_aux2_mem_read,
1.1.1.8 ! root      470:                                 slavio_aux2_mem_write, s,
        !           471:                                 DEVICE_NATIVE_ENDIAN);
1.1.1.6   root      472:     sysbus_init_mmio(dev, MISC_SIZE, io);
                    473: 
1.1.1.7   root      474:     qdev_init_gpio_in(&dev->qdev, slavio_set_power_fail, 1);
                    475: 
                    476:     return 0;
1.1.1.6   root      477: }
                    478: 
                    479: static SysBusDeviceInfo slavio_misc_info = {
                    480:     .init = slavio_misc_init1,
                    481:     .qdev.name  = "slavio_misc",
                    482:     .qdev.size  = sizeof(MiscState),
1.1.1.7   root      483:     .qdev.vmsd  = &vmstate_misc,
                    484:     .qdev.reset  = slavio_misc_reset,
1.1.1.6   root      485: };
1.1.1.5   root      486: 
1.1.1.6   root      487: static SysBusDeviceInfo apc_info = {
                    488:     .init = apc_init1,
                    489:     .qdev.name  = "apc",
                    490:     .qdev.size  = sizeof(MiscState),
                    491: };
                    492: 
                    493: static void slavio_misc_register_devices(void)
                    494: {
                    495:     sysbus_register_withprop(&slavio_misc_info);
                    496:     sysbus_register_withprop(&apc_info);
1.1       root      497: }
1.1.1.6   root      498: 
                    499: device_init(slavio_misc_register_devices)

unix.superglobalmegacorp.com

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