| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Intel XScale PXA255/270 processor support. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2006 Openedhand Ltd. | 
					
						
							|  |  |  |  * Written by Andrzej Zaborowski <balrog@zabor.org> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-06-26 12:21:35 +10:00
										 |  |  |  * This code is licensed under the GPL. | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-07 16:23:45 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
											  
											
												hw/arm: Replace fprintf(stderr, "*\n" with error_report()
Replace a large number of the fprintf(stderr, "*\n" calls with
error_report(). The functions were renamed with these commands and then
compiler issues where manually fixed.
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
Some lines where then manually tweaked to pass checkpatch.
The 'qemu: ' prefix was manually removed from the hw/arm/boot.c file.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Cc: qemu-arm@nongnu.org
Conversions that aren't followed by exit() dropped, because they might
be inappropriate.
Also trim trailing punctuation from error messages.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20180203084315.20497-3-armbru@redhat.com>
											
										 
											2018-02-03 09:43:03 +01:00
										 |  |  | #include "qemu/error-report.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
											  
											
												include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef.  Since then, we've moved to include qemu/osdep.h
everywhere.  Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h.  That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h.  Include qapi/error.h in .c files that need it and don't
get it now.  Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly.  Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h.  Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third.  Unfortunately, the number depending on
qapi-types.h shrinks only a little.  More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
											
										 
											2016-03-14 09:01:28 +01:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2023-01-09 12:53:04 +01:00
										 |  |  | #include "exec/address-spaces.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-19 21:51:44 +01:00
										 |  |  | #include "cpu.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"
 | 
					
						
							| 
									
										
										
										
											2013-02-05 17:06:20 +01:00
										 |  |  | #include "hw/arm/pxa.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:04 +01:00
										 |  |  | #include "sysemu/sysemu.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-05 17:06:20 +01:00
										 |  |  | #include "hw/char/serial.h"
 | 
					
						
							|  |  |  | #include "hw/i2c/i2c.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | #include "hw/irq.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:51 +02:00
										 |  |  | #include "hw/qdev-properties.h"
 | 
					
						
							| 
									
										
										
										
											2020-12-11 17:05:12 -05:00
										 |  |  | #include "hw/qdev-properties-system.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-21 14:15:03 +00:00
										 |  |  | #include "hw/ssi/ssi.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-05 23:22:10 +02:00
										 |  |  | #include "hw/sd/sd.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-26 18:26:44 +04:00
										 |  |  | #include "chardev/char-fe.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:04 +01:00
										 |  |  | #include "sysemu/blockdev.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-04 18:05:51 +01:00
										 |  |  | #include "sysemu/qtest.h"
 | 
					
						
							| 
									
										
										
										
											2021-11-29 20:55:05 +00:00
										 |  |  | #include "sysemu/rtc.h"
 | 
					
						
							| 
									
										
										
										
											2016-03-20 19:16:19 +02:00
										 |  |  | #include "qemu/cutils.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  | #include "qemu/log.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2022-04-30 22:49:43 -07:00
										 |  |  | #include "target/arm/cpregs.h"
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct { | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     hwaddr io_base; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     int irqn; | 
					
						
							|  |  |  | } pxa255_serial[] = { | 
					
						
							|  |  |  |     { 0x40100000, PXA2XX_PIC_FFUART }, | 
					
						
							|  |  |  |     { 0x40200000, PXA2XX_PIC_BTUART }, | 
					
						
							|  |  |  |     { 0x40700000, PXA2XX_PIC_STUART }, | 
					
						
							|  |  |  |     { 0x41600000, PXA25X_PIC_HWUART }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							|  |  |  | }, pxa270_serial[] = { | 
					
						
							|  |  |  |     { 0x40100000, PXA2XX_PIC_FFUART }, | 
					
						
							|  |  |  |     { 0x40200000, PXA2XX_PIC_BTUART }, | 
					
						
							|  |  |  |     { 0x40700000, PXA2XX_PIC_STUART }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-11 19:48:33 +00:00
										 |  |  | typedef struct PXASSPDef { | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     hwaddr io_base; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     int irqn; | 
					
						
							| 
									
										
										
										
											2007-11-11 19:48:33 +00:00
										 |  |  | } PXASSPDef; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | static PXASSPDef pxa250_ssp[] = { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     { 0x41000000, PXA2XX_PIC_SSP }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							| 
									
										
										
										
											2007-11-11 19:48:33 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PXASSPDef pxa255_ssp[] = { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     { 0x41000000, PXA2XX_PIC_SSP }, | 
					
						
							|  |  |  |     { 0x41400000, PXA25X_PIC_NSSP }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							| 
									
										
										
										
											2007-11-11 19:48:33 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | static PXASSPDef pxa26x_ssp[] = { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     { 0x41000000, PXA2XX_PIC_SSP }, | 
					
						
							|  |  |  |     { 0x41400000, PXA25X_PIC_NSSP }, | 
					
						
							|  |  |  |     { 0x41500000, PXA26X_PIC_ASSP }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							| 
									
										
										
										
											2007-11-11 19:48:33 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PXASSPDef pxa27x_ssp[] = { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     { 0x41000000, PXA2XX_PIC_SSP }, | 
					
						
							|  |  |  |     { 0x41700000, PXA27X_PIC_SSP2 }, | 
					
						
							|  |  |  |     { 0x41900000, PXA2XX_PIC_SSP3 }, | 
					
						
							|  |  |  |     { 0, 0 } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PMCR	0x00	/* Power Manager Control register */
 | 
					
						
							|  |  |  | #define PSSR	0x04	/* Power Manager Sleep Status register */
 | 
					
						
							|  |  |  | #define PSPR	0x08	/* Power Manager Scratch-Pad register */
 | 
					
						
							|  |  |  | #define PWER	0x0c	/* Power Manager Wake-Up Enable register */
 | 
					
						
							|  |  |  | #define PRER	0x10	/* Power Manager Rising-Edge Detect Enable register */
 | 
					
						
							|  |  |  | #define PFER	0x14	/* Power Manager Falling-Edge Detect Enable register */
 | 
					
						
							|  |  |  | #define PEDR	0x18	/* Power Manager Edge-Detect Status register */
 | 
					
						
							|  |  |  | #define PCFR	0x1c	/* Power Manager General Configuration register */
 | 
					
						
							|  |  |  | #define PGSR0	0x20	/* Power Manager GPIO Sleep-State register 0 */
 | 
					
						
							|  |  |  | #define PGSR1	0x24	/* Power Manager GPIO Sleep-State register 1 */
 | 
					
						
							|  |  |  | #define PGSR2	0x28	/* Power Manager GPIO Sleep-State register 2 */
 | 
					
						
							|  |  |  | #define PGSR3	0x2c	/* Power Manager GPIO Sleep-State register 3 */
 | 
					
						
							|  |  |  | #define RCSR	0x30	/* Reset Controller Status register */
 | 
					
						
							|  |  |  | #define PSLR	0x34	/* Power Manager Sleep Configuration register */
 | 
					
						
							|  |  |  | #define PTSR	0x38	/* Power Manager Standby Configuration register */
 | 
					
						
							|  |  |  | #define PVCR	0x40	/* Power Manager Voltage Change Control register */
 | 
					
						
							|  |  |  | #define PUCR	0x4c	/* Power Manager USIM Card Control/Status register */
 | 
					
						
							|  |  |  | #define PKWR	0x50	/* Power Manager Keyboard Wake-Up Enable register */
 | 
					
						
							|  |  |  | #define PKSR	0x54	/* Power Manager Keyboard Level-Detect Status */
 | 
					
						
							|  |  |  | #define PCMD0	0x80	/* Power Manager I2C Command register File 0 */
 | 
					
						
							|  |  |  | #define PCMD31	0xfc	/* Power Manager I2C Command register File 31 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case PMCR ... PCMD31: | 
					
						
							|  |  |  |         if (addr & 3) | 
					
						
							|  |  |  |             goto fail; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return s->pm_regs[addr >> 2]; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |     fail: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_pm_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case PMCR: | 
					
						
							| 
									
										
										
										
											2011-11-09 20:46:35 +00:00
										 |  |  |         /* Clear the write-one-to-clear bits... */ | 
					
						
							|  |  |  |         s->pm_regs[addr >> 2] &= ~(value & 0x2a); | 
					
						
							|  |  |  |         /* ...and set the plain r/w bits */ | 
					
						
							| 
									
										
										
										
											2011-11-13 14:18:39 +00:00
										 |  |  |         s->pm_regs[addr >> 2] &= ~0x15; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         s->pm_regs[addr >> 2] |= value & 0x15; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PSSR:	/* Read-clean registers */ | 
					
						
							|  |  |  |     case RCSR: | 
					
						
							|  |  |  |     case PKSR: | 
					
						
							|  |  |  |         s->pm_regs[addr >> 2] &= ~value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default:	/* Read-write registers */ | 
					
						
							| 
									
										
										
										
											2010-09-18 05:53:15 +00:00
										 |  |  |         if (!(addr & 3)) { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             s->pm_regs[addr >> 2] = value; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_pm_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_pm_read, | 
					
						
							|  |  |  |     .write = pxa2xx_pm_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 14:54:38 +01:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_pm = { | 
					
						
							|  |  |  |     .name = "pxa2xx_pm", | 
					
						
							|  |  |  |     .version_id = 0, | 
					
						
							|  |  |  |     .minimum_version_id = 0, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2010-12-02 14:54:38 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | #define CCCR	0x00	/* Core Clock Configuration register */
 | 
					
						
							|  |  |  | #define CKEN	0x04	/* Clock Enable register */
 | 
					
						
							|  |  |  | #define OSCC	0x08	/* Oscillator Configuration register */
 | 
					
						
							|  |  |  | #define CCSR	0x0c	/* Core Clock Status register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case CCCR: | 
					
						
							|  |  |  |     case CKEN: | 
					
						
							|  |  |  |     case OSCC: | 
					
						
							|  |  |  |         return s->cm_regs[addr >> 2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case CCSR: | 
					
						
							|  |  |  |         return s->cm_regs[CCCR >> 2] | (3 << 28); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_cm_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case CCCR: | 
					
						
							|  |  |  |     case CKEN: | 
					
						
							|  |  |  |         s->cm_regs[addr >> 2] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case OSCC: | 
					
						
							| 
									
										
										
										
											2007-05-08 19:20:04 +00:00
										 |  |  |         s->cm_regs[addr >> 2] &= ~0x6c; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         s->cm_regs[addr >> 2] |= value & 0x6e; | 
					
						
							| 
									
										
										
										
											2007-05-08 19:20:04 +00:00
										 |  |  |         if ((value >> 1) & 1)			/* OON */ | 
					
						
							|  |  |  |             s->cm_regs[addr >> 2] |= 1 << 0;	/* Oscillator is now stable */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_cm_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_cm_read, | 
					
						
							|  |  |  |     .write = pxa2xx_cm_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 14:31:14 +01:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_cm = { | 
					
						
							|  |  |  |     .name = "pxa2xx_cm", | 
					
						
							|  |  |  |     .version_id = 0, | 
					
						
							|  |  |  |     .minimum_version_id = 0, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2010-12-02 14:31:14 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4), | 
					
						
							|  |  |  |         VMSTATE_UINT32(clkcfg, PXA2xxState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(pmnc, PXA2xxState), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  |     return s->clkcfg; | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri, | 
					
						
							|  |  |  |                                 uint64_t value) | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							|  |  |  |     s->clkcfg = value & 0xf; | 
					
						
							|  |  |  |     if (value & 2) { | 
					
						
							|  |  |  |         printf("%s: CPU frequency change attempt\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, | 
					
						
							|  |  |  |                                  uint64_t value) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     static const char *pwrmode[8] = { | 
					
						
							|  |  |  |         "Normal", "Idle", "Deep-idle", "Standby", | 
					
						
							|  |  |  |         "Sleep", "reserved (!)", "reserved (!)", "Deep-sleep", | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     if (value & 8) { | 
					
						
							|  |  |  |         printf("%s: CPU voltage change attempt\n", __func__); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     switch (value & 7) { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |         /* Do nothing */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     case 1: | 
					
						
							|  |  |  |         /* Idle */ | 
					
						
							| 
									
										
										
										
											2014-03-10 14:56:29 +00:00
										 |  |  |         if (!(s->cm_regs[CCCR >> 2] & (1U << 31))) { /* CPDIS */ | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |             cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /* Fall through.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |         /* Deep-Idle */ | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |         cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |         s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */ | 
					
						
							|  |  |  |         goto message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 3: | 
					
						
							| 
									
										
										
										
											2014-02-26 17:20:06 +00:00
										 |  |  |         s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC; | 
					
						
							|  |  |  |         s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I; | 
					
						
							| 
									
										
										
										
											2014-12-11 12:07:50 +00:00
										 |  |  |         s->cpu->env.cp15.sctlr_ns = 0; | 
					
						
							| 
									
										
										
										
											2015-04-26 16:49:25 +01:00
										 |  |  |         s->cpu->env.cp15.cpacr_el1 = 0; | 
					
						
							| 
									
										
										
										
											2014-12-11 12:07:51 +00:00
										 |  |  |         s->cpu->env.cp15.ttbr0_el[1] = 0; | 
					
						
							| 
									
										
										
										
											2014-12-11 12:07:51 +00:00
										 |  |  |         s->cpu->env.cp15.dacr_ns = 0; | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |         s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */ | 
					
						
							|  |  |  |         s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * The scratch-pad register is almost universally used | 
					
						
							|  |  |  |          * for storing the return address on suspend.  For the | 
					
						
							|  |  |  |          * lack of a resuming bootloader, perform a jump | 
					
						
							|  |  |  |          * directly to that address. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         memset(s->cpu->env.regs, 0, 4 * 15); | 
					
						
							|  |  |  |         s->cpu->env.regs[15] = s->pm_regs[PSPR >> 2]; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |         buffer = 0xe59ff000; /* ldr     pc, [pc, #0] */ | 
					
						
							|  |  |  |         cpu_physical_memory_write(0, &buffer, 4); | 
					
						
							|  |  |  |         buffer = s->pm_regs[PSPR >> 2]; | 
					
						
							|  |  |  |         cpu_physical_memory_write(8, &buffer, 4); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |         /* Suspend */ | 
					
						
							| 
									
										
										
										
											2013-05-27 05:17:50 +02:00
										 |  |  |         cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |         goto message; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     message: | 
					
						
							|  |  |  |         printf("%s: machine entered %s mode\n", __func__, | 
					
						
							|  |  |  |                pwrmode[value & 7]); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri) | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  |     return s->pmnc; | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri, | 
					
						
							|  |  |  |                                 uint64_t value) | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							|  |  |  |     s->pmnc = value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  | static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri) | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     PXA2xxState *s = (PXA2xxState *)ri->opaque; | 
					
						
							|  |  |  |     if (s->pmnc & 1) { | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  |         return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-02-20 10:35:54 +00:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const ARMCPRegInfo pxa_cp_reginfo[] = { | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     /* cp14 crm==1: perf registers */ | 
					
						
							|  |  |  |     { .name = "CPPMNC", .cp = 14, .crn = 0, .crm = 1, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_IO, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .readfn = pxa2xx_cppmnc_read, .writefn = pxa2xx_cppmnc_write }, | 
					
						
							|  |  |  |     { .name = "CPCCNT", .cp = 14, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_IO, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .readfn = pxa2xx_cpccnt_read, .writefn = arm_cp_write_ignore }, | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     { .name = "CPINTEN", .cp = 14, .crn = 4, .crm = 1, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     { .name = "CPFLAG", .cp = 14, .crn = 5, .crm = 1, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     { .name = "CPEVTSEL", .cp = 14, .crn = 8, .crm = 1, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     /* cp14 crm==2: performance count registers */ | 
					
						
							|  |  |  |     { .name = "CPPMN0", .cp = 14, .crn = 0, .crm = 2, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							| 
									
										
										
										
											2013-02-02 15:13:02 +00:00
										 |  |  |     { .name = "CPPMN1", .cp = 14, .crn = 1, .crm = 2, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							|  |  |  |     { .name = "CPPMN2", .cp = 14, .crn = 2, .crm = 2, .opc1 = 0, .opc2 = 0, | 
					
						
							|  |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							|  |  |  |     { .name = "CPPMN3", .cp = 14, .crn = 2, .crm = 3, .opc1 = 0, .opc2 = 0, | 
					
						
							|  |  |  |       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     /* cp14 crn==6: CLKCFG */ | 
					
						
							|  |  |  |     { .name = "CLKCFG", .cp = 14, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_IO, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .readfn = pxa2xx_clkcfg_read, .writefn = pxa2xx_clkcfg_write }, | 
					
						
							|  |  |  |     /* cp14 crn==7: PWRMODE */ | 
					
						
							|  |  |  |     { .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0, | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |       .access = PL1_RW, .type = ARM_CP_IO, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |       .readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write }, | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pxa2xx_setup_cp14(PXA2xxState *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     define_arm_cp_regs_with_opaque(s->cpu, pxa_cp_reginfo, s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | #define MDCNFG		0x00	/* SDRAM Configuration register */
 | 
					
						
							|  |  |  | #define MDREFR		0x04	/* SDRAM Refresh Control register */
 | 
					
						
							|  |  |  | #define MSC0		0x08	/* Static Memory Control register 0 */
 | 
					
						
							|  |  |  | #define MSC1		0x0c	/* Static Memory Control register 1 */
 | 
					
						
							|  |  |  | #define MSC2		0x10	/* Static Memory Control register 2 */
 | 
					
						
							|  |  |  | #define MECR		0x14	/* Expansion Memory Bus Config register */
 | 
					
						
							|  |  |  | #define SXCNFG		0x1c	/* Synchronous Static Memory Config register */
 | 
					
						
							|  |  |  | #define MCMEM0		0x28	/* PC Card Memory Socket 0 Timing register */
 | 
					
						
							|  |  |  | #define MCMEM1		0x2c	/* PC Card Memory Socket 1 Timing register */
 | 
					
						
							|  |  |  | #define MCATT0		0x30	/* PC Card Attribute Socket 0 register */
 | 
					
						
							|  |  |  | #define MCATT1		0x34	/* PC Card Attribute Socket 1 register */
 | 
					
						
							|  |  |  | #define MCIO0		0x38	/* PC Card I/O Socket 0 Timing register */
 | 
					
						
							|  |  |  | #define MCIO1		0x3c	/* PC Card I/O Socket 1 Timing register */
 | 
					
						
							|  |  |  | #define MDMRS		0x40	/* SDRAM Mode Register Set Config register */
 | 
					
						
							|  |  |  | #define BOOT_DEF	0x44	/* Boot-time Default Configuration register */
 | 
					
						
							|  |  |  | #define ARB_CNTL	0x48	/* Arbiter Control register */
 | 
					
						
							|  |  |  | #define BSCNTR0		0x4c	/* Memory Buffer Strength Control register 0 */
 | 
					
						
							|  |  |  | #define BSCNTR1		0x50	/* Memory Buffer Strength Control register 1 */
 | 
					
						
							|  |  |  | #define LCDBSCNTR	0x54	/* LCD Buffer Strength Control register */
 | 
					
						
							|  |  |  | #define MDMRSLP		0x58	/* Low Power SDRAM Mode Set Config register */
 | 
					
						
							|  |  |  | #define BSCNTR2		0x5c	/* Memory Buffer Strength Control register 2 */
 | 
					
						
							|  |  |  | #define BSCNTR3		0x60	/* Memory Buffer Strength Control register 3 */
 | 
					
						
							|  |  |  | #define SA1110		0x64	/* SA-1110 Memory Compatibility register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case MDCNFG ... SA1110: | 
					
						
							|  |  |  |         if ((addr & 3) == 0) | 
					
						
							|  |  |  |             return s->mm_regs[addr >> 2]; | 
					
						
							| 
									
										
										
										
											2018-08-01 17:14:09 +02:00
										 |  |  |         /* fall through */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_mm_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case MDCNFG ... SA1110: | 
					
						
							|  |  |  |         if ((addr & 3) == 0) { | 
					
						
							|  |  |  |             s->mm_regs[addr >> 2] = value; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-11 14:18:44 +02:00
										 |  |  |         /* fallthrough */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_mm_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_mm_read, | 
					
						
							|  |  |  |     .write = pxa2xx_mm_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 14:36:57 +01:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_mm = { | 
					
						
							|  |  |  |     .name = "pxa2xx_mm", | 
					
						
							|  |  |  |     .version_id = 0, | 
					
						
							|  |  |  |     .minimum_version_id = 0, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2010-12-02 14:36:57 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  | #define TYPE_PXA2XX_SSP "pxa2xx-ssp"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxSSPState, PXA2XX_SSP) | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | /* Synchronous Serial Ports */ | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct PXA2xxSSPState { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     qemu_irq irq; | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     uint32_t enable; | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |     SSIBus *bus; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint32_t sscr[2]; | 
					
						
							|  |  |  |     uint32_t sspsp; | 
					
						
							|  |  |  |     uint32_t ssto; | 
					
						
							|  |  |  |     uint32_t ssitr; | 
					
						
							|  |  |  |     uint32_t sssr; | 
					
						
							|  |  |  |     uint8_t sstsa; | 
					
						
							|  |  |  |     uint8_t ssrsa; | 
					
						
							|  |  |  |     uint8_t ssacd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t rx_fifo[16]; | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     uint32_t rx_level; | 
					
						
							|  |  |  |     uint32_t rx_start; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static bool pxa2xx_ssp_vmstate_validate(void *opaque, int version_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PXA2xxSSPState *s = opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return s->rx_start < sizeof(s->rx_fifo); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const VMStateDescription vmstate_pxa2xx_ssp = { | 
					
						
							|  |  |  |     .name = "pxa2xx-ssp", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							|  |  |  |     .fields = (VMStateField[]) { | 
					
						
							|  |  |  |         VMSTATE_UINT32(enable, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32_ARRAY(sscr, PXA2xxSSPState, 2), | 
					
						
							|  |  |  |         VMSTATE_UINT32(sspsp, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(ssto, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(ssitr, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(sssr, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT8(sstsa, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT8(ssrsa, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT8(ssacd, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rx_level, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rx_start, PXA2xxSSPState), | 
					
						
							|  |  |  |         VMSTATE_VALIDATE("fifo is 16 bytes", pxa2xx_ssp_vmstate_validate), | 
					
						
							|  |  |  |         VMSTATE_UINT32_ARRAY(rx_fifo, PXA2xxSSPState, 16), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | #define SSCR0	0x00	/* SSP Control register 0 */
 | 
					
						
							|  |  |  | #define SSCR1	0x04	/* SSP Control register 1 */
 | 
					
						
							|  |  |  | #define SSSR	0x08	/* SSP Status register */
 | 
					
						
							|  |  |  | #define SSITR	0x0c	/* SSP Interrupt Test register */
 | 
					
						
							|  |  |  | #define SSDR	0x10	/* SSP Data register */
 | 
					
						
							|  |  |  | #define SSTO	0x28	/* SSP Time-Out register */
 | 
					
						
							|  |  |  | #define SSPSP	0x2c	/* SSP Programmable Serial Protocol register */
 | 
					
						
							|  |  |  | #define SSTSA	0x30	/* SSP TX Time Slot Active register */
 | 
					
						
							|  |  |  | #define SSRSA	0x34	/* SSP RX Time Slot Active register */
 | 
					
						
							|  |  |  | #define SSTSS	0x38	/* SSP Time Slot Status register */
 | 
					
						
							|  |  |  | #define SSACD	0x3c	/* SSP Audio Clock Divider register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Bitfields for above registers */ | 
					
						
							|  |  |  | #define SSCR0_SPI(x)	(((x) & 0x30) == 0x00)
 | 
					
						
							|  |  |  | #define SSCR0_SSP(x)	(((x) & 0x30) == 0x10)
 | 
					
						
							|  |  |  | #define SSCR0_UWIRE(x)	(((x) & 0x30) == 0x20)
 | 
					
						
							|  |  |  | #define SSCR0_PSP(x)	(((x) & 0x30) == 0x30)
 | 
					
						
							|  |  |  | #define SSCR0_SSE	(1 << 7)
 | 
					
						
							|  |  |  | #define SSCR0_RIM	(1 << 22)
 | 
					
						
							|  |  |  | #define SSCR0_TIM	(1 << 23)
 | 
					
						
							| 
									
										
										
										
											2014-03-10 14:56:29 +00:00
										 |  |  | #define SSCR0_MOD       (1U << 31)
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | #define SSCR0_DSS(x)	(((((x) >> 16) & 0x10) | ((x) & 0xf)) + 1)
 | 
					
						
							|  |  |  | #define SSCR1_RIE	(1 << 0)
 | 
					
						
							|  |  |  | #define SSCR1_TIE	(1 << 1)
 | 
					
						
							|  |  |  | #define SSCR1_LBM	(1 << 2)
 | 
					
						
							|  |  |  | #define SSCR1_MWDS	(1 << 5)
 | 
					
						
							|  |  |  | #define SSCR1_TFT(x)	((((x) >> 6) & 0xf) + 1)
 | 
					
						
							|  |  |  | #define SSCR1_RFT(x)	((((x) >> 10) & 0xf) + 1)
 | 
					
						
							|  |  |  | #define SSCR1_EFWR	(1 << 14)
 | 
					
						
							|  |  |  | #define SSCR1_PINTE	(1 << 18)
 | 
					
						
							|  |  |  | #define SSCR1_TINTE	(1 << 19)
 | 
					
						
							|  |  |  | #define SSCR1_RSRE	(1 << 20)
 | 
					
						
							|  |  |  | #define SSCR1_TSRE	(1 << 21)
 | 
					
						
							|  |  |  | #define SSCR1_EBCEI	(1 << 29)
 | 
					
						
							|  |  |  | #define SSITR_INT	(7 << 5)
 | 
					
						
							|  |  |  | #define SSSR_TNF	(1 << 2)
 | 
					
						
							|  |  |  | #define SSSR_RNE	(1 << 3)
 | 
					
						
							|  |  |  | #define SSSR_TFS	(1 << 5)
 | 
					
						
							|  |  |  | #define SSSR_RFS	(1 << 6)
 | 
					
						
							|  |  |  | #define SSSR_ROR	(1 << 7)
 | 
					
						
							|  |  |  | #define SSSR_PINT	(1 << 18)
 | 
					
						
							|  |  |  | #define SSSR_TINT	(1 << 19)
 | 
					
						
							|  |  |  | #define SSSR_EOC	(1 << 20)
 | 
					
						
							|  |  |  | #define SSSR_TUR	(1 << 21)
 | 
					
						
							|  |  |  | #define SSSR_BCE	(1 << 23)
 | 
					
						
							|  |  |  | #define SSSR_RW		0x00bc0080
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static void pxa2xx_ssp_int_update(PXA2xxSSPState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int level = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     level |= s->ssitr & SSITR_INT; | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_BCE)  &&  (s->sscr[1] & SSCR1_EBCEI); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_TUR)  && !(s->sscr[0] & SSCR0_TIM); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_EOC)  &&  (s->sssr & (SSSR_TINT | SSSR_PINT)); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_TINT) &&  (s->sscr[1] & SSCR1_TINTE); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_PINT) &&  (s->sscr[1] & SSCR1_PINTE); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_ROR)  && !(s->sscr[0] & SSCR0_RIM); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_RFS)  &&  (s->sscr[1] & SSCR1_RIE); | 
					
						
							|  |  |  |     level |= (s->sssr & SSSR_TFS)  &&  (s->sscr[1] & SSCR1_TIE); | 
					
						
							|  |  |  |     qemu_set_irq(s->irq, !!level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static void pxa2xx_ssp_fifo_update(PXA2xxSSPState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     s->sssr &= ~(0xf << 12);	/* Clear RFL */ | 
					
						
							|  |  |  |     s->sssr &= ~(0xf << 8);	/* Clear TFL */ | 
					
						
							| 
									
										
										
										
											2010-09-18 05:53:15 +00:00
										 |  |  |     s->sssr &= ~SSSR_TFS; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->sssr &= ~SSSR_TNF; | 
					
						
							|  |  |  |     if (s->enable) { | 
					
						
							|  |  |  |         s->sssr |= ((s->rx_level - 1) & 0xf) << 12; | 
					
						
							|  |  |  |         if (s->rx_level >= SSCR1_RFT(s->sscr[1])) | 
					
						
							|  |  |  |             s->sssr |= SSSR_RFS; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             s->sssr &= ~SSSR_RFS; | 
					
						
							|  |  |  |         if (s->rx_level) | 
					
						
							|  |  |  |             s->sssr |= SSSR_RNE; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             s->sssr &= ~SSSR_RNE; | 
					
						
							| 
									
										
										
										
											2010-09-18 05:53:15 +00:00
										 |  |  |         /* TX FIFO is never filled, so it is always in underrun
 | 
					
						
							|  |  |  |            condition if SSP is enabled */ | 
					
						
							|  |  |  |         s->sssr |= SSSR_TFS; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         s->sssr |= SSSR_TNF; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pxa2xx_ssp_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxSSPState *s = (PXA2xxSSPState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint32_t retval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case SSCR0: | 
					
						
							|  |  |  |         return s->sscr[0]; | 
					
						
							|  |  |  |     case SSCR1: | 
					
						
							|  |  |  |         return s->sscr[1]; | 
					
						
							|  |  |  |     case SSPSP: | 
					
						
							|  |  |  |         return s->sspsp; | 
					
						
							|  |  |  |     case SSTO: | 
					
						
							|  |  |  |         return s->ssto; | 
					
						
							|  |  |  |     case SSITR: | 
					
						
							|  |  |  |         return s->ssitr; | 
					
						
							|  |  |  |     case SSSR: | 
					
						
							|  |  |  |         return s->sssr | s->ssitr; | 
					
						
							|  |  |  |     case SSDR: | 
					
						
							|  |  |  |         if (!s->enable) | 
					
						
							|  |  |  |             return 0xffffffff; | 
					
						
							|  |  |  |         if (s->rx_level < 1) { | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |             printf("%s: SSP Rx Underrun\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             return 0xffffffff; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         s->rx_level --; | 
					
						
							|  |  |  |         retval = s->rx_fifo[s->rx_start ++]; | 
					
						
							|  |  |  |         s->rx_start &= 0xf; | 
					
						
							|  |  |  |         pxa2xx_ssp_fifo_update(s); | 
					
						
							|  |  |  |         return retval; | 
					
						
							|  |  |  |     case SSTSA: | 
					
						
							|  |  |  |         return s->sstsa; | 
					
						
							|  |  |  |     case SSRSA: | 
					
						
							|  |  |  |         return s->ssrsa; | 
					
						
							|  |  |  |     case SSTSS: | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     case SSACD: | 
					
						
							|  |  |  |         return s->ssacd; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_ssp_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                              uint64_t value64, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxSSPState *s = (PXA2xxSSPState *) opaque; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     uint32_t value = value64; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case SSCR0: | 
					
						
							|  |  |  |         s->sscr[0] = value & 0xc7ffffff; | 
					
						
							|  |  |  |         s->enable = value & SSCR0_SSE; | 
					
						
							|  |  |  |         if (value & SSCR0_MOD) | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |             printf("%s: Attempt to use network mode\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         if (s->enable && SSCR0_DSS(value) < 4) | 
					
						
							| 
									
										
										
										
											2020-11-02 17:55:23 +08:00
										 |  |  |             printf("%s: Wrong data size: %u bits\n", __func__, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                             SSCR0_DSS(value)); | 
					
						
							|  |  |  |         if (!(value & SSCR0_SSE)) { | 
					
						
							|  |  |  |             s->sssr = 0; | 
					
						
							|  |  |  |             s->ssitr = 0; | 
					
						
							|  |  |  |             s->rx_level = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         pxa2xx_ssp_fifo_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSCR1: | 
					
						
							|  |  |  |         s->sscr[1] = value; | 
					
						
							|  |  |  |         if (value & (SSCR1_LBM | SSCR1_EFWR)) | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |             printf("%s: Attempt to use SSP test mode\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         pxa2xx_ssp_fifo_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSPSP: | 
					
						
							|  |  |  |         s->sspsp = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSTO: | 
					
						
							|  |  |  |         s->ssto = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSITR: | 
					
						
							|  |  |  |         s->ssitr = value & SSITR_INT; | 
					
						
							|  |  |  |         pxa2xx_ssp_int_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSSR: | 
					
						
							|  |  |  |         s->sssr &= ~(value & SSSR_RW); | 
					
						
							|  |  |  |         pxa2xx_ssp_int_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSDR: | 
					
						
							|  |  |  |         if (SSCR0_UWIRE(s->sscr[0])) { | 
					
						
							|  |  |  |             if (s->sscr[1] & SSCR1_MWDS) | 
					
						
							|  |  |  |                 value &= 0xffff; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 value &= 0xff; | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |             /* Note how 32bits overflow does no harm here */ | 
					
						
							|  |  |  |             value &= (1 << SSCR0_DSS(s->sscr[0])) - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Data goes from here to the Tx FIFO and is shifted out from
 | 
					
						
							|  |  |  |          * there directly to the slave, no need to buffer it. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (s->enable) { | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |             uint32_t readval; | 
					
						
							|  |  |  |             readval = ssi_transfer(s->bus, value); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             if (s->rx_level < 0x10) { | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |                 s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = readval; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                 s->sssr |= SSSR_ROR; | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         pxa2xx_ssp_fifo_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSTSA: | 
					
						
							|  |  |  |         s->sstsa = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSRSA: | 
					
						
							|  |  |  |         s->ssrsa = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSACD: | 
					
						
							|  |  |  |         s->ssacd = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_ssp_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_ssp_read, | 
					
						
							|  |  |  |     .write = pxa2xx_ssp_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static void pxa2xx_ssp_reset(DeviceState *d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PXA2xxSSPState *s = PXA2XX_SSP(d); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->enable = 0; | 
					
						
							|  |  |  |     s->sscr[0] = s->sscr[1] = 0; | 
					
						
							|  |  |  |     s->sspsp = 0; | 
					
						
							|  |  |  |     s->ssto = 0; | 
					
						
							|  |  |  |     s->ssitr = 0; | 
					
						
							|  |  |  |     s->sssr = 0; | 
					
						
							|  |  |  |     s->sstsa = 0; | 
					
						
							|  |  |  |     s->ssrsa = 0; | 
					
						
							|  |  |  |     s->ssacd = 0; | 
					
						
							|  |  |  |     s->rx_start = s->rx_level = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-20 17:32:29 +01:00
										 |  |  | static void pxa2xx_ssp_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-20 17:32:29 +01:00
										 |  |  |     DeviceState *dev = DEVICE(obj); | 
					
						
							|  |  |  |     PXA2xxSSPState *s = PXA2XX_SSP(obj); | 
					
						
							|  |  |  |     SysBusDevice *sbd = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |     sysbus_init_irq(sbd, &s->irq); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-20 17:32:29 +01:00
										 |  |  |     memory_region_init_io(&s->iomem, obj, &pxa2xx_ssp_ops, s, | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |                           "pxa2xx-ssp", 0x1000); | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |     sysbus_init_mmio(sbd, &s->iomem); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |     s->bus = ssi_create_bus(dev, "ssi"); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | /* Real-Time Clock */ | 
					
						
							|  |  |  | #define RCNR		0x00	/* RTC Counter register */
 | 
					
						
							|  |  |  | #define RTAR		0x04	/* RTC Alarm register */
 | 
					
						
							|  |  |  | #define RTSR		0x08	/* RTC Status register */
 | 
					
						
							|  |  |  | #define RTTR		0x0c	/* RTC Timer Trim register */
 | 
					
						
							|  |  |  | #define RDCR		0x10	/* RTC Day Counter register */
 | 
					
						
							|  |  |  | #define RYCR		0x14	/* RTC Year Counter register */
 | 
					
						
							|  |  |  | #define RDAR1		0x18	/* RTC Wristwatch Day Alarm register 1 */
 | 
					
						
							|  |  |  | #define RYAR1		0x1c	/* RTC Wristwatch Year Alarm register 1 */
 | 
					
						
							|  |  |  | #define RDAR2		0x20	/* RTC Wristwatch Day Alarm register 2 */
 | 
					
						
							|  |  |  | #define RYAR2		0x24	/* RTC Wristwatch Year Alarm register 2 */
 | 
					
						
							|  |  |  | #define SWCR		0x28	/* RTC Stopwatch Counter register */
 | 
					
						
							|  |  |  | #define SWAR1		0x2c	/* RTC Stopwatch Alarm register 1 */
 | 
					
						
							|  |  |  | #define SWAR2		0x30	/* RTC Stopwatch Alarm register 2 */
 | 
					
						
							|  |  |  | #define RTCPICR		0x34	/* RTC Periodic Interrupt Counter register */
 | 
					
						
							|  |  |  | #define PIAR		0x38	/* RTC Periodic Interrupt Alarm register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  | #define TYPE_PXA2XX_RTC "pxa2xx_rtc"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxRTCState, PXA2XX_RTC) | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct PXA2xxRTCState { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     uint32_t rttr; | 
					
						
							|  |  |  |     uint32_t rtsr; | 
					
						
							|  |  |  |     uint32_t rtar; | 
					
						
							|  |  |  |     uint32_t rdar1; | 
					
						
							|  |  |  |     uint32_t rdar2; | 
					
						
							|  |  |  |     uint32_t ryar1; | 
					
						
							|  |  |  |     uint32_t ryar2; | 
					
						
							|  |  |  |     uint32_t swar1; | 
					
						
							|  |  |  |     uint32_t swar2; | 
					
						
							|  |  |  |     uint32_t piar; | 
					
						
							|  |  |  |     uint32_t last_rcnr; | 
					
						
							|  |  |  |     uint32_t last_rdcr; | 
					
						
							|  |  |  |     uint32_t last_rycr; | 
					
						
							|  |  |  |     uint32_t last_swcr; | 
					
						
							|  |  |  |     uint32_t last_rtcpicr; | 
					
						
							|  |  |  |     int64_t last_hz; | 
					
						
							|  |  |  |     int64_t last_sw; | 
					
						
							|  |  |  |     int64_t last_pi; | 
					
						
							|  |  |  |     QEMUTimer *rtc_hz; | 
					
						
							|  |  |  |     QEMUTimer *rtc_rdal1; | 
					
						
							|  |  |  |     QEMUTimer *rtc_rdal2; | 
					
						
							|  |  |  |     QEMUTimer *rtc_swal1; | 
					
						
							|  |  |  |     QEMUTimer *rtc_swal2; | 
					
						
							|  |  |  |     QEMUTimer *rtc_pi; | 
					
						
							|  |  |  |     qemu_irq rtc_irq; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |     qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |     int64_t rt = qemu_clock_get_ms(rtc_clock); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->last_rcnr += ((rt - s->last_hz) << 15) / | 
					
						
							|  |  |  |             (1000 * ((s->rttr & 0xffff) + 1)); | 
					
						
							|  |  |  |     s->last_rdcr += ((rt - s->last_hz) << 15) / | 
					
						
							|  |  |  |             (1000 * ((s->rttr & 0xffff) + 1)); | 
					
						
							|  |  |  |     s->last_hz = rt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |     int64_t rt = qemu_clock_get_ms(rtc_clock); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     if (s->rtsr & (1 << 12)) | 
					
						
							|  |  |  |         s->last_swcr += (rt - s->last_sw) / 10; | 
					
						
							|  |  |  |     s->last_sw = rt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |     int64_t rt = qemu_clock_get_ms(rtc_clock); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     if (s->rtsr & (1 << 15)) | 
					
						
							|  |  |  |         s->last_swcr += rt - s->last_pi; | 
					
						
							|  |  |  |     s->last_pi = rt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                 uint32_t rtsr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_hz, s->last_hz + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                 (((s->rtar - s->last_rcnr) * 1000 * | 
					
						
							|  |  |  |                   ((s->rttr & 0xffff) + 1)) >> 15)); | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_hz); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((rtsr & (1 << 5)) && !(rtsr & (1 << 4))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_rdal1, s->last_hz + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                 (((s->rdar1 - s->last_rdcr) * 1000 * | 
					
						
							|  |  |  |                   ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */ | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_rdal1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((rtsr & (1 << 7)) && !(rtsr & (1 << 6))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_rdal2, s->last_hz + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                 (((s->rdar2 - s->last_rdcr) * 1000 * | 
					
						
							|  |  |  |                   ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */ | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_rdal2); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((rtsr & 0x1200) == 0x1200 && !(rtsr & (1 << 8))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_swal1, s->last_sw + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                         (s->swar1 - s->last_swcr) * 10); /* TODO: fixup */ | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_swal1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((rtsr & 0x1800) == 0x1800 && !(rtsr & (1 << 10))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_swal2, s->last_sw + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                         (s->swar2 - s->last_swcr) * 10); /* TODO: fixup */ | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_swal2); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((rtsr & 0xc000) == 0xc000 && !(rtsr & (1 << 13))) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_mod(s->rtc_pi, s->last_pi + | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |                         (s->piar & 0xffff) - s->last_rtcpicr); | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |         timer_del(s->rtc_pi); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_hz_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 0); | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_rdal1_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 4); | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_rdal2_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 6); | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_swal1_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 8); | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_swal2_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 10); | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void pxa2xx_rtc_pi_tick(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->rtsr |= (1 << 13); | 
					
						
							|  |  |  |     pxa2xx_rtc_piupdate(s); | 
					
						
							|  |  |  |     s->last_rtcpicr = 0; | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |     pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case RTTR: | 
					
						
							|  |  |  |         return s->rttr; | 
					
						
							|  |  |  |     case RTSR: | 
					
						
							|  |  |  |         return s->rtsr; | 
					
						
							|  |  |  |     case RTAR: | 
					
						
							|  |  |  |         return s->rtar; | 
					
						
							|  |  |  |     case RDAR1: | 
					
						
							|  |  |  |         return s->rdar1; | 
					
						
							|  |  |  |     case RDAR2: | 
					
						
							|  |  |  |         return s->rdar2; | 
					
						
							|  |  |  |     case RYAR1: | 
					
						
							|  |  |  |         return s->ryar1; | 
					
						
							|  |  |  |     case RYAR2: | 
					
						
							|  |  |  |         return s->ryar2; | 
					
						
							|  |  |  |     case SWAR1: | 
					
						
							|  |  |  |         return s->swar1; | 
					
						
							|  |  |  |     case SWAR2: | 
					
						
							|  |  |  |         return s->swar2; | 
					
						
							|  |  |  |     case PIAR: | 
					
						
							|  |  |  |         return s->piar; | 
					
						
							|  |  |  |     case RCNR: | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |         return s->last_rcnr + | 
					
						
							|  |  |  |             ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) / | 
					
						
							|  |  |  |             (1000 * ((s->rttr & 0xffff) + 1)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     case RDCR: | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |         return s->last_rdcr + | 
					
						
							|  |  |  |             ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) / | 
					
						
							|  |  |  |             (1000 * ((s->rttr & 0xffff) + 1)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     case RYCR: | 
					
						
							|  |  |  |         return s->last_rycr; | 
					
						
							|  |  |  |     case SWCR: | 
					
						
							|  |  |  |         if (s->rtsr & (1 << 12)) | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |             return s->last_swcr + | 
					
						
							|  |  |  |                 (qemu_clock_get_ms(rtc_clock) - s->last_sw) / 10; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |             return s->last_swcr; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_rtc_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                              uint64_t value64, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     uint32_t value = value64; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case RTTR: | 
					
						
							| 
									
										
										
										
											2014-03-10 14:56:29 +00:00
										 |  |  |         if (!(s->rttr & (1U << 31))) { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             pxa2xx_rtc_hzupdate(s); | 
					
						
							|  |  |  |             s->rttr = value; | 
					
						
							|  |  |  |             pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RTSR: | 
					
						
							|  |  |  |         if ((s->rtsr ^ value) & (1 << 15)) | 
					
						
							|  |  |  |             pxa2xx_rtc_piupdate(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((s->rtsr ^ value) & (1 << 12)) | 
					
						
							|  |  |  |             pxa2xx_rtc_swupdate(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (((s->rtsr ^ value) & 0x4aac) | (value & ~0xdaac)) | 
					
						
							|  |  |  |             pxa2xx_rtc_alarm_update(s, value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s->rtsr = (value & 0xdaac) | (s->rtsr & ~(value & ~0xdaac)); | 
					
						
							|  |  |  |         pxa2xx_rtc_int_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RTAR: | 
					
						
							|  |  |  |         s->rtar = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RDAR1: | 
					
						
							|  |  |  |         s->rdar1 = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RDAR2: | 
					
						
							|  |  |  |         s->rdar2 = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RYAR1: | 
					
						
							|  |  |  |         s->ryar1 = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RYAR2: | 
					
						
							|  |  |  |         s->ryar2 = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SWAR1: | 
					
						
							|  |  |  |         pxa2xx_rtc_swupdate(s); | 
					
						
							|  |  |  |         s->swar1 = value; | 
					
						
							|  |  |  |         s->last_swcr = 0; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SWAR2: | 
					
						
							|  |  |  |         s->swar2 = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PIAR: | 
					
						
							|  |  |  |         s->piar = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RCNR: | 
					
						
							|  |  |  |         pxa2xx_rtc_hzupdate(s); | 
					
						
							|  |  |  |         s->last_rcnr = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RDCR: | 
					
						
							|  |  |  |         pxa2xx_rtc_hzupdate(s); | 
					
						
							|  |  |  |         s->last_rdcr = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RYCR: | 
					
						
							|  |  |  |         s->last_rycr = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SWCR: | 
					
						
							|  |  |  |         pxa2xx_rtc_swupdate(s); | 
					
						
							|  |  |  |         s->last_swcr = value; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case RTCPICR: | 
					
						
							|  |  |  |         pxa2xx_rtc_piupdate(s); | 
					
						
							|  |  |  |         s->last_rtcpicr = value & 0xffff; | 
					
						
							|  |  |  |         pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_rtc_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_rtc_read, | 
					
						
							|  |  |  |     .write = pxa2xx_rtc_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  | static void pxa2xx_rtc_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  |     PXA2xxRTCState *s = PXA2XX_RTC(obj); | 
					
						
							|  |  |  |     SysBusDevice *dev = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2008-02-17 11:42:19 +00:00
										 |  |  |     struct tm tm; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     int wom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->rttr = 0x7fff; | 
					
						
							|  |  |  |     s->rtsr = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-17 11:42:19 +00:00
										 |  |  |     qemu_get_timedate(&tm, 0); | 
					
						
							|  |  |  |     wom = ((tm.tm_mday - 1) / 7) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 21:34:52 +00:00
										 |  |  |     s->last_rcnr = (uint32_t) mktimegm(&tm); | 
					
						
							| 
									
										
										
										
											2008-02-17 11:42:19 +00:00
										 |  |  |     s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) | | 
					
						
							|  |  |  |             (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec; | 
					
						
							|  |  |  |     s->last_rycr = ((tm.tm_year + 1900) << 9) | | 
					
						
							|  |  |  |             ((tm.tm_mon + 1) << 5) | tm.tm_mday; | 
					
						
							|  |  |  |     s->last_swcr = (tm.tm_hour << 19) | | 
					
						
							|  |  |  |             (tm.tm_min << 13) | (tm.tm_sec << 7); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->last_rtcpicr = 0; | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |     s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-05 16:09:15 +00:00
										 |  |  |     sysbus_init_irq(dev, &s->rtc_irq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s, | 
					
						
							|  |  |  |                           "pxa2xx-rtc", 0x10000); | 
					
						
							|  |  |  |     sysbus_init_mmio(dev, &s->iomem); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pxa2xx_rtc_realize(DeviceState *dev, Error **errp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PXA2xxRTCState *s = PXA2XX_RTC(dev); | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:04 +01:00
										 |  |  |     s->rtc_hz    = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick,    s); | 
					
						
							|  |  |  |     s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s); | 
					
						
							|  |  |  |     s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s); | 
					
						
							|  |  |  |     s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s); | 
					
						
							|  |  |  |     s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s); | 
					
						
							|  |  |  |     s->rtc_pi    = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick,    s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-25 12:29:12 +01:00
										 |  |  | static int pxa2xx_rtc_pre_save(void *opaque) | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  |     pxa2xx_rtc_hzupdate(s); | 
					
						
							|  |  |  |     pxa2xx_rtc_piupdate(s); | 
					
						
							|  |  |  |     pxa2xx_rtc_swupdate(s); | 
					
						
							| 
									
										
										
										
											2017-09-25 12:29:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static int pxa2xx_rtc_post_load(void *opaque, int version_id) | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |     PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     pxa2xx_rtc_alarm_update(s, s->rtsr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_rtc_regs = { | 
					
						
							|  |  |  |     .name = "pxa2xx_rtc", | 
					
						
							|  |  |  |     .version_id = 0, | 
					
						
							|  |  |  |     .minimum_version_id = 0, | 
					
						
							|  |  |  |     .pre_save = pxa2xx_rtc_pre_save, | 
					
						
							|  |  |  |     .post_load = pxa2xx_rtc_post_load, | 
					
						
							|  |  |  |     .fields = (VMStateField[]) { | 
					
						
							|  |  |  |         VMSTATE_UINT32(rttr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rtsr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rtar, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rdar1, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rdar2, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(ryar1, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(ryar2, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(swar1, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(swar2, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(piar, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(last_rcnr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(last_rdcr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(last_rycr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(last_swcr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_INT64(last_hz, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_INT64(last_sw, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_INT64(last_pi, PXA2xxRTCState), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST(), | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void pxa2xx_rtc_sysbus_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->desc = "PXA2xx RTC Controller"; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_pxa2xx_rtc_regs; | 
					
						
							| 
									
										
										
										
											2020-03-05 16:09:15 +00:00
										 |  |  |     dc->realize = pxa2xx_rtc_realize; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo pxa2xx_rtc_sysbus_info = { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  |     .name          = TYPE_PXA2XX_RTC, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PXA2xxRTCState), | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  |     .instance_init = pxa2xx_rtc_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = pxa2xx_rtc_sysbus_class_init, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | /* I2C Interface */ | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CSlaveState, PXA2XX_I2C_SLAVE) | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct PXA2xxI2CSlaveState { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     I2CSlave parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     PXA2xxI2CState *host; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | struct PXA2xxI2CState { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     PXA2xxI2CSlaveState *slave; | 
					
						
							| 
									
										
										
										
											2013-08-03 00:18:51 +02:00
										 |  |  |     I2CBus *bus; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     qemu_irq irq; | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  |     uint32_t offset; | 
					
						
							|  |  |  |     uint32_t region_size; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint16_t control; | 
					
						
							|  |  |  |     uint16_t status; | 
					
						
							|  |  |  |     uint8_t ibmr; | 
					
						
							|  |  |  |     uint8_t data; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define IBMR	0x80	/* I2C Bus Monitor register */
 | 
					
						
							|  |  |  | #define IDBR	0x88	/* I2C Data Buffer register */
 | 
					
						
							|  |  |  | #define ICR	0x90	/* I2C Control register */
 | 
					
						
							|  |  |  | #define ISR	0x98	/* I2C Status register */
 | 
					
						
							|  |  |  | #define ISAR	0xa0	/* I2C Slave Address register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static void pxa2xx_i2c_update(PXA2xxI2CState *s) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     uint16_t level = 0; | 
					
						
							|  |  |  |     level |= s->status & s->control & (1 << 10);		/* BED */ | 
					
						
							|  |  |  |     level |= (s->status & (1 << 7)) && (s->control & (1 << 9));	/* IRF */ | 
					
						
							|  |  |  |     level |= (s->status & (1 << 6)) && (s->control & (1 << 8));	/* ITE */ | 
					
						
							|  |  |  |     level |= s->status & (1 << 9);				/* SAD */ | 
					
						
							|  |  |  |     qemu_set_irq(s->irq, !!level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* These are only stubs now.  */ | 
					
						
							| 
									
										
										
										
											2017-01-09 11:40:20 +00:00
										 |  |  | static int pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     PXA2xxI2CState *s = slave->host; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (event) { | 
					
						
							|  |  |  |     case I2C_START_SEND: | 
					
						
							|  |  |  |         s->status |= (1 << 9);				/* set SAD */ | 
					
						
							|  |  |  |         s->status &= ~(1 << 0);				/* clear RWM */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case I2C_START_RECV: | 
					
						
							|  |  |  |         s->status |= (1 << 9);				/* set SAD */ | 
					
						
							|  |  |  |         s->status |= 1 << 0;				/* set RWM */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case I2C_FINISH: | 
					
						
							|  |  |  |         s->status |= (1 << 4);				/* set SSD */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case I2C_NACK: | 
					
						
							|  |  |  |         s->status |= 1 << 1;				/* set ACKNAK */ | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2022-06-30 09:21:14 +02:00
										 |  |  |     default: | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     pxa2xx_i2c_update(s); | 
					
						
							| 
									
										
										
										
											2017-01-09 11:40:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 11:50:50 -06:00
										 |  |  | static uint8_t pxa2xx_i2c_rx(I2CSlave *i2c) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     PXA2xxI2CState *s = slave->host; | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) { | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (s->status & (1 << 0)) {			/* RWM */ | 
					
						
							|  |  |  |         s->status |= 1 << 6;			/* set ITE */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pxa2xx_i2c_update(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return s->data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 20:28:27 -06:00
										 |  |  | static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     PXA2xxI2CState *s = slave->host; | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) { | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!(s->status & (1 << 0))) {		/* RWM */ | 
					
						
							|  |  |  |         s->status |= 1 << 7;			/* set IRF */ | 
					
						
							|  |  |  |         s->data = data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pxa2xx_i2c_update(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxI2CState *s = (PXA2xxI2CState *) opaque; | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     I2CSlave *slave; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-07 01:49:28 +00:00
										 |  |  |     addr -= s->offset; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case ICR: | 
					
						
							|  |  |  |         return s->control; | 
					
						
							|  |  |  |     case ISR: | 
					
						
							|  |  |  |         return s->status | (i2c_bus_busy(s->bus) << 2); | 
					
						
							|  |  |  |     case ISAR: | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |         slave = I2C_SLAVE(s->slave); | 
					
						
							|  |  |  |         return slave->address; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     case IDBR: | 
					
						
							|  |  |  |         return s->data; | 
					
						
							|  |  |  |     case IBMR: | 
					
						
							|  |  |  |         if (s->status & (1 << 2)) | 
					
						
							|  |  |  |             s->ibmr ^= 3;	/* Fake SCL and SDA pin changes */ | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             s->ibmr = 0; | 
					
						
							|  |  |  |         return s->ibmr; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_i2c_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                              uint64_t value64, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxI2CState *s = (PXA2xxI2CState *) opaque; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     uint32_t value = value64; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     int ack; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-07 01:49:28 +00:00
										 |  |  |     addr -= s->offset; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case ICR: | 
					
						
							|  |  |  |         s->control = value & 0xfff7; | 
					
						
							|  |  |  |         if ((value & (1 << 3)) && (value & (1 << 6))) {	/* TB and IUE */ | 
					
						
							|  |  |  |             /* TODO: slave mode */ | 
					
						
							|  |  |  |             if (value & (1 << 0)) {			/* START condition */ | 
					
						
							|  |  |  |                 if (s->data & 1) | 
					
						
							|  |  |  |                     s->status |= 1 << 0;		/* set RWM */ | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     s->status &= ~(1 << 0);		/* clear RWM */ | 
					
						
							|  |  |  |                 ack = !i2c_start_transfer(s->bus, s->data >> 1, s->data & 1); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 if (s->status & (1 << 0)) {		/* RWM */ | 
					
						
							|  |  |  |                     s->data = i2c_recv(s->bus); | 
					
						
							|  |  |  |                     if (value & (1 << 2))		/* ACKNAK */ | 
					
						
							|  |  |  |                         i2c_nack(s->bus); | 
					
						
							|  |  |  |                     ack = 1; | 
					
						
							|  |  |  |                 } else | 
					
						
							|  |  |  |                     ack = !i2c_send(s->bus, s->data); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (value & (1 << 1))			/* STOP condition */ | 
					
						
							|  |  |  |                 i2c_end_transfer(s->bus); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (ack) { | 
					
						
							|  |  |  |                 if (value & (1 << 0))			/* START condition */ | 
					
						
							|  |  |  |                     s->status |= 1 << 6;		/* set ITE */ | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     if (s->status & (1 << 0))		/* RWM */ | 
					
						
							|  |  |  |                         s->status |= 1 << 7;		/* set IRF */ | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         s->status |= 1 << 6;		/* set ITE */ | 
					
						
							|  |  |  |                 s->status &= ~(1 << 1);			/* clear ACKNAK */ | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 s->status |= 1 << 6;			/* set ITE */ | 
					
						
							|  |  |  |                 s->status |= 1 << 10;			/* set BED */ | 
					
						
							|  |  |  |                 s->status |= 1 << 1;			/* set ACKNAK */ | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!(value & (1 << 3)) && (value & (1 << 6)))	/* !TB and IUE */ | 
					
						
							|  |  |  |             if (value & (1 << 4))			/* MA */ | 
					
						
							|  |  |  |                 i2c_end_transfer(s->bus); | 
					
						
							|  |  |  |         pxa2xx_i2c_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ISR: | 
					
						
							|  |  |  |         s->status &= ~(value & 0x07f0); | 
					
						
							|  |  |  |         pxa2xx_i2c_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ISAR: | 
					
						
							| 
									
										
										
										
											2021-06-17 13:53:31 +02:00
										 |  |  |         i2c_slave_set_address(I2C_SLAVE(s->slave), value & 0x7f); | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case IDBR: | 
					
						
							|  |  |  |         s->data = value & 0xff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_i2c_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_i2c_read, | 
					
						
							|  |  |  |     .write = pxa2xx_i2c_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:34 +02:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_i2c_slave = { | 
					
						
							|  |  |  |     .name = "pxa2xx_i2c_slave", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |         VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState), | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:34 +02:00
										 |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:34 +02:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_i2c = { | 
					
						
							|  |  |  |     .name = "pxa2xx_i2c", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:34 +02:00
										 |  |  |         VMSTATE_UINT16(control, PXA2xxI2CState), | 
					
						
							|  |  |  |         VMSTATE_UINT16(status, PXA2xxI2CState), | 
					
						
							|  |  |  |         VMSTATE_UINT8(ibmr, PXA2xxI2CState), | 
					
						
							|  |  |  |         VMSTATE_UINT8(data, PXA2xxI2CState), | 
					
						
							|  |  |  |         VMSTATE_STRUCT_POINTER(slave, PXA2xxI2CState, | 
					
						
							| 
									
										
										
										
											2014-01-01 21:56:57 +00:00
										 |  |  |                                vmstate_pxa2xx_i2c_slave, PXA2xxI2CSlaveState), | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:34 +02:00
										 |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data) | 
					
						
							| 
									
										
										
										
											2011-12-04 20:39:20 -06:00
										 |  |  | { | 
					
						
							|  |  |  |     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     k->event = pxa2xx_i2c_event; | 
					
						
							|  |  |  |     k->recv = pxa2xx_i2c_rx; | 
					
						
							|  |  |  |     k->send = pxa2xx_i2c_tx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo pxa2xx_i2c_slave_info = { | 
					
						
							| 
									
										
										
										
											2013-12-19 21:44:53 +01:00
										 |  |  |     .name          = TYPE_PXA2XX_I2C_SLAVE, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_I2C_SLAVE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PXA2xxI2CSlaveState), | 
					
						
							|  |  |  |     .class_init    = pxa2xx_i2c_slave_class_init, | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base, | 
					
						
							| 
									
										
										
										
											2008-12-07 01:49:28 +00:00
										 |  |  |                 qemu_irq irq, uint32_t region_size) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     DeviceState *dev; | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  |     SysBusDevice *i2c_dev; | 
					
						
							|  |  |  |     PXA2xxI2CState *s; | 
					
						
							| 
									
										
										
										
											2013-08-03 00:18:51 +02:00
										 |  |  |     I2CBus *i2cbus; | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion.  More to come in
this series.
Coccinelle script:
    @ depends on !(file in "hw/arm/highbank.c")@
    expression bus, type_name, dev, expr;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr;
    identifier DOWN;
    @@
    -    dev = DOWN(qdev_create(bus, type_name));
    +    dev = DOWN(qdev_new(type_name));
         ... when != dev = expr
    -    qdev_init_nofail(DEVICE(dev));
    +    qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
    @@
    expression bus, type_name, expr;
    identifier dev;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr, errp;
    symbol true;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
    @@
    expression bus, type_name, expr, errp;
    identifier dev;
    symbol true;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name.  Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:31:58 +02:00
										 |  |  |     dev = qdev_new(TYPE_PXA2XX_I2C); | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     qdev_prop_set_uint32(dev, "size", region_size + 1); | 
					
						
							|  |  |  |     qdev_prop_set_uint32(dev, "offset", base & region_size); | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     i2c_dev = SYS_BUS_DEVICE(dev); | 
					
						
							| 
									
										
											  
											
												sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
    @@
    expression dev, errp;
    @@
    -    qdev_realize(DEVICE(dev), NULL, errp);
    +    sysbus_realize(SYS_BUS_DEVICE(dev), errp);
    @@
    expression sysbus_dev, dev, errp;
    @@
    +    sysbus_dev = SYS_BUS_DEVICE(dev);
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    -    sysbus_dev = SYS_BUS_DEVICE(dev);
    @@
    expression sysbus_dev, dev, errp;
    expression expr;
    @@
         sysbus_dev = SYS_BUS_DEVICE(dev);
         ... when != dev = expr;
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(DEVICE(dev), NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:32:34 +02:00
										 |  |  |     sysbus_realize_and_unref(i2c_dev, &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  |     sysbus_mmio_map(i2c_dev, 0, base & ~region_size); | 
					
						
							|  |  |  |     sysbus_connect_irq(i2c_dev, 0, irq); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     s = PXA2XX_I2C(i2c_dev); | 
					
						
							| 
									
										
										
										
											2008-07-01 23:16:53 +00:00
										 |  |  |     /* FIXME: Should the slave device really be on a separate bus?  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:05:01 +02:00
										 |  |  |     i2cbus = i2c_init_bus(dev, "dummy"); | 
					
						
							| 
									
										
										
										
											2020-07-06 00:41:53 +02:00
										 |  |  |     s->slave = PXA2XX_I2C_SLAVE(i2c_slave_create_simple(i2cbus, | 
					
						
							|  |  |  |                                                         TYPE_PXA2XX_I2C_SLAVE, | 
					
						
							|  |  |  |                                                         0)); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  |     s->slave->host = s; | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  | static void pxa2xx_i2c_initfn(Object *obj) | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  |     DeviceState *dev = DEVICE(obj); | 
					
						
							|  |  |  |     PXA2xxI2CState *s = PXA2XX_I2C(obj); | 
					
						
							|  |  |  |     SysBusDevice *sbd = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 19:22:18 +01:00
										 |  |  |     s->bus = i2c_init_bus(dev, NULL); | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  |     memory_region_init_io(&s->iomem, obj, &pxa2xx_i2c_ops, s, | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |                           "pxa2xx-i2c", s->region_size); | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     sysbus_init_mmio(sbd, &s->iomem); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->irq); | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-03 00:18:51 +02:00
										 |  |  | I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s) | 
					
						
							| 
									
										
										
										
											2007-05-23 21:47:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return s->bus; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static Property pxa2xx_i2c_properties[] = { | 
					
						
							|  |  |  |     DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000), | 
					
						
							|  |  |  |     DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0), | 
					
						
							|  |  |  |     DEFINE_PROP_END_OF_LIST(), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pxa2xx_i2c_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->desc = "PXA2xx I2C Bus Controller"; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_pxa2xx_i2c; | 
					
						
							| 
									
										
										
										
											2020-01-10 19:30:32 +04:00
										 |  |  |     device_class_set_props(dc, pxa2xx_i2c_properties); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo pxa2xx_i2c_info = { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:56:59 +02:00
										 |  |  |     .name          = TYPE_PXA2XX_I2C, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PXA2xxI2CState), | 
					
						
							| 
									
										
										
										
											2016-03-07 15:05:45 +08:00
										 |  |  |     .instance_init = pxa2xx_i2c_initfn, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = pxa2xx_i2c_class_init, | 
					
						
							| 
									
										
										
										
											2011-02-11 23:57:39 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | /* PXA Inter-IC Sound Controller */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     i2s->rx_len = 0; | 
					
						
							|  |  |  |     i2s->tx_len = 0; | 
					
						
							|  |  |  |     i2s->fifo_len = 0; | 
					
						
							|  |  |  |     i2s->clk = 0x1a; | 
					
						
							|  |  |  |     i2s->control[0] = 0x00; | 
					
						
							|  |  |  |     i2s->control[1] = 0x00; | 
					
						
							|  |  |  |     i2s->status = 0x00; | 
					
						
							|  |  |  |     i2s->mask = 0x00; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SACR_TFTH(val)	((val >> 8) & 0xf)
 | 
					
						
							|  |  |  | #define SACR_RFTH(val)	((val >> 12) & 0xf)
 | 
					
						
							|  |  |  | #define SACR_DREC(val)	(val & (1 << 3))
 | 
					
						
							|  |  |  | #define SACR_DPRL(val)	(val & (1 << 4))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int rfs, tfs; | 
					
						
							|  |  |  |     rfs = SACR_RFTH(i2s->control[0]) < i2s->rx_len && | 
					
						
							|  |  |  |             !SACR_DREC(i2s->control[1]); | 
					
						
							|  |  |  |     tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) && | 
					
						
							|  |  |  |             i2s->enable && !SACR_DPRL(i2s->control[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |     qemu_set_irq(i2s->rx_dma, rfs); | 
					
						
							|  |  |  |     qemu_set_irq(i2s->tx_dma, tfs); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     i2s->status &= 0xe0; | 
					
						
							| 
									
										
										
										
											2007-07-27 21:49:15 +00:00
										 |  |  |     if (i2s->fifo_len < 16 || !i2s->enable) | 
					
						
							|  |  |  |         i2s->status |= 1 << 0;			/* TNF */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     if (i2s->rx_len) | 
					
						
							|  |  |  |         i2s->status |= 1 << 1;			/* RNE */ | 
					
						
							|  |  |  |     if (i2s->enable) | 
					
						
							|  |  |  |         i2s->status |= 1 << 2;			/* BSY */ | 
					
						
							|  |  |  |     if (tfs) | 
					
						
							|  |  |  |         i2s->status |= 1 << 3;			/* TFS */ | 
					
						
							|  |  |  |     if (rfs) | 
					
						
							|  |  |  |         i2s->status |= 1 << 4;			/* RFS */ | 
					
						
							|  |  |  |     if (!(i2s->tx_len && i2s->enable)) | 
					
						
							|  |  |  |         i2s->status |= i2s->fifo_len << 8;	/* TFL */ | 
					
						
							|  |  |  |     i2s->status |= MAX(i2s->rx_len, 0xf) << 12;	/* RFL */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qemu_set_irq(i2s->irq, i2s->status & i2s->mask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SACR0	0x00	/* Serial Audio Global Control register */
 | 
					
						
							|  |  |  | #define SACR1	0x04	/* Serial Audio I2S/MSB-Justified Control register */
 | 
					
						
							|  |  |  | #define SASR0	0x0c	/* Serial Audio Interface and FIFO Status register */
 | 
					
						
							|  |  |  | #define SAIMR	0x14	/* Serial Audio Interrupt Mask register */
 | 
					
						
							|  |  |  | #define SAICR	0x18	/* Serial Audio Interrupt Clear register */
 | 
					
						
							|  |  |  | #define SADIV	0x60	/* Serial Audio Clock Divider register */
 | 
					
						
							|  |  |  | #define SADR	0x80	/* Serial Audio Data register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case SACR0: | 
					
						
							|  |  |  |         return s->control[0]; | 
					
						
							|  |  |  |     case SACR1: | 
					
						
							|  |  |  |         return s->control[1]; | 
					
						
							|  |  |  |     case SASR0: | 
					
						
							|  |  |  |         return s->status; | 
					
						
							|  |  |  |     case SAIMR: | 
					
						
							|  |  |  |         return s->mask; | 
					
						
							|  |  |  |     case SAICR: | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     case SADIV: | 
					
						
							|  |  |  |         return s->clk; | 
					
						
							|  |  |  |     case SADR: | 
					
						
							|  |  |  |         if (s->rx_len > 0) { | 
					
						
							|  |  |  |             s->rx_len --; | 
					
						
							|  |  |  |             pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |             return s->codec_in(s->opaque); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_i2s_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                              uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint32_t *sample; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case SACR0: | 
					
						
							|  |  |  |         if (value & (1 << 3))				/* RST */ | 
					
						
							|  |  |  |             pxa2xx_i2s_reset(s); | 
					
						
							|  |  |  |         s->control[0] = value & 0xff3d; | 
					
						
							|  |  |  |         if (!s->enable && (value & 1) && s->tx_len) {	/* ENB */ | 
					
						
							|  |  |  |             for (sample = s->fifo; s->fifo_len > 0; s->fifo_len --, sample ++) | 
					
						
							|  |  |  |                 s->codec_out(s->opaque, *sample); | 
					
						
							|  |  |  |             s->status &= ~(1 << 7);			/* I2SOFF */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (value & (1 << 4))				/* EFWR */ | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |             printf("%s: Attempt to use special function\n", __func__); | 
					
						
							| 
									
										
										
										
											2011-02-20 21:23:59 +02:00
										 |  |  |         s->enable = (value & 9) == 1;			/* ENB && !RST*/ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SACR1: | 
					
						
							|  |  |  |         s->control[1] = value & 0x0039; | 
					
						
							|  |  |  |         if (value & (1 << 5))				/* ENLBF */ | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |             printf("%s: Attempt to use loopback function\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         if (value & (1 << 4))				/* DPRL */ | 
					
						
							|  |  |  |             s->fifo_len = 0; | 
					
						
							|  |  |  |         pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SAIMR: | 
					
						
							|  |  |  |         s->mask = value & 0x0078; | 
					
						
							|  |  |  |         pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SAICR: | 
					
						
							|  |  |  |         s->status &= ~(value & (3 << 5)); | 
					
						
							|  |  |  |         pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SADIV: | 
					
						
							|  |  |  |         s->clk = value & 0x007f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case SADR: | 
					
						
							|  |  |  |         if (s->tx_len && s->enable) { | 
					
						
							|  |  |  |             s->tx_len --; | 
					
						
							|  |  |  |             pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |             s->codec_out(s->opaque, value); | 
					
						
							|  |  |  |         } else if (s->fifo_len < 16) { | 
					
						
							|  |  |  |             s->fifo[s->fifo_len ++] = value; | 
					
						
							|  |  |  |             pxa2xx_i2s_update(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_i2s_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_i2s_read, | 
					
						
							|  |  |  |     .write = pxa2xx_i2s_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 14:14:56 +01:00
										 |  |  | static const VMStateDescription vmstate_pxa2xx_i2s = { | 
					
						
							|  |  |  |     .name = "pxa2xx_i2s", | 
					
						
							|  |  |  |     .version_id = 0, | 
					
						
							|  |  |  |     .minimum_version_id = 0, | 
					
						
							| 
									
										
										
										
											2014-05-13 16:09:35 +01:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2010-12-02 14:14:56 +01:00
										 |  |  |         VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2), | 
					
						
							|  |  |  |         VMSTATE_UINT32(status, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(mask, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(clk, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_INT32(enable, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_INT32(rx_len, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_INT32(tx_len, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_INT32(fifo_len, PXA2xxI2SState), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint32_t *sample; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Signal FIFO errors */ | 
					
						
							|  |  |  |     if (s->enable && s->tx_len) | 
					
						
							|  |  |  |         s->status |= 1 << 5;		/* TUR */ | 
					
						
							|  |  |  |     if (s->enable && s->rx_len) | 
					
						
							|  |  |  |         s->status |= 1 << 6;		/* ROR */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Should be tx - MIN(tx, s->fifo_len) but we don't really need to
 | 
					
						
							|  |  |  |      * handle the cases where it makes a difference.  */ | 
					
						
							|  |  |  |     s->tx_len = tx - s->fifo_len; | 
					
						
							|  |  |  |     s->rx_len = rx; | 
					
						
							|  |  |  |     /* Note that is s->codec_out wasn't set, we wouldn't get called.  */ | 
					
						
							|  |  |  |     if (s->enable) | 
					
						
							|  |  |  |         for (sample = s->fifo; s->fifo_len; s->fifo_len --, sample ++) | 
					
						
							|  |  |  |             s->codec_out(s->opaque, *sample); | 
					
						
							|  |  |  |     pxa2xx_i2s_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem, | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |                 hwaddr base, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                 qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     PXA2xxI2SState *s = g_new0(PXA2xxI2SState, 1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->irq = irq; | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |     s->rx_dma = rx_dma; | 
					
						
							|  |  |  |     s->tx_dma = tx_dma; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->data_req = pxa2xx_i2s_data_req; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pxa2xx_i2s_reset(s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem, NULL, &pxa2xx_i2s_ops, s, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                           "pxa2xx-i2s", 0x100000); | 
					
						
							|  |  |  |     memory_region_add_subregion(sysmem, base, &s->iomem); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-02 14:14:56 +01:00
										 |  |  |     vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s); | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* PXA Fast Infra-red Communications Port */ | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | struct PXA2xxFIrState { | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     qemu_irq irq; | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |     qemu_irq rx_dma; | 
					
						
							|  |  |  |     qemu_irq tx_dma; | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     uint32_t enable; | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:51 +03:00
										 |  |  |     CharBackend chr; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     uint8_t control[3]; | 
					
						
							|  |  |  |     uint8_t status[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     uint32_t rx_len; | 
					
						
							|  |  |  |     uint32_t rx_start; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint8_t rx_fifo[64]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static void pxa2xx_fir_reset(DeviceState *d) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     PXA2xxFIrState *s = PXA2XX_FIR(d); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->control[0] = 0x00; | 
					
						
							|  |  |  |     s->control[1] = 0x00; | 
					
						
							|  |  |  |     s->control[2] = 0x00; | 
					
						
							|  |  |  |     s->status[0] = 0x00; | 
					
						
							|  |  |  |     s->status[1] = 0x00; | 
					
						
							|  |  |  |     s->enable = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  | static inline void pxa2xx_fir_update(PXA2xxFIrState *s) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     static const int tresh[4] = { 8, 16, 32, 0 }; | 
					
						
							|  |  |  |     int intr = 0; | 
					
						
							|  |  |  |     if ((s->control[0] & (1 << 4)) &&			/* RXE */ | 
					
						
							|  |  |  |                     s->rx_len >= tresh[s->control[2] & 3])	/* TRIG */ | 
					
						
							|  |  |  |         s->status[0] |= 1 << 4;				/* RFS */ | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         s->status[0] &= ~(1 << 4);			/* RFS */ | 
					
						
							|  |  |  |     if (s->control[0] & (1 << 3))			/* TXE */ | 
					
						
							|  |  |  |         s->status[0] |= 1 << 3;				/* TFS */ | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         s->status[0] &= ~(1 << 3);			/* TFS */ | 
					
						
							|  |  |  |     if (s->rx_len) | 
					
						
							|  |  |  |         s->status[1] |= 1 << 2;				/* RNE */ | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         s->status[1] &= ~(1 << 2);			/* RNE */ | 
					
						
							|  |  |  |     if (s->control[0] & (1 << 4))			/* RXE */ | 
					
						
							|  |  |  |         s->status[1] |= 1 << 0;				/* RSY */ | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         s->status[1] &= ~(1 << 0);			/* RSY */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     intr |= (s->control[0] & (1 << 5)) &&		/* RIE */ | 
					
						
							|  |  |  |             (s->status[0] & (1 << 4));			/* RFS */ | 
					
						
							|  |  |  |     intr |= (s->control[0] & (1 << 6)) &&		/* TIE */ | 
					
						
							|  |  |  |             (s->status[0] & (1 << 3));			/* TFS */ | 
					
						
							|  |  |  |     intr |= (s->control[2] & (1 << 4)) &&		/* TRAIL */ | 
					
						
							|  |  |  |             (s->status[0] & (1 << 6));			/* EOC */ | 
					
						
							|  |  |  |     intr |= (s->control[0] & (1 << 2)) &&		/* TUS */ | 
					
						
							|  |  |  |             (s->status[0] & (1 << 1));			/* TUR */ | 
					
						
							|  |  |  |     intr |= s->status[0] & 0x25;			/* FRE, RAB, EIF */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |     qemu_set_irq(s->rx_dma, (s->status[0] >> 4) & 1); | 
					
						
							|  |  |  |     qemu_set_irq(s->tx_dma, (s->status[0] >> 3) & 1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     qemu_set_irq(s->irq, intr && s->enable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ICCR0	0x00	/* FICP Control register 0 */
 | 
					
						
							|  |  |  | #define ICCR1	0x04	/* FICP Control register 1 */
 | 
					
						
							|  |  |  | #define ICCR2	0x08	/* FICP Control register 2 */
 | 
					
						
							|  |  |  | #define ICDR	0x0c	/* FICP Data register */
 | 
					
						
							|  |  |  | #define ICSR0	0x14	/* FICP Status register 0 */
 | 
					
						
							|  |  |  | #define ICSR1	0x18	/* FICP Status register 1 */
 | 
					
						
							|  |  |  | #define ICFOR	0x1c	/* FICP FIFO Occupancy Status register */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                                 unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint8_t ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case ICCR0: | 
					
						
							|  |  |  |         return s->control[0]; | 
					
						
							|  |  |  |     case ICCR1: | 
					
						
							|  |  |  |         return s->control[1]; | 
					
						
							|  |  |  |     case ICCR2: | 
					
						
							|  |  |  |         return s->control[2]; | 
					
						
							|  |  |  |     case ICDR: | 
					
						
							|  |  |  |         s->status[0] &= ~0x01; | 
					
						
							|  |  |  |         s->status[1] &= ~0x72; | 
					
						
							|  |  |  |         if (s->rx_len) { | 
					
						
							|  |  |  |             s->rx_len --; | 
					
						
							|  |  |  |             ret = s->rx_fifo[s->rx_start ++]; | 
					
						
							|  |  |  |             s->rx_start &= 63; | 
					
						
							|  |  |  |             pxa2xx_fir_update(s); | 
					
						
							|  |  |  |             return ret; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |         printf("%s: Rx FIFO underrun.\n", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case ICSR0: | 
					
						
							|  |  |  |         return s->status[0]; | 
					
						
							|  |  |  |     case ICSR1: | 
					
						
							|  |  |  |         return s->status[1] | (1 << 3);			/* TNF */ | 
					
						
							|  |  |  |     case ICFOR: | 
					
						
							|  |  |  |         return s->rx_len; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad read offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pxa2xx_fir_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |                              uint64_t value64, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     uint32_t value = value64; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     uint8_t ch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case ICCR0: | 
					
						
							|  |  |  |         s->control[0] = value; | 
					
						
							|  |  |  |         if (!(value & (1 << 4)))			/* RXE */ | 
					
						
							|  |  |  |             s->rx_len = s->rx_start = 0; | 
					
						
							| 
									
										
										
										
											2010-09-18 07:01:48 +00:00
										 |  |  |         if (!(value & (1 << 3))) {                      /* TXE */ | 
					
						
							|  |  |  |             /* Nop */ | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         s->enable = value & 1;				/* ITR */ | 
					
						
							|  |  |  |         if (!s->enable) | 
					
						
							|  |  |  |             s->status[0] = 0; | 
					
						
							|  |  |  |         pxa2xx_fir_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case ICCR1: | 
					
						
							|  |  |  |         s->control[1] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case ICCR2: | 
					
						
							|  |  |  |         s->control[2] = value & 0x3f; | 
					
						
							|  |  |  |         pxa2xx_fir_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case ICDR: | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:51 +03:00
										 |  |  |         if (s->control[2] & (1 << 2)) { /* TXP */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             ch = value; | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:51 +03:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             ch = ~value; | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:51 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:59 +03:00
										 |  |  |         if (s->enable && (s->control[0] & (1 << 3))) { /* TXE */ | 
					
						
							| 
									
										
										
										
											2016-09-06 14:56:04 +01:00
										 |  |  |             /* XXX this blocks entire thread. Rewrite to use
 | 
					
						
							|  |  |  |              * qemu_chr_fe_write and background I/O callbacks */ | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:55 +03:00
										 |  |  |             qemu_chr_fe_write_all(&s->chr, &ch, 1); | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:51 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case ICSR0: | 
					
						
							|  |  |  |         s->status[0] &= ~(value & 0x66); | 
					
						
							|  |  |  |         pxa2xx_fir_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case ICFOR: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2020-06-02 13:44:35 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Bad write offset 0x%"HWADDR_PRIx"\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  | static const MemoryRegionOps pxa2xx_fir_ops = { | 
					
						
							|  |  |  |     .read = pxa2xx_fir_read, | 
					
						
							|  |  |  |     .write = pxa2xx_fir_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pxa2xx_fir_is_empty(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     return (s->rx_len < 64); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     if (!(s->control[0] & (1 << 4)))			/* RXE */ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (size --) { | 
					
						
							|  |  |  |         s->status[1] |= 1 << 4;				/* EOF */ | 
					
						
							|  |  |  |         if (s->rx_len >= 64) { | 
					
						
							|  |  |  |             s->status[1] |= 1 << 6;			/* ROR */ | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->control[2] & (1 << 3))			/* RXP */ | 
					
						
							|  |  |  |             s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = *(buf ++); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = ~*(buf ++); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pxa2xx_fir_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												chardev: Use QEMUChrEvent enum in IOEventHandler typedef
The Chardev events are listed in the QEMUChrEvent enum.
By using the enum in the IOEventHandler typedef we:
- make the IOEventHandler type more explicit (this handler
  process out-of-band information, while the IOReadHandler
  is in-band),
- help static code analyzers.
This patch was produced with the following spatch script:
  @match@
  expression backend, opaque, context, set_open;
  identifier fd_can_read, fd_read, fd_event, be_change;
  @@
  qemu_chr_fe_set_handlers(backend, fd_can_read, fd_read, fd_event,
                           be_change, opaque, context, set_open);
  @depends on match@
  identifier opaque, event;
  identifier match.fd_event;
  @@
   static
  -void fd_event(void *opaque, int event)
  +void fd_event(void *opaque, QEMUChrEvent event)
   {
   ...
   }
Then the typedef was modified manually in
include/chardev/char-fe.h.
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20191218172009.8868-15-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
											
										 
											2019-12-18 18:20:09 +01:00
										 |  |  | static void pxa2xx_fir_event(void *opaque, QEMUChrEvent event) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static void pxa2xx_fir_instance_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     PXA2xxFIrState *s = PXA2XX_FIR(obj); | 
					
						
							|  |  |  |     SysBusDevice *sbd = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-01 10:59:51 +02:00
										 |  |  |     memory_region_init_io(&s->iomem, obj, &pxa2xx_fir_ops, s, | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |                           "pxa2xx-fir", 0x1000); | 
					
						
							|  |  |  |     sysbus_init_mmio(sbd, &s->iomem); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->irq); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->rx_dma); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->tx_dma); | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static void pxa2xx_fir_realize(DeviceState *dev, Error **errp) | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     PXA2xxFIrState *s = PXA2XX_FIR(dev); | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-22 12:52:59 +03:00
										 |  |  |     qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty, | 
					
						
							| 
									
										
										
										
											2017-07-06 15:08:49 +03:00
										 |  |  |                              pxa2xx_fir_rx, pxa2xx_fir_event, NULL, s, NULL, | 
					
						
							|  |  |  |                              true); | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PXA2xxFIrState *s = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     return s->rx_start < ARRAY_SIZE(s->rx_fifo); | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static const VMStateDescription pxa2xx_fir_vmsd = { | 
					
						
							|  |  |  |     .name = "pxa2xx-fir", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							|  |  |  |     .fields = (VMStateField[]) { | 
					
						
							|  |  |  |         VMSTATE_UINT32(enable, PXA2xxFIrState), | 
					
						
							|  |  |  |         VMSTATE_UINT8_ARRAY(control, PXA2xxFIrState, 3), | 
					
						
							|  |  |  |         VMSTATE_UINT8_ARRAY(status, PXA2xxFIrState, 2), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rx_len, PXA2xxFIrState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(rx_start, PXA2xxFIrState), | 
					
						
							|  |  |  |         VMSTATE_VALIDATE("fifo is 64 bytes", pxa2xx_fir_vmstate_validate), | 
					
						
							|  |  |  |         VMSTATE_UINT8_ARRAY(rx_fifo, PXA2xxFIrState, 64), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static Property pxa2xx_fir_properties[] = { | 
					
						
							|  |  |  |     DEFINE_PROP_CHR("chardev", PXA2xxFIrState, chr), | 
					
						
							|  |  |  |     DEFINE_PROP_END_OF_LIST(), | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static void pxa2xx_fir_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     dc->realize = pxa2xx_fir_realize; | 
					
						
							|  |  |  |     dc->vmsd = &pxa2xx_fir_vmsd; | 
					
						
							| 
									
										
										
										
											2020-01-10 19:30:32 +04:00
										 |  |  |     device_class_set_props(dc, pxa2xx_fir_properties); | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     dc->reset = pxa2xx_fir_reset; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static const TypeInfo pxa2xx_fir_info = { | 
					
						
							|  |  |  |     .name = TYPE_PXA2XX_FIR, | 
					
						
							|  |  |  |     .parent = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PXA2xxFIrState), | 
					
						
							|  |  |  |     .class_init = pxa2xx_fir_class_init, | 
					
						
							|  |  |  |     .instance_init = pxa2xx_fir_instance_init, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, | 
					
						
							|  |  |  |                                        hwaddr base, | 
					
						
							|  |  |  |                                        qemu_irq irq, qemu_irq rx_dma, | 
					
						
							|  |  |  |                                        qemu_irq tx_dma, | 
					
						
							| 
									
										
										
										
											2016-12-07 16:20:22 +03:00
										 |  |  |                                        Chardev *chr) | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     DeviceState *dev; | 
					
						
							|  |  |  |     SysBusDevice *sbd; | 
					
						
							| 
									
										
										
										
											2007-05-24 18:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion.  More to come in
this series.
Coccinelle script:
    @ depends on !(file in "hw/arm/highbank.c")@
    expression bus, type_name, dev, expr;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr;
    identifier DOWN;
    @@
    -    dev = DOWN(qdev_create(bus, type_name));
    +    dev = DOWN(qdev_new(type_name));
         ... when != dev = expr
    -    qdev_init_nofail(DEVICE(dev));
    +    qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
    @@
    expression bus, type_name, expr;
    identifier dev;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr, errp;
    symbol true;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
    @@
    expression bus, type_name, expr, errp;
    identifier dev;
    symbol true;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name.  Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:31:58 +02:00
										 |  |  |     dev = qdev_new(TYPE_PXA2XX_FIR); | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     qdev_prop_set_chr(dev, "chardev", chr); | 
					
						
							|  |  |  |     sbd = SYS_BUS_DEVICE(dev); | 
					
						
							| 
									
										
											  
											
												sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
    @@
    expression dev, errp;
    @@
    -    qdev_realize(DEVICE(dev), NULL, errp);
    +    sysbus_realize(SYS_BUS_DEVICE(dev), errp);
    @@
    expression sysbus_dev, dev, errp;
    @@
    +    sysbus_dev = SYS_BUS_DEVICE(dev);
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    -    sysbus_dev = SYS_BUS_DEVICE(dev);
    @@
    expression sysbus_dev, dev, errp;
    expression expr;
    @@
         sysbus_dev = SYS_BUS_DEVICE(dev);
         ... when != dev = expr;
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(DEVICE(dev), NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:32:34 +02:00
										 |  |  |     sysbus_realize_and_unref(sbd, &error_fatal); | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     sysbus_mmio_map(sbd, 0, base); | 
					
						
							|  |  |  |     sysbus_connect_irq(sbd, 0, irq); | 
					
						
							|  |  |  |     sysbus_connect_irq(sbd, 1, rx_dma); | 
					
						
							|  |  |  |     sysbus_connect_irq(sbd, 2, tx_dma); | 
					
						
							|  |  |  |     return PXA2XX_FIR(dev); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-17 14:07:13 +00:00
										 |  |  | static void pxa2xx_reset(void *opaque, int line, int level) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s = (PXA2xxState *) opaque; | 
					
						
							| 
									
										
										
										
											2007-11-17 14:07:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     if (level && (s->pm_regs[PCFR >> 2] & 0x10)) {	/* GPR_EN */ | 
					
						
							| 
									
										
										
										
											2012-05-03 23:47:04 +02:00
										 |  |  |         cpu_reset(CPU(s->cpu)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |         /* TODO: reset peripherals */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Initialise a PXA270 integrated chip (ARM based core).  */ | 
					
						
							| 
									
										
										
										
											2023-01-09 12:53:05 +01:00
										 |  |  | PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-09 12:53:05 +01:00
										 |  |  |     MemoryRegion *address_space = get_system_memory(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2009-07-22 16:42:57 +02:00
										 |  |  |     DriveInfo *dinfo; | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     s = g_new0(PXA2xxState, 1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 18:04:57 +02:00
										 |  |  |     if (strncmp(cpu_type, "pxa27", 5)) { | 
					
						
							| 
									
										
											  
											
												hw/arm: Replace fprintf(stderr, "*\n" with error_report()
Replace a large number of the fprintf(stderr, "*\n" calls with
error_report(). The functions were renamed with these commands and then
compiler issues where manually fixed.
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N;N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
find ./* -type f -exec sed -i \
    'N; {s|fprintf(stderr, "\(.*\)\\n"\(.*\));|error_report("\1"\2);|Ig}' \
    {} +
Some lines where then manually tweaked to pass checkpatch.
The 'qemu: ' prefix was manually removed from the hw/arm/boot.c file.
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Cc: qemu-arm@nongnu.org
Conversions that aren't followed by exit() dropped, because they might
be inappropriate.
Also trim trailing punctuation from error messages.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20180203084315.20497-3-armbru@redhat.com>
											
										 
											2018-02-03 09:43:03 +01:00
										 |  |  |         error_report("Machine requires a PXA27x processor"); | 
					
						
							| 
									
										
										
										
											2007-05-01 01:03:32 +00:00
										 |  |  |         exit(1); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-27 14:59:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 18:04:57 +02:00
										 |  |  |     s->cpu = ARM_CPU(cpu_create(cpu_type)); | 
					
						
							| 
									
										
										
										
											2014-06-18 00:55:18 -07:00
										 |  |  |     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0); | 
					
						
							| 
									
										
										
										
											2007-11-17 14:07:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-08 19:03:12 +00:00
										 |  |  |     /* SDRAM & Internal Memory Storage */ | 
					
						
							| 
									
										
										
										
											2017-07-07 15:42:53 +01:00
										 |  |  |     memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size, | 
					
						
							| 
									
										
											  
											
												Fix bad error handling after memory_region_init_ram()
Symptom:
    $ qemu-system-x86_64 -m 10000000
    Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
    upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
    Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions.  Before the commit, we report the error and exit(1), in
one place, ram_block_add().  The commit lifts the error handling up
the call chain some, to three places.  Fine.  Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
  Commit 4994653 (right after commit ef701d7) lifted the error
  handling further, through memory_region_init_ram(), multiplying the
  incorrect use of &error_abort.  Later on, imitation of existing
  (bad) code may have created more.
* memory_region_init_ram_ptr()
  The &error_abort is still there.
* memory_region_init_rom_device()
  Doesn't need fixing, because commit 33e0eb5 (soon after commit
  ef701d7) lifted the error handling further, and in the process
  changed it from &error_abort to passing it up the call chain.
  Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
    @r@
    expression mr, owner, name, size, err;
    position p;
    @@
            memory_region_init_ram(mr, owner, name, size,
    (
    -                              &error_abort
    +                              &error_fatal
    |
                                   err@p
    )
                                  );
    @script:python@
        p << r.p;
    @@
    print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal.  This is the fix.
If the last argument is anything else, its position is reported.  This
lets us check the fix is complete.  Four positions get reported:
* ram_backend_memory_alloc()
  Error is passed up the call chain, ultimately through
  user_creatable_complete().  As far as I can tell, it's callers all
  handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
  DeviceClass.realize() methods, errors handled sanely further up the
  call chain.
We're good.  Test case again behaves:
    $ qemu-system-x86_64 -m 10000000
    qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
    [Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
											
										 
											2015-09-11 16:51:43 +02:00
										 |  |  |                            &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram); | 
					
						
							| 
									
										
										
										
											2017-07-07 15:42:53 +01:00
										 |  |  |     memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000, | 
					
						
							| 
									
										
											  
											
												Fix bad error handling after memory_region_init_ram()
Symptom:
    $ qemu-system-x86_64 -m 10000000
    Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
    upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
    Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions.  Before the commit, we report the error and exit(1), in
one place, ram_block_add().  The commit lifts the error handling up
the call chain some, to three places.  Fine.  Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
  Commit 4994653 (right after commit ef701d7) lifted the error
  handling further, through memory_region_init_ram(), multiplying the
  incorrect use of &error_abort.  Later on, imitation of existing
  (bad) code may have created more.
* memory_region_init_ram_ptr()
  The &error_abort is still there.
* memory_region_init_rom_device()
  Doesn't need fixing, because commit 33e0eb5 (soon after commit
  ef701d7) lifted the error handling further, and in the process
  changed it from &error_abort to passing it up the call chain.
  Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
    @r@
    expression mr, owner, name, size, err;
    position p;
    @@
            memory_region_init_ram(mr, owner, name, size,
    (
    -                              &error_abort
    +                              &error_fatal
    |
                                   err@p
    )
                                  );
    @script:python@
        p << r.p;
    @@
    print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal.  This is the fix.
If the last argument is anything else, its position is reported.  This
lets us check the fix is complete.  Four positions get reported:
* ram_backend_memory_alloc()
  Error is passed up the call chain, ultimately through
  user_creatable_complete().  As far as I can tell, it's callers all
  handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
  DeviceClass.realize() methods, errors handled sanely further up the
  call chain.
We're good.  Test case again behaves:
    $ qemu-system-x86_64 -m 10000000
    qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
    [Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
											
										 
											2015-09-11 16:51:43 +02:00
										 |  |  |                            &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE, | 
					
						
							|  |  |  |                                 &s->internal); | 
					
						
							| 
									
										
										
										
											2007-05-08 19:03:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 00:01:27 +02:00
										 |  |  |     s->pic = pxa2xx_pic_init(0x40d00000, s->cpu); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |     s->dma = pxa27x_dma_init(0x40000000, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 14:14:44 +01:00
										 |  |  |     sysbus_create_varargs("pxa27x-timer", 0x40a00000, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11), | 
					
						
							|  |  |  |                     NULL); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 06:18:02 +01:00
										 |  |  |     s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 13:59:13 +02:00
										 |  |  |     s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI)); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:22:10 +02:00
										 |  |  |     dinfo = drive_get(IF_SD, 0, 0); | 
					
						
							|  |  |  |     if (dinfo) { | 
					
						
							|  |  |  |         DeviceState *carddev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Create and plug in the sd card */ | 
					
						
							|  |  |  |         carddev = qdev_new(TYPE_SD_CARD); | 
					
						
							|  |  |  |         qdev_prop_set_drive_err(carddev, "drive", | 
					
						
							|  |  |  |                                 blk_by_legacy_dinfo(dinfo), &error_fatal); | 
					
						
							|  |  |  |         qdev_realize_and_unref(carddev, qdev_get_child_bus(DEVICE(s->mmc), | 
					
						
							|  |  |  |                                                            "sd-bus"), | 
					
						
							|  |  |  |                                &error_fatal); | 
					
						
							|  |  |  |     } else if (!qtest_enabled()) { | 
					
						
							|  |  |  |         warn_report("missing SecureDigital device"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |     for (i = 0; pxa270_serial[i].io_base; i++) { | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |         if (serial_hd(i)) { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:19 -07:00
										 |  |  |             serial_mm_init(address_space, pxa270_serial[i].io_base, 2, | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |                            qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn), | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |                            14857000 / 16, serial_hd(i), | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |                            DEVICE_NATIVE_ENDIAN); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |     if (serial_hd(i)) | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |         s->fir = pxa2xx_fir_init(address_space, 0x40800000, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP), | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                         qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP), | 
					
						
							|  |  |  |                         qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP), | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |                         serial_hd(i)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-30 14:50:19 +01:00
										 |  |  |     s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->cm_base = 0x41300000; | 
					
						
							| 
									
										
										
										
											2007-07-24 01:07:44 +00:00
										 |  |  |     s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */ | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->clkcfg = 0x00000009;		/* Turbo mode active */ | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:31:14 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     pxa2xx_setup_cp14(s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->mm_base = 0x48000000; | 
					
						
							|  |  |  |     s->mm_regs[MDMRS >> 2] = 0x00020002; | 
					
						
							|  |  |  |     s->mm_regs[MDREFR >> 2] = 0x03ca4000; | 
					
						
							|  |  |  |     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */ | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:36:57 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-28 11:26:15 +00:00
										 |  |  |     s->pm_base = 0x40f00000; | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:54:38 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); | 
					
						
							| 
									
										
										
										
											2007-05-28 11:26:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     for (i = 0; pxa27x_ssp[i].io_base; i ++); | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     s->ssp = g_new0(SSIBus *, i); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     for (i = 0; pxa27x_ssp[i].io_base; i ++) { | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |         DeviceState *dev; | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |         dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa27x_ssp[i].io_base, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                         qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn)); | 
					
						
							| 
									
										
										
										
											2009-05-23 00:05:19 +01:00
										 |  |  |         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi"); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 17:50:24 -03:00
										 |  |  |     sysbus_create_simple("sysbus-ohci", 0x4c000000, | 
					
						
							|  |  |  |                          qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-30 14:50:12 +01:00
										 |  |  |     s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000); | 
					
						
							|  |  |  |     s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  |     sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |     s->i2c[0] = pxa2xx_i2c_init(0x40301600, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); | 
					
						
							|  |  |  |     s->i2c[1] = pxa2xx_i2c_init(0x40f00100, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     s->i2s = pxa2xx_i2s_init(address_space, 0x40400000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-30 14:50:15 +01:00
										 |  |  |     s->kp = pxa27x_keypad_init(address_space, 0x41500000, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD)); | 
					
						
							| 
									
										
										
										
											2007-12-16 12:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     /* GPIO1 resets the processor */ | 
					
						
							| 
									
										
										
										
											2007-07-12 10:59:21 +00:00
										 |  |  |     /* The handler can be overridden by board-specific code */ | 
					
						
							| 
									
										
										
										
											2011-01-21 19:57:50 +03:00
										 |  |  |     qdev_connect_gpio_out(s->gpio, 1, s->reset); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Initialise a PXA255 integrated chip (ARM based core).  */ | 
					
						
							| 
									
										
										
										
											2023-01-09 12:53:04 +01:00
										 |  |  | PXA2xxState *pxa255_init(unsigned int sdram_size) | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-09 12:53:04 +01:00
										 |  |  |     MemoryRegion *address_space = get_system_memory(); | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     PXA2xxState *s; | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2009-07-22 16:42:57 +02:00
										 |  |  |     DriveInfo *dinfo; | 
					
						
							| 
									
										
										
										
											2007-11-10 15:15:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     s = g_new0(PXA2xxState, 1); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-13 18:04:57 +02:00
										 |  |  |     s->cpu = ARM_CPU(cpu_create(ARM_CPU_TYPE_NAME("pxa255"))); | 
					
						
							| 
									
										
										
										
											2014-06-18 00:55:18 -07:00
										 |  |  |     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0); | 
					
						
							| 
									
										
										
										
											2007-11-17 14:07:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-08 19:03:12 +00:00
										 |  |  |     /* SDRAM & Internal Memory Storage */ | 
					
						
							| 
									
										
										
										
											2017-07-07 15:42:53 +01:00
										 |  |  |     memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size, | 
					
						
							| 
									
										
											  
											
												Fix bad error handling after memory_region_init_ram()
Symptom:
    $ qemu-system-x86_64 -m 10000000
    Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
    upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
    Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions.  Before the commit, we report the error and exit(1), in
one place, ram_block_add().  The commit lifts the error handling up
the call chain some, to three places.  Fine.  Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
  Commit 4994653 (right after commit ef701d7) lifted the error
  handling further, through memory_region_init_ram(), multiplying the
  incorrect use of &error_abort.  Later on, imitation of existing
  (bad) code may have created more.
* memory_region_init_ram_ptr()
  The &error_abort is still there.
* memory_region_init_rom_device()
  Doesn't need fixing, because commit 33e0eb5 (soon after commit
  ef701d7) lifted the error handling further, and in the process
  changed it from &error_abort to passing it up the call chain.
  Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
    @r@
    expression mr, owner, name, size, err;
    position p;
    @@
            memory_region_init_ram(mr, owner, name, size,
    (
    -                              &error_abort
    +                              &error_fatal
    |
                                   err@p
    )
                                  );
    @script:python@
        p << r.p;
    @@
    print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal.  This is the fix.
If the last argument is anything else, its position is reported.  This
lets us check the fix is complete.  Four positions get reported:
* ram_backend_memory_alloc()
  Error is passed up the call chain, ultimately through
  user_creatable_complete().  As far as I can tell, it's callers all
  handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
  DeviceClass.realize() methods, errors handled sanely further up the
  call chain.
We're good.  Test case again behaves:
    $ qemu-system-x86_64 -m 10000000
    qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
    [Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
											
										 
											2015-09-11 16:51:43 +02:00
										 |  |  |                            &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram); | 
					
						
							| 
									
										
										
										
											2017-07-07 15:42:53 +01:00
										 |  |  |     memory_region_init_ram(&s->internal, NULL, "pxa255.internal", | 
					
						
							| 
									
										
											  
											
												Fix bad error handling after memory_region_init_ram()
Symptom:
    $ qemu-system-x86_64 -m 10000000
    Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
    upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
    Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions.  Before the commit, we report the error and exit(1), in
one place, ram_block_add().  The commit lifts the error handling up
the call chain some, to three places.  Fine.  Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
  Commit 4994653 (right after commit ef701d7) lifted the error
  handling further, through memory_region_init_ram(), multiplying the
  incorrect use of &error_abort.  Later on, imitation of existing
  (bad) code may have created more.
* memory_region_init_ram_ptr()
  The &error_abort is still there.
* memory_region_init_rom_device()
  Doesn't need fixing, because commit 33e0eb5 (soon after commit
  ef701d7) lifted the error handling further, and in the process
  changed it from &error_abort to passing it up the call chain.
  Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
    @r@
    expression mr, owner, name, size, err;
    position p;
    @@
            memory_region_init_ram(mr, owner, name, size,
    (
    -                              &error_abort
    +                              &error_fatal
    |
                                   err@p
    )
                                  );
    @script:python@
        p << r.p;
    @@
    print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal.  This is the fix.
If the last argument is anything else, its position is reported.  This
lets us check the fix is complete.  Four positions get reported:
* ram_backend_memory_alloc()
  Error is passed up the call chain, ultimately through
  user_creatable_complete().  As far as I can tell, it's callers all
  handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
  DeviceClass.realize() methods, errors handled sanely further up the
  call chain.
We're good.  Test case again behaves:
    $ qemu-system-x86_64 -m 10000000
    qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
    [Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
											
										 
											2015-09-11 16:51:43 +02:00
										 |  |  |                            PXA2XX_INTERNAL_SIZE, &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE, | 
					
						
							|  |  |  |                                 &s->internal); | 
					
						
							| 
									
										
										
										
											2007-05-08 19:03:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 00:01:27 +02:00
										 |  |  |     s->pic = pxa2xx_pic_init(0x40d00000, s->cpu); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |     s->dma = pxa255_dma_init(0x40000000, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 14:14:44 +01:00
										 |  |  |     sysbus_create_varargs("pxa25x-timer", 0x40a00000, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3), | 
					
						
							|  |  |  |                     NULL); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 06:18:02 +01:00
										 |  |  |     s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 13:59:13 +02:00
										 |  |  |     s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI)); | 
					
						
							| 
									
										
										
										
											2020-07-05 23:22:10 +02:00
										 |  |  |     dinfo = drive_get(IF_SD, 0, 0); | 
					
						
							|  |  |  |     if (dinfo) { | 
					
						
							|  |  |  |         DeviceState *carddev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Create and plug in the sd card */ | 
					
						
							|  |  |  |         carddev = qdev_new(TYPE_SD_CARD); | 
					
						
							|  |  |  |         qdev_prop_set_drive_err(carddev, "drive", | 
					
						
							|  |  |  |                                 blk_by_legacy_dinfo(dinfo), &error_fatal); | 
					
						
							|  |  |  |         qdev_realize_and_unref(carddev, qdev_get_child_bus(DEVICE(s->mmc), | 
					
						
							|  |  |  |                                                            "sd-bus"), | 
					
						
							|  |  |  |                                &error_fatal); | 
					
						
							|  |  |  |     } else if (!qtest_enabled()) { | 
					
						
							|  |  |  |         warn_report("missing SecureDigital device"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |     for (i = 0; pxa255_serial[i].io_base; i++) { | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |         if (serial_hd(i)) { | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:19 -07:00
										 |  |  |             serial_mm_init(address_space, pxa255_serial[i].io_base, 2, | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |                            qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn), | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |                            14745600 / 16, serial_hd(i), | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |                            DEVICE_NATIVE_ENDIAN); | 
					
						
							| 
									
										
										
										
											2010-03-21 19:47:11 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-03-21 19:47:11 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-11 16:07:14 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |     if (serial_hd(i)) | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |         s->fir = pxa2xx_fir_init(address_space, 0x40800000, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP), | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                         qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP), | 
					
						
							|  |  |  |                         qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP), | 
					
						
							| 
									
										
										
										
											2018-04-20 15:52:43 +01:00
										 |  |  |                         serial_hd(i)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-30 14:50:19 +01:00
										 |  |  |     s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->cm_base = 0x41300000; | 
					
						
							| 
									
										
										
										
											2016-10-28 14:12:31 +01:00
										 |  |  |     s->cm_regs[CCCR >> 2] = 0x00000121;         /* from datasheet */ | 
					
						
							|  |  |  |     s->cm_regs[CKEN >> 2] = 0x00017def;         /* from datasheet */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     s->clkcfg = 0x00000009;		/* Turbo mode active */ | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:31:14 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-20 11:57:07 +00:00
										 |  |  |     pxa2xx_setup_cp14(s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->mm_base = 0x48000000; | 
					
						
							|  |  |  |     s->mm_regs[MDMRS >> 2] = 0x00020002; | 
					
						
							|  |  |  |     s->mm_regs[MDREFR >> 2] = 0x03ca4000; | 
					
						
							|  |  |  |     s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */ | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:36:57 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-28 11:26:15 +00:00
										 |  |  |     s->pm_base = 0x40f00000; | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100); | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem); | 
					
						
							| 
									
										
										
										
											2010-12-02 14:54:38 +01:00
										 |  |  |     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); | 
					
						
							| 
									
										
										
										
											2007-05-28 11:26:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     for (i = 0; pxa255_ssp[i].io_base; i ++); | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     s->ssp = g_new0(SSIBus *, i); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     for (i = 0; pxa255_ssp[i].io_base; i ++) { | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:09 +01:00
										 |  |  |         DeviceState *dev; | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |         dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa255_ssp[i].io_base, | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |                         qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn)); | 
					
						
							| 
									
										
										
										
											2009-05-23 00:05:19 +01:00
										 |  |  |         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi"); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-30 14:50:12 +01:00
										 |  |  |     s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000); | 
					
						
							|  |  |  |     s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-24 01:50:26 +02:00
										 |  |  |     sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:13:42 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 12:13:38 +01:00
										 |  |  |     s->i2c[0] = pxa2xx_i2c_init(0x40301600, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); | 
					
						
							|  |  |  |     s->i2c[1] = pxa2xx_i2c_init(0x40f00100, | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-25 18:19:19 +03:00
										 |  |  |     s->i2s = pxa2xx_i2s_init(address_space, 0x40400000, | 
					
						
							| 
									
										
										
										
											2011-03-03 15:04:51 +01:00
										 |  |  |                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S), | 
					
						
							|  |  |  |                     qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S)); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* GPIO1 resets the processor */ | 
					
						
							| 
									
										
										
										
											2007-07-12 10:59:21 +00:00
										 |  |  |     /* The handler can be overridden by board-specific code */ | 
					
						
							| 
									
										
										
										
											2011-01-21 19:57:50 +03:00
										 |  |  |     qdev_connect_gpio_out(s->gpio, 1, s->reset); | 
					
						
							| 
									
										
										
										
											2007-04-30 01:26:42 +00:00
										 |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     dc->reset = pxa2xx_ssp_reset; | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     dc->vmsd = &vmstate_pxa2xx_ssp; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo pxa2xx_ssp_info = { | 
					
						
							| 
									
										
										
										
											2013-07-24 01:45:10 +02:00
										 |  |  |     .name          = TYPE_PXA2XX_SSP, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(PXA2xxSSPState), | 
					
						
							| 
									
										
										
										
											2017-04-20 17:32:29 +01:00
										 |  |  |     .instance_init = pxa2xx_ssp_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = pxa2xx_ssp_class_init, | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void pxa2xx_register_types(void) | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&pxa2xx_i2c_slave_info); | 
					
						
							|  |  |  |     type_register_static(&pxa2xx_ssp_info); | 
					
						
							|  |  |  |     type_register_static(&pxa2xx_i2c_info); | 
					
						
							|  |  |  |     type_register_static(&pxa2xx_rtc_sysbus_info); | 
					
						
							| 
									
										
										
										
											2015-06-15 18:06:09 +01:00
										 |  |  |     type_register_static(&pxa2xx_fir_info); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:08 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(pxa2xx_register_types) |