| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |  * Arm PrimeCell PL181 MultiMedia Card Interface | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2007 CodeSourcery. | 
					
						
							|  |  |  |  * Written by Paul Brook | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-06-26 12:21:35 +10:00
										 |  |  |  * This code is licensed under the GPL. | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:17:05 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:04 +01:00
										 |  |  | #include "sysemu/blockdev.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:45 +02:00
										 |  |  | #include "migration/vmstate.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | #include "hw/irq.h"
 | 
					
						
							| 
									
										
										
										
											2015-10-08 18:51:01 +05:30
										 |  |  | #include "hw/sd/sd.h"
 | 
					
						
							| 
									
										
										
										
											2015-12-15 13:16:16 +01:00
										 |  |  | #include "qemu/log.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
											  
											
												hw/sd/pl181: 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.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Message-Id: <488ba8d4c562ea44119de8ea0f385a898bd8fa1e.1513790495.git.alistair.francis@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2017-12-20 09:24:47 -08:00
										 |  |  | #include "qemu/error-report.h"
 | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  | #include "trace.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define PL181_FIFO_LEN 16
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  | #define TYPE_PL181 "pl181"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(PL181State, PL181) | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  | #define TYPE_PL181_BUS "pl181-bus"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct PL181State { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 13:54:48 +02:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  |     SDBus sdbus; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     uint32_t clock; | 
					
						
							|  |  |  |     uint32_t power; | 
					
						
							|  |  |  |     uint32_t cmdarg; | 
					
						
							|  |  |  |     uint32_t cmd; | 
					
						
							|  |  |  |     uint32_t datatimer; | 
					
						
							|  |  |  |     uint32_t datalength; | 
					
						
							|  |  |  |     uint32_t respcmd; | 
					
						
							|  |  |  |     uint32_t response[4]; | 
					
						
							|  |  |  |     uint32_t datactrl; | 
					
						
							|  |  |  |     uint32_t datacnt; | 
					
						
							|  |  |  |     uint32_t status; | 
					
						
							|  |  |  |     uint32_t mask[2]; | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  |     int32_t fifo_pos; | 
					
						
							|  |  |  |     int32_t fifo_len; | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |     /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
 | 
					
						
							| 
									
										
										
										
											2015-09-08 22:45:14 +01:00
										 |  |  |        while it is reading the FIFO.  We hack around this by deferring | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |        subsequent transfers until after the driver polls the status word. | 
					
						
							|  |  |  |        http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  |     int32_t linux_hack; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:54:31 +02:00
										 |  |  |     uint32_t fifo[PL181_FIFO_LEN]; /* TODO use Fifo32 */ | 
					
						
							| 
									
										
										
										
											2007-04-07 18:14:41 +00:00
										 |  |  |     qemu_irq irq[2]; | 
					
						
							| 
									
										
										
										
											2011-02-21 20:57:49 +00:00
										 |  |  |     /* GPIO outputs for 'card is readonly' and 'card inserted' */ | 
					
						
							| 
									
										
										
										
											2020-07-05 13:39:53 +02:00
										 |  |  |     qemu_irq card_readonly; | 
					
						
							|  |  |  |     qemu_irq card_inserted; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  | static const VMStateDescription vmstate_pl181 = { | 
					
						
							|  |  |  |     .name = "pl181", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							|  |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  |         VMSTATE_UINT32(clock, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(power, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(cmdarg, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(cmd, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(datatimer, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(datalength, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(respcmd, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32_ARRAY(response, PL181State, 4), | 
					
						
							|  |  |  |         VMSTATE_UINT32(datactrl, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(datacnt, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32(status, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32_ARRAY(mask, PL181State, 2), | 
					
						
							|  |  |  |         VMSTATE_INT32(fifo_pos, PL181State), | 
					
						
							|  |  |  |         VMSTATE_INT32(fifo_len, PL181State), | 
					
						
							|  |  |  |         VMSTATE_INT32(linux_hack, PL181State), | 
					
						
							|  |  |  |         VMSTATE_UINT32_ARRAY(fifo, PL181State, PL181_FIFO_LEN), | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | #define PL181_CMD_INDEX     0x3f
 | 
					
						
							|  |  |  | #define PL181_CMD_RESPONSE  (1 << 6)
 | 
					
						
							|  |  |  | #define PL181_CMD_LONGRESP  (1 << 7)
 | 
					
						
							|  |  |  | #define PL181_CMD_INTERRUPT (1 << 8)
 | 
					
						
							|  |  |  | #define PL181_CMD_PENDING   (1 << 9)
 | 
					
						
							|  |  |  | #define PL181_CMD_ENABLE    (1 << 10)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PL181_DATA_ENABLE             (1 << 0)
 | 
					
						
							|  |  |  | #define PL181_DATA_DIRECTION          (1 << 1)
 | 
					
						
							|  |  |  | #define PL181_DATA_MODE               (1 << 2)
 | 
					
						
							|  |  |  | #define PL181_DATA_DMAENABLE          (1 << 3)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PL181_STATUS_CMDCRCFAIL       (1 << 0)
 | 
					
						
							|  |  |  | #define PL181_STATUS_DATACRCFAIL      (1 << 1)
 | 
					
						
							|  |  |  | #define PL181_STATUS_CMDTIMEOUT       (1 << 2)
 | 
					
						
							|  |  |  | #define PL181_STATUS_DATATIMEOUT      (1 << 3)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXUNDERRUN       (1 << 4)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXOVERRUN        (1 << 5)
 | 
					
						
							|  |  |  | #define PL181_STATUS_CMDRESPEND       (1 << 6)
 | 
					
						
							|  |  |  | #define PL181_STATUS_CMDSENT          (1 << 7)
 | 
					
						
							|  |  |  | #define PL181_STATUS_DATAEND          (1 << 8)
 | 
					
						
							|  |  |  | #define PL181_STATUS_DATABLOCKEND     (1 << 10)
 | 
					
						
							|  |  |  | #define PL181_STATUS_CMDACTIVE        (1 << 11)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXACTIVE         (1 << 12)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXACTIVE         (1 << 13)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXFIFOHALFEMPTY  (1 << 14)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXFIFOHALFFULL   (1 << 15)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXFIFOFULL       (1 << 16)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXFIFOFULL       (1 << 17)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXFIFOEMPTY      (1 << 18)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXFIFOEMPTY      (1 << 19)
 | 
					
						
							|  |  |  | #define PL181_STATUS_TXDATAAVLBL      (1 << 20)
 | 
					
						
							|  |  |  | #define PL181_STATUS_RXDATAAVLBL      (1 << 21)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PL181_STATUS_TX_FIFO (PL181_STATUS_TXACTIVE \
 | 
					
						
							|  |  |  |                              |PL181_STATUS_TXFIFOHALFEMPTY \ | 
					
						
							|  |  |  |                              |PL181_STATUS_TXFIFOFULL \ | 
					
						
							|  |  |  |                              |PL181_STATUS_TXFIFOEMPTY \ | 
					
						
							|  |  |  |                              |PL181_STATUS_TXDATAAVLBL) | 
					
						
							|  |  |  | #define PL181_STATUS_RX_FIFO (PL181_STATUS_RXACTIVE \
 | 
					
						
							|  |  |  |                              |PL181_STATUS_RXFIFOHALFFULL \ | 
					
						
							|  |  |  |                              |PL181_STATUS_RXFIFOFULL \ | 
					
						
							|  |  |  |                              |PL181_STATUS_RXFIFOEMPTY \ | 
					
						
							|  |  |  |                              |PL181_STATUS_RXDATAAVLBL) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const unsigned char pl181_id[] = | 
					
						
							|  |  |  | { 0x81, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  | static void pl181_update(PL181State *s) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							| 
									
										
										
										
											2007-04-07 18:14:41 +00:00
										 |  |  |         qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  | static void pl181_fifo_push(PL181State *s, uint32_t value) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->fifo_len == PL181_FIFO_LEN) { | 
					
						
							| 
									
										
											  
											
												hw/sd/pl181: 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.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Message-Id: <488ba8d4c562ea44119de8ea0f385a898bd8fa1e.1513790495.git.alistair.francis@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2017-12-20 09:24:47 -08:00
										 |  |  |         error_report("%s: FIFO overflow", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     n = (s->fifo_pos + s->fifo_len) & (PL181_FIFO_LEN - 1); | 
					
						
							|  |  |  |     s->fifo_len++; | 
					
						
							|  |  |  |     s->fifo[n] = value; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |     trace_pl181_fifo_push(value); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  | static uint32_t pl181_fifo_pop(PL181State *s) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     uint32_t value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->fifo_len == 0) { | 
					
						
							| 
									
										
											  
											
												hw/sd/pl181: 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.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Message-Id: <488ba8d4c562ea44119de8ea0f385a898bd8fa1e.1513790495.git.alistair.francis@xilinx.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2017-12-20 09:24:47 -08:00
										 |  |  |         error_report("%s: FIFO underflow", __func__); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     value = s->fifo[s->fifo_pos]; | 
					
						
							|  |  |  |     s->fifo_len--; | 
					
						
							|  |  |  |     s->fifo_pos = (s->fifo_pos + 1) & (PL181_FIFO_LEN - 1); | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |     trace_pl181_fifo_pop(value); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     return value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 19:42:05 +02:00
										 |  |  | static void pl181_do_command(PL181State *s) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-10 01:44:56 +01:00
										 |  |  |     SDRequest request; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     uint8_t response[16]; | 
					
						
							|  |  |  |     int rlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     request.cmd = s->cmd & PL181_CMD_INDEX; | 
					
						
							|  |  |  |     request.arg = s->cmdarg; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |     trace_pl181_command_send(request.cmd, request.arg); | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  |     rlen = sdbus_do_command(&s->sdbus, &request, response); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     if (rlen < 0) | 
					
						
							|  |  |  |         goto error; | 
					
						
							|  |  |  |     if (s->cmd & PL181_CMD_RESPONSE) { | 
					
						
							|  |  |  |         if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP))) | 
					
						
							|  |  |  |             goto error; | 
					
						
							|  |  |  |         if (rlen != 4 && rlen != 16) | 
					
						
							|  |  |  |             goto error; | 
					
						
							| 
									
										
										
										
											2018-06-29 15:11:20 +01:00
										 |  |  |         s->response[0] = ldl_be_p(&response[0]); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         if (rlen == 4) { | 
					
						
							|  |  |  |             s->response[1] = s->response[2] = s->response[3] = 0; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-06-29 15:11:20 +01:00
										 |  |  |             s->response[1] = ldl_be_p(&response[4]); | 
					
						
							|  |  |  |             s->response[2] = ldl_be_p(&response[8]); | 
					
						
							|  |  |  |             s->response[3] = ldl_be_p(&response[12]) & ~1; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |         trace_pl181_command_response_pending(); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         s->status |= PL181_STATUS_CMDRESPEND; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |         trace_pl181_command_sent(); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         s->status |= PL181_STATUS_CMDSENT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | error: | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |     trace_pl181_command_timeout(); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     s->status |= PL181_STATUS_CMDTIMEOUT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-11 22:48:58 +00:00
										 |  |  | /* Transfer data between the card and the FIFO.  This is complicated by
 | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |    the FIFO holding 32-bit words and the card taking data in single byte | 
					
						
							|  |  |  |    chunks.  FIFO bytes are transferred in little-endian order.  */ | 
					
						
							| 
									
										
										
										
											2007-09-17 08:09:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  | static void pl181_fifo_run(PL181State *s) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     uint32_t bits; | 
					
						
							| 
									
										
										
										
											2010-02-22 20:42:51 +00:00
										 |  |  |     uint32_t value = 0; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     int n; | 
					
						
							|  |  |  |     int is_read; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0; | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  |     if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus)) | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |             && !s->linux_hack) { | 
					
						
							| 
									
										
										
										
											2010-02-22 15:33:59 +00:00
										 |  |  |         if (is_read) { | 
					
						
							|  |  |  |             n = 0; | 
					
						
							|  |  |  |             while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) { | 
					
						
							| 
									
										
										
										
											2020-08-14 11:23:42 +02:00
										 |  |  |                 value |= (uint32_t)sdbus_read_byte(&s->sdbus) << (n * 8); | 
					
						
							| 
									
										
										
										
											2010-02-22 15:33:59 +00:00
										 |  |  |                 s->datacnt--; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |                 n++; | 
					
						
							|  |  |  |                 if (n == 4) { | 
					
						
							|  |  |  |                     pl181_fifo_push(s, value); | 
					
						
							|  |  |  |                     n = 0; | 
					
						
							| 
									
										
										
										
											2010-02-22 15:33:59 +00:00
										 |  |  |                     value = 0; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-02-22 15:33:59 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (n != 0) { | 
					
						
							|  |  |  |                 pl181_fifo_push(s, value); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { /* write */ | 
					
						
							|  |  |  |             n = 0; | 
					
						
							|  |  |  |             while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) { | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |                 if (n == 0) { | 
					
						
							|  |  |  |                     value = pl181_fifo_pop(s); | 
					
						
							|  |  |  |                     n = 4; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-02-22 15:33:59 +00:00
										 |  |  |                 n--; | 
					
						
							|  |  |  |                 s->datacnt--; | 
					
						
							| 
									
										
										
										
											2020-08-14 11:23:41 +02:00
										 |  |  |                 sdbus_write_byte(&s->sdbus, value & 0xff); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |                 value >>= 8; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO); | 
					
						
							|  |  |  |     if (s->datacnt == 0) { | 
					
						
							|  |  |  |         s->status |= PL181_STATUS_DATAEND; | 
					
						
							|  |  |  |         /* HACK: */ | 
					
						
							|  |  |  |         s->status |= PL181_STATUS_DATABLOCKEND; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |         trace_pl181_fifo_transfer_complete(); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |     if (s->datacnt == 0 && s->fifo_len == 0) { | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         s->datactrl &= ~PL181_DATA_ENABLE; | 
					
						
							| 
									
										
										
										
											2020-07-05 19:57:50 +02:00
										 |  |  |         trace_pl181_data_engine_idle(); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         /* Update FIFO bits.  */ | 
					
						
							|  |  |  |         bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE; | 
					
						
							|  |  |  |         if (s->fifo_len == 0) { | 
					
						
							|  |  |  |             bits |= PL181_STATUS_TXFIFOEMPTY; | 
					
						
							|  |  |  |             bits |= PL181_STATUS_RXFIFOEMPTY; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             bits |= PL181_STATUS_TXDATAAVLBL; | 
					
						
							|  |  |  |             bits |= PL181_STATUS_RXDATAAVLBL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (s->fifo_len == 16) { | 
					
						
							|  |  |  |             bits |= PL181_STATUS_TXFIFOFULL; | 
					
						
							|  |  |  |             bits |= PL181_STATUS_RXFIFOFULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (s->fifo_len <= 8) { | 
					
						
							|  |  |  |             bits |= PL181_STATUS_TXFIFOHALFEMPTY; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (s->fifo_len >= 8) { | 
					
						
							|  |  |  |             bits |= PL181_STATUS_RXFIFOHALFFULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (s->datactrl & PL181_DATA_DIRECTION) { | 
					
						
							|  |  |  |             bits &= PL181_STATUS_RX_FIFO; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             bits &= PL181_STATUS_TX_FIFO; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         s->status |= bits; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t pl181_read(void *opaque, hwaddr offset, | 
					
						
							| 
									
										
										
										
											2011-10-11 13:54:48 +02:00
										 |  |  |                            unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  |     PL181State *s = (PL181State *)opaque; | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |     uint32_t tmp; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (offset >= 0xfe0 && offset < 0x1000) { | 
					
						
							|  |  |  |         return pl181_id[(offset - 0xfe0) >> 2]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     switch (offset) { | 
					
						
							|  |  |  |     case 0x00: /* Power */ | 
					
						
							|  |  |  |         return s->power; | 
					
						
							|  |  |  |     case 0x04: /* Clock */ | 
					
						
							|  |  |  |         return s->clock; | 
					
						
							|  |  |  |     case 0x08: /* Argument */ | 
					
						
							|  |  |  |         return s->cmdarg; | 
					
						
							|  |  |  |     case 0x0c: /* Command */ | 
					
						
							|  |  |  |         return s->cmd; | 
					
						
							|  |  |  |     case 0x10: /* RespCmd */ | 
					
						
							|  |  |  |         return s->respcmd; | 
					
						
							|  |  |  |     case 0x14: /* Response0 */ | 
					
						
							|  |  |  |         return s->response[0]; | 
					
						
							|  |  |  |     case 0x18: /* Response1 */ | 
					
						
							|  |  |  |         return s->response[1]; | 
					
						
							|  |  |  |     case 0x1c: /* Response2 */ | 
					
						
							|  |  |  |         return s->response[2]; | 
					
						
							|  |  |  |     case 0x20: /* Response3 */ | 
					
						
							|  |  |  |         return s->response[3]; | 
					
						
							|  |  |  |     case 0x24: /* DataTimer */ | 
					
						
							|  |  |  |         return s->datatimer; | 
					
						
							|  |  |  |     case 0x28: /* DataLength */ | 
					
						
							|  |  |  |         return s->datalength; | 
					
						
							|  |  |  |     case 0x2c: /* DataCtrl */ | 
					
						
							|  |  |  |         return s->datactrl; | 
					
						
							|  |  |  |     case 0x30: /* DataCnt */ | 
					
						
							|  |  |  |         return s->datacnt; | 
					
						
							|  |  |  |     case 0x34: /* Status */ | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |         tmp = s->status; | 
					
						
							|  |  |  |         if (s->linux_hack) { | 
					
						
							|  |  |  |             s->linux_hack = 0; | 
					
						
							|  |  |  |             pl181_fifo_run(s); | 
					
						
							|  |  |  |             pl181_update(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return tmp; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     case 0x3c: /* Mask0 */ | 
					
						
							|  |  |  |         return s->mask[0]; | 
					
						
							|  |  |  |     case 0x40: /* Mask1 */ | 
					
						
							|  |  |  |         return s->mask[1]; | 
					
						
							|  |  |  |     case 0x48: /* FifoCnt */ | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |         /* The documentation is somewhat vague about exactly what FifoCnt
 | 
					
						
							|  |  |  |            does.  On real hardware it appears to be when decrememnted | 
					
						
							| 
									
										
										
										
											2011-11-29 16:52:39 +08:00
										 |  |  |            when a word is transferred between the FIFO and the serial | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |            data engine.  DataCnt is decremented after each byte is | 
					
						
							| 
									
										
										
										
											2011-11-29 16:52:39 +08:00
										 |  |  |            transferred between the serial engine and the card. | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |            We don't emulate this level of detail, so both can be the same.  */ | 
					
						
							|  |  |  |         tmp = (s->datacnt + 3) >> 2; | 
					
						
							|  |  |  |         if (s->linux_hack) { | 
					
						
							|  |  |  |             s->linux_hack = 0; | 
					
						
							|  |  |  |             pl181_fifo_run(s); | 
					
						
							|  |  |  |             pl181_update(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return tmp; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */ | 
					
						
							|  |  |  |     case 0x90: case 0x94: case 0x98: case 0x9c: | 
					
						
							|  |  |  |     case 0xa0: case 0xa4: case 0xa8: case 0xac: | 
					
						
							|  |  |  |     case 0xb0: case 0xb4: case 0xb8: case 0xbc: | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |         if (s->fifo_len == 0) { | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |             qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n"); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             uint32_t value; | 
					
						
							|  |  |  |             value = pl181_fifo_pop(s); | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |             s->linux_hack = 1; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |             pl181_fifo_run(s); | 
					
						
							|  |  |  |             pl181_update(s); | 
					
						
							|  |  |  |             return value; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "pl181_read: Bad offset %x\n", (int)offset); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void pl181_write(void *opaque, hwaddr offset, | 
					
						
							| 
									
										
										
										
											2011-10-11 13:54:48 +02:00
										 |  |  |                         uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  |     PL181State *s = (PL181State *)opaque; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (offset) { | 
					
						
							|  |  |  |     case 0x00: /* Power */ | 
					
						
							|  |  |  |         s->power = value & 0xff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x04: /* Clock */ | 
					
						
							|  |  |  |         s->clock = value & 0xff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x08: /* Argument */ | 
					
						
							|  |  |  |         s->cmdarg = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0c: /* Command */ | 
					
						
							|  |  |  |         s->cmd = value; | 
					
						
							|  |  |  |         if (s->cmd & PL181_CMD_ENABLE) { | 
					
						
							|  |  |  |             if (s->cmd & PL181_CMD_INTERRUPT) { | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |                 qemu_log_mask(LOG_UNIMP, | 
					
						
							|  |  |  |                               "pl181: Interrupt mode not implemented\n"); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |             } if (s->cmd & PL181_CMD_PENDING) { | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |                 qemu_log_mask(LOG_UNIMP, | 
					
						
							|  |  |  |                               "pl181: Pending commands not implemented\n"); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-07-05 19:42:05 +02:00
										 |  |  |                 pl181_do_command(s); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |                 pl181_fifo_run(s); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             /* The command has completed one way or the other.  */ | 
					
						
							|  |  |  |             s->cmd &= ~PL181_CMD_ENABLE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x24: /* DataTimer */ | 
					
						
							|  |  |  |         s->datatimer = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x28: /* DataLength */ | 
					
						
							|  |  |  |         s->datalength = value & 0xffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x2c: /* DataCtrl */ | 
					
						
							|  |  |  |         s->datactrl = value & 0xff; | 
					
						
							|  |  |  |         if (value & PL181_DATA_ENABLE) { | 
					
						
							|  |  |  |             s->datacnt = s->datalength; | 
					
						
							|  |  |  |             pl181_fifo_run(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x38: /* Clear */ | 
					
						
							|  |  |  |         s->status &= ~(value & 0x7ff); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x3c: /* Mask0 */ | 
					
						
							|  |  |  |         s->mask[0] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x40: /* Mask1 */ | 
					
						
							|  |  |  |         s->mask[1] = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */ | 
					
						
							|  |  |  |     case 0x90: case 0x94: case 0x98: case 0x9c: | 
					
						
							|  |  |  |     case 0xa0: case 0xa4: case 0xa8: case 0xac: | 
					
						
							|  |  |  |     case 0xb0: case 0xb4: case 0xb8: case 0xbc: | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |         if (s->datacnt == 0) { | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |             qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n"); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             pl181_fifo_push(s, value); | 
					
						
							|  |  |  |             pl181_fifo_run(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2012-10-18 14:11:37 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "pl181_write: Bad offset %x\n", (int)offset); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     pl181_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 13:54:48 +02:00
										 |  |  | static const MemoryRegionOps pl181_ops = { | 
					
						
							|  |  |  |     .read = pl181_read, | 
					
						
							|  |  |  |     .write = pl181_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  | static void pl181_set_readonly(DeviceState *dev, bool level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PL181State *s = (PL181State *)dev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qemu_set_irq(s->card_readonly, level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pl181_set_inserted(DeviceState *dev, bool level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PL181State *s = (PL181State *)dev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qemu_set_irq(s->card_inserted, level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  | static void pl181_reset(DeviceState *d) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  |     PL181State *s = PL181(d); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->power = 0; | 
					
						
							|  |  |  |     s->cmdarg = 0; | 
					
						
							|  |  |  |     s->cmd = 0; | 
					
						
							|  |  |  |     s->datatimer = 0; | 
					
						
							|  |  |  |     s->datalength = 0; | 
					
						
							|  |  |  |     s->respcmd = 0; | 
					
						
							|  |  |  |     s->response[0] = 0; | 
					
						
							|  |  |  |     s->response[1] = 0; | 
					
						
							|  |  |  |     s->response[2] = 0; | 
					
						
							|  |  |  |     s->response[3] = 0; | 
					
						
							|  |  |  |     s->datatimer = 0; | 
					
						
							|  |  |  |     s->datalength = 0; | 
					
						
							|  |  |  |     s->datactrl = 0; | 
					
						
							|  |  |  |     s->datacnt = 0; | 
					
						
							|  |  |  |     s->status = 0; | 
					
						
							| 
									
										
										
										
											2007-06-09 14:07:54 +00:00
										 |  |  |     s->linux_hack = 0; | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  |     s->mask[0] = 0; | 
					
						
							|  |  |  |     s->mask[1] = 0; | 
					
						
							| 
									
										
										
										
											2011-02-21 20:57:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  |     /* Reset other state based on current card insertion/readonly status */ | 
					
						
							|  |  |  |     pl181_set_inserted(DEVICE(s), sdbus_get_inserted(&s->sdbus)); | 
					
						
							|  |  |  |     pl181_set_readonly(DEVICE(s), sdbus_get_readonly(&s->sdbus)); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  | static void pl181_init(Object *obj) | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  |     DeviceState *dev = DEVICE(obj); | 
					
						
							|  |  |  |     PL181State *s = PL181(obj); | 
					
						
							|  |  |  |     SysBusDevice *sbd = SYS_BUS_DEVICE(obj); | 
					
						
							| 
									
										
										
										
											2007-04-06 16:49:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  |     memory_region_init_io(&s->iomem, obj, &pl181_ops, s, "pl181", 0x1000); | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  |     sysbus_init_mmio(sbd, &s->iomem); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->irq[0]); | 
					
						
							|  |  |  |     sysbus_init_irq(sbd, &s->irq[1]); | 
					
						
							| 
									
										
										
										
											2020-07-05 13:39:53 +02:00
										 |  |  |     qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1); | 
					
						
							|  |  |  |     qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1); | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), | 
					
						
							|  |  |  |                         TYPE_PL181_BUS, dev, "sd-bus"); | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void pl181_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *k = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     k->vmsd = &vmstate_pl181; | 
					
						
							|  |  |  |     k->reset = pl181_reset; | 
					
						
							| 
									
										
										
										
											2020-07-05 14:24:24 +02:00
										 |  |  |     /* Reason: output IRQs should be wired up */ | 
					
						
							| 
									
										
										
										
											2017-05-03 17:35:44 -03:00
										 |  |  |     k->user_creatable = false; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo pl181_info = { | 
					
						
							| 
									
										
										
										
											2013-07-27 13:23:41 +02:00
										 |  |  |     .name          = TYPE_PL181, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							| 
									
										
										
										
											2013-07-27 13:20:09 +02:00
										 |  |  |     .instance_size = sizeof(PL181State), | 
					
						
							| 
									
										
										
										
											2016-06-14 15:59:14 +01:00
										 |  |  |     .instance_init = pl181_init, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .class_init    = pl181_class_init, | 
					
						
							| 
									
										
										
										
											2011-12-19 12:01:44 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  | static void pl181_bus_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SDBusClass *sbc = SD_BUS_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sbc->set_inserted = pl181_set_inserted; | 
					
						
							|  |  |  |     sbc->set_readonly = pl181_set_readonly; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const TypeInfo pl181_bus_info = { | 
					
						
							|  |  |  |     .name = TYPE_PL181_BUS, | 
					
						
							|  |  |  |     .parent = TYPE_SD_BUS, | 
					
						
							|  |  |  |     .instance_size = sizeof(SDBus), | 
					
						
							|  |  |  |     .class_init = pl181_bus_class_init, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void pl181_register_types(void) | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:07 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&pl181_info); | 
					
						
							| 
									
										
										
										
											2018-01-23 04:58:35 +01:00
										 |  |  |     type_register_static(&pl181_bus_info); | 
					
						
							| 
									
										
										
										
											2009-05-14 22:35:07 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(pl181_register_types) |