Revision 8d13fcc0 hw/etraxfs_pic.c

b/hw/etraxfs_pic.c
29 29

  
30 30
#define D(x)
31 31

  
32
#define R_RW_MASK	0
33
#define R_R_VECT	1
34
#define R_R_MASKED_VECT	2
35
#define R_R_NMI		3
36
#define R_R_GURU	4
37
#define R_MAX		5
38

  
32 39
struct fs_pic_state_t
33 40
{
34 41
	CPUState *env;
35

  
36
	uint32_t rw_mask;
37
	/* Active interrupt lines.  */
38
	uint32_t r_vect;
39
	/* Active lines, gated through the mask.  */
40
	uint32_t r_masked_vect;
41
	uint32_t r_nmi;
42
	uint32_t r_guru;
42
	uint32_t regs[R_MAX];
43 43
};
44 44

  
45 45
static void pic_update(struct fs_pic_state_t *fs)
46 46
{	
47 47
	CPUState *env = fs->env;
48
	int i;
49 48
	uint32_t vector = 0;
49
	int i;
50 50

  
51
	fs->r_masked_vect = fs->r_vect & fs->rw_mask;
51
	fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
52 52

  
53 53
	/* The ETRAX interrupt controller signals interrupts to teh core
54 54
	   through an interrupt request wire and an irq vector bus. If 
55 55
	   multiple interrupts are simultaneously active it chooses vector 
56 56
	   0x30 and lets the sw choose the priorities.  */
57
	if (fs->r_masked_vect) {
58
		uint32_t mv = fs->r_masked_vect;
57
	if (fs->regs[R_R_MASKED_VECT]) {
58
		uint32_t mv = fs->regs[R_R_MASKED_VECT];
59 59
		for (i = 0; i < 31; i++) {
60 60
			if (mv & 1) {
61 61
				vector = 0x31 + i;
......
83 83
	struct fs_pic_state_t *fs = opaque;
84 84
	uint32_t rval;
85 85

  
86
	switch (addr)
87
	{
88
		case 0x0: 
89
			rval = fs->rw_mask;
90
			break;
91
		case 0x4: 
92
			rval = fs->r_vect;
93
			break;
94
		case 0x8: 
95
			rval = fs->r_masked_vect;
96
			break;
97
		case 0xc: 
98
			rval = fs->r_nmi;
99
			break;
100
		case 0x10: 
101
			rval = fs->r_guru;
102
			break;
103
		default:
104
			cpu_abort(fs->env, "invalid PIC register.\n");
105
			break;
106

  
107
	}
86
	rval = fs->regs[addr >> 2];
108 87
	D(printf("%s %x=%x\n", __func__, addr, rval));
109 88
	return rval;
110 89
}
......
114 93
{
115 94
	struct fs_pic_state_t *fs = opaque;
116 95
	D(printf("%s addr=%x val=%x\n", __func__, addr, value));
117
	switch (addr) 
118
	{
119
		case 0x0: 
120
			fs->rw_mask = value;
121
			pic_update(fs);
122
			break;
123
		default:
124
			cpu_abort(fs->env, "invalid PIC register.\n");
125
			break;
96

  
97
	if (addr == R_RW_MASK) {
98
		fs->regs[R_RW_MASK] = value;
99
		pic_update(fs);
126 100
	}
127 101
}
128 102

  
......
147 121
static void irq_handler(void *opaque, int irq, int level)
148 122
{	
149 123
	struct fs_pic_state_t *fs = (void *)opaque;
150

  
151
	D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n", 
152
		 __func__, irq, level,
153
		 fs->rw_mask, fs->r_vect, fs->r_masked_vect));
154

  
155 124
	irq -= 1;
156
	fs->r_vect &= ~(1 << irq);
157
	fs->r_vect |= (!!level << irq);
125
	fs->regs[R_R_VECT] &= ~(1 << irq);
126
	fs->regs[R_R_VECT] |= (!!level << irq);
158 127

  
159 128
	pic_update(fs);
160 129
}
......
167 136

  
168 137
	mask = 1 << irq;
169 138
	if (level)
170
		fs->r_nmi |= mask;
139
		fs->regs[R_R_NMI] |= mask;
171 140
	else
172
		fs->r_nmi &= ~mask;
141
		fs->regs[R_R_NMI] &= ~mask;
173 142

  
174
	if (fs->r_nmi)
143
	if (fs->regs[R_R_NMI])
175 144
		cpu_interrupt(env, CPU_INTERRUPT_NMI);
176 145
	else
177 146
		cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
......
180 149
static void guru_handler(void *opaque, int irq, int level)
181 150
{	
182 151
	struct fs_pic_state_t *fs = (void *)opaque;
183
	CPUState *env = fs->env;
184
	cpu_abort(env, "%s unsupported exception\n", __func__);
185

  
152
	cpu_abort(fs->env, "%s unsupported exception\n", __func__);
186 153
}
187 154

  
188 155
struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
......
200 167
	pic->guru = qemu_allocate_irqs(guru_handler, fs, 1);
201 168

  
202 169
	intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
203
	cpu_register_physical_memory(base, 0x14, intr_vect_regs);
170
	cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs);
204 171

  
205 172
	return pic;
206 173
}

Also available in: Unified diff