| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Written by Richard Henderson. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This work is licensed under the GNU GPL license version 2 or later. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:17:04 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  | #include "qemu/units.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"
 | 
					
						
							| 
									
										
										
										
											2022-12-22 11:03:24 +01:00
										 |  |  | #include "hw/pci/pci_host.h"
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | #include "cpu.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | #include "hw/irq.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-18 17:36:02 +01:00
										 |  |  | #include "alpha_sys.h"
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  | #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:20 +10:00
										 |  |  | #define TYPE_TYPHOON_IOMMU_MEMORY_REGION "typhoon-iommu-memory-region"
 | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | typedef struct TyphoonCchip { | 
					
						
							|  |  |  |     MemoryRegion region; | 
					
						
							|  |  |  |     uint64_t misc; | 
					
						
							|  |  |  |     uint64_t drir; | 
					
						
							|  |  |  |     uint64_t dim[4]; | 
					
						
							|  |  |  |     uint32_t iic[4]; | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  |     AlphaCPU *cpu[4]; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } TyphoonCchip; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct TyphoonWindow { | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |     uint64_t wba; | 
					
						
							|  |  |  |     uint64_t wsm; | 
					
						
							|  |  |  |     uint64_t tba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } TyphoonWindow; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | typedef struct TyphoonPchip { | 
					
						
							|  |  |  |     MemoryRegion region; | 
					
						
							|  |  |  |     MemoryRegion reg_iack; | 
					
						
							|  |  |  |     MemoryRegion reg_mem; | 
					
						
							|  |  |  |     MemoryRegion reg_io; | 
					
						
							|  |  |  |     MemoryRegion reg_conf; | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     AddressSpace iommu_as; | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:19 +10:00
										 |  |  |     IOMMUMemoryRegion iommu; | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     uint64_t ctl; | 
					
						
							|  |  |  |     TyphoonWindow win[4]; | 
					
						
							|  |  |  | } TyphoonPchip; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(TyphoonState, TYPHOON_PCI_HOST_BRIDGE) | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | struct TyphoonState { | 
					
						
							| 
									
										
										
										
											2012-08-20 19:08:09 +02:00
										 |  |  |     PCIHostState parent_obj; | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     TyphoonCchip cchip; | 
					
						
							|  |  |  |     TyphoonPchip pchip; | 
					
						
							|  |  |  |     MemoryRegion dchip_region; | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Called when one of DRIR or DIM changes.  */ | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  | static void cpu_irq_change(AlphaCPU *cpu, uint64_t req) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     /* If there are any non-masked interrupts, tell the cpu.  */ | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  |     if (cpu != NULL) { | 
					
						
							| 
									
										
										
										
											2013-01-17 22:30:20 +01:00
										 |  |  |         CPUState *cs = CPU(cpu); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         if (req) { | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |             cpu_interrupt(cs, CPU_INTERRUPT_HARD); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2013-01-17 22:30:20 +01:00
										 |  |  |             cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | static MemTxResult cchip_read(void *opaque, hwaddr addr, | 
					
						
							|  |  |  |                               uint64_t *data, unsigned size, | 
					
						
							|  |  |  |                               MemTxAttrs attrs) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-27 05:17:50 +02:00
										 |  |  |     CPUState *cpu = current_cpu; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     TyphoonState *s = opaque; | 
					
						
							|  |  |  |     uint64_t ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case 0x0000: | 
					
						
							|  |  |  |         /* CSC: Cchip System Configuration Register.  */ | 
					
						
							|  |  |  |         /* All sorts of data here; probably the only thing relevant is
 | 
					
						
							|  |  |  |            PIP<14> Pchip 1 Present = 0.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0040: | 
					
						
							|  |  |  |         /* MTR: Memory Timing Register.  */ | 
					
						
							|  |  |  |         /* All sorts of stuff related to real DRAM.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0080: | 
					
						
							|  |  |  |         /* MISC: Miscellaneous Register.  */ | 
					
						
							| 
									
										
										
										
											2012-12-17 06:18:02 +01:00
										 |  |  |         ret = s->cchip.misc | (cpu->cpu_index & 3); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x00c0: | 
					
						
							|  |  |  |         /* MPD: Memory Presence Detect Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0100: /* AAR0 */ | 
					
						
							|  |  |  |     case 0x0140: /* AAR1 */ | 
					
						
							|  |  |  |     case 0x0180: /* AAR2 */ | 
					
						
							|  |  |  |     case 0x01c0: /* AAR3 */ | 
					
						
							|  |  |  |         /* AAR: Array Address Register.  */ | 
					
						
							|  |  |  |         /* All sorts of information about DRAM.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0200: | 
					
						
							|  |  |  |         /* DIM0: Device Interrupt Mask Register, CPU0.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[0]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0240: | 
					
						
							|  |  |  |         /* DIM1: Device Interrupt Mask Register, CPU1.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[1]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0280: | 
					
						
							|  |  |  |         /* DIR0: Device Interrupt Request Register, CPU0.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[0] & s->cchip.drir; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x02c0: | 
					
						
							|  |  |  |         /* DIR1: Device Interrupt Request Register, CPU1.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[1] & s->cchip.drir; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0300: | 
					
						
							|  |  |  |         /* DRIR: Device Raw Interrupt Request Register.  */ | 
					
						
							|  |  |  |         ret = s->cchip.drir; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0340: | 
					
						
							|  |  |  |         /* PRBEN: Probe Enable Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0380: | 
					
						
							|  |  |  |         /* IIC0: Interval Ignore Count Register, CPU0.  */ | 
					
						
							|  |  |  |         ret = s->cchip.iic[0]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x03c0: | 
					
						
							|  |  |  |         /* IIC1: Interval Ignore Count Register, CPU1.  */ | 
					
						
							|  |  |  |         ret = s->cchip.iic[1]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0400: /* MPR0 */ | 
					
						
							|  |  |  |     case 0x0440: /* MPR1 */ | 
					
						
							|  |  |  |     case 0x0480: /* MPR2 */ | 
					
						
							|  |  |  |     case 0x04c0: /* MPR3 */ | 
					
						
							|  |  |  |         /* MPR: Memory Programming Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0580: | 
					
						
							|  |  |  |         /* TTR: TIGbus Timing Register.  */ | 
					
						
							|  |  |  |         /* All sorts of stuff related to interrupt delivery timings.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x05c0: | 
					
						
							|  |  |  |         /* TDR: TIGbug Device Timing Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0600: | 
					
						
							|  |  |  |         /* DIM2: Device Interrupt Mask Register, CPU2.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[2]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0640: | 
					
						
							|  |  |  |         /* DIM3: Device Interrupt Mask Register, CPU3.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[3]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0680: | 
					
						
							|  |  |  |         /* DIR2: Device Interrupt Request Register, CPU2.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[2] & s->cchip.drir; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x06c0: | 
					
						
							|  |  |  |         /* DIR3: Device Interrupt Request Register, CPU3.  */ | 
					
						
							|  |  |  |         ret = s->cchip.dim[3] & s->cchip.drir; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0700: | 
					
						
							|  |  |  |         /* IIC2: Interval Ignore Count Register, CPU2.  */ | 
					
						
							|  |  |  |         ret = s->cchip.iic[2]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0740: | 
					
						
							|  |  |  |         /* IIC3: Interval Ignore Count Register, CPU3.  */ | 
					
						
							|  |  |  |         ret = s->cchip.iic[3]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0780: | 
					
						
							|  |  |  |         /* PWR: Power Management Control.   */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     case 0x0c00: /* CMONCTLA */ | 
					
						
							|  |  |  |     case 0x0c40: /* CMONCTLB */ | 
					
						
							|  |  |  |     case 0x0c80: /* CMONCNT01 */ | 
					
						
							|  |  |  |     case 0x0cc0: /* CMONCNT23 */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |         return MEMTX_ERROR; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |     *data = ret; | 
					
						
							|  |  |  |     return MEMTX_OK; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     /* Skip this.  It's all related to DRAM timing and setup.  */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | static MemTxResult pchip_read(void *opaque, hwaddr addr, uint64_t *data, | 
					
						
							|  |  |  |                               unsigned size, MemTxAttrs attrs) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							|  |  |  |     uint64_t ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case 0x0000: | 
					
						
							|  |  |  |         /* WSBA0: Window Space Base Address Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[0].wba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0040: | 
					
						
							|  |  |  |         /* WSBA1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[1].wba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0080: | 
					
						
							|  |  |  |         /* WSBA2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[2].wba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x00c0: | 
					
						
							|  |  |  |         /* WSBA3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[3].wba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0100: | 
					
						
							|  |  |  |         /* WSM0: Window Space Mask Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[0].wsm; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0140: | 
					
						
							|  |  |  |         /* WSM1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[1].wsm; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0180: | 
					
						
							|  |  |  |         /* WSM2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[2].wsm; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x01c0: | 
					
						
							|  |  |  |         /* WSM3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[3].wsm; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0200: | 
					
						
							|  |  |  |         /* TBA0: Translated Base Address Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[0].tba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0240: | 
					
						
							|  |  |  |         /* TBA1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[1].tba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0280: | 
					
						
							|  |  |  |         /* TBA2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[2].tba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x02c0: | 
					
						
							|  |  |  |         /* TBA3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         ret = s->pchip.win[3].tba; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0300: | 
					
						
							|  |  |  |         /* PCTL: Pchip Control Register.  */ | 
					
						
							|  |  |  |         ret = s->pchip.ctl; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0340: | 
					
						
							|  |  |  |         /* PLAT: Pchip Master Latency Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x03c0: | 
					
						
							|  |  |  |         /* PERROR: Pchip Error Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0400: | 
					
						
							|  |  |  |         /* PERRMASK: Pchip Error Mask Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0440: | 
					
						
							|  |  |  |         /* PERRSET: Pchip Error Set Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0480: | 
					
						
							|  |  |  |         /* TLBIV: Translation Buffer Invalidate Virtual Register (WO).  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x04c0: | 
					
						
							|  |  |  |         /* TLBIA: Translation Buffer Invalidate All Register (WO).  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0500: /* PMONCTL */ | 
					
						
							|  |  |  |     case 0x0540: /* PMONCNT */ | 
					
						
							|  |  |  |     case 0x0800: /* SPRST */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |         return MEMTX_ERROR; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |     *data = ret; | 
					
						
							|  |  |  |     return MEMTX_OK; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | static MemTxResult cchip_write(void *opaque, hwaddr addr, | 
					
						
							|  |  |  |                                uint64_t val, unsigned size, | 
					
						
							|  |  |  |                                MemTxAttrs attrs) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |     uint64_t oldval, newval; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case 0x0000: | 
					
						
							|  |  |  |         /* CSC: Cchip System Configuration Register.  */ | 
					
						
							|  |  |  |         /* All sorts of data here; nothing relevant RW.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0040: | 
					
						
							|  |  |  |         /* MTR: Memory Timing Register.  */ | 
					
						
							|  |  |  |         /* All sorts of stuff related to real DRAM.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0080: | 
					
						
							|  |  |  |         /* MISC: Miscellaneous Register.  */ | 
					
						
							|  |  |  |         newval = oldval = s->cchip.misc; | 
					
						
							|  |  |  |         newval &= ~(val & 0x10000ff0);     /* W1C fields */ | 
					
						
							|  |  |  |         if (val & 0x100000) { | 
					
						
							|  |  |  |             newval &= ~0xff0000ull;        /* ACL clears ABT and ABW */ | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             newval |= val & 0x00f00000;    /* ABT field is W1S */ | 
					
						
							|  |  |  |             if ((newval & 0xf0000) == 0) { | 
					
						
							|  |  |  |                 newval |= val & 0xf0000;   /* ABW field is W1S iff zero */ | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         newval &= ~0xf0000000000ull;       /* WO and RW fields */ | 
					
						
							|  |  |  |         newval |= val & 0xf0000000000ull; | 
					
						
							|  |  |  |         s->cchip.misc = newval; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Pass on changes to IPI and ITI state.  */ | 
					
						
							|  |  |  |         if ((newval ^ oldval) & 0xff0) { | 
					
						
							|  |  |  |             int i; | 
					
						
							|  |  |  |             for (i = 0; i < 4; ++i) { | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  |                 AlphaCPU *cpu = s->cchip.cpu[i]; | 
					
						
							|  |  |  |                 if (cpu != NULL) { | 
					
						
							| 
									
										
										
										
											2013-01-17 22:30:20 +01:00
										 |  |  |                     CPUState *cs = CPU(cpu); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |                     /* IPI can be either cleared or set by the write.  */ | 
					
						
							|  |  |  |                     if (newval & (1 << (i + 8))) { | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |                         cpu_interrupt(cs, CPU_INTERRUPT_SMP); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |                     } else { | 
					
						
							| 
									
										
										
										
											2013-01-17 22:30:20 +01:00
										 |  |  |                         cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     /* ITI can only be cleared by the write.  */ | 
					
						
							|  |  |  |                     if ((newval & (1 << (i + 4))) == 0) { | 
					
						
							| 
									
										
										
										
											2013-01-17 22:30:20 +01:00
										 |  |  |                         cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x00c0: | 
					
						
							|  |  |  |         /* MPD: Memory Presence Detect Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0100: /* AAR0 */ | 
					
						
							|  |  |  |     case 0x0140: /* AAR1 */ | 
					
						
							|  |  |  |     case 0x0180: /* AAR2 */ | 
					
						
							|  |  |  |     case 0x01c0: /* AAR3 */ | 
					
						
							|  |  |  |         /* AAR: Array Address Register.  */ | 
					
						
							|  |  |  |         /* All sorts of information about DRAM.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0200: /* DIM0 */ | 
					
						
							|  |  |  |         /* DIM: Device Interrupt Mask Register, CPU0.  */ | 
					
						
							|  |  |  |         s->cchip.dim[0] = val; | 
					
						
							|  |  |  |         cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0240: /* DIM1 */ | 
					
						
							|  |  |  |         /* DIM: Device Interrupt Mask Register, CPU1.  */ | 
					
						
							| 
									
										
										
										
											2016-11-22 16:53:53 +01:00
										 |  |  |         s->cchip.dim[1] = val; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0280: /* DIR0 (RO) */ | 
					
						
							|  |  |  |     case 0x02c0: /* DIR1 (RO) */ | 
					
						
							|  |  |  |     case 0x0300: /* DRIR (RO) */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0340: | 
					
						
							|  |  |  |         /* PRBEN: Probe Enable Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0380: /* IIC0 */ | 
					
						
							|  |  |  |         s->cchip.iic[0] = val & 0xffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x03c0: /* IIC1 */ | 
					
						
							|  |  |  |         s->cchip.iic[1] = val & 0xffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0400: /* MPR0 */ | 
					
						
							|  |  |  |     case 0x0440: /* MPR1 */ | 
					
						
							|  |  |  |     case 0x0480: /* MPR2 */ | 
					
						
							|  |  |  |     case 0x04c0: /* MPR3 */ | 
					
						
							|  |  |  |         /* MPR: Memory Programming Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0580: | 
					
						
							|  |  |  |         /* TTR: TIGbus Timing Register.  */ | 
					
						
							|  |  |  |         /* All sorts of stuff related to interrupt delivery timings.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x05c0: | 
					
						
							|  |  |  |         /* TDR: TIGbug Device Timing Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0600: | 
					
						
							|  |  |  |         /* DIM2: Device Interrupt Mask Register, CPU2.  */ | 
					
						
							|  |  |  |         s->cchip.dim[2] = val; | 
					
						
							|  |  |  |         cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0640: | 
					
						
							|  |  |  |         /* DIM3: Device Interrupt Mask Register, CPU3.  */ | 
					
						
							|  |  |  |         s->cchip.dim[3] = val; | 
					
						
							|  |  |  |         cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0680: /* DIR2 (RO) */ | 
					
						
							|  |  |  |     case 0x06c0: /* DIR3 (RO) */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0700: /* IIC2 */ | 
					
						
							|  |  |  |         s->cchip.iic[2] = val & 0xffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0740: /* IIC3 */ | 
					
						
							|  |  |  |         s->cchip.iic[3] = val & 0xffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0780: | 
					
						
							|  |  |  |         /* PWR: Power Management Control.   */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     case 0x0c00: /* CMONCTLA */ | 
					
						
							|  |  |  |     case 0x0c40: /* CMONCTLB */ | 
					
						
							|  |  |  |     case 0x0c80: /* CMONCNT01 */ | 
					
						
							|  |  |  |     case 0x0cc0: /* CMONCNT23 */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |         return MEMTX_ERROR; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return MEMTX_OK; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void dchip_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |                         uint64_t val, unsigned size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* Skip this.  It's all related to DRAM timing and setup.  */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | static MemTxResult pchip_write(void *opaque, hwaddr addr, | 
					
						
							|  |  |  |                                uint64_t val, unsigned size, | 
					
						
							|  |  |  |                                MemTxAttrs attrs) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |     uint64_t oldval; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case 0x0000: | 
					
						
							|  |  |  |         /* WSBA0: Window Space Base Address Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[0].wba = val & 0xfff00003u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0040: | 
					
						
							|  |  |  |         /* WSBA1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[1].wba = val & 0xfff00003u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0080: | 
					
						
							|  |  |  |         /* WSBA2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[2].wba = val & 0xfff00003u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x00c0: | 
					
						
							|  |  |  |         /* WSBA3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0100: | 
					
						
							|  |  |  |         /* WSM0: Window Space Mask Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[0].wsm = val & 0xfff00000u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0140: | 
					
						
							|  |  |  |         /* WSM1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[1].wsm = val & 0xfff00000u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0180: | 
					
						
							|  |  |  |         /* WSM2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[2].wsm = val & 0xfff00000u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x01c0: | 
					
						
							|  |  |  |         /* WSM3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[3].wsm = val & 0xfff00000u; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0200: | 
					
						
							|  |  |  |         /* TBA0: Translated Base Address Register.  */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[0].tba = val & 0x7fffffc00ull; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0240: | 
					
						
							|  |  |  |         /* TBA1 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[1].tba = val & 0x7fffffc00ull; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x0280: | 
					
						
							|  |  |  |         /* TBA2 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[2].tba = val & 0x7fffffc00ull; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case 0x02c0: | 
					
						
							|  |  |  |         /* TBA3 */ | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |         s->pchip.win[3].tba = val & 0x7fffffc00ull; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0300: | 
					
						
							|  |  |  |         /* PCTL: Pchip Control Register.  */ | 
					
						
							|  |  |  |         oldval = s->pchip.ctl; | 
					
						
							|  |  |  |         oldval &= ~0x00001cff0fc7ffull;       /* RW fields */ | 
					
						
							|  |  |  |         oldval |= val & 0x00001cff0fc7ffull; | 
					
						
							|  |  |  |         s->pchip.ctl = oldval; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0340: | 
					
						
							|  |  |  |         /* PLAT: Pchip Master Latency Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x03c0: | 
					
						
							|  |  |  |         /* PERROR: Pchip Error Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0400: | 
					
						
							|  |  |  |         /* PERRMASK: Pchip Error Mask Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0440: | 
					
						
							|  |  |  |         /* PERRSET: Pchip Error Set Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0480: | 
					
						
							|  |  |  |         /* TLBIV: Translation Buffer Invalidate Virtual Register.  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x04c0: | 
					
						
							|  |  |  |         /* TLBIA: Translation Buffer Invalidate All Register (WO).  */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0500: | 
					
						
							|  |  |  |         /* PMONCTL */ | 
					
						
							|  |  |  |     case 0x0540: | 
					
						
							|  |  |  |         /* PMONCNT */ | 
					
						
							|  |  |  |     case 0x0800: | 
					
						
							|  |  |  |         /* SPRST */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |         return MEMTX_ERROR; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return MEMTX_OK; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const MemoryRegionOps cchip_ops = { | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |     .read_with_attrs = cchip_read, | 
					
						
							|  |  |  |     .write_with_attrs = cchip_write, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     .endianness = DEVICE_LITTLE_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         .max_access_size = 8, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     .impl = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							|  |  |  |         .max_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const MemoryRegionOps dchip_ops = { | 
					
						
							|  |  |  |     .read = dchip_read, | 
					
						
							|  |  |  |     .write = dchip_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_LITTLE_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         .max_access_size = 8, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     .impl = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         .max_access_size = 8, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const MemoryRegionOps pchip_ops = { | 
					
						
							| 
									
										
										
										
											2018-12-10 17:33:50 +00:00
										 |  |  |     .read_with_attrs = pchip_read, | 
					
						
							|  |  |  |     .write_with_attrs = pchip_write, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     .endianness = DEVICE_LITTLE_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |         .max_access_size = 8, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     .impl = { | 
					
						
							| 
									
										
										
										
											2013-07-08 14:57:39 -07:00
										 |  |  |         .min_access_size = 8, | 
					
						
							|  |  |  |         .max_access_size = 8, | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  | /* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
 | 
					
						
							|  |  |  |    using the given translated address and mask.  */ | 
					
						
							|  |  |  | static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     *ret = (IOMMUTLBEntry) { | 
					
						
							|  |  |  |         .target_as = &address_space_memory, | 
					
						
							|  |  |  |         .translated_addr = taddr, | 
					
						
							|  |  |  |         .addr_mask = mask, | 
					
						
							|  |  |  |         .perm = IOMMU_RW, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A subroutine of typhoon_translate_iommu that handles scatter-gather
 | 
					
						
							|  |  |  |    translation, given the address of the PTE.  */ | 
					
						
							|  |  |  | static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
											  
											
												Switch non-CPU callers from ld/st*_phys to address_space_ld/st*
Switch all the uses of ld/st*_phys to address_space_ld/st*,
except for those cases where the address space is the CPU's
(ie cs->as). This was done with the following script which
generates a Coccinelle patch.
A few over-80-columns lines in the result were rewrapped by
hand where Coccinelle failed to do the wrapping automatically,
as well as one location where it didn't put a line-continuation
'\' when wrapping lines on a change made to a match inside
a macro definition.
===begin===
#!/bin/sh -e
# Usage:
# ./ldst-phys.spatch.sh > ldst-phys.spatch
# spatch -sp_file ldst-phys.spatch -dir . | sed -e '/^+/s/\t/        /g' > out.patch
# patch -p1 < out.patch
for FN in ub uw_le uw_be l_le l_be q_le q_be uw l q; do
cat <<EOF
@ cpu_matches_ld_${FN} @
expression E1,E2;
identifier as;
@@
ld${FN}_phys(E1->as,E2)
@ other_matches_ld_${FN} depends on !cpu_matches_ld_${FN} @
expression E1,E2;
@@
-ld${FN}_phys(E1,E2)
+address_space_ld${FN}(E1,E2, MEMTXATTRS_UNSPECIFIED, NULL)
EOF
done
for FN in b w_le w_be l_le l_be q_le q_be w l q; do
cat <<EOF
@ cpu_matches_st_${FN} @
expression E1,E2,E3;
identifier as;
@@
st${FN}_phys(E1->as,E2,E3)
@ other_matches_st_${FN} depends on !cpu_matches_st_${FN} @
expression E1,E2,E3;
@@
-st${FN}_phys(E1,E2,E3)
+address_space_st${FN}(E1,E2,E3, MEMTXATTRS_UNSPECIFIED, NULL)
EOF
done
===endit===
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
											
										 
											2015-04-26 16:49:24 +01:00
										 |  |  |     uint64_t pte = address_space_ldq(&address_space_memory, pte_addr, | 
					
						
							|  |  |  |                                      MEMTXATTRS_UNSPECIFIED, NULL); | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Check valid bit.  */ | 
					
						
							|  |  |  |     if ((pte & 1) == 0) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A subroutine of typhoon_translate_iommu that handles one of the
 | 
					
						
							|  |  |  |    four single-address-cycle translation windows.  */ | 
					
						
							|  |  |  | static bool window_translate(TyphoonWindow *win, hwaddr addr, | 
					
						
							|  |  |  |                              IOMMUTLBEntry *ret) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t wba = win->wba; | 
					
						
							|  |  |  |     uint64_t wsm = win->wsm; | 
					
						
							|  |  |  |     uint64_t tba = win->tba; | 
					
						
							|  |  |  |     uint64_t wsm_ext = wsm | 0xfffff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Check for window disabled.  */ | 
					
						
							|  |  |  |     if ((wba & 1) == 0) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Check for window hit.  */ | 
					
						
							|  |  |  |     if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (wba & 2) { | 
					
						
							|  |  |  |         /* Scatter-gather translation.  */ | 
					
						
							|  |  |  |         hwaddr pte_addr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* See table 10-6, Generating PTE address for PCI DMA Address.  */ | 
					
						
							|  |  |  |         pte_addr  = tba & ~(wsm >> 10); | 
					
						
							|  |  |  |         pte_addr |= (addr & (wsm | 0xfe000)) >> 10; | 
					
						
							|  |  |  |         return pte_translate(pte_addr, ret); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2018-12-13 23:37:37 +01:00
										 |  |  |         /* Direct-mapped translation.  */ | 
					
						
							|  |  |  |         return make_iommu_tlbe(tba & ~wsm_ext, wsm_ext, ret); | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Handle PCI-to-system address translation.  */ | 
					
						
							|  |  |  | /* TODO: A translation failure here ought to set PCI error codes on the
 | 
					
						
							|  |  |  |    Pchip and generate a machine check interrupt.  */ | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:19 +10:00
										 |  |  | static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu, | 
					
						
							|  |  |  |                                              hwaddr addr, | 
					
						
							| 
									
										
										
										
											2018-06-15 14:57:16 +01:00
										 |  |  |                                              IOMMUAccessFlags flag, | 
					
						
							|  |  |  |                                              int iommu_idx) | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu); | 
					
						
							|  |  |  |     IOMMUTLBEntry ret; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (addr <= 0xffffffffu) { | 
					
						
							|  |  |  |         /* Single-address cycle.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Check for the Window Hole, inhibiting matching.  */ | 
					
						
							|  |  |  |         if ((pchip->ctl & 0x20) | 
					
						
							|  |  |  |             && addr >= 0x80000 | 
					
						
							|  |  |  |             && addr <= 0xfffff) { | 
					
						
							|  |  |  |             goto failure; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Check the first three windows.  */ | 
					
						
							|  |  |  |         for (i = 0; i < 3; ++i) { | 
					
						
							|  |  |  |             if (window_translate(&pchip->win[i], addr, &ret)) { | 
					
						
							|  |  |  |                 goto success; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Check the fourth window for DAC disable.  */ | 
					
						
							|  |  |  |         if ((pchip->win[3].wba & 0x80000000000ull) == 0 | 
					
						
							| 
									
										
										
										
											2018-12-13 23:37:37 +01:00
										 |  |  |             && window_translate(&pchip->win[3], addr, &ret)) { | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |             goto success; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         /* Double-address cycle.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (addr >= 0x10000000000ull && addr < 0x20000000000ull) { | 
					
						
							|  |  |  |             /* Check for the DMA monster window.  */ | 
					
						
							|  |  |  |             if (pchip->ctl & 0x40) { | 
					
						
							|  |  |  |                 /* See 10.1.4.4; in particular <39:35> is ignored.  */ | 
					
						
							|  |  |  |                 make_iommu_tlbe(0, 0x007ffffffffull, &ret); | 
					
						
							| 
									
										
										
										
											2018-12-13 23:37:37 +01:00
										 |  |  |                 goto success; | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-29 17:51:20 +02:00
										 |  |  |         if (addr >= 0x80000000000ull && addr <= 0xfffffffffffull) { | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |             /* Check the fourth window for DAC enable and window enable.  */ | 
					
						
							|  |  |  |             if ((pchip->win[3].wba & 0x80000000001ull) == 0x80000000001ull) { | 
					
						
							|  |  |  |                 uint64_t pte_addr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 pte_addr  = pchip->win[3].tba & 0x7ffc00000ull; | 
					
						
							|  |  |  |                 pte_addr |= (addr & 0xffffe000u) >> 10; | 
					
						
							|  |  |  |                 if (pte_translate(pte_addr, &ret)) { | 
					
						
							| 
									
										
										
										
											2018-12-13 23:37:37 +01:00
										 |  |  |                         goto success; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  failure: | 
					
						
							|  |  |  |     ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE }; | 
					
						
							|  |  |  |  success: | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							|  |  |  |     return &s->pchip.iommu_as; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | static void typhoon_set_irq(void *opaque, int irq, int level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							|  |  |  |     uint64_t drir; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL.  */ | 
					
						
							|  |  |  |     drir = s->cchip.drir; | 
					
						
							|  |  |  |     if (level) { | 
					
						
							|  |  |  |         drir |= 1ull << irq; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         drir &= ~(1ull << irq); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     s->cchip.drir = drir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 4; ++i) { | 
					
						
							|  |  |  |         cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void typhoon_set_isa_irq(void *opaque, int irq, int level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     typhoon_set_irq(opaque, 55, level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void typhoon_set_timer_irq(void *opaque, int irq, int level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = opaque; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Thankfully, the mc146818rtc code doesn't track the IRQ state,
 | 
					
						
							|  |  |  |        and so we don't have to worry about missing interrupts just | 
					
						
							|  |  |  |        because we never actually ACK the interrupt.  Just ignore any | 
					
						
							|  |  |  |        case of the interrupt level going low.  */ | 
					
						
							|  |  |  |     if (level == 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Deliver the interrupt to each CPU, considering each CPU's IIC.  */ | 
					
						
							|  |  |  |     for (i = 0; i < 4; ++i) { | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  |         AlphaCPU *cpu = s->cchip.cpu[i]; | 
					
						
							|  |  |  |         if (cpu != NULL) { | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |             uint32_t iic = s->cchip.iic[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /* ??? The verbage in Section 10.2.2.10 isn't 100% clear.
 | 
					
						
							|  |  |  |                Bit 24 is the OverFlow bit, RO, and set when the count | 
					
						
							|  |  |  |                decrements past 0.  When is OF cleared?  My guess is that | 
					
						
							|  |  |  |                OF is actually cleared when the IIC is written, and that | 
					
						
							|  |  |  |                the ICNT field always decrements.  At least, that's an | 
					
						
							|  |  |  |                interpretation that makes sense, and "allows the CPU to | 
					
						
							|  |  |  |                determine exactly how mant interval timer ticks were | 
					
						
							|  |  |  |                skipped".  At least within the next 4M ticks...  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000); | 
					
						
							|  |  |  |             s->cchip.iic[i] = iic; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (iic & 0x1000000) { | 
					
						
							|  |  |  |                 /* Set the ITI bit for this cpu.  */ | 
					
						
							|  |  |  |                 s->cchip.misc |= 1 << (i + 4); | 
					
						
							|  |  |  |                 /* And signal the interrupt.  */ | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |                 cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-28 10:40:08 -07:00
										 |  |  | static void typhoon_alarm_timer(void *opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3); | 
					
						
							|  |  |  |     int cpu = (uintptr_t)opaque & 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set the ITI bit for this cpu.  */ | 
					
						
							|  |  |  |     s->cchip.misc |= 1 << (cpu + 4); | 
					
						
							| 
									
										
										
										
											2013-01-18 15:03:43 +01:00
										 |  |  |     cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER); | 
					
						
							| 
									
										
										
										
											2011-04-28 10:40:08 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 07:15:38 -07:00
										 |  |  | PCIBus *typhoon_init(MemoryRegion *ram, qemu_irq *p_isa_irq, | 
					
						
							|  |  |  |                      qemu_irq *p_rtc_irq, AlphaCPU *cpus[4], | 
					
						
							|  |  |  |                      pci_map_irq_fn sys_map_irq, uint8_t devfn_min) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							|  |  |  |     MemoryRegion *addr_space = get_system_memory(); | 
					
						
							|  |  |  |     DeviceState *dev; | 
					
						
							|  |  |  |     TyphoonState *s; | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  |     PCIHostState *phb; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     PCIBus *b; | 
					
						
							| 
									
										
										
										
											2011-04-28 10:40:08 -07:00
										 |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10: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_TYPHOON_PCI_HOST_BRIDGE); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  |     s = TYPHOON_PCI_HOST_BRIDGE(dev); | 
					
						
							| 
									
										
										
										
											2012-08-20 19:08:08 +02:00
										 |  |  |     phb = PCI_HOST_BRIDGE(dev); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |     s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */ | 
					
						
							|  |  |  |     s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     /* Remember the CPUs so that we can deliver interrupts to them.  */ | 
					
						
							| 
									
										
										
										
											2011-04-28 10:40:08 -07:00
										 |  |  |     for (i = 0; i < 4; i++) { | 
					
						
							| 
									
										
										
										
											2012-10-16 02:45:53 +02:00
										 |  |  |         AlphaCPU *cpu = cpus[i]; | 
					
						
							|  |  |  |         s->cchip.cpu[i] = cpu; | 
					
						
							|  |  |  |         if (cpu != NULL) { | 
					
						
							| 
									
										
										
										
											2013-08-21 16:03:08 +01:00
										 |  |  |             cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | 
					
						
							| 
									
										
										
										
											2011-04-28 10:40:08 -07:00
										 |  |  |                                                  typhoon_alarm_timer, | 
					
						
							|  |  |  |                                                  (void *)((uintptr_t)s + i)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 07:15:38 -07:00
										 |  |  |     *p_isa_irq = qemu_allocate_irq(typhoon_set_isa_irq, s, 0); | 
					
						
							| 
									
										
										
										
											2015-05-29 13:27:09 +08:00
										 |  |  |     *p_rtc_irq = qemu_allocate_irq(typhoon_set_timer_irq, s, 0); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Main memory region, 0x00.0000.0000.  Real hardware supports 32GB,
 | 
					
						
							|  |  |  |        but the address space hole reserved at this point is 8TB.  */ | 
					
						
							| 
									
										
										
										
											2020-02-19 11:08:42 -05:00
										 |  |  |     memory_region_add_subregion(addr_space, 0, ram); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* TIGbus, 0x801.0000.0000, 1GB.  */ | 
					
						
							|  |  |  |     /* ??? The TIGbus is used for delivering interrupts, and access to
 | 
					
						
							|  |  |  |        the flash ROM.  I'm not sure that we need to implement it at all.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Pchip0 CSRs, 0x801.8000.0000, 256MB.  */ | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->pchip.region, OBJECT(s), &pchip_ops, s, "pchip0", | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           256 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x80180000000ULL, | 
					
						
							|  |  |  |                                 &s->pchip.region); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Cchip CSRs, 0x801.A000.0000, 256MB.  */ | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->cchip.region, OBJECT(s), &cchip_ops, s, "cchip0", | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           256 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x801a0000000ULL, | 
					
						
							|  |  |  |                                 &s->cchip.region); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Dchip CSRs, 0x801.B000.0000, 256MB.  */ | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->dchip_region, OBJECT(s), &dchip_ops, s, "dchip0", | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           256 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x801b0000000ULL, | 
					
						
							|  |  |  |                                 &s->dchip_region); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */ | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |     memory_region_init(&s->pchip.reg_mem, OBJECT(s), "pci0-mem", 4 * GiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x80000000000ULL, | 
					
						
							|  |  |  |                                 &s->pchip.reg_mem); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */ | 
					
						
							| 
									
										
										
										
											2013-07-08 15:46:37 -07:00
										 |  |  |     memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops, | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           NULL, "pci0-io", 32 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x801fc000000ULL, | 
					
						
							|  |  |  |                                 &s->pchip.reg_io); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 19:46:22 +11:00
										 |  |  |     b = pci_register_root_bus(dev, "pci", | 
					
						
							|  |  |  |                               typhoon_set_irq, sys_map_irq, s, | 
					
						
							|  |  |  |                               &s->pchip.reg_mem, &s->pchip.reg_io, | 
					
						
							| 
									
										
										
										
											2021-06-13 14:15:47 -07:00
										 |  |  |                               devfn_min, 64, TYPE_PCI_BUS); | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  |     phb->bus = b; | 
					
						
							| 
									
										
											  
											
												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(SYS_BUS_DEVICE(dev), &error_fatal); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |     /* Host memory as seen from the PCI side, via the IOMMU.  */ | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:20 +10:00
										 |  |  |     memory_region_init_iommu(&s->pchip.iommu, sizeof(s->pchip.iommu), | 
					
						
							|  |  |  |                              TYPE_TYPHOON_IOMMU_MEMORY_REGION, OBJECT(s), | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |                              "iommu-typhoon", UINT64_MAX); | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:19 +10:00
										 |  |  |     address_space_init(&s->pchip.iommu_as, MEMORY_REGION(&s->pchip.iommu), | 
					
						
							|  |  |  |                        "pchip0-pci"); | 
					
						
							| 
									
										
										
										
											2013-08-04 15:27:13 -10:00
										 |  |  |     pci_setup_iommu(b, typhoon_pci_dma_iommu, s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  |     /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */ | 
					
						
							| 
									
										
										
										
											2013-07-08 13:55:30 -07:00
										 |  |  |     memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops, | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           b, "pci0-iack", 64 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x801f8000000ULL, | 
					
						
							|  |  |  |                                 &s->pchip.reg_iack); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */ | 
					
						
							| 
									
										
										
										
											2013-07-08 13:55:30 -07:00
										 |  |  |     memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops, | 
					
						
							| 
									
										
										
										
											2018-06-25 09:42:14 -03:00
										 |  |  |                           b, "pci0-conf", 16 * MiB); | 
					
						
							| 
									
										
										
										
											2011-10-09 08:50:50 +02:00
										 |  |  |     memory_region_add_subregion(addr_space, 0x801fe000000ULL, | 
					
						
							|  |  |  |                                 &s->pchip.reg_conf); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* For the record, these are the mappings for the second PCI bus.
 | 
					
						
							|  |  |  |        We can get away with not implementing them because we indicate | 
					
						
							|  |  |  |        via the Cchip.CSC<PIP> bit that Pchip1 is not present.  */ | 
					
						
							|  |  |  |     /* Pchip1 PCI memory, 0x802.0000.0000, 4GB.  */ | 
					
						
							|  |  |  |     /* Pchip1 CSRs, 0x802.8000.0000, 256MB.  */ | 
					
						
							|  |  |  |     /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB.  */ | 
					
						
							|  |  |  |     /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB.  */ | 
					
						
							|  |  |  |     /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return b; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:56 +02:00
										 |  |  | static const TypeInfo typhoon_pcihost_info = { | 
					
						
							| 
									
										
										
										
											2012-08-20 19:07:57 +02:00
										 |  |  |     .name          = TYPE_TYPHOON_PCI_HOST_BRIDGE, | 
					
						
							| 
									
										
										
										
											2012-08-20 19:08:08 +02:00
										 |  |  |     .parent        = TYPE_PCI_HOST_BRIDGE, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .instance_size = sizeof(TyphoonState), | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:20 +10:00
										 |  |  | static void typhoon_iommu_memory_region_class_init(ObjectClass *klass, | 
					
						
							|  |  |  |                                                    void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     imrc->translate = typhoon_translate_iommu; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const TypeInfo typhoon_iommu_memory_region_info = { | 
					
						
							|  |  |  |     .parent = TYPE_IOMMU_MEMORY_REGION, | 
					
						
							|  |  |  |     .name = TYPE_TYPHOON_IOMMU_MEMORY_REGION, | 
					
						
							|  |  |  |     .class_init = typhoon_iommu_memory_region_class_init, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void typhoon_register_types(void) | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&typhoon_pcihost_info); | 
					
						
							| 
									
										
										
										
											2017-07-11 13:56:20 +10:00
										 |  |  |     type_register_static(&typhoon_iommu_memory_region_info); | 
					
						
							| 
									
										
										
										
											2011-08-25 11:38:59 -10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | type_init(typhoon_register_types) |