bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 1 | /* |
| 2 | * QEMU Sparc SLAVIO aux io port emulation |
ths | 5fafdf2 | 2007-09-16 21:08:06 +0000 | [diff] [blame] | 3 | * |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 4 | * Copyright (c) 2005 Fabrice Bellard |
ths | 5fafdf2 | 2007-09-16 21:08:06 +0000 | [diff] [blame] | 5 | * |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 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 | */ |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 24 | |
pbrook | 87ecb68 | 2007-11-17 17:14:51 +0000 | [diff] [blame] | 25 | #include "sysemu.h" |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 26 | #include "sysbus.h" |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 27 | #include "trace.h" |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 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 | |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 37 | typedef struct MiscState { |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 38 | SysBusDevice busdev; |
Benoît Canet | dd703aa | 2011-11-15 12:13:52 +0100 | [diff] [blame] | 39 | MemoryRegion cfg_iomem; |
Benoît Canet | 96891e5 | 2011-11-15 12:13:53 +0100 | [diff] [blame] | 40 | MemoryRegion diag_iomem; |
Benoît Canet | 2e66ac3 | 2011-11-15 12:13:54 +0100 | [diff] [blame] | 41 | MemoryRegion mdm_iomem; |
Benoît Canet | aca23c7 | 2011-11-15 12:13:55 +0100 | [diff] [blame] | 42 | MemoryRegion led_iomem; |
Benoît Canet | cd64a52 | 2011-11-15 12:13:56 +0100 | [diff] [blame] | 43 | MemoryRegion sysctrl_iomem; |
Benoît Canet | cccd43c | 2011-11-15 12:13:57 +0100 | [diff] [blame] | 44 | MemoryRegion aux1_iomem; |
Benoît Canet | 40ce02f | 2011-11-15 12:13:58 +0100 | [diff] [blame] | 45 | MemoryRegion aux2_iomem; |
pbrook | d537cf6 | 2007-04-07 18:14:41 +0000 | [diff] [blame] | 46 | qemu_irq irq; |
Blue Swirl | 97bbb10 | 2011-08-07 19:03:18 +0000 | [diff] [blame] | 47 | qemu_irq fdc_tc; |
Blue Swirl | d37adb0 | 2009-08-29 16:37:09 +0300 | [diff] [blame] | 48 | uint32_t dummy; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 49 | uint8_t config; |
| 50 | uint8_t aux1, aux2; |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 51 | uint8_t diag, mctrl; |
Blue Swirl | d37adb0 | 2009-08-29 16:37:09 +0300 | [diff] [blame] | 52 | uint8_t sysctrl; |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 53 | uint16_t leds; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 54 | } MiscState; |
| 55 | |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 56 | typedef struct APCState { |
| 57 | SysBusDevice busdev; |
Benoît Canet | 9c48dee | 2011-11-15 12:13:51 +0100 | [diff] [blame] | 58 | MemoryRegion iomem; |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 59 | qemu_irq cpu_halt; |
| 60 | } APCState; |
| 61 | |
blueswir1 | 5aca8c3 | 2007-05-26 17:39:43 +0000 | [diff] [blame] | 62 | #define MISC_SIZE 1 |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 63 | #define SYSCTRL_SIZE 4 |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 64 | |
blueswir1 | 2be17eb | 2008-03-21 18:05:23 +0000 | [diff] [blame] | 65 | #define AUX1_TC 0x02 |
| 66 | |
blueswir1 | 7debeb8 | 2007-12-01 14:53:22 +0000 | [diff] [blame] | 67 | #define AUX2_PWROFF 0x01 |
| 68 | #define AUX2_PWRINTCLR 0x02 |
| 69 | #define AUX2_PWRFAIL 0x20 |
| 70 | |
| 71 | #define CFG_PWRINTEN 0x08 |
| 72 | |
| 73 | #define SYS_RESET 0x01 |
| 74 | #define SYS_RESETSTAT 0x02 |
| 75 | |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 76 | static void slavio_misc_update_irq(void *opaque) |
| 77 | { |
| 78 | MiscState *s = opaque; |
| 79 | |
blueswir1 | 7debeb8 | 2007-12-01 14:53:22 +0000 | [diff] [blame] | 80 | if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) { |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 81 | trace_slavio_misc_update_irq_raise(); |
pbrook | d537cf6 | 2007-04-07 18:14:41 +0000 | [diff] [blame] | 82 | qemu_irq_raise(s->irq); |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 83 | } else { |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 84 | trace_slavio_misc_update_irq_lower(); |
pbrook | d537cf6 | 2007-04-07 18:14:41 +0000 | [diff] [blame] | 85 | qemu_irq_lower(s->irq); |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 86 | } |
| 87 | } |
| 88 | |
Blue Swirl | 1795057 | 2009-10-24 15:27:23 +0000 | [diff] [blame] | 89 | static void slavio_misc_reset(DeviceState *d) |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 90 | { |
Blue Swirl | 1795057 | 2009-10-24 15:27:23 +0000 | [diff] [blame] | 91 | MiscState *s = container_of(d, MiscState, busdev.qdev); |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 92 | |
bellard | 4e3b1ea | 2005-10-30 17:24:19 +0000 | [diff] [blame] | 93 | // Diagnostic and system control registers not cleared in reset |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 94 | s->config = s->aux1 = s->aux2 = s->mctrl = 0; |
| 95 | } |
| 96 | |
Blue Swirl | b2b6f6e | 2009-08-09 07:27:29 +0000 | [diff] [blame] | 97 | static void slavio_set_power_fail(void *opaque, int irq, int power_failing) |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 98 | { |
| 99 | MiscState *s = opaque; |
| 100 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 101 | trace_slavio_set_power_fail(power_failing, s->config); |
blueswir1 | 7debeb8 | 2007-12-01 14:53:22 +0000 | [diff] [blame] | 102 | if (power_failing && (s->config & CFG_PWRINTEN)) { |
| 103 | s->aux2 |= AUX2_PWRFAIL; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 104 | } else { |
blueswir1 | 7debeb8 | 2007-12-01 14:53:22 +0000 | [diff] [blame] | 105 | s->aux2 &= ~AUX2_PWRFAIL; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 106 | } |
| 107 | slavio_misc_update_irq(s); |
| 108 | } |
| 109 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 110 | static void slavio_cfg_mem_writeb(void *opaque, target_phys_addr_t addr, |
Benoît Canet | dd703aa | 2011-11-15 12:13:52 +0100 | [diff] [blame] | 111 | uint64_t val, unsigned size) |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 112 | { |
| 113 | MiscState *s = opaque; |
| 114 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 115 | trace_slavio_cfg_mem_writeb(val & 0xff); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 116 | s->config = val & 0xff; |
| 117 | slavio_misc_update_irq(s); |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 118 | } |
| 119 | |
Benoît Canet | dd703aa | 2011-11-15 12:13:52 +0100 | [diff] [blame] | 120 | static uint64_t slavio_cfg_mem_readb(void *opaque, target_phys_addr_t addr, |
| 121 | unsigned size) |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 122 | { |
| 123 | MiscState *s = opaque; |
| 124 | uint32_t ret = 0; |
| 125 | |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 126 | ret = s->config; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 127 | trace_slavio_cfg_mem_readb(ret); |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 128 | return ret; |
| 129 | } |
| 130 | |
Benoît Canet | dd703aa | 2011-11-15 12:13:52 +0100 | [diff] [blame] | 131 | static const MemoryRegionOps slavio_cfg_mem_ops = { |
| 132 | .read = slavio_cfg_mem_readb, |
| 133 | .write = slavio_cfg_mem_writeb, |
| 134 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 135 | .valid = { |
| 136 | .min_access_size = 1, |
| 137 | .max_access_size = 1, |
| 138 | }, |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 139 | }; |
| 140 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 141 | static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr, |
Benoît Canet | 96891e5 | 2011-11-15 12:13:53 +0100 | [diff] [blame] | 142 | uint64_t val, unsigned size) |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 143 | { |
| 144 | MiscState *s = opaque; |
| 145 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 146 | trace_slavio_diag_mem_writeb(val & 0xff); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 147 | s->diag = val & 0xff; |
| 148 | } |
| 149 | |
Benoît Canet | 96891e5 | 2011-11-15 12:13:53 +0100 | [diff] [blame] | 150 | static uint64_t slavio_diag_mem_readb(void *opaque, target_phys_addr_t addr, |
| 151 | unsigned size) |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 152 | { |
| 153 | MiscState *s = opaque; |
| 154 | uint32_t ret = 0; |
| 155 | |
| 156 | ret = s->diag; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 157 | trace_slavio_diag_mem_readb(ret); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 158 | return ret; |
| 159 | } |
| 160 | |
Benoît Canet | 96891e5 | 2011-11-15 12:13:53 +0100 | [diff] [blame] | 161 | static const MemoryRegionOps slavio_diag_mem_ops = { |
| 162 | .read = slavio_diag_mem_readb, |
| 163 | .write = slavio_diag_mem_writeb, |
| 164 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 165 | .valid = { |
| 166 | .min_access_size = 1, |
| 167 | .max_access_size = 1, |
| 168 | }, |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 169 | }; |
| 170 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 171 | static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr, |
Benoît Canet | 2e66ac3 | 2011-11-15 12:13:54 +0100 | [diff] [blame] | 172 | uint64_t val, unsigned size) |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 173 | { |
| 174 | MiscState *s = opaque; |
| 175 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 176 | trace_slavio_mdm_mem_writeb(val & 0xff); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 177 | s->mctrl = val & 0xff; |
| 178 | } |
| 179 | |
Benoît Canet | 2e66ac3 | 2011-11-15 12:13:54 +0100 | [diff] [blame] | 180 | static uint64_t slavio_mdm_mem_readb(void *opaque, target_phys_addr_t addr, |
| 181 | unsigned size) |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 182 | { |
| 183 | MiscState *s = opaque; |
| 184 | uint32_t ret = 0; |
| 185 | |
| 186 | ret = s->mctrl; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 187 | trace_slavio_mdm_mem_readb(ret); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 188 | return ret; |
| 189 | } |
| 190 | |
Benoît Canet | 2e66ac3 | 2011-11-15 12:13:54 +0100 | [diff] [blame] | 191 | static const MemoryRegionOps slavio_mdm_mem_ops = { |
| 192 | .read = slavio_mdm_mem_readb, |
| 193 | .write = slavio_mdm_mem_writeb, |
| 194 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 195 | .valid = { |
| 196 | .min_access_size = 1, |
| 197 | .max_access_size = 1, |
| 198 | }, |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 199 | }; |
| 200 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 201 | static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr, |
Benoît Canet | cccd43c | 2011-11-15 12:13:57 +0100 | [diff] [blame] | 202 | uint64_t val, unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 203 | { |
| 204 | MiscState *s = opaque; |
| 205 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 206 | trace_slavio_aux1_mem_writeb(val & 0xff); |
blueswir1 | 2be17eb | 2008-03-21 18:05:23 +0000 | [diff] [blame] | 207 | if (val & AUX1_TC) { |
| 208 | // Send a pulse to floppy terminal count line |
| 209 | if (s->fdc_tc) { |
| 210 | qemu_irq_raise(s->fdc_tc); |
| 211 | qemu_irq_lower(s->fdc_tc); |
| 212 | } |
| 213 | val &= ~AUX1_TC; |
| 214 | } |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 215 | s->aux1 = val & 0xff; |
| 216 | } |
| 217 | |
Benoît Canet | cccd43c | 2011-11-15 12:13:57 +0100 | [diff] [blame] | 218 | static uint64_t slavio_aux1_mem_readb(void *opaque, target_phys_addr_t addr, |
| 219 | unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 220 | { |
| 221 | MiscState *s = opaque; |
| 222 | uint32_t ret = 0; |
| 223 | |
| 224 | ret = s->aux1; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 225 | trace_slavio_aux1_mem_readb(ret); |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 226 | return ret; |
| 227 | } |
| 228 | |
Benoît Canet | cccd43c | 2011-11-15 12:13:57 +0100 | [diff] [blame] | 229 | static const MemoryRegionOps slavio_aux1_mem_ops = { |
| 230 | .read = slavio_aux1_mem_readb, |
| 231 | .write = slavio_aux1_mem_writeb, |
| 232 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 233 | .valid = { |
| 234 | .min_access_size = 1, |
| 235 | .max_access_size = 1, |
| 236 | }, |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 237 | }; |
| 238 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 239 | static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr, |
Benoît Canet | 40ce02f | 2011-11-15 12:13:58 +0100 | [diff] [blame] | 240 | uint64_t val, unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 241 | { |
| 242 | MiscState *s = opaque; |
| 243 | |
| 244 | val &= AUX2_PWRINTCLR | AUX2_PWROFF; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 245 | trace_slavio_aux2_mem_writeb(val & 0xff); |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 246 | val |= s->aux2 & AUX2_PWRFAIL; |
| 247 | if (val & AUX2_PWRINTCLR) // Clear Power Fail int |
| 248 | val &= AUX2_PWROFF; |
| 249 | s->aux2 = val; |
| 250 | if (val & AUX2_PWROFF) |
| 251 | qemu_system_shutdown_request(); |
| 252 | slavio_misc_update_irq(s); |
| 253 | } |
| 254 | |
Benoît Canet | 40ce02f | 2011-11-15 12:13:58 +0100 | [diff] [blame] | 255 | static uint64_t slavio_aux2_mem_readb(void *opaque, target_phys_addr_t addr, |
| 256 | unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 257 | { |
| 258 | MiscState *s = opaque; |
| 259 | uint32_t ret = 0; |
| 260 | |
| 261 | ret = s->aux2; |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 262 | trace_slavio_aux2_mem_readb(ret); |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 263 | return ret; |
| 264 | } |
| 265 | |
Benoît Canet | 40ce02f | 2011-11-15 12:13:58 +0100 | [diff] [blame] | 266 | static const MemoryRegionOps slavio_aux2_mem_ops = { |
| 267 | .read = slavio_aux2_mem_readb, |
| 268 | .write = slavio_aux2_mem_writeb, |
| 269 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 270 | .valid = { |
| 271 | .min_access_size = 1, |
| 272 | .max_access_size = 1, |
| 273 | }, |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 274 | }; |
| 275 | |
Benoît Canet | 9c48dee | 2011-11-15 12:13:51 +0100 | [diff] [blame] | 276 | static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, |
| 277 | uint64_t val, unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 278 | { |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 279 | APCState *s = opaque; |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 280 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 281 | trace_apc_mem_writeb(val & 0xff); |
blueswir1 | 6d0c293 | 2008-11-02 10:51:05 +0000 | [diff] [blame] | 282 | qemu_irq_raise(s->cpu_halt); |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 283 | } |
| 284 | |
Benoît Canet | 9c48dee | 2011-11-15 12:13:51 +0100 | [diff] [blame] | 285 | static uint64_t apc_mem_readb(void *opaque, target_phys_addr_t addr, |
| 286 | unsigned size) |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 287 | { |
| 288 | uint32_t ret = 0; |
| 289 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 290 | trace_apc_mem_readb(ret); |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 291 | return ret; |
| 292 | } |
| 293 | |
Benoît Canet | 9c48dee | 2011-11-15 12:13:51 +0100 | [diff] [blame] | 294 | static const MemoryRegionOps apc_mem_ops = { |
| 295 | .read = apc_mem_readb, |
| 296 | .write = apc_mem_writeb, |
| 297 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 298 | .valid = { |
| 299 | .min_access_size = 1, |
| 300 | .max_access_size = 1, |
| 301 | } |
blueswir1 | 0019ad5 | 2008-01-27 09:49:28 +0000 | [diff] [blame] | 302 | }; |
| 303 | |
Benoît Canet | cd64a52 | 2011-11-15 12:13:56 +0100 | [diff] [blame] | 304 | static uint64_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr, |
| 305 | unsigned size) |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 306 | { |
| 307 | MiscState *s = opaque; |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 308 | uint32_t ret = 0; |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 309 | |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 310 | switch (addr) { |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 311 | case 0: |
| 312 | ret = s->sysctrl; |
| 313 | break; |
| 314 | default: |
| 315 | break; |
| 316 | } |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 317 | trace_slavio_sysctrl_mem_readl(ret); |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 318 | return ret; |
| 319 | } |
| 320 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 321 | static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr, |
Benoît Canet | cd64a52 | 2011-11-15 12:13:56 +0100 | [diff] [blame] | 322 | uint64_t val, unsigned size) |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 323 | { |
| 324 | MiscState *s = opaque; |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 325 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 326 | trace_slavio_sysctrl_mem_writel(val); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 327 | switch (addr) { |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 328 | case 0: |
blueswir1 | 7debeb8 | 2007-12-01 14:53:22 +0000 | [diff] [blame] | 329 | if (val & SYS_RESET) { |
| 330 | s->sysctrl = SYS_RESETSTAT; |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 331 | qemu_system_reset_request(); |
| 332 | } |
| 333 | break; |
| 334 | default: |
| 335 | break; |
| 336 | } |
| 337 | } |
| 338 | |
Benoît Canet | cd64a52 | 2011-11-15 12:13:56 +0100 | [diff] [blame] | 339 | static const MemoryRegionOps slavio_sysctrl_mem_ops = { |
| 340 | .read = slavio_sysctrl_mem_readl, |
| 341 | .write = slavio_sysctrl_mem_writel, |
| 342 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 343 | .valid = { |
| 344 | .min_access_size = 4, |
| 345 | .max_access_size = 4, |
| 346 | }, |
blueswir1 | bfa30a3 | 2007-11-04 17:27:07 +0000 | [diff] [blame] | 347 | }; |
| 348 | |
Benoît Canet | aca23c7 | 2011-11-15 12:13:55 +0100 | [diff] [blame] | 349 | static uint64_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr, |
| 350 | unsigned size) |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 351 | { |
| 352 | MiscState *s = opaque; |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 353 | uint32_t ret = 0; |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 354 | |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 355 | switch (addr) { |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 356 | case 0: |
| 357 | ret = s->leds; |
| 358 | break; |
| 359 | default: |
| 360 | break; |
| 361 | } |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 362 | trace_slavio_led_mem_readw(ret); |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 363 | return ret; |
| 364 | } |
| 365 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 366 | static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr, |
Benoît Canet | aca23c7 | 2011-11-15 12:13:55 +0100 | [diff] [blame] | 367 | uint64_t val, unsigned size) |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 368 | { |
| 369 | MiscState *s = opaque; |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 370 | |
Blue Swirl | 97bf485 | 2010-10-31 09:24:14 +0000 | [diff] [blame] | 371 | trace_slavio_led_mem_readw(val & 0xffff); |
blueswir1 | a8f48dc | 2008-12-02 17:51:19 +0000 | [diff] [blame] | 372 | switch (addr) { |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 373 | case 0: |
blueswir1 | d5296cb | 2007-12-01 15:02:20 +0000 | [diff] [blame] | 374 | s->leds = val; |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 375 | break; |
| 376 | default: |
| 377 | break; |
| 378 | } |
| 379 | } |
| 380 | |
Benoît Canet | aca23c7 | 2011-11-15 12:13:55 +0100 | [diff] [blame] | 381 | static const MemoryRegionOps slavio_led_mem_ops = { |
| 382 | .read = slavio_led_mem_readw, |
| 383 | .write = slavio_led_mem_writew, |
| 384 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 385 | .valid = { |
| 386 | .min_access_size = 2, |
| 387 | .max_access_size = 2, |
| 388 | }, |
blueswir1 | 6a3b9cc | 2007-11-11 17:56:38 +0000 | [diff] [blame] | 389 | }; |
| 390 | |
Blue Swirl | d37adb0 | 2009-08-29 16:37:09 +0300 | [diff] [blame] | 391 | static const VMStateDescription vmstate_misc = { |
| 392 | .name ="slavio_misc", |
| 393 | .version_id = 1, |
| 394 | .minimum_version_id = 1, |
| 395 | .minimum_version_id_old = 1, |
| 396 | .fields = (VMStateField []) { |
| 397 | VMSTATE_UINT32(dummy, MiscState), |
| 398 | VMSTATE_UINT8(config, MiscState), |
| 399 | VMSTATE_UINT8(aux1, MiscState), |
| 400 | VMSTATE_UINT8(aux2, MiscState), |
| 401 | VMSTATE_UINT8(diag, MiscState), |
| 402 | VMSTATE_UINT8(mctrl, MiscState), |
| 403 | VMSTATE_UINT8(sysctrl, MiscState), |
| 404 | VMSTATE_END_OF_LIST() |
| 405 | } |
| 406 | }; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 407 | |
Gerd Hoffmann | 81a322d | 2009-08-14 10:36:05 +0200 | [diff] [blame] | 408 | static int apc_init1(SysBusDevice *dev) |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 409 | { |
| 410 | APCState *s = FROM_SYSBUS(APCState, dev); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 411 | |
| 412 | sysbus_init_irq(dev, &s->cpu_halt); |
| 413 | |
| 414 | /* Power management (APC) XXX: not a Slavio device */ |
Benoît Canet | 9c48dee | 2011-11-15 12:13:51 +0100 | [diff] [blame] | 415 | memory_region_init_io(&s->iomem, &apc_mem_ops, s, |
| 416 | "apc", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 417 | sysbus_init_mmio(dev, &s->iomem); |
Gerd Hoffmann | 81a322d | 2009-08-14 10:36:05 +0200 | [diff] [blame] | 418 | return 0; |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 419 | } |
| 420 | |
Gerd Hoffmann | 81a322d | 2009-08-14 10:36:05 +0200 | [diff] [blame] | 421 | static int slavio_misc_init1(SysBusDevice *dev) |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 422 | { |
| 423 | MiscState *s = FROM_SYSBUS(MiscState, dev); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 424 | |
| 425 | sysbus_init_irq(dev, &s->irq); |
| 426 | sysbus_init_irq(dev, &s->fdc_tc); |
| 427 | |
| 428 | /* 8 bit registers */ |
| 429 | /* Slavio control */ |
Benoît Canet | dd703aa | 2011-11-15 12:13:52 +0100 | [diff] [blame] | 430 | memory_region_init_io(&s->cfg_iomem, &slavio_cfg_mem_ops, s, |
| 431 | "configuration", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 432 | sysbus_init_mmio(dev, &s->cfg_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 433 | |
| 434 | /* Diagnostics */ |
Benoît Canet | 96891e5 | 2011-11-15 12:13:53 +0100 | [diff] [blame] | 435 | memory_region_init_io(&s->diag_iomem, &slavio_diag_mem_ops, s, |
| 436 | "diagnostic", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 437 | sysbus_init_mmio(dev, &s->diag_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 438 | |
| 439 | /* Modem control */ |
Benoît Canet | 2e66ac3 | 2011-11-15 12:13:54 +0100 | [diff] [blame] | 440 | memory_region_init_io(&s->mdm_iomem, &slavio_mdm_mem_ops, s, |
| 441 | "modem", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 442 | sysbus_init_mmio(dev, &s->mdm_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 443 | |
| 444 | /* 16 bit registers */ |
| 445 | /* ss600mp diag LEDs */ |
Benoît Canet | aca23c7 | 2011-11-15 12:13:55 +0100 | [diff] [blame] | 446 | memory_region_init_io(&s->led_iomem, &slavio_led_mem_ops, s, |
| 447 | "leds", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 448 | sysbus_init_mmio(dev, &s->led_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 449 | |
| 450 | /* 32 bit registers */ |
| 451 | /* System control */ |
Benoît Canet | cd64a52 | 2011-11-15 12:13:56 +0100 | [diff] [blame] | 452 | memory_region_init_io(&s->sysctrl_iomem, &slavio_sysctrl_mem_ops, s, |
| 453 | "system-control", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 454 | sysbus_init_mmio(dev, &s->sysctrl_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 455 | |
| 456 | /* AUX 1 (Misc System Functions) */ |
Benoît Canet | cccd43c | 2011-11-15 12:13:57 +0100 | [diff] [blame] | 457 | memory_region_init_io(&s->aux1_iomem, &slavio_aux1_mem_ops, s, |
| 458 | "misc-system-functions", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 459 | sysbus_init_mmio(dev, &s->aux1_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 460 | |
| 461 | /* AUX 2 (Software Powerdown Control) */ |
Benoît Canet | 40ce02f | 2011-11-15 12:13:58 +0100 | [diff] [blame] | 462 | memory_region_init_io(&s->aux2_iomem, &slavio_aux2_mem_ops, s, |
| 463 | "software-powerdown-control", MISC_SIZE); |
Avi Kivity | 750ecd4 | 2011-11-27 11:38:10 +0200 | [diff] [blame] | 464 | sysbus_init_mmio(dev, &s->aux2_iomem); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 465 | |
Blue Swirl | b2b6f6e | 2009-08-09 07:27:29 +0000 | [diff] [blame] | 466 | qdev_init_gpio_in(&dev->qdev, slavio_set_power_fail, 1); |
| 467 | |
Gerd Hoffmann | 81a322d | 2009-08-14 10:36:05 +0200 | [diff] [blame] | 468 | return 0; |
bellard | 3475187 | 2005-07-02 14:31:34 +0000 | [diff] [blame] | 469 | } |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 470 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 471 | static void slavio_misc_class_init(ObjectClass *klass, void *data) |
| 472 | { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 473 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 474 | SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); |
| 475 | |
| 476 | k->init = slavio_misc_init1; |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 477 | dc->reset = slavio_misc_reset; |
| 478 | dc->vmsd = &vmstate_misc; |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 479 | } |
| 480 | |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 481 | static TypeInfo slavio_misc_info = { |
| 482 | .name = "slavio_misc", |
| 483 | .parent = TYPE_SYS_BUS_DEVICE, |
| 484 | .instance_size = sizeof(MiscState), |
| 485 | .class_init = slavio_misc_class_init, |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 486 | }; |
| 487 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 488 | static void apc_class_init(ObjectClass *klass, void *data) |
| 489 | { |
| 490 | SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); |
| 491 | |
| 492 | k->init = apc_init1; |
| 493 | } |
| 494 | |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 495 | static TypeInfo apc_info = { |
| 496 | .name = "apc", |
| 497 | .parent = TYPE_SYS_BUS_DEVICE, |
| 498 | .instance_size = sizeof(MiscState), |
| 499 | .class_init = apc_class_init, |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 500 | }; |
| 501 | |
Andreas Färber | 83f7d43 | 2012-02-09 15:20:55 +0100 | [diff] [blame] | 502 | static void slavio_misc_register_types(void) |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 503 | { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 504 | type_register_static(&slavio_misc_info); |
| 505 | type_register_static(&apc_info); |
Blue Swirl | 2582cfa | 2009-07-13 16:51:27 +0000 | [diff] [blame] | 506 | } |
| 507 | |
Andreas Färber | 83f7d43 | 2012-02-09 15:20:55 +0100 | [diff] [blame] | 508 | type_init(slavio_misc_register_types) |