| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU Crystal CS4231 audio chip emulation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2006 Fabrice Bellard | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | 
					
						
							|  |  |  |  * of this software and associated documentation files (the "Software"), to deal | 
					
						
							|  |  |  |  * in the Software without restriction, including without limitation the rights | 
					
						
							|  |  |  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
					
						
							|  |  |  |  * copies of the Software, and to permit persons to whom the Software is | 
					
						
							|  |  |  |  * furnished to do so, subject to the following conditions: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The above copyright notice and this permission notice shall be included in | 
					
						
							|  |  |  |  * all copies or substantial portions of the Software. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
					
						
							|  |  |  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
					
						
							|  |  |  |  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
					
						
							|  |  |  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
					
						
							|  |  |  |  * THE SOFTWARE. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-18 17:33:52 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:45 +02:00
										 |  |  | #include "migration/vmstate.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  | #include "trace.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * In addition to Crystal CS4231 there is a DMA controller on Sparc. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-02 17:47:02 +00:00
										 |  |  | #define CS_SIZE 0x40
 | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | #define CS_REGS 16
 | 
					
						
							|  |  |  | #define CS_DREGS 32
 | 
					
						
							|  |  |  | #define CS_MAXDREG (CS_DREGS - 1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												hw: Replace anti-social QOM type names
Several QOM type names contain ',':
    ARM,bitband-memory
    etraxfs,pic
    etraxfs,serial
    etraxfs,timer
    fsl,imx25
    fsl,imx31
    fsl,imx6
    fsl,imx6ul
    fsl,imx7
    grlib,ahbpnp
    grlib,apbpnp
    grlib,apbuart
    grlib,gptimer
    grlib,irqmp
    qemu,register
    SUNW,bpp
    SUNW,CS4231
    SUNW,DBRI
    SUNW,DBRI.prom
    SUNW,fdtwo
    SUNW,sx
    SUNW,tcx
    xilinx,zynq_slcr
    xlnx,zynqmp
    xlnx,zynqmp-pmu-soc
    xlnx,zynq-xadc
These are all device types.  They can't be plugged with -device /
device_add, except for xlnx,zynqmp-pmu-soc, and I doubt that one
actually works.
They *can* be used with -device / device_add to request help.
Usability is poor, though: you have to double the comma, like this:
    $ qemu-system-x86_64 -device SUNW,,fdtwo,help
Trap for the unwary.  The fact that this was broken in
device-introspect-test for more than six years until commit e27bd49876
fixed it demonstrates that "the unwary" includes seasoned developers.
One QOM type name contains ' ': "ICH9 SMB".  Because having to
remember just one way to quote would be too easy.
Rename the "SUNW,FOO types to "sun-FOO".  Summarily replace ',' and '
' by '-' in the other type names.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210304140229.575481-2-armbru@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
											
										 
											2021-03-04 15:02:28 +01:00
										 |  |  | #define TYPE_CS4231 "sun-CS4231"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | typedef struct CSState CSState; | 
					
						
							| 
									
										
										
										
											2020-08-31 17:07:33 -04:00
										 |  |  | DECLARE_INSTANCE_CHECKER(CSState, CS4231, | 
					
						
							|  |  |  |                          TYPE_CS4231) | 
					
						
							| 
									
										
										
										
											2013-07-24 10:04:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct CSState { | 
					
						
							| 
									
										
										
										
											2013-07-24 10:04:31 +02:00
										 |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-09 16:10:07 +02:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  |     qemu_irq irq; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     uint32_t regs[CS_REGS]; | 
					
						
							|  |  |  |     uint8_t dregs[CS_DREGS]; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
 | 
					
						
							|  |  |  | #define CS_VER 0xa0
 | 
					
						
							|  |  |  | #define CS_CDC_VER 0x8a
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 16:20:32 +00:00
										 |  |  | static void cs_reset(DeviceState *d) | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-24 10:04:31 +02:00
										 |  |  |     CSState *s = CS4231(d); | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     memset(s->regs, 0, CS_REGS * 4); | 
					
						
							|  |  |  |     memset(s->dregs, 0, CS_DREGS); | 
					
						
							|  |  |  |     s->dregs[12] = CS_CDC_VER; | 
					
						
							|  |  |  |     s->dregs[25] = CS_VER; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t cs_mem_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-09 16:10:07 +02:00
										 |  |  |                             unsigned size) | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     CSState *s = opaque; | 
					
						
							|  |  |  |     uint32_t saddr, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:47:02 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |         switch (CS_RAP(s)) { | 
					
						
							|  |  |  |         case 3: // Write only
 | 
					
						
							|  |  |  |             ret = 0; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             ret = s->dregs[CS_RAP(s)]; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_cs4231_mem_readl_dreg(CS_RAP(s), ret); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     default: | 
					
						
							|  |  |  |         ret = s->regs[saddr]; | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_cs4231_mem_readl_reg(saddr, ret); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void cs_mem_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-09 16:10:07 +02:00
										 |  |  |                          uint64_t val, unsigned size) | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     CSState *s = opaque; | 
					
						
							|  |  |  |     uint32_t saddr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:47:02 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_cs4231_mem_writel_reg(saddr, s->regs[saddr], val); | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 1: | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_cs4231_mem_writel_dreg(CS_RAP(s), s->dregs[CS_RAP(s)], val); | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |         switch(CS_RAP(s)) { | 
					
						
							|  |  |  |         case 11: | 
					
						
							|  |  |  |         case 25: // Read only
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case 12: | 
					
						
							|  |  |  |             val &= 0x40; | 
					
						
							|  |  |  |             val |= CS_CDC_VER; // Codec version
 | 
					
						
							|  |  |  |             s->dregs[CS_RAP(s)] = val; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             s->dregs[CS_RAP(s)] = val; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 2: // Read only
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 4: | 
					
						
							| 
									
										
										
										
											2009-10-24 16:20:32 +00:00
										 |  |  |         if (val & 1) { | 
					
						
							| 
									
										
										
										
											2013-07-24 10:04:31 +02:00
										 |  |  |             cs_reset(DEVICE(s)); | 
					
						
							| 
									
										
										
										
											2009-10-24 16:20:32 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |         val &= 0x7f; | 
					
						
							|  |  |  |         s->regs[saddr] = val; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         s->regs[saddr] = val; | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-09 16:10:07 +02:00
										 |  |  | static const MemoryRegionOps cs_mem_ops = { | 
					
						
							|  |  |  |     .read = cs_mem_read, | 
					
						
							|  |  |  |     .write = cs_mem_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 16:20:32 +00:00
										 |  |  | static const VMStateDescription vmstate_cs4231 = { | 
					
						
							|  |  |  |     .name ="cs4231", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2014-04-16 15:32:32 +02:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2009-10-24 16:20:32 +00:00
										 |  |  |         VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS), | 
					
						
							|  |  |  |         VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 11:46:57 +08:00
										 |  |  | static void cs4231_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-13 11:46:57 +08:00
										 |  |  |     CSState *s = CS4231(obj); | 
					
						
							|  |  |  |     SysBusDevice *dev = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 11:46:57 +08:00
										 |  |  |     memory_region_init_io(&s->iomem, obj, &cs_mem_ops, s, "cs4321", | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |                           CS_SIZE); | 
					
						
							| 
									
										
										
										
											2011-11-27 11:38:10 +02:00
										 |  |  |     sysbus_init_mmio(dev, &s->iomem); | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  |     sysbus_init_irq(dev, &s->irq); | 
					
						
							| 
									
										
										
										
											2006-09-10 19:25:12 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void cs4231_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->reset = cs_reset; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_cs4231; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo cs4231_info = { | 
					
						
							| 
									
										
										
										
											2013-07-24 10:04:31 +02:00
										 |  |  |     .name          = TYPE_CS4231, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(CSState), | 
					
						
							| 
									
										
										
										
											2016-05-13 11:46:57 +08:00
										 |  |  |     .instance_init = cs4231_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = cs4231_class_init, | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void cs4231_register_types(void) | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&cs4231_info); | 
					
						
							| 
									
										
										
										
											2009-07-16 13:47:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(cs4231_register_types) |