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

1.1     ! root        1: /*
        !             2:  * QEMU Sparc SLAVIO aux io port emulation
        !             3:  * 
        !             4:  * Copyright (c) 2005 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 "vl.h"
        !            25: /* debug misc */
        !            26: //#define DEBUG_MISC
        !            27: 
        !            28: /*
        !            29:  * This is the auxio port, chip control and system control part of
        !            30:  * chip STP2001 (Slave I/O), also produced as NCR89C105. See
        !            31:  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
        !            32:  *
        !            33:  * This also includes the PMC CPU idle controller.
        !            34:  */
        !            35: 
        !            36: #ifdef DEBUG_MISC
        !            37: #define MISC_DPRINTF(fmt, args...) \
        !            38: do { printf("MISC: " fmt , ##args); } while (0)
        !            39: #else
        !            40: #define MISC_DPRINTF(fmt, args...)
        !            41: #endif
        !            42: 
        !            43: typedef struct MiscState {
        !            44:     int irq;
        !            45:     uint8_t config;
        !            46:     uint8_t aux1, aux2;
        !            47:     uint8_t diag, mctrl;
        !            48: } MiscState;
        !            49: 
        !            50: #define MISC_MAXADDR 1
        !            51: 
        !            52: static void slavio_misc_update_irq(void *opaque)
        !            53: {
        !            54:     MiscState *s = opaque;
        !            55: 
        !            56:     if ((s->aux2 & 0x4) && (s->config & 0x8)) {
        !            57:         pic_set_irq(s->irq, 1);
        !            58:     } else {
        !            59:         pic_set_irq(s->irq, 0);
        !            60:     }
        !            61: }
        !            62: 
        !            63: static void slavio_misc_reset(void *opaque)
        !            64: {
        !            65:     MiscState *s = opaque;
        !            66: 
        !            67:     // Diagnostic register not cleared in reset
        !            68:     s->config = s->aux1 = s->aux2 = s->mctrl = 0;
        !            69: }
        !            70: 
        !            71: void slavio_set_power_fail(void *opaque, int power_failing)
        !            72: {
        !            73:     MiscState *s = opaque;
        !            74: 
        !            75:     MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
        !            76:     if (power_failing && (s->config & 0x8)) {
        !            77:        s->aux2 |= 0x4;
        !            78:     } else {
        !            79:        s->aux2 &= ~0x4;
        !            80:     }
        !            81:     slavio_misc_update_irq(s);
        !            82: }
        !            83: 
        !            84: static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
        !            85: {
        !            86:     MiscState *s = opaque;
        !            87: 
        !            88:     switch (addr & 0xfff0000) {
        !            89:     case 0x1800000:
        !            90:        MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
        !            91:        s->config = val & 0xff;
        !            92:        slavio_misc_update_irq(s);
        !            93:        break;
        !            94:     case 0x1900000:
        !            95:        MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
        !            96:        s->aux1 = val & 0xff;
        !            97:        break;
        !            98:     case 0x1910000:
        !            99:        val &= 0x3;
        !           100:        MISC_DPRINTF("Write aux2 %2.2x\n", val);
        !           101:        val |= s->aux2 & 0x4;
        !           102:        if (val & 0x2) // Clear Power Fail int
        !           103:            val &= 0x1;
        !           104:        s->aux2 = val;
        !           105:        if (val & 1)
        !           106:            qemu_system_shutdown_request();
        !           107:        slavio_misc_update_irq(s);
        !           108:        break;
        !           109:     case 0x1a00000:
        !           110:        MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
        !           111:        s->diag = val & 0xff;
        !           112:        break;
        !           113:     case 0x1b00000:
        !           114:        MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
        !           115:        s->mctrl = val & 0xff;
        !           116:        break;
        !           117:     case 0x1f00000:
        !           118:        MISC_DPRINTF("Write system control %2.2x\n", val & 0xff);
        !           119:        if (val & 1)
        !           120:            qemu_system_reset_request();
        !           121:        break;
        !           122:     case 0xa000000:
        !           123:        MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
        !           124: #if 0
        !           125:        // XXX: halting CPU does not work
        !           126:        raise_exception(EXCP_HLT);
        !           127:        cpu_loop_exit();
        !           128: #endif
        !           129:        break;
        !           130:     }
        !           131: }
        !           132: 
        !           133: static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
        !           134: {
        !           135:     MiscState *s = opaque;
        !           136:     uint32_t ret = 0;
        !           137: 
        !           138:     switch (addr & 0xfff0000) {
        !           139:     case 0x1800000:
        !           140:        ret = s->config;
        !           141:        MISC_DPRINTF("Read config %2.2x\n", ret);
        !           142:        break;
        !           143:     case 0x1900000:
        !           144:        ret = s->aux1;
        !           145:        MISC_DPRINTF("Read aux1 %2.2x\n", ret);
        !           146:        break;
        !           147:     case 0x1910000:
        !           148:        ret = s->aux2;
        !           149:        MISC_DPRINTF("Read aux2 %2.2x\n", ret);
        !           150:        break;
        !           151:     case 0x1a00000:
        !           152:        ret = s->diag;
        !           153:        MISC_DPRINTF("Read diag %2.2x\n", ret);
        !           154:        break;
        !           155:     case 0x1b00000:
        !           156:        ret = s->mctrl;
        !           157:        MISC_DPRINTF("Read modem control %2.2x\n", ret);
        !           158:        break;
        !           159:     case 0x1f00000:
        !           160:        MISC_DPRINTF("Read system control %2.2x\n", ret);
        !           161:        break;
        !           162:     case 0xa000000:
        !           163:        MISC_DPRINTF("Read power management %2.2x\n", ret);
        !           164:        break;
        !           165:     }
        !           166:     return ret;
        !           167: }
        !           168: 
        !           169: static CPUReadMemoryFunc *slavio_misc_mem_read[3] = {
        !           170:     slavio_misc_mem_readb,
        !           171:     slavio_misc_mem_readb,
        !           172:     slavio_misc_mem_readb,
        !           173: };
        !           174: 
        !           175: static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
        !           176:     slavio_misc_mem_writeb,
        !           177:     slavio_misc_mem_writeb,
        !           178:     slavio_misc_mem_writeb,
        !           179: };
        !           180: 
        !           181: static void slavio_misc_save(QEMUFile *f, void *opaque)
        !           182: {
        !           183:     MiscState *s = opaque;
        !           184: 
        !           185:     qemu_put_be32s(f, &s->irq);
        !           186:     qemu_put_8s(f, &s->config);
        !           187:     qemu_put_8s(f, &s->aux1);
        !           188:     qemu_put_8s(f, &s->aux2);
        !           189:     qemu_put_8s(f, &s->diag);
        !           190:     qemu_put_8s(f, &s->mctrl);
        !           191: }
        !           192: 
        !           193: static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
        !           194: {
        !           195:     MiscState *s = opaque;
        !           196: 
        !           197:     if (version_id != 1)
        !           198:         return -EINVAL;
        !           199: 
        !           200:     qemu_get_be32s(f, &s->irq);
        !           201:     qemu_get_8s(f, &s->config);
        !           202:     qemu_get_8s(f, &s->aux1);
        !           203:     qemu_get_8s(f, &s->aux2);
        !           204:     qemu_get_8s(f, &s->diag);
        !           205:     qemu_get_8s(f, &s->mctrl);
        !           206:     return 0;
        !           207: }
        !           208: 
        !           209: void *slavio_misc_init(uint32_t base, int irq)
        !           210: {
        !           211:     int slavio_misc_io_memory;
        !           212:     MiscState *s;
        !           213: 
        !           214:     s = qemu_mallocz(sizeof(MiscState));
        !           215:     if (!s)
        !           216:         return NULL;
        !           217: 
        !           218:     slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
        !           219:     // Slavio control
        !           220:     cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory);
        !           221:     // AUX 1
        !           222:     cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory);
        !           223:     // AUX 2
        !           224:     cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory);
        !           225:     // Diagnostics
        !           226:     cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory);
        !           227:     // Modem control
        !           228:     cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory);
        !           229:     // System control
        !           230:     cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory);
        !           231:     // Power management
        !           232:     cpu_register_physical_memory(base + 0xa000000, MISC_MAXADDR, slavio_misc_io_memory);
        !           233: 
        !           234:     s->irq = irq;
        !           235: 
        !           236:     register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
        !           237:     qemu_register_reset(slavio_misc_reset, s);
        !           238:     slavio_misc_reset(s);
        !           239:     return s;
        !           240: }

unix.superglobalmegacorp.com

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