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 373475187dSbellard typedef struct MiscState { 382582cfa0SBlue Swirl SysBusDevice busdev; 39dd703aaeSBenoît Canet MemoryRegion cfg_iomem; 4096891e59SBenoît Canet MemoryRegion diag_iomem; 412e66ac3dSBenoît Canet MemoryRegion mdm_iomem; 42aca23c71SBenoît Canet MemoryRegion led_iomem; 43cd64a524SBenoît Canet MemoryRegion sysctrl_iomem; 44cccd43c5SBenoît Canet MemoryRegion aux1_iomem; 4540ce02fcSBenoît Canet MemoryRegion aux2_iomem; 46d537cf6cSpbrook qemu_irq irq; 4797bbb109SBlue Swirl qemu_irq fdc_tc; 48d37adb09SBlue Swirl uint32_t dummy; 493475187dSbellard uint8_t config; 503475187dSbellard uint8_t aux1, aux2; 51bfa30a38Sblueswir1 uint8_t diag, mctrl; 52d37adb09SBlue Swirl uint8_t sysctrl; 536a3b9cc9Sblueswir1 uint16_t leds; 543475187dSbellard } MiscState; 553475187dSbellard 562582cfa0SBlue Swirl typedef struct APCState { 572582cfa0SBlue Swirl SysBusDevice busdev; 589c48dee6SBenoît Canet MemoryRegion iomem; 592582cfa0SBlue Swirl qemu_irq cpu_halt; 602582cfa0SBlue Swirl } APCState; 612582cfa0SBlue Swirl 625aca8c3bSblueswir1 #define MISC_SIZE 1 63a8f48dccSblueswir1 #define SYSCTRL_SIZE 4 643475187dSbellard 652be17ebdSblueswir1 #define AUX1_TC 0x02 662be17ebdSblueswir1 677debeb82Sblueswir1 #define AUX2_PWROFF 0x01 687debeb82Sblueswir1 #define AUX2_PWRINTCLR 0x02 697debeb82Sblueswir1 #define AUX2_PWRFAIL 0x20 707debeb82Sblueswir1 717debeb82Sblueswir1 #define CFG_PWRINTEN 0x08 727debeb82Sblueswir1 737debeb82Sblueswir1 #define SYS_RESET 0x01 747debeb82Sblueswir1 #define SYS_RESETSTAT 0x02 757debeb82Sblueswir1 763475187dSbellard static void slavio_misc_update_irq(void *opaque) 773475187dSbellard { 783475187dSbellard MiscState *s = opaque; 793475187dSbellard 807debeb82Sblueswir1 if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) { 8197bf4851SBlue Swirl trace_slavio_misc_update_irq_raise(); 82d537cf6cSpbrook qemu_irq_raise(s->irq); 833475187dSbellard } else { 8497bf4851SBlue Swirl trace_slavio_misc_update_irq_lower(); 85d537cf6cSpbrook qemu_irq_lower(s->irq); 863475187dSbellard } 873475187dSbellard } 883475187dSbellard 891795057aSBlue Swirl static void slavio_misc_reset(DeviceState *d) 903475187dSbellard { 911795057aSBlue Swirl MiscState *s = container_of(d, MiscState, busdev.qdev); 923475187dSbellard 934e3b1ea1Sbellard // Diagnostic and system control registers not cleared in reset 943475187dSbellard s->config = s->aux1 = s->aux2 = s->mctrl = 0; 953475187dSbellard } 963475187dSbellard 97b2b6f6ecSBlue Swirl static void slavio_set_power_fail(void *opaque, int irq, int power_failing) 983475187dSbellard { 993475187dSbellard MiscState *s = opaque; 1003475187dSbellard 10197bf4851SBlue Swirl trace_slavio_set_power_fail(power_failing, s->config); 1027debeb82Sblueswir1 if (power_failing && (s->config & CFG_PWRINTEN)) { 1037debeb82Sblueswir1 s->aux2 |= AUX2_PWRFAIL; 1043475187dSbellard } else { 1057debeb82Sblueswir1 s->aux2 &= ~AUX2_PWRFAIL; 1063475187dSbellard } 1073475187dSbellard slavio_misc_update_irq(s); 1083475187dSbellard } 1093475187dSbellard 110a8170e5eSAvi Kivity static void slavio_cfg_mem_writeb(void *opaque, hwaddr addr, 111dd703aaeSBenoît Canet uint64_t val, unsigned size) 1123475187dSbellard { 1133475187dSbellard MiscState *s = opaque; 1143475187dSbellard 11597bf4851SBlue Swirl trace_slavio_cfg_mem_writeb(val & 0xff); 1163475187dSbellard s->config = val & 0xff; 1173475187dSbellard slavio_misc_update_irq(s); 1183475187dSbellard } 1193475187dSbellard 120a8170e5eSAvi Kivity static uint64_t slavio_cfg_mem_readb(void *opaque, hwaddr addr, 121dd703aaeSBenoît Canet unsigned size) 1223475187dSbellard { 1233475187dSbellard MiscState *s = opaque; 1243475187dSbellard uint32_t ret = 0; 1253475187dSbellard 1263475187dSbellard ret = s->config; 12797bf4851SBlue Swirl trace_slavio_cfg_mem_readb(ret); 1283475187dSbellard return ret; 1293475187dSbellard } 1303475187dSbellard 131dd703aaeSBenoît Canet static const MemoryRegionOps slavio_cfg_mem_ops = { 132dd703aaeSBenoît Canet .read = slavio_cfg_mem_readb, 133dd703aaeSBenoît Canet .write = slavio_cfg_mem_writeb, 134dd703aaeSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 135dd703aaeSBenoît Canet .valid = { 136dd703aaeSBenoît Canet .min_access_size = 1, 137dd703aaeSBenoît Canet .max_access_size = 1, 138dd703aaeSBenoît Canet }, 139a8f48dccSblueswir1 }; 140a8f48dccSblueswir1 141a8170e5eSAvi Kivity static void slavio_diag_mem_writeb(void *opaque, hwaddr addr, 14296891e59SBenoît Canet uint64_t val, unsigned size) 143a8f48dccSblueswir1 { 144a8f48dccSblueswir1 MiscState *s = opaque; 145a8f48dccSblueswir1 14697bf4851SBlue Swirl trace_slavio_diag_mem_writeb(val & 0xff); 147a8f48dccSblueswir1 s->diag = val & 0xff; 148a8f48dccSblueswir1 } 149a8f48dccSblueswir1 150a8170e5eSAvi Kivity static uint64_t slavio_diag_mem_readb(void *opaque, hwaddr addr, 15196891e59SBenoît Canet unsigned size) 152a8f48dccSblueswir1 { 153a8f48dccSblueswir1 MiscState *s = opaque; 154a8f48dccSblueswir1 uint32_t ret = 0; 155a8f48dccSblueswir1 156a8f48dccSblueswir1 ret = s->diag; 15797bf4851SBlue Swirl trace_slavio_diag_mem_readb(ret); 158a8f48dccSblueswir1 return ret; 159a8f48dccSblueswir1 } 160a8f48dccSblueswir1 16196891e59SBenoît Canet static const MemoryRegionOps slavio_diag_mem_ops = { 16296891e59SBenoît Canet .read = slavio_diag_mem_readb, 16396891e59SBenoît Canet .write = slavio_diag_mem_writeb, 16496891e59SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 16596891e59SBenoît Canet .valid = { 16696891e59SBenoît Canet .min_access_size = 1, 16796891e59SBenoît Canet .max_access_size = 1, 16896891e59SBenoît Canet }, 169a8f48dccSblueswir1 }; 170a8f48dccSblueswir1 171a8170e5eSAvi Kivity static void slavio_mdm_mem_writeb(void *opaque, hwaddr addr, 1722e66ac3dSBenoît Canet uint64_t val, unsigned size) 173a8f48dccSblueswir1 { 174a8f48dccSblueswir1 MiscState *s = opaque; 175a8f48dccSblueswir1 17697bf4851SBlue Swirl trace_slavio_mdm_mem_writeb(val & 0xff); 177a8f48dccSblueswir1 s->mctrl = val & 0xff; 178a8f48dccSblueswir1 } 179a8f48dccSblueswir1 180a8170e5eSAvi Kivity static uint64_t slavio_mdm_mem_readb(void *opaque, hwaddr addr, 1812e66ac3dSBenoît Canet unsigned size) 182a8f48dccSblueswir1 { 183a8f48dccSblueswir1 MiscState *s = opaque; 184a8f48dccSblueswir1 uint32_t ret = 0; 185a8f48dccSblueswir1 186a8f48dccSblueswir1 ret = s->mctrl; 18797bf4851SBlue Swirl trace_slavio_mdm_mem_readb(ret); 188a8f48dccSblueswir1 return ret; 189a8f48dccSblueswir1 } 190a8f48dccSblueswir1 1912e66ac3dSBenoît Canet static const MemoryRegionOps slavio_mdm_mem_ops = { 1922e66ac3dSBenoît Canet .read = slavio_mdm_mem_readb, 1932e66ac3dSBenoît Canet .write = slavio_mdm_mem_writeb, 1942e66ac3dSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 1952e66ac3dSBenoît Canet .valid = { 1962e66ac3dSBenoît Canet .min_access_size = 1, 1972e66ac3dSBenoît Canet .max_access_size = 1, 1982e66ac3dSBenoît Canet }, 1993475187dSbellard }; 2003475187dSbellard 201a8170e5eSAvi Kivity static void slavio_aux1_mem_writeb(void *opaque, hwaddr addr, 202cccd43c5SBenoît Canet uint64_t val, unsigned size) 2030019ad53Sblueswir1 { 2040019ad53Sblueswir1 MiscState *s = opaque; 2050019ad53Sblueswir1 20697bf4851SBlue Swirl trace_slavio_aux1_mem_writeb(val & 0xff); 2072be17ebdSblueswir1 if (val & AUX1_TC) { 2082be17ebdSblueswir1 // Send a pulse to floppy terminal count line 2092be17ebdSblueswir1 if (s->fdc_tc) { 2102be17ebdSblueswir1 qemu_irq_raise(s->fdc_tc); 2112be17ebdSblueswir1 qemu_irq_lower(s->fdc_tc); 2122be17ebdSblueswir1 } 2132be17ebdSblueswir1 val &= ~AUX1_TC; 2142be17ebdSblueswir1 } 2150019ad53Sblueswir1 s->aux1 = val & 0xff; 2160019ad53Sblueswir1 } 2170019ad53Sblueswir1 218a8170e5eSAvi Kivity static uint64_t slavio_aux1_mem_readb(void *opaque, hwaddr addr, 219cccd43c5SBenoît Canet unsigned size) 2200019ad53Sblueswir1 { 2210019ad53Sblueswir1 MiscState *s = opaque; 2220019ad53Sblueswir1 uint32_t ret = 0; 2230019ad53Sblueswir1 2240019ad53Sblueswir1 ret = s->aux1; 22597bf4851SBlue Swirl trace_slavio_aux1_mem_readb(ret); 2260019ad53Sblueswir1 return ret; 2270019ad53Sblueswir1 } 2280019ad53Sblueswir1 229cccd43c5SBenoît Canet static const MemoryRegionOps slavio_aux1_mem_ops = { 230cccd43c5SBenoît Canet .read = slavio_aux1_mem_readb, 231cccd43c5SBenoît Canet .write = slavio_aux1_mem_writeb, 232cccd43c5SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 233cccd43c5SBenoît Canet .valid = { 234cccd43c5SBenoît Canet .min_access_size = 1, 235cccd43c5SBenoît Canet .max_access_size = 1, 236cccd43c5SBenoît Canet }, 2370019ad53Sblueswir1 }; 2380019ad53Sblueswir1 239a8170e5eSAvi Kivity static void slavio_aux2_mem_writeb(void *opaque, hwaddr addr, 24040ce02fcSBenoît Canet uint64_t val, unsigned size) 2410019ad53Sblueswir1 { 2420019ad53Sblueswir1 MiscState *s = opaque; 2430019ad53Sblueswir1 2440019ad53Sblueswir1 val &= AUX2_PWRINTCLR | AUX2_PWROFF; 24597bf4851SBlue Swirl trace_slavio_aux2_mem_writeb(val & 0xff); 2460019ad53Sblueswir1 val |= s->aux2 & AUX2_PWRFAIL; 2470019ad53Sblueswir1 if (val & AUX2_PWRINTCLR) // Clear Power Fail int 2480019ad53Sblueswir1 val &= AUX2_PWROFF; 2490019ad53Sblueswir1 s->aux2 = val; 2500019ad53Sblueswir1 if (val & AUX2_PWROFF) 2510019ad53Sblueswir1 qemu_system_shutdown_request(); 2520019ad53Sblueswir1 slavio_misc_update_irq(s); 2530019ad53Sblueswir1 } 2540019ad53Sblueswir1 255a8170e5eSAvi Kivity static uint64_t slavio_aux2_mem_readb(void *opaque, hwaddr addr, 25640ce02fcSBenoît Canet unsigned size) 2570019ad53Sblueswir1 { 2580019ad53Sblueswir1 MiscState *s = opaque; 2590019ad53Sblueswir1 uint32_t ret = 0; 2600019ad53Sblueswir1 2610019ad53Sblueswir1 ret = s->aux2; 26297bf4851SBlue Swirl trace_slavio_aux2_mem_readb(ret); 2630019ad53Sblueswir1 return ret; 2640019ad53Sblueswir1 } 2650019ad53Sblueswir1 26640ce02fcSBenoît Canet static const MemoryRegionOps slavio_aux2_mem_ops = { 26740ce02fcSBenoît Canet .read = slavio_aux2_mem_readb, 26840ce02fcSBenoît Canet .write = slavio_aux2_mem_writeb, 26940ce02fcSBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 27040ce02fcSBenoît Canet .valid = { 27140ce02fcSBenoît Canet .min_access_size = 1, 27240ce02fcSBenoît Canet .max_access_size = 1, 27340ce02fcSBenoît Canet }, 2740019ad53Sblueswir1 }; 2750019ad53Sblueswir1 276a8170e5eSAvi Kivity static void apc_mem_writeb(void *opaque, hwaddr addr, 2779c48dee6SBenoît Canet uint64_t val, unsigned size) 2780019ad53Sblueswir1 { 2792582cfa0SBlue Swirl APCState *s = opaque; 2800019ad53Sblueswir1 28197bf4851SBlue Swirl trace_apc_mem_writeb(val & 0xff); 2826d0c293dSblueswir1 qemu_irq_raise(s->cpu_halt); 2830019ad53Sblueswir1 } 2840019ad53Sblueswir1 285a8170e5eSAvi Kivity static uint64_t apc_mem_readb(void *opaque, hwaddr addr, 2869c48dee6SBenoît Canet unsigned size) 2870019ad53Sblueswir1 { 2880019ad53Sblueswir1 uint32_t ret = 0; 2890019ad53Sblueswir1 29097bf4851SBlue Swirl trace_apc_mem_readb(ret); 2910019ad53Sblueswir1 return ret; 2920019ad53Sblueswir1 } 2930019ad53Sblueswir1 2949c48dee6SBenoît Canet static const MemoryRegionOps apc_mem_ops = { 2959c48dee6SBenoît Canet .read = apc_mem_readb, 2969c48dee6SBenoît Canet .write = apc_mem_writeb, 2979c48dee6SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 2989c48dee6SBenoît Canet .valid = { 2999c48dee6SBenoît Canet .min_access_size = 1, 3009c48dee6SBenoît Canet .max_access_size = 1, 3019c48dee6SBenoît Canet } 3020019ad53Sblueswir1 }; 3030019ad53Sblueswir1 304a8170e5eSAvi Kivity static uint64_t slavio_sysctrl_mem_readl(void *opaque, hwaddr addr, 305cd64a524SBenoît Canet unsigned size) 306bfa30a38Sblueswir1 { 307bfa30a38Sblueswir1 MiscState *s = opaque; 308a8f48dccSblueswir1 uint32_t ret = 0; 309bfa30a38Sblueswir1 310a8f48dccSblueswir1 switch (addr) { 311bfa30a38Sblueswir1 case 0: 312bfa30a38Sblueswir1 ret = s->sysctrl; 313bfa30a38Sblueswir1 break; 314bfa30a38Sblueswir1 default: 315bfa30a38Sblueswir1 break; 316bfa30a38Sblueswir1 } 31797bf4851SBlue Swirl trace_slavio_sysctrl_mem_readl(ret); 318bfa30a38Sblueswir1 return ret; 319bfa30a38Sblueswir1 } 320bfa30a38Sblueswir1 321a8170e5eSAvi Kivity static void slavio_sysctrl_mem_writel(void *opaque, hwaddr addr, 322cd64a524SBenoît Canet uint64_t val, unsigned size) 323bfa30a38Sblueswir1 { 324bfa30a38Sblueswir1 MiscState *s = opaque; 325bfa30a38Sblueswir1 32697bf4851SBlue Swirl trace_slavio_sysctrl_mem_writel(val); 327a8f48dccSblueswir1 switch (addr) { 328bfa30a38Sblueswir1 case 0: 3297debeb82Sblueswir1 if (val & SYS_RESET) { 3307debeb82Sblueswir1 s->sysctrl = SYS_RESETSTAT; 331bfa30a38Sblueswir1 qemu_system_reset_request(); 332bfa30a38Sblueswir1 } 333bfa30a38Sblueswir1 break; 334bfa30a38Sblueswir1 default: 335bfa30a38Sblueswir1 break; 336bfa30a38Sblueswir1 } 337bfa30a38Sblueswir1 } 338bfa30a38Sblueswir1 339cd64a524SBenoît Canet static const MemoryRegionOps slavio_sysctrl_mem_ops = { 340cd64a524SBenoît Canet .read = slavio_sysctrl_mem_readl, 341cd64a524SBenoît Canet .write = slavio_sysctrl_mem_writel, 342cd64a524SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 343cd64a524SBenoît Canet .valid = { 344cd64a524SBenoît Canet .min_access_size = 4, 345cd64a524SBenoît Canet .max_access_size = 4, 346cd64a524SBenoît Canet }, 347bfa30a38Sblueswir1 }; 348bfa30a38Sblueswir1 349a8170e5eSAvi Kivity static uint64_t slavio_led_mem_readw(void *opaque, hwaddr addr, 350aca23c71SBenoît Canet unsigned size) 3516a3b9cc9Sblueswir1 { 3526a3b9cc9Sblueswir1 MiscState *s = opaque; 353a8f48dccSblueswir1 uint32_t ret = 0; 3546a3b9cc9Sblueswir1 355a8f48dccSblueswir1 switch (addr) { 3566a3b9cc9Sblueswir1 case 0: 3576a3b9cc9Sblueswir1 ret = s->leds; 3586a3b9cc9Sblueswir1 break; 3596a3b9cc9Sblueswir1 default: 3606a3b9cc9Sblueswir1 break; 3616a3b9cc9Sblueswir1 } 36297bf4851SBlue Swirl trace_slavio_led_mem_readw(ret); 3636a3b9cc9Sblueswir1 return ret; 3646a3b9cc9Sblueswir1 } 3656a3b9cc9Sblueswir1 366a8170e5eSAvi Kivity static void slavio_led_mem_writew(void *opaque, hwaddr addr, 367aca23c71SBenoît Canet uint64_t val, unsigned size) 3686a3b9cc9Sblueswir1 { 3696a3b9cc9Sblueswir1 MiscState *s = opaque; 3706a3b9cc9Sblueswir1 371*f3a64b8cSMarkus Armbruster trace_slavio_led_mem_writew(val & 0xffff); 372a8f48dccSblueswir1 switch (addr) { 3736a3b9cc9Sblueswir1 case 0: 374d5296cb5Sblueswir1 s->leds = val; 3756a3b9cc9Sblueswir1 break; 3766a3b9cc9Sblueswir1 default: 3776a3b9cc9Sblueswir1 break; 3786a3b9cc9Sblueswir1 } 3796a3b9cc9Sblueswir1 } 3806a3b9cc9Sblueswir1 381aca23c71SBenoît Canet static const MemoryRegionOps slavio_led_mem_ops = { 382aca23c71SBenoît Canet .read = slavio_led_mem_readw, 383aca23c71SBenoît Canet .write = slavio_led_mem_writew, 384aca23c71SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 385aca23c71SBenoît Canet .valid = { 386aca23c71SBenoît Canet .min_access_size = 2, 387aca23c71SBenoît Canet .max_access_size = 2, 388aca23c71SBenoît Canet }, 3896a3b9cc9Sblueswir1 }; 3906a3b9cc9Sblueswir1 391d37adb09SBlue Swirl static const VMStateDescription vmstate_misc = { 392d37adb09SBlue Swirl .name ="slavio_misc", 393d37adb09SBlue Swirl .version_id = 1, 394d37adb09SBlue Swirl .minimum_version_id = 1, 395d37adb09SBlue Swirl .minimum_version_id_old = 1, 396d37adb09SBlue Swirl .fields = (VMStateField []) { 397d37adb09SBlue Swirl VMSTATE_UINT32(dummy, MiscState), 398d37adb09SBlue Swirl VMSTATE_UINT8(config, MiscState), 399d37adb09SBlue Swirl VMSTATE_UINT8(aux1, MiscState), 400d37adb09SBlue Swirl VMSTATE_UINT8(aux2, MiscState), 401d37adb09SBlue Swirl VMSTATE_UINT8(diag, MiscState), 402d37adb09SBlue Swirl VMSTATE_UINT8(mctrl, MiscState), 403d37adb09SBlue Swirl VMSTATE_UINT8(sysctrl, MiscState), 404d37adb09SBlue Swirl VMSTATE_END_OF_LIST() 4053475187dSbellard } 406d37adb09SBlue Swirl }; 4073475187dSbellard 40881a322d4SGerd Hoffmann static int apc_init1(SysBusDevice *dev) 4092582cfa0SBlue Swirl { 4102582cfa0SBlue Swirl APCState *s = FROM_SYSBUS(APCState, dev); 4112582cfa0SBlue Swirl 4122582cfa0SBlue Swirl sysbus_init_irq(dev, &s->cpu_halt); 4132582cfa0SBlue Swirl 4142582cfa0SBlue Swirl /* Power management (APC) XXX: not a Slavio device */ 4153c161542SPaolo Bonzini memory_region_init_io(&s->iomem, OBJECT(s), &apc_mem_ops, s, 4169c48dee6SBenoît Canet "apc", MISC_SIZE); 417750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->iomem); 41881a322d4SGerd Hoffmann return 0; 4192582cfa0SBlue Swirl } 4202582cfa0SBlue Swirl 42181a322d4SGerd Hoffmann static int slavio_misc_init1(SysBusDevice *dev) 4222582cfa0SBlue Swirl { 4232582cfa0SBlue Swirl MiscState *s = FROM_SYSBUS(MiscState, dev); 4242582cfa0SBlue Swirl 4252582cfa0SBlue Swirl sysbus_init_irq(dev, &s->irq); 4262582cfa0SBlue Swirl sysbus_init_irq(dev, &s->fdc_tc); 4272582cfa0SBlue Swirl 4282582cfa0SBlue Swirl /* 8 bit registers */ 4292582cfa0SBlue Swirl /* Slavio control */ 4303c161542SPaolo Bonzini memory_region_init_io(&s->cfg_iomem, OBJECT(s), &slavio_cfg_mem_ops, s, 431dd703aaeSBenoît Canet "configuration", MISC_SIZE); 432750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->cfg_iomem); 433a8f48dccSblueswir1 4342582cfa0SBlue Swirl /* Diagnostics */ 4353c161542SPaolo Bonzini memory_region_init_io(&s->diag_iomem, OBJECT(s), &slavio_diag_mem_ops, s, 43696891e59SBenoît Canet "diagnostic", MISC_SIZE); 437750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->diag_iomem); 438a8f48dccSblueswir1 4392582cfa0SBlue Swirl /* Modem control */ 4403c161542SPaolo Bonzini memory_region_init_io(&s->mdm_iomem, OBJECT(s), &slavio_mdm_mem_ops, s, 4412e66ac3dSBenoît Canet "modem", MISC_SIZE); 442750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->mdm_iomem); 4433475187dSbellard 4446a3b9cc9Sblueswir1 /* 16 bit registers */ 4452582cfa0SBlue Swirl /* ss600mp diag LEDs */ 4463c161542SPaolo Bonzini memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s, 447aca23c71SBenoît Canet "leds", MISC_SIZE); 448750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->led_iomem); 4496a3b9cc9Sblueswir1 450bfa30a38Sblueswir1 /* 32 bit registers */ 4512582cfa0SBlue Swirl /* System control */ 4523c161542SPaolo Bonzini memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s, 453cd64a524SBenoît Canet "system-control", MISC_SIZE); 454750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->sysctrl_iomem); 4550019ad53Sblueswir1 4562582cfa0SBlue Swirl /* AUX 1 (Misc System Functions) */ 4573c161542SPaolo Bonzini memory_region_init_io(&s->aux1_iomem, OBJECT(s), &slavio_aux1_mem_ops, s, 458cccd43c5SBenoît Canet "misc-system-functions", MISC_SIZE); 459750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->aux1_iomem); 4600019ad53Sblueswir1 4612582cfa0SBlue Swirl /* AUX 2 (Software Powerdown Control) */ 4623c161542SPaolo Bonzini memory_region_init_io(&s->aux2_iomem, OBJECT(s), &slavio_aux2_mem_ops, s, 46340ce02fcSBenoît Canet "software-powerdown-control", MISC_SIZE); 464750ecd44SAvi Kivity sysbus_init_mmio(dev, &s->aux2_iomem); 4650019ad53Sblueswir1 466b2b6f6ecSBlue Swirl qdev_init_gpio_in(&dev->qdev, slavio_set_power_fail, 1); 467b2b6f6ecSBlue Swirl 46881a322d4SGerd Hoffmann return 0; 4693475187dSbellard } 4702582cfa0SBlue Swirl 471999e12bbSAnthony Liguori static void slavio_misc_class_init(ObjectClass *klass, void *data) 472999e12bbSAnthony Liguori { 47339bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass); 474999e12bbSAnthony Liguori SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 475999e12bbSAnthony Liguori 476999e12bbSAnthony Liguori k->init = slavio_misc_init1; 47739bffca2SAnthony Liguori dc->reset = slavio_misc_reset; 47839bffca2SAnthony Liguori dc->vmsd = &vmstate_misc; 479999e12bbSAnthony Liguori } 480999e12bbSAnthony Liguori 4818c43a6f0SAndreas Färber static const TypeInfo slavio_misc_info = { 482999e12bbSAnthony Liguori .name = "slavio_misc", 48339bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 48439bffca2SAnthony Liguori .instance_size = sizeof(MiscState), 485999e12bbSAnthony Liguori .class_init = slavio_misc_class_init, 4862582cfa0SBlue Swirl }; 4872582cfa0SBlue Swirl 488999e12bbSAnthony Liguori static void apc_class_init(ObjectClass *klass, void *data) 489999e12bbSAnthony Liguori { 490999e12bbSAnthony Liguori SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 491999e12bbSAnthony Liguori 492999e12bbSAnthony Liguori k->init = apc_init1; 493999e12bbSAnthony Liguori } 494999e12bbSAnthony Liguori 4958c43a6f0SAndreas Färber static const TypeInfo apc_info = { 496999e12bbSAnthony Liguori .name = "apc", 49739bffca2SAnthony Liguori .parent = TYPE_SYS_BUS_DEVICE, 49839bffca2SAnthony Liguori .instance_size = sizeof(MiscState), 499999e12bbSAnthony Liguori .class_init = apc_class_init, 5002582cfa0SBlue Swirl }; 5012582cfa0SBlue Swirl 50283f7d43aSAndreas Färber static void slavio_misc_register_types(void) 5032582cfa0SBlue Swirl { 50439bffca2SAnthony Liguori type_register_static(&slavio_misc_info); 50539bffca2SAnthony Liguori type_register_static(&apc_info); 5062582cfa0SBlue Swirl } 5072582cfa0SBlue Swirl 50883f7d43aSAndreas Färber type_init(slavio_misc_register_types) 509