13475187dSbellard /* 23475187dSbellard * QEMU Sparc SLAVIO aux io port emulation 33475187dSbellard * 43475187dSbellard * Copyright (c) 2005 Fabrice Bellard 53475187dSbellard * 63475187dSbellard * Permission is hereby granted, free of charge, to any person obtaining a copy 73475187dSbellard * of this software and associated documentation files (the "Software"), to deal 83475187dSbellard * in the Software without restriction, including without limitation the rights 93475187dSbellard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 103475187dSbellard * copies of the Software, and to permit persons to whom the Software is 113475187dSbellard * furnished to do so, subject to the following conditions: 123475187dSbellard * 133475187dSbellard * The above copyright notice and this permission notice shall be included in 143475187dSbellard * all copies or substantial portions of the Software. 153475187dSbellard * 163475187dSbellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 173475187dSbellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 183475187dSbellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 193475187dSbellard * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 203475187dSbellard * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 213475187dSbellard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 223475187dSbellard * THE SOFTWARE. 233475187dSbellard */ 242582cfa0SBlue Swirl 259c17d615SPaolo Bonzini #include "sysemu/sysemu.h" 2683c9f4caSPaolo Bonzini #include "hw/sysbus.h" 2797bf4851SBlue Swirl #include "trace.h" 283475187dSbellard 293475187dSbellard /* 303475187dSbellard * This is the auxio port, chip control and system control part of 313475187dSbellard * chip STP2001 (Slave I/O), also produced as NCR89C105. See 323475187dSbellard * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt 333475187dSbellard * 343475187dSbellard * This also includes the PMC CPU idle controller. 353475187dSbellard */ 363475187dSbellard 3795eb2084SAndreas Färber #define TYPE_SLAVIO_MISC "slavio_misc" 3895eb2084SAndreas Färber #define SLAVIO_MISC(obj) OBJECT_CHECK(MiscState, (obj), TYPE_SLAVIO_MISC) 3995eb2084SAndreas Färber 403475187dSbellard typedef struct MiscState { 4195eb2084SAndreas Färber SysBusDevice parent_obj; 4295eb2084SAndreas Färber 43dd703aaeSBenoît Canet MemoryRegion cfg_iomem; 4496891e59SBenoît Canet MemoryRegion diag_iomem; 452e66ac3dSBenoît Canet MemoryRegion mdm_iomem; 46aca23c71SBenoît Canet MemoryRegion led_iomem; 47cd64a524SBenoît Canet MemoryRegion sysctrl_iomem; 48cccd43c5SBenoît Canet MemoryRegion aux1_iomem; 4940ce02fcSBenoît Canet MemoryRegion aux2_iomem; 50d537cf6cSpbrook qemu_irq irq; 5197bbb109SBlue Swirl qemu_irq fdc_tc; 52d37adb09SBlue Swirl uint32_t dummy; 533475187dSbellard uint8_t config; 543475187dSbellard uint8_t aux1, aux2; 55bfa30a38Sblueswir1 uint8_t diag, mctrl; 56d37adb09SBlue Swirl uint8_t sysctrl; 576a3b9cc9Sblueswir1 uint16_t leds; 583475187dSbellard } MiscState; 593475187dSbellard 60*f1a0a79fSAndreas Färber #define TYPE_APC "apc" 61*f1a0a79fSAndreas Färber #define APC(obj) OBJECT_CHECK(APCState, (obj), TYPE_APC) 62*f1a0a79fSAndreas Färber 632582cfa0SBlue Swirl typedef struct APCState { 64*f1a0a79fSAndreas Färber SysBusDevice parent_obj; 65*f1a0a79fSAndreas Färber 669c48dee6SBenoît Canet MemoryRegion iomem; 672582cfa0SBlue Swirl qemu_irq cpu_halt; 682582cfa0SBlue Swirl } APCState; 692582cfa0SBlue Swirl 705aca8c3bSblueswir1 #define MISC_SIZE 1 71a8f48dccSblueswir1 #define SYSCTRL_SIZE 4 723475187dSbellard 732be17ebdSblueswir1 #define AUX1_TC 0x02 742be17ebdSblueswir1 757debeb82Sblueswir1 #define AUX2_PWROFF 0x01 767debeb82Sblueswir1 #define AUX2_PWRINTCLR 0x02 777debeb82Sblueswir1 #define AUX2_PWRFAIL 0x20 787debeb82Sblueswir1 797debeb82Sblueswir1 #define CFG_PWRINTEN 0x08 807debeb82Sblueswir1 817debeb82Sblueswir1 #define SYS_RESET 0x01 827debeb82Sblueswir1 #define SYS_RESETSTAT 0x02 837debeb82Sblueswir1 843475187dSbellard static void slavio_misc_update_irq(void *opaque) 853475187dSbellard { 863475187dSbellard MiscState *s = opaque; 873475187dSbellard 887debeb82Sblueswir1 if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) { 8997bf4851SBlue Swirl trace_slavio_misc_update_irq_raise(); 90d537cf6cSpbrook qemu_irq_raise(s->irq); 913475187dSbellard } else { 9297bf4851SBlue Swirl trace_slavio_misc_update_irq_lower(); 93d537cf6cSpbrook qemu_irq_lower(s->irq); 943475187dSbellard } 953475187dSbellard } 963475187dSbellard 971795057aSBlue Swirl static void slavio_misc_reset(DeviceState *d) 983475187dSbellard { 9995eb2084SAndreas Färber MiscState *s = SLAVIO_MISC(d); 1003475187dSbellard 1014e3b1ea1Sbellard // Diagnostic and system control registers not cleared in reset 1023475187dSbellard s->config = s->aux1 = s->aux2 = s->mctrl = 0; 1033475187dSbellard } 1043475187dSbellard 105b2b6f6ecSBlue Swirl static void slavio_set_power_fail(void *opaque, int irq, int power_failing) 1063475187dSbellard { 1073475187dSbellard MiscState *s = opaque; 1083475187dSbellard 10997bf4851SBlue Swirl trace_slavio_set_power_fail(power_failing, s->config); 1107debeb82Sblueswir1 if (power_failing && (s->config & CFG_PWRINTEN)) { 1117debeb82Sblueswir1 s->aux2 |= AUX2_PWRFAIL; 1123475187dSbellard } else { 1137debeb82Sblueswir1 s->aux2 &= ~AUX2_PWRFAIL; 1143475187dSbellard } 1153475187dSbellard slavio_misc_update_irq(s); 1163475187dSbellard } 1173475187dSbellard 118a8170e5eSAvi Kivity static void slavio_cfg_mem_writeb(void *opaque, hwaddr addr, 119dd703aaeSBenoît Canet uint64_t val, unsigned size) 1203475187dSbellard { 1213475187dSbellard MiscState *s = opaque; 1223475187dSbellard 12397bf4851SBlue Swirl trace_slavio_cfg_mem_writeb(val & 0xff); 1243475187dSbellard s->config = val & 0xff; 1253475187dSbellard slavio_misc_update_irq(s); 1263475187dSbellard } 1273475187dSbellard 128a8170e5eSAvi Kivity static uint64_t slavio_cfg_mem_readb(void *opaque, hwaddr addr, 129dd703aaeSBenoît Canet unsigned size) 1303475187dSbellard { 1313475187dSbellard MiscState *s = opaque; 1323475187dSbellard uint32_t ret = 0; 1333475187dSbellard 1343475187dSbellard ret = s->config; 13597bf4851SBlue Swirl trace_slavio_cfg_mem_readb(ret); 1363475187dSbellard return ret; 1373475187dSbellard } 1383475187dSbellard 139dd703aaeSBenoît Canet static const MemoryRegionOps slavio_cfg_mem_ops = { 140dd703aaeSBenoît Canet .read = slavio_cfg_mem_readb, 141dd703aaeSBenoît Canet .write = slavio_cfg_mem_writeb, 142dd703aaeSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 143dd703aaeSBenoît Canet .valid = { 144dd703aaeSBenoît Canet .min_access_size = 1, 145dd703aaeSBenoît Canet .max_access_size = 1, 146dd703aaeSBenoît Canet }, 147a8f48dccSblueswir1 }; 148a8f48dccSblueswir1 149a8170e5eSAvi Kivity static void slavio_diag_mem_writeb(void *opaque, hwaddr addr, 15096891e59SBenoît Canet uint64_t val, unsigned size) 151a8f48dccSblueswir1 { 152a8f48dccSblueswir1 MiscState *s = opaque; 153a8f48dccSblueswir1 15497bf4851SBlue Swirl trace_slavio_diag_mem_writeb(val & 0xff); 155a8f48dccSblueswir1 s->diag = val & 0xff; 156a8f48dccSblueswir1 } 157a8f48dccSblueswir1 158a8170e5eSAvi Kivity static uint64_t slavio_diag_mem_readb(void *opaque, hwaddr addr, 15996891e59SBenoît Canet unsigned size) 160a8f48dccSblueswir1 { 161a8f48dccSblueswir1 MiscState *s = opaque; 162a8f48dccSblueswir1 uint32_t ret = 0; 163a8f48dccSblueswir1 164a8f48dccSblueswir1 ret = s->diag; 16597bf4851SBlue Swirl trace_slavio_diag_mem_readb(ret); 166a8f48dccSblueswir1 return ret; 167a8f48dccSblueswir1 } 168a8f48dccSblueswir1 16996891e59SBenoît Canet static const MemoryRegionOps slavio_diag_mem_ops = { 17096891e59SBenoît Canet .read = slavio_diag_mem_readb, 17196891e59SBenoît Canet .write = slavio_diag_mem_writeb, 17296891e59SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 17396891e59SBenoît Canet .valid = { 17496891e59SBenoît Canet .min_access_size = 1, 17596891e59SBenoît Canet .max_access_size = 1, 17696891e59SBenoît Canet }, 177a8f48dccSblueswir1 }; 178a8f48dccSblueswir1 179a8170e5eSAvi Kivity static void slavio_mdm_mem_writeb(void *opaque, hwaddr addr, 1802e66ac3dSBenoît Canet uint64_t val, unsigned size) 181a8f48dccSblueswir1 { 182a8f48dccSblueswir1 MiscState *s = opaque; 183a8f48dccSblueswir1 18497bf4851SBlue Swirl trace_slavio_mdm_mem_writeb(val & 0xff); 185a8f48dccSblueswir1 s->mctrl = val & 0xff; 186a8f48dccSblueswir1 } 187a8f48dccSblueswir1 188a8170e5eSAvi Kivity static uint64_t slavio_mdm_mem_readb(void *opaque, hwaddr addr, 1892e66ac3dSBenoît Canet unsigned size) 190a8f48dccSblueswir1 { 191a8f48dccSblueswir1 MiscState *s = opaque; 192a8f48dccSblueswir1 uint32_t ret = 0; 193a8f48dccSblueswir1 194a8f48dccSblueswir1 ret = s->mctrl; 19597bf4851SBlue Swirl trace_slavio_mdm_mem_readb(ret); 196a8f48dccSblueswir1 return ret; 197a8f48dccSblueswir1 } 198a8f48dccSblueswir1 1992e66ac3dSBenoît Canet static const MemoryRegionOps slavio_mdm_mem_ops = { 2002e66ac3dSBenoît Canet .read = slavio_mdm_mem_readb, 2012e66ac3dSBenoît Canet .write = slavio_mdm_mem_writeb, 2022e66ac3dSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 2032e66ac3dSBenoît Canet .valid = { 2042e66ac3dSBenoît Canet .min_access_size = 1, 2052e66ac3dSBenoît Canet .max_access_size = 1, 2062e66ac3dSBenoît Canet }, 2073475187dSbellard }; 2083475187dSbellard 209a8170e5eSAvi Kivity static void slavio_aux1_mem_writeb(void *opaque, hwaddr addr, 210cccd43c5SBenoît Canet uint64_t val, unsigned size) 2110019ad53Sblueswir1 { 2120019ad53Sblueswir1 MiscState *s = opaque; 2130019ad53Sblueswir1 21497bf4851SBlue Swirl trace_slavio_aux1_mem_writeb(val & 0xff); 2152be17ebdSblueswir1 if (val & AUX1_TC) { 2162be17ebdSblueswir1 // Send a pulse to floppy terminal count line 2172be17ebdSblueswir1 if (s->fdc_tc) { 2182be17ebdSblueswir1 qemu_irq_raise(s->fdc_tc); 2192be17ebdSblueswir1 qemu_irq_lower(s->fdc_tc); 2202be17ebdSblueswir1 } 2212be17ebdSblueswir1 val &= ~AUX1_TC; 2222be17ebdSblueswir1 } 2230019ad53Sblueswir1 s->aux1 = val & 0xff; 2240019ad53Sblueswir1 } 2250019ad53Sblueswir1 226a8170e5eSAvi Kivity static uint64_t slavio_aux1_mem_readb(void *opaque, hwaddr addr, 227cccd43c5SBenoît Canet unsigned size) 2280019ad53Sblueswir1 { 2290019ad53Sblueswir1 MiscState *s = opaque; 2300019ad53Sblueswir1 uint32_t ret = 0; 2310019ad53Sblueswir1 2320019ad53Sblueswir1 ret = s->aux1; 23397bf4851SBlue Swirl trace_slavio_aux1_mem_readb(ret); 2340019ad53Sblueswir1 return ret; 2350019ad53Sblueswir1 } 2360019ad53Sblueswir1 237cccd43c5SBenoît Canet static const MemoryRegionOps slavio_aux1_mem_ops = { 238cccd43c5SBenoît Canet .read = slavio_aux1_mem_readb, 239cccd43c5SBenoît Canet .write = slavio_aux1_mem_writeb, 240cccd43c5SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 241cccd43c5SBenoît Canet .valid = { 242cccd43c5SBenoît Canet .min_access_size = 1, 243cccd43c5SBenoît Canet .max_access_size = 1, 244cccd43c5SBenoît Canet }, 2450019ad53Sblueswir1 }; 2460019ad53Sblueswir1 247a8170e5eSAvi Kivity static void slavio_aux2_mem_writeb(void *opaque, hwaddr addr, 24840ce02fcSBenoît Canet uint64_t val, unsigned size) 2490019ad53Sblueswir1 { 2500019ad53Sblueswir1 MiscState *s = opaque; 2510019ad53Sblueswir1 2520019ad53Sblueswir1 val &= AUX2_PWRINTCLR | AUX2_PWROFF; 25397bf4851SBlue Swirl trace_slavio_aux2_mem_writeb(val & 0xff); 2540019ad53Sblueswir1 val |= s->aux2 & AUX2_PWRFAIL; 2550019ad53Sblueswir1 if (val & AUX2_PWRINTCLR) // Clear Power Fail int 2560019ad53Sblueswir1 val &= AUX2_PWROFF; 2570019ad53Sblueswir1 s->aux2 = val; 2580019ad53Sblueswir1 if (val & AUX2_PWROFF) 2590019ad53Sblueswir1 qemu_system_shutdown_request(); 2600019ad53Sblueswir1 slavio_misc_update_irq(s); 2610019ad53Sblueswir1 } 2620019ad53Sblueswir1 263a8170e5eSAvi Kivity static uint64_t slavio_aux2_mem_readb(void *opaque, hwaddr addr, 26440ce02fcSBenoît Canet unsigned size) 2650019ad53Sblueswir1 { 2660019ad53Sblueswir1 MiscState *s = opaque; 2670019ad53Sblueswir1 uint32_t ret = 0; 2680019ad53Sblueswir1 2690019ad53Sblueswir1 ret = s->aux2; 27097bf4851SBlue Swirl trace_slavio_aux2_mem_readb(ret); 2710019ad53Sblueswir1 return ret; 2720019ad53Sblueswir1 } 2730019ad53Sblueswir1 27440ce02fcSBenoît Canet static const MemoryRegionOps slavio_aux2_mem_ops = { 27540ce02fcSBenoît Canet .read = slavio_aux2_mem_readb, 27640ce02fcSBenoît Canet .write = slavio_aux2_mem_writeb, 27740ce02fcSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 27840ce02fcSBenoît Canet .valid = { 27940ce02fcSBenoît Canet .min_access_size = 1, 28040ce02fcSBenoît Canet .max_access_size = 1, 28140ce02fcSBenoît Canet }, 2820019ad53Sblueswir1 }; 2830019ad53Sblueswir1 284a8170e5eSAvi Kivity static void apc_mem_writeb(void *opaque, hwaddr addr, 2859c48dee6SBenoît Canet uint64_t val, unsigned size) 2860019ad53Sblueswir1 { 2872582cfa0SBlue Swirl APCState *s = opaque; 2880019ad53Sblueswir1 28997bf4851SBlue Swirl trace_apc_mem_writeb(val & 0xff); 2906d0c293dSblueswir1 qemu_irq_raise(s->cpu_halt); 2910019ad53Sblueswir1 } 2920019ad53Sblueswir1 293a8170e5eSAvi Kivity static uint64_t apc_mem_readb(void *opaque, hwaddr addr, 2949c48dee6SBenoît Canet unsigned size) 2950019ad53Sblueswir1 { 2960019ad53Sblueswir1 uint32_t ret = 0; 2970019ad53Sblueswir1 29897bf4851SBlue Swirl trace_apc_mem_readb(ret); 2990019ad53Sblueswir1 return ret; 3000019ad53Sblueswir1 } 3010019ad53Sblueswir1 3029c48dee6SBenoît Canet static const MemoryRegionOps apc_mem_ops = { 3039c48dee6SBenoît Canet .read = apc_mem_readb, 3049c48dee6SBenoît Canet .write = apc_mem_writeb, 3059c48dee6SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 3069c48dee6SBenoît Canet .valid = { 3079c48dee6SBenoît Canet .min_access_size = 1, 3089c48dee6SBenoît Canet .max_access_size = 1, 3099c48dee6SBenoît Canet } 3100019ad53Sblueswir1 }; 3110019ad53Sblueswir1 312a8170e5eSAvi Kivity static uint64_t slavio_sysctrl_mem_readl(void *opaque, hwaddr addr, 313cd64a524SBenoît Canet unsigned size) 314bfa30a38Sblueswir1 { 315bfa30a38Sblueswir1 MiscState *s = opaque; 316a8f48dccSblueswir1 uint32_t ret = 0; 317bfa30a38Sblueswir1 318a8f48dccSblueswir1 switch (addr) { 319bfa30a38Sblueswir1 case 0: 320bfa30a38Sblueswir1 ret = s->sysctrl; 321bfa30a38Sblueswir1 break; 322bfa30a38Sblueswir1 default: 323bfa30a38Sblueswir1 break; 324bfa30a38Sblueswir1 } 32597bf4851SBlue Swirl trace_slavio_sysctrl_mem_readl(ret); 326bfa30a38Sblueswir1 return ret; 327bfa30a38Sblueswir1 } 328bfa30a38Sblueswir1 329a8170e5eSAvi Kivity static void slavio_sysctrl_mem_writel(void *opaque, hwaddr addr, 330cd64a524SBenoît Canet uint64_t val, unsigned size) 331bfa30a38Sblueswir1 { 332bfa30a38Sblueswir1 MiscState *s = opaque; 333bfa30a38Sblueswir1 33497bf4851SBlue Swirl trace_slavio_sysctrl_mem_writel(val); 335a8f48dccSblueswir1 switch (addr) { 336bfa30a38Sblueswir1 case 0: 3377debeb82Sblueswir1 if (val & SYS_RESET) { 3387debeb82Sblueswir1 s->sysctrl = SYS_RESETSTAT; 339bfa30a38Sblueswir1 qemu_system_reset_request(); 340bfa30a38Sblueswir1 } 341bfa30a38Sblueswir1 break; 342bfa30a38Sblueswir1 default: 343bfa30a38Sblueswir1 break; 344bfa30a38Sblueswir1 } 345bfa30a38Sblueswir1 } 346bfa30a38Sblueswir1 347cd64a524SBenoît Canet static const MemoryRegionOps slavio_sysctrl_mem_ops = { 348cd64a524SBenoît Canet .read = slavio_sysctrl_mem_readl, 349cd64a524SBenoît Canet .write = slavio_sysctrl_mem_writel, 350cd64a524SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 351cd64a524SBenoît Canet .valid = { 352cd64a524SBenoît Canet .min_access_size = 4, 353cd64a524SBenoît Canet .max_access_size = 4, 354cd64a524SBenoît Canet }, 355bfa30a38Sblueswir1 }; 356bfa30a38Sblueswir1 357a8170e5eSAvi Kivity static uint64_t slavio_led_mem_readw(void *opaque, hwaddr addr, 358aca23c71SBenoît Canet unsigned size) 3596a3b9cc9Sblueswir1 { 3606a3b9cc9Sblueswir1 MiscState *s = opaque; 361a8f48dccSblueswir1 uint32_t ret = 0; 3626a3b9cc9Sblueswir1 363a8f48dccSblueswir1 switch (addr) { 3646a3b9cc9Sblueswir1 case 0: 3656a3b9cc9Sblueswir1 ret = s->leds; 3666a3b9cc9Sblueswir1 break; 3676a3b9cc9Sblueswir1 default: 3686a3b9cc9Sblueswir1 break; 3696a3b9cc9Sblueswir1 } 37097bf4851SBlue Swirl trace_slavio_led_mem_readw(ret); 3716a3b9cc9Sblueswir1 return ret; 3726a3b9cc9Sblueswir1 } 3736a3b9cc9Sblueswir1 374a8170e5eSAvi Kivity static void slavio_led_mem_writew(void *opaque, hwaddr addr, 375aca23c71SBenoît Canet uint64_t val, unsigned size) 3766a3b9cc9Sblueswir1 { 3776a3b9cc9Sblueswir1 MiscState *s = opaque; 3786a3b9cc9Sblueswir1 379f3a64b8cSMarkus Armbruster trace_slavio_led_mem_writew(val & 0xffff); 380a8f48dccSblueswir1 switch (addr) { 3816a3b9cc9Sblueswir1 case 0: 382d5296cb5Sblueswir1 s->leds = val; 3836a3b9cc9Sblueswir1 break; 3846a3b9cc9Sblueswir1 default: 3856a3b9cc9Sblueswir1 break; 3866a3b9cc9Sblueswir1 } 3876a3b9cc9Sblueswir1 } 3886a3b9cc9Sblueswir1 389aca23c71SBenoît Canet static const MemoryRegionOps slavio_led_mem_ops = { 390aca23c71SBenoît Canet .read = slavio_led_mem_readw, 391aca23c71SBenoît Canet .write = slavio_led_mem_writew, 392aca23c71SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 393aca23c71SBenoît Canet .valid = { 394aca23c71SBenoît Canet .min_access_size = 2, 395aca23c71SBenoît Canet .max_access_size = 2, 396aca23c71SBenoît Canet }, 3976a3b9cc9Sblueswir1 }; 3986a3b9cc9Sblueswir1 399d37adb09SBlue Swirl static const VMStateDescription vmstate_misc = { 400d37adb09SBlue Swirl .name ="slavio_misc", 401d37adb09SBlue Swirl .version_id = 1, 402d37adb09SBlue Swirl .minimum_version_id = 1, 403d37adb09SBlue Swirl .minimum_version_id_old = 1, 404d37adb09SBlue Swirl .fields = (VMStateField []) { 405d37adb09SBlue Swirl VMSTATE_UINT32(dummy, MiscState), 406d37adb09SBlue Swirl VMSTATE_UINT8(config, MiscState), 407d37adb09SBlue Swirl VMSTATE_UINT8(aux1, MiscState), 408d37adb09SBlue Swirl VMSTATE_UINT8(aux2, MiscState), 409d37adb09SBlue Swirl VMSTATE_UINT8(diag, MiscState), 410d37adb09SBlue Swirl VMSTATE_UINT8(mctrl, MiscState), 411d37adb09SBlue Swirl VMSTATE_UINT8(sysctrl, MiscState), 412d37adb09SBlue Swirl VMSTATE_END_OF_LIST() 4133475187dSbellard } 414d37adb09SBlue Swirl }; 4153475187dSbellard 41681a322d4SGerd Hoffmann static int apc_init1(SysBusDevice *dev) 4172582cfa0SBlue Swirl { 418*f1a0a79fSAndreas Färber APCState *s = APC(dev); 4192582cfa0SBlue Swirl 4202582cfa0SBlue Swirl sysbus_init_irq(dev, &s->cpu_halt); 4212582cfa0SBlue Swirl 4222582cfa0SBlue Swirl /* Power management (APC) XXX: not a Slavio device */ 4233c161542SPaolo Bonzini memory_region_init_io(&s->iomem, OBJECT(s), &apc_mem_ops, s, 4249c48dee6SBenoît Canet "apc", MISC_SIZE); 425750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->iomem); 42681a322d4SGerd Hoffmann return 0; 4272582cfa0SBlue Swirl } 4282582cfa0SBlue Swirl 42995eb2084SAndreas Färber static int slavio_misc_init1(SysBusDevice *sbd) 4302582cfa0SBlue Swirl { 43195eb2084SAndreas Färber DeviceState *dev = DEVICE(sbd); 43295eb2084SAndreas Färber MiscState *s = SLAVIO_MISC(dev); 4332582cfa0SBlue Swirl 43495eb2084SAndreas Färber sysbus_init_irq(sbd, &s->irq); 43595eb2084SAndreas Färber sysbus_init_irq(sbd, &s->fdc_tc); 4362582cfa0SBlue Swirl 4372582cfa0SBlue Swirl /* 8 bit registers */ 4382582cfa0SBlue Swirl /* Slavio control */ 4393c161542SPaolo Bonzini memory_region_init_io(&s->cfg_iomem, OBJECT(s), &slavio_cfg_mem_ops, s, 440dd703aaeSBenoît Canet "configuration", MISC_SIZE); 44195eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->cfg_iomem); 442a8f48dccSblueswir1 4432582cfa0SBlue Swirl /* Diagnostics */ 4443c161542SPaolo Bonzini memory_region_init_io(&s->diag_iomem, OBJECT(s), &slavio_diag_mem_ops, s, 44596891e59SBenoît Canet "diagnostic", MISC_SIZE); 44695eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->diag_iomem); 447a8f48dccSblueswir1 4482582cfa0SBlue Swirl /* Modem control */ 4493c161542SPaolo Bonzini memory_region_init_io(&s->mdm_iomem, OBJECT(s), &slavio_mdm_mem_ops, s, 4502e66ac3dSBenoît Canet "modem", MISC_SIZE); 45195eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->mdm_iomem); 4523475187dSbellard 4536a3b9cc9Sblueswir1 /* 16 bit registers */ 4542582cfa0SBlue Swirl /* ss600mp diag LEDs */ 4553c161542SPaolo Bonzini memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s, 456aca23c71SBenoît Canet "leds", MISC_SIZE); 45795eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->led_iomem); 4586a3b9cc9Sblueswir1 459bfa30a38Sblueswir1 /* 32 bit registers */ 4602582cfa0SBlue Swirl /* System control */ 4613c161542SPaolo Bonzini memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s, 462cd64a524SBenoît Canet "system-control", MISC_SIZE); 46395eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->sysctrl_iomem); 4640019ad53Sblueswir1 4652582cfa0SBlue Swirl /* AUX 1 (Misc System Functions) */ 4663c161542SPaolo Bonzini memory_region_init_io(&s->aux1_iomem, OBJECT(s), &slavio_aux1_mem_ops, s, 467cccd43c5SBenoît Canet "misc-system-functions", MISC_SIZE); 46895eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->aux1_iomem); 4690019ad53Sblueswir1 4702582cfa0SBlue Swirl /* AUX 2 (Software Powerdown Control) */ 4713c161542SPaolo Bonzini memory_region_init_io(&s->aux2_iomem, OBJECT(s), &slavio_aux2_mem_ops, s, 47240ce02fcSBenoît Canet "software-powerdown-control", MISC_SIZE); 47395eb2084SAndreas Färber sysbus_init_mmio(sbd, &s->aux2_iomem); 4740019ad53Sblueswir1 47595eb2084SAndreas Färber qdev_init_gpio_in(dev, slavio_set_power_fail, 1); 476b2b6f6ecSBlue Swirl 47781a322d4SGerd Hoffmann return 0; 4783475187dSbellard } 4792582cfa0SBlue Swirl 480999e12bbSAnthony Liguori static void slavio_misc_class_init(ObjectClass *klass, void *data) 481999e12bbSAnthony Liguori { 48239bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass); 483999e12bbSAnthony Liguori SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 484999e12bbSAnthony Liguori 485999e12bbSAnthony Liguori k->init = slavio_misc_init1; 48639bffca2SAnthony Liguori dc->reset = slavio_misc_reset; 48739bffca2SAnthony Liguori dc->vmsd = &vmstate_misc; 488999e12bbSAnthony Liguori } 489999e12bbSAnthony Liguori 4908c43a6f0SAndreas Färber static const TypeInfo slavio_misc_info = { 49195eb2084SAndreas Färber .name = TYPE_SLAVIO_MISC, 49239bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 49339bffca2SAnthony Liguori .instance_size = sizeof(MiscState), 494999e12bbSAnthony Liguori .class_init = slavio_misc_class_init, 4952582cfa0SBlue Swirl }; 4962582cfa0SBlue Swirl 497999e12bbSAnthony Liguori static void apc_class_init(ObjectClass *klass, void *data) 498999e12bbSAnthony Liguori { 499999e12bbSAnthony Liguori SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 500999e12bbSAnthony Liguori 501999e12bbSAnthony Liguori k->init = apc_init1; 502999e12bbSAnthony Liguori } 503999e12bbSAnthony Liguori 5048c43a6f0SAndreas Färber static const TypeInfo apc_info = { 505*f1a0a79fSAndreas Färber .name = TYPE_APC, 50639bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 50739bffca2SAnthony Liguori .instance_size = sizeof(MiscState), 508999e12bbSAnthony Liguori .class_init = apc_class_init, 5092582cfa0SBlue Swirl }; 5102582cfa0SBlue Swirl 51183f7d43aSAndreas Färber static void slavio_misc_register_types(void) 5122582cfa0SBlue Swirl { 51339bffca2SAnthony Liguori type_register_static(&slavio_misc_info); 51439bffca2SAnthony Liguori type_register_static(&apc_info); 5152582cfa0SBlue Swirl } 5162582cfa0SBlue Swirl 51783f7d43aSAndreas Färber type_init(slavio_misc_register_types) 518