| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU Sparc SLAVIO interrupt controller emulation | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-04-06 20:47:48 +00:00
										 |  |  |  * Copyright (c) 2003-2005 Fabrice Bellard | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | 
					
						
							|  |  |  |  * of this software and associated documentation files (the "Software"), to deal | 
					
						
							|  |  |  |  * in the Software without restriction, including without limitation the rights | 
					
						
							|  |  |  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
					
						
							|  |  |  |  * copies of the Software, and to permit persons to whom the Software is | 
					
						
							|  |  |  |  * furnished to do so, subject to the following conditions: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The above copyright notice and this permission notice shall be included in | 
					
						
							|  |  |  |  * all copies or substantial portions of the Software. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
					
						
							|  |  |  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
					
						
							|  |  |  |  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
					
						
							|  |  |  |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
					
						
							|  |  |  |  * THE SOFTWARE. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 17:06:20 +01:00
										 |  |  | #include "hw/sparc/sun4m.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:19:49 +01:00
										 |  |  | #include "monitor/monitor.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  | #include "trace.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-17 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | //#define DEBUG_IRQ_COUNT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Registers of interrupt controller in sun4m. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This is the interrupt controller part of chip STP2001 (Slave I/O), also | 
					
						
							|  |  |  |  * produced as NCR89C105. See | 
					
						
							|  |  |  |  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * There is a system master controller and one for each cpu. | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MAX_CPUS 16
 | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  | #define MAX_PILS 16
 | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | struct SLAVIO_INTCTLState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct SLAVIO_CPUINTCTLState { | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |     struct SLAVIO_INTCTLState *master; | 
					
						
							| 
									
										
										
										
											2011-08-07 19:06:26 +00:00
										 |  |  |     uint32_t intreg_pending; | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |     uint32_t cpu; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |     uint32_t irl_out; | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | } SLAVIO_CPUINTCTLState; | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  | #define TYPE_SLAVIO_INTCTL "slavio_intctl"
 | 
					
						
							|  |  |  | #define SLAVIO_INTCTL(obj) \
 | 
					
						
							|  |  |  |     OBJECT_CHECK(SLAVIO_INTCTLState, (obj), TYPE_SLAVIO_INTCTL) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | typedef struct SLAVIO_INTCTLState { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 12:13:59 +01:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | #ifdef DEBUG_IRQ_COUNT
 | 
					
						
							|  |  |  |     uint64_t irq_count[32]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |     qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS]; | 
					
						
							|  |  |  |     SLAVIO_CPUINTCTLState slaves[MAX_CPUS]; | 
					
						
							| 
									
										
										
										
											2011-08-07 19:06:26 +00:00
										 |  |  |     uint32_t intregm_pending; | 
					
						
							|  |  |  |     uint32_t intregm_disabled; | 
					
						
							|  |  |  |     uint32_t target_cpu; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } SLAVIO_INTCTLState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define INTCTL_MAXADDR 0xf
 | 
					
						
							| 
									
										
										
										
											2007-05-26 17:39:43 +00:00
										 |  |  | #define INTCTL_SIZE (INTCTL_MAXADDR + 1)
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  | #define INTCTLM_SIZE 0x14
 | 
					
						
							| 
									
										
										
										
											2007-12-28 18:48:39 +00:00
										 |  |  | #define MASTER_IRQ_MASK ~0x0fa2007f
 | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  | #define MASTER_DISABLE 0x80000000
 | 
					
						
							| 
									
										
										
										
											2007-12-29 20:09:57 +00:00
										 |  |  | #define CPU_SOFTIRQ_MASK 0xfffe0000
 | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  | #define CPU_IRQ_INT15_IN (1 << 15)
 | 
					
						
							|  |  |  | #define CPU_IRQ_TIMER_IN (1 << 14)
 | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  | static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // per-cpu interrupt controller
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t slavio_intctl_mem_readl(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |                                         unsigned size) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     SLAVIO_CPUINTCTLState *s = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |     uint32_t saddr, ret; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 0: | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |         ret = s->intreg_pending; | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         ret = 0; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_intctl_mem_readl(s->cpu, addr, ret); | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void slavio_intctl_mem_writel(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |                                      uint64_t val, unsigned size) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     SLAVIO_CPUINTCTLState *s = opaque; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     uint32_t saddr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_intctl_mem_writel(s->cpu, addr, val); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 1: // clear pending softints
 | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |         val &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN; | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |         s->intreg_pending &= ~val; | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s->master, 1); | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_slavio_intctl_mem_writel_clear(s->cpu, val, s->intreg_pending); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     case 2: // set softint
 | 
					
						
							| 
									
										
										
										
											2007-12-29 20:09:57 +00:00
										 |  |  |         val &= CPU_SOFTIRQ_MASK; | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |         s->intreg_pending |= val; | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s->master, 1); | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_slavio_intctl_mem_writel_set(s->cpu, val, s->intreg_pending); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  | static const MemoryRegionOps slavio_intctl_mem_ops = { | 
					
						
							|  |  |  |     .read = slavio_intctl_mem_readl, | 
					
						
							|  |  |  |     .write = slavio_intctl_mem_writel, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							|  |  |  |         .min_access_size = 4, | 
					
						
							|  |  |  |         .max_access_size = 4, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // master system interrupt controller
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t slavio_intctlm_mem_readl(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:13:59 +01:00
										 |  |  |                                          unsigned size) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |     uint32_t saddr, ret; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 0: | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  |         ret = s->intregm_pending & ~MASTER_DISABLE; | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     case 1: | 
					
						
							| 
									
										
										
										
											2007-12-28 18:48:39 +00:00
										 |  |  |         ret = s->intregm_disabled & MASTER_IRQ_MASK; | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     case 4: | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         ret = s->target_cpu; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  |         ret = 0; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_intctlm_mem_readl(addr, ret); | 
					
						
							| 
									
										
										
										
											2007-05-27 19:42:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void slavio_intctlm_mem_writel(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:13:59 +01:00
										 |  |  |                                       uint64_t val, unsigned size) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = opaque; | 
					
						
							|  |  |  |     uint32_t saddr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 17:51:19 +00:00
										 |  |  |     saddr = addr >> 2; | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_intctlm_mem_writel(addr, val); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     switch (saddr) { | 
					
						
							|  |  |  |     case 2: // clear (enable)
 | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         // Force clear unused bits
 | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  |         val &= MASTER_IRQ_MASK; | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         s->intregm_disabled &= ~val; | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_slavio_intctlm_mem_writel_enable(val, s->intregm_disabled); | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s, 1); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-01-16 09:06:32 +00:00
										 |  |  |     case 3: // set (disable; doesn't affect pending)
 | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         // Force clear unused bits
 | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  |         val &= MASTER_IRQ_MASK; | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         s->intregm_disabled |= val; | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s, 1); | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_slavio_intctlm_mem_writel_disable(val, s->intregm_disabled); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     case 4: | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         s->target_cpu = val & (MAX_CPUS - 1); | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s, 1); | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |         trace_slavio_intctlm_mem_writel_target(s->target_cpu); | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     default: | 
					
						
							| 
									
										
										
										
											2007-10-06 11:28:21 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 12:13:59 +01:00
										 |  |  | static const MemoryRegionOps slavio_intctlm_mem_ops = { | 
					
						
							|  |  |  |     .read = slavio_intctlm_mem_readl, | 
					
						
							|  |  |  |     .write = slavio_intctlm_mem_writel, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							|  |  |  |         .min_access_size = 4, | 
					
						
							|  |  |  |         .max_access_size = 4, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-23 12:23:30 +00:00
										 |  |  | void slavio_pic_info(Monitor *mon, DeviceState *dev) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							| 
									
										
										
										
											2009-03-05 23:01:23 +00:00
										 |  |  |         monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i, | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |                        s->slaves[i].intreg_pending); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-05 23:01:23 +00:00
										 |  |  |     monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n", | 
					
						
							|  |  |  |                    s->intregm_pending, s->intregm_disabled); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-23 12:23:30 +00:00
										 |  |  | void slavio_irq_info(Monitor *mon, DeviceState *dev) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #ifndef DEBUG_IRQ_COUNT
 | 
					
						
							| 
									
										
										
										
											2009-03-05 23:01:23 +00:00
										 |  |  |     monitor_printf(mon, "irq statistic code not compiled.\n"); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  |     int64_t count; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     s = SLAVIO_INTCTL(dev); | 
					
						
							| 
									
										
										
										
											2009-03-05 23:01:23 +00:00
										 |  |  |     monitor_printf(mon, "IRQ statistics:\n"); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     for (i = 0; i < 32; i++) { | 
					
						
							|  |  |  |         count = s->irq_count[i]; | 
					
						
							|  |  |  |         if (count > 0) | 
					
						
							| 
									
										
										
										
											2009-03-05 23:01:23 +00:00
										 |  |  |             monitor_printf(mon, "%2d: %" PRId64 "\n", i, count); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-08 20:36:08 +00:00
										 |  |  | static const uint32_t intbit_to_level[] = { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |     2, 3, 5, 7, 9, 11, 13, 2,   3, 5, 7, 9, 11, 13, 12, 12, | 
					
						
							|  |  |  |     6, 13, 4, 10, 8, 9, 11, 0,  0, 0, 0, 15, 15, 15, 15, 0, | 
					
						
							| 
									
										
										
										
											2009-08-08 20:36:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  | static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs) | 
					
						
							| 
									
										
										
										
											2005-04-06 20:47:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-08-04 10:50:30 +00:00
										 |  |  |     uint32_t pending = s->intregm_pending, pil_pending; | 
					
						
							|  |  |  |     unsigned int i, j; | 
					
						
							| 
									
										
										
										
											2005-04-06 20:47:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     pending &= ~s->intregm_disabled; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_check_interrupts(pending, s->intregm_disabled); | 
					
						
							| 
									
										
										
										
											2005-12-05 20:31:52 +00:00
										 |  |  |     for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							| 
									
										
										
										
											2007-08-04 10:50:30 +00:00
										 |  |  |         pil_pending = 0; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* If we are the current interrupt target, get hard interrupts */ | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  |         if (pending && !(s->intregm_disabled & MASTER_DISABLE) && | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |             (i == s->target_cpu)) { | 
					
						
							|  |  |  |             for (j = 0; j < 32; j++) { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |                 if ((pending & (1 << j)) && intbit_to_level[j]) { | 
					
						
							| 
									
										
										
										
											2009-08-08 20:36:08 +00:00
										 |  |  |                     pil_pending |= 1 << intbit_to_level[j]; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Calculate current pending hard interrupts for display */ | 
					
						
							|  |  |  |         s->slaves[i].intreg_pending &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN | | 
					
						
							|  |  |  |             CPU_IRQ_TIMER_IN; | 
					
						
							|  |  |  |         if (i == s->target_cpu) { | 
					
						
							|  |  |  |             for (j = 0; j < 32; j++) { | 
					
						
							| 
									
										
										
										
											2014-03-17 16:00:39 +00:00
										 |  |  |                 if ((s->intregm_pending & (1U << j)) && intbit_to_level[j]) { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |                     s->slaves[i].intreg_pending |= 1 << intbit_to_level[j]; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-21 20:23:21 +02:00
										 |  |  |         /* Level 15 and CPU timer interrupts are only masked when
 | 
					
						
							|  |  |  |            the MASTER_DISABLE bit is set */ | 
					
						
							|  |  |  |         if (!(s->intregm_disabled & MASTER_DISABLE)) { | 
					
						
							|  |  |  |             pil_pending |= s->slaves[i].intreg_pending & | 
					
						
							|  |  |  |                 (CPU_IRQ_INT15_IN | CPU_IRQ_TIMER_IN); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* Add soft interrupts */ | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |         pil_pending |= (s->slaves[i].intreg_pending & CPU_SOFTIRQ_MASK) >> 16; | 
					
						
							| 
									
										
										
										
											2007-08-04 10:50:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         if (set_irqs) { | 
					
						
							| 
									
										
										
										
											2011-01-31 10:42:26 +00:00
										 |  |  |             /* Since there is not really an interrupt 0 (and pil_pending
 | 
					
						
							|  |  |  |              * and irl_out bit zero are thus always zero) there is no need | 
					
						
							|  |  |  |              * to do anything with cpu_irqs[i][0] and it is OK not to do | 
					
						
							|  |  |  |              * the j=0 iteration of this loop. | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             for (j = MAX_PILS-1; j > 0; j--) { | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |                 if (pil_pending & (1 << j)) { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |                     if (!(s->slaves[i].irl_out & (1 << j))) { | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |                         qemu_irq_raise(s->cpu_irqs[i][j]); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } else { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |                     if (s->slaves[i].irl_out & (1 << j)) { | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |                         qemu_irq_lower(s->cpu_irqs[i][j]); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2005-12-05 20:31:52 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |         s->slaves[i].irl_out = pil_pending; | 
					
						
							| 
									
										
										
										
											2005-12-05 20:31:52 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-04-06 20:47:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * "irq" here is the bit number in the system interrupt register to | 
					
						
							|  |  |  |  * separate serial and keyboard interrupts sharing a level. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-05-27 16:37:49 +00:00
										 |  |  | static void slavio_set_irq(void *opaque, int irq, int level) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = opaque; | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |     uint32_t mask = 1 << irq; | 
					
						
							| 
									
										
										
										
											2009-08-08 20:36:08 +00:00
										 |  |  |     uint32_t pil = intbit_to_level[irq]; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |     unsigned int i; | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_set_irq(s->target_cpu, irq, pil, level); | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |     if (pil > 0) { | 
					
						
							|  |  |  |         if (level) { | 
					
						
							| 
									
										
										
										
											2007-08-04 10:50:30 +00:00
										 |  |  | #ifdef DEBUG_IRQ_COUNT
 | 
					
						
							|  |  |  |             s->irq_count[pil]++; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |             s->intregm_pending |= mask; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |             if (pil == 15) { | 
					
						
							|  |  |  |                 for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							|  |  |  |                     s->slaves[i].intreg_pending |= 1 << pil; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             s->intregm_pending &= ~mask; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |             if (pil == 15) { | 
					
						
							|  |  |  |                 for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							|  |  |  |                     s->slaves[i].intreg_pending &= ~(1 << pil); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2007-05-27 16:42:29 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |         slavio_check_interrupts(s, 1); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-27 16:37:49 +00:00
										 |  |  | static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) | 
					
						
							| 
									
										
										
										
											2005-12-05 20:31:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-31 09:24:14 +00:00
										 |  |  |     trace_slavio_set_timer_irq_cpu(cpu, level); | 
					
						
							| 
									
										
										
										
											2007-05-27 16:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-01 20:57:25 +00:00
										 |  |  |     if (level) { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |         s->slaves[cpu].intreg_pending |= CPU_IRQ_TIMER_IN; | 
					
						
							| 
									
										
										
										
											2008-01-01 20:57:25 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |         s->slaves[cpu].intreg_pending &= ~CPU_IRQ_TIMER_IN; | 
					
						
							| 
									
										
										
										
											2008-01-01 20:57:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-05-27 16:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |     slavio_check_interrupts(s, 1); | 
					
						
							| 
									
										
										
										
											2005-12-05 20:31:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | static void slavio_set_irq_all(void *opaque, int irq, int level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (irq < 32) { | 
					
						
							|  |  |  |         slavio_set_irq(opaque, irq, level); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         slavio_set_timer_irq_cpu(opaque, irq - 32, level); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 22:48:21 +02:00
										 |  |  | static int vmstate_intctl_post_load(void *opaque, int version_id) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = opaque; | 
					
						
							| 
									
										
										
										
											2007-09-17 08:09:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  |     slavio_check_interrupts(s, 0); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  | static const VMStateDescription vmstate_intctl_cpu = { | 
					
						
							|  |  |  |     .name ="slavio_intctl_cpu", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2014-04-16 16:01:33 +02:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  |         VMSTATE_UINT32(intreg_pending, SLAVIO_CPUINTCTLState), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  | static const VMStateDescription vmstate_intctl = { | 
					
						
							|  |  |  |     .name ="slavio_intctl", | 
					
						
							|  |  |  |     .version_id = 1, | 
					
						
							|  |  |  |     .minimum_version_id = 1, | 
					
						
							| 
									
										
										
										
											2009-09-10 03:04:30 +02:00
										 |  |  |     .post_load = vmstate_intctl_post_load, | 
					
						
							| 
									
										
										
										
											2014-04-16 16:01:33 +02:00
										 |  |  |     .fields = (VMStateField[]) { | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  |         VMSTATE_STRUCT_ARRAY(slaves, SLAVIO_INTCTLState, MAX_CPUS, 1, | 
					
						
							|  |  |  |                              vmstate_intctl_cpu, SLAVIO_CPUINTCTLState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(intregm_pending, SLAVIO_INTCTLState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(intregm_disabled, SLAVIO_INTCTLState), | 
					
						
							|  |  |  |         VMSTATE_UINT32(target_cpu, SLAVIO_INTCTLState), | 
					
						
							|  |  |  |         VMSTATE_END_OF_LIST() | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-28 20:22:52 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 19:44:37 +00:00
										 |  |  | static void slavio_intctl_reset(DeviceState *d) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     SLAVIO_INTCTLState *s = SLAVIO_INTCTL(d); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |         s->slaves[i].intreg_pending = 0; | 
					
						
							| 
									
										
										
										
											2009-08-25 18:29:36 +00:00
										 |  |  |         s->slaves[i].irl_out = 0; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-11-17 21:01:04 +00:00
										 |  |  |     s->intregm_disabled = ~MASTER_IRQ_MASK; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  |     s->intregm_pending = 0; | 
					
						
							|  |  |  |     s->target_cpu = 0; | 
					
						
							| 
									
										
										
										
											2009-06-17 17:20:01 +00:00
										 |  |  |     slavio_check_interrupts(s, 0); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  | static int slavio_intctl_init1(SysBusDevice *sbd) | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     DeviceState *dev = DEVICE(sbd); | 
					
						
							|  |  |  |     SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev); | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |     unsigned int i, j; | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |     char slave_name[45]; | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     qdev_init_gpio_in(dev, slavio_set_irq_all, 32 + MAX_CPUS); | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->iomem, OBJECT(s), &slavio_intctlm_mem_ops, s, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:13:59 +01:00
										 |  |  |                           "master-interrupt-controller", INTCTLM_SIZE); | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     sysbus_init_mmio(sbd, &s->iomem); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < MAX_CPUS; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |         snprintf(slave_name, sizeof(slave_name), | 
					
						
							|  |  |  |                  "slave-interrupt-controller-%i", i); | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |         for (j = 0; j < MAX_PILS; j++) { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |             sysbus_init_irq(sbd, &s->cpu_irqs[i][j]); | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |         memory_region_init_io(&s->slaves[i].iomem, OBJECT(s), | 
					
						
							|  |  |  |                               &slavio_intctl_mem_ops, | 
					
						
							| 
									
										
										
										
											2011-11-15 12:14:00 +01:00
										 |  |  |                               &s->slaves[i], slave_name, INTCTL_SIZE); | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |         sysbus_init_mmio(sbd, &s->slaves[i].iomem); | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  |         s->slaves[i].cpu = i; | 
					
						
							|  |  |  |         s->slaves[i].master = s; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-24 19:44:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-14 10:36:05 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | static void slavio_intctl_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  |     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     k->init = slavio_intctl_init1; | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     dc->reset = slavio_intctl_reset; | 
					
						
							|  |  |  |     dc->vmsd = &vmstate_intctl; | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo slavio_intctl_info = { | 
					
						
							| 
									
										
										
										
											2013-07-26 20:40:40 +02:00
										 |  |  |     .name          = TYPE_SLAVIO_INTCTL, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(SLAVIO_INTCTLState), | 
					
						
							|  |  |  |     .class_init    = slavio_intctl_class_init, | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-05-27 16:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void slavio_intctl_register_types(void) | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&slavio_intctl_info); | 
					
						
							| 
									
										
										
										
											2004-12-19 23:18:01 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-07-16 14:15:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | type_init(slavio_intctl_register_types) |