Revision 979d98ca

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
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 38

  
39 39
struct fs_pic_state
40 40
{
41
	CPUState *env;
42
	uint32_t regs[R_MAX];
41
    CPUState *env;
42
    uint32_t regs[R_MAX];
43 43
};
44 44

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

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

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

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

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

  
81 81
static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
82 82
{
83
	struct fs_pic_state *fs = opaque;
84
	uint32_t rval;
83
    struct fs_pic_state *fs = opaque;
84
    uint32_t rval;
85 85

  
86
	rval = fs->regs[addr >> 2];
87
	D(printf("%s %x=%x\n", __func__, addr, rval));
88
	return rval;
86
    rval = fs->regs[addr >> 2];
87
    D(printf("%s %x=%x\n", __func__, addr, rval));
88
    return rval;
89 89
}
90 90

  
91 91
static void
92 92
pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
93 93
{
94
	struct fs_pic_state *fs = opaque;
95
	D(printf("%s addr=%x val=%x\n", __func__, addr, value));
94
    struct fs_pic_state *fs = opaque;
95
    D(printf("%s addr=%x val=%x\n", __func__, addr, value));
96 96

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

  
103 103
static CPUReadMemoryFunc *pic_read[] = {
104
	NULL, NULL,
105
	&pic_readl,
104
    NULL, NULL,
105
    &pic_readl,
106 106
};
107 107

  
108 108
static CPUWriteMemoryFunc *pic_write[] = {
109
	NULL, NULL,
110
	&pic_writel,
109
    NULL, NULL,
110
    &pic_writel,
111 111
};
112 112

  
113 113
void pic_info(Monitor *mon)
......
119 119
}
120 120

  
121 121
static void nmi_handler(void *opaque, int irq, int level)
122
{	
123
	struct fs_pic_state *fs = (void *)opaque;
124
	CPUState *env = fs->env;
125
	uint32_t mask;
126

  
127
	mask = 1 << irq;
128
	if (level)
129
		fs->regs[R_R_NMI] |= mask;
130
	else
131
		fs->regs[R_R_NMI] &= ~mask;
132

  
133
	if (fs->regs[R_R_NMI])
134
		cpu_interrupt(env, CPU_INTERRUPT_NMI);
135
	else
136
		cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
122
{   
123
    struct fs_pic_state *fs = (void *)opaque;
124
    CPUState *env = fs->env;
125
    uint32_t mask;
126

  
127
    mask = 1 << irq;
128
    if (level)
129
        fs->regs[R_R_NMI] |= mask;
130
    else
131
        fs->regs[R_R_NMI] &= ~mask;
132

  
133
    if (fs->regs[R_R_NMI])
134
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
135
    else
136
        cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
137 137
}
138 138

  
139 139
static void irq_handler(void *opaque, int irq, int level)
140
{	
141
	struct fs_pic_state *fs = (void *)opaque;
140
{   
141
    struct fs_pic_state *fs = (void *)opaque;
142 142

  
143
	if (irq >= 30)
144
		return nmi_handler(opaque, irq, level);
143
    if (irq >= 30)
144
        return nmi_handler(opaque, irq, level);
145 145

  
146
	irq -= 1;
147
	fs->regs[R_R_VECT] &= ~(1 << irq);
148
	fs->regs[R_R_VECT] |= (!!level << irq);
149
	pic_update(fs);
146
    irq -= 1;
147
    fs->regs[R_R_VECT] &= ~(1 << irq);
148
    fs->regs[R_R_VECT] |= (!!level << irq);
149
    pic_update(fs);
150 150
}
151 151

  
152 152
qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
153 153
{
154
	struct fs_pic_state *fs = NULL;
155
	qemu_irq *irq;
156
	int intr_vect_regs;
154
    struct fs_pic_state *fs = NULL;
155
    qemu_irq *irq;
156
    int intr_vect_regs;
157 157

  
158
	fs = qemu_mallocz(sizeof *fs);
159
	fs->env = env;
160
	irq = qemu_allocate_irqs(irq_handler, fs, 32);
158
    fs = qemu_mallocz(sizeof *fs);
159
    fs->env = env;
160
    irq = qemu_allocate_irqs(irq_handler, fs, 32);
161 161

  
162
	intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
163
	cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs);
164
	return irq;
162
    intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
163
    cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs);
164
    return irq;
165 165
}

Also available in: Unified diff