Revision 70ea255d

b/hw/etraxfs_pic.c
41 41
	uint32_t r_guru;
42 42
};
43 43

  
44
static uint32_t pic_readb (void *opaque, target_phys_addr_t addr)
45
{
46
	return 0;
47
}
48
static uint32_t pic_readw (void *opaque, target_phys_addr_t addr)
49
{
50
	return 0;
44
static void pic_update(struct fs_pic_state_t *fs)
45
{	
46
	CPUState *env = fs->env;
47
	int i;
48
	uint32_t vector = 0;
49

  
50
	fs->r_masked_vect = fs->r_vect & fs->rw_mask;
51

  
52
	/* The ETRAX interrupt controller signals interrupts to teh core
53
	   through an interrupt request wire and an irq vector bus. If 
54
	   multiple interrupts are simultaneously active it chooses vector 
55
	   0x30 and lets the sw choose the priorities.  */
56
	if (fs->r_masked_vect) {
57
		uint32_t mv = fs->r_masked_vect;
58
		for (i = 0; i < 31; i++) {
59
			if (mv & 1) {
60
				vector = 0x31 + i;
61
				/* Check for multiple interrupts.  */
62
				if (mv > 1)
63
					vector = 0x30;
64
				break;
65
			}
66
			mv >>= 1;
67
		}
68
		if (vector) {
69
			env->interrupt_vector = vector;
70
			D(printf("%s vector=%x\n", __func__, vector));
71
			cpu_interrupt(env, CPU_INTERRUPT_HARD);
72
		}
73
	} else {
74
		env->interrupt_vector = 0;
75
		cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
76
		D(printf("%s reset irqs\n", __func__));
77
	}
51 78
}
52 79

  
53 80
static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
......
82 109
}
83 110

  
84 111
static void
85
pic_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
86
{
87
}
88

  
89
static void
90
pic_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
91
{
92
}
93

  
94
static void
95 112
pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
96 113
{
97 114
	struct fs_pic_state_t *fs = opaque;
......
100 117
	{
101 118
		case 0x0: 
102 119
			fs->rw_mask = value;
103
			break;
104
		case 0x4: 
105
			fs->r_vect = value;
106
			break;
107
		case 0x8: 
108
			fs->r_masked_vect = value;
109
			break;
110
		case 0xc: 
111
			fs->r_nmi = value;
112
			break;
113
		case 0x10: 
114
			fs->r_guru = value;
120
			pic_update(fs);
115 121
			break;
116 122
		default:
117 123
			cpu_abort(fs->env, "invalid PIC register.\n");
......
120 126
}
121 127

  
122 128
static CPUReadMemoryFunc *pic_read[] = {
123
	&pic_readb,
124
	&pic_readw,
129
	NULL, NULL,
125 130
	&pic_readl,
126 131
};
127 132

  
128 133
static CPUWriteMemoryFunc *pic_write[] = {
129
	&pic_writeb,
130
	&pic_writew,
134
	NULL, NULL,
131 135
	&pic_writel,
132 136
};
133 137

  
......
142 146
static void irq_handler(void *opaque, int irq, int level)
143 147
{	
144 148
	struct fs_pic_state_t *fs = (void *)opaque;
145
	CPUState *env = fs->env;
146
	int i;
147
	uint32_t vector = 0;
148 149

  
149 150
	D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n", 
150 151
		 __func__, irq, level,
......
153 154
	irq -= 1;
154 155
	fs->r_vect &= ~(1 << irq);
155 156
	fs->r_vect |= (!!level << irq);
156
	fs->r_masked_vect = fs->r_vect & fs->rw_mask;
157 157

  
158
	/* The ETRAX interrupt controller signals interrupts to teh core
159
	   through an interrupt request wire and an irq vector bus. If 
160
	   multiple interrupts are simultaneously active it chooses vector 
161
	   0x30 and lets the sw choose the priorities.  */
162
	if (fs->r_masked_vect) {
163
		uint32_t mv = fs->r_masked_vect;
164
		for (i = 0; i < 31; i++) {
165
			if (mv & 1) {
166
				vector = 0x31 + i;
167
				/* Check for multiple interrupts.  */
168
				if (mv > 1)
169
					vector = 0x30;
170
				break;
171
			}
172
			mv >>= 1;
173
		}
174
		if (vector) {
175
			env->interrupt_vector = vector;
176
			D(printf("%s vector=%x\n", __func__, vector));
177
			cpu_interrupt(env, CPU_INTERRUPT_HARD);
178
		}
179
	} else {
180
		env->interrupt_vector = 0;
181
		cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
182
		D(printf("%s reset irqs\n", __func__));
183
	}
158
	pic_update(fs);
184 159
}
185 160

  
186 161
static void nmi_handler(void *opaque, int irq, int level)
......
209 184

  
210 185
}
211 186

  
212

  
213 187
struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
214 188
{
215 189
	struct fs_pic_state_t *fs = NULL;

Also available in: Unified diff