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