dev_irqc.cc Source File
Back to the index.
src
devices
dev_irqc.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2007-2009 Anders Gavare. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
*
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* 3. The name of the author may not be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*
27
*
28
* COMMENT: Generic IRQ controller for the test machines
29
*/
30
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include "
cpu.h
"
36
#include "
device.h
"
37
#include "
interrupt.h
"
38
#include "
machine.h
"
39
#include "
memory.h
"
40
#include "
misc.h
"
41
42
#include "
testmachine/dev_irqc.h
"
43
44
45
#define N_IRQC_INTERRUPTS 32
46
47
struct
irqc_data
{
48
struct
interrupt
irq
;
/* Connected to the CPU */
49
50
int
asserted
;
/* Current CPU irq assertion */
51
52
uint32_t
status
;
/* Interrupt Status register */
53
uint32_t
enabled
;
/* Interrupt Enable register */
54
};
55
56
57
void
irqc_interrupt_assert
(
struct
interrupt
*
interrupt
)
58
{
59
struct
irqc_data
*d = (
struct
irqc_data
*)
interrupt
->
extra
;
60
d->
status
|=
interrupt
->
line
;
61
62
if
((d->
status
& d->
enabled
) && !d->
asserted
) {
63
INTERRUPT_ASSERT
(d->
irq
);
64
d->
asserted
= 1;
65
}
66
}
67
68
69
void
irqc_interrupt_deassert
(
struct
interrupt
*
interrupt
)
70
{
71
struct
irqc_data
*d = (
struct
irqc_data
*)
interrupt
->
extra
;
72
d->
status
&= ~
interrupt
->
line
;
73
74
if
(!(d->
status
& d->
enabled
) && d->
asserted
) {
75
INTERRUPT_DEASSERT
(d->
irq
);
76
d->
asserted
= 0;
77
}
78
}
79
80
81
DEVICE_ACCESS
(irqc)
82
{
83
struct
irqc_data
*d = (
struct
irqc_data
*) extra;
84
uint64_t idata = 0, odata = 0;
85
86
if
(writeflag ==
MEM_WRITE
)
87
idata =
memory_readmax64
(
cpu
,
data
, len);
88
89
switch
(relative_addr) {
90
91
case
DEV_IRQC_IRQ
:
92
/* Status register: */
93
if
(writeflag ==
MEM_READ
) {
94
odata = d->
status
;
95
}
else
{
96
fatal
(
"[ irqc: WARNING! write to DEV_IRQC_IRQ ]\n"
);
97
}
98
break
;
99
100
case
DEV_IRQC_MASK
:
101
/* Mask interrupts by clearing Enable bits: */
102
if
(writeflag ==
MEM_READ
) {
103
fatal
(
"[ irqc: WARNING! read from DEV_IRQC_MASK ]\n"
);
104
}
else
{
105
int
old_assert = d->
status
& d->
enabled
;
106
int
new_assert;
107
108
d->
enabled
&= ~(1 << idata);
109
110
new_assert = d->
status
& d->
enabled
;
111
112
if
(!old_assert && new_assert)
113
INTERRUPT_ASSERT
(d->
irq
);
114
else
if
(old_assert && !new_assert)
115
INTERRUPT_DEASSERT
(d->
irq
);
116
}
117
break
;
118
119
case
DEV_IRQC_UNMASK
:
120
/* Unmask interrupts by setting Enable bits: */
121
if
(writeflag ==
MEM_READ
) {
122
fatal
(
"[ irqc: WARNING! read from DEV_IRQC_UNMASK ]\n"
);
123
}
else
{
124
int
old_assert = d->
status
& d->
enabled
;
125
int
new_assert;
126
127
d->
enabled
|= (1 << idata);
128
129
new_assert = d->
status
& d->
enabled
;
130
131
if
(!old_assert && new_assert)
132
INTERRUPT_ASSERT
(d->
irq
);
133
else
if
(old_assert && !new_assert)
134
INTERRUPT_DEASSERT
(d->
irq
);
135
}
136
break
;
137
138
default
:
if
(writeflag ==
MEM_WRITE
) {
139
fatal
(
"[ irqc: unimplemented write to "
140
"offset 0x%x: data=0x%x ]\n"
, (
int
)
141
relative_addr, (
int
)idata);
142
}
else
{
143
fatal
(
"[ irqc: unimplemented read from "
144
"offset 0x%x ]\n"
, (
int
)relative_addr);
145
}
146
}
147
148
if
(writeflag ==
MEM_READ
)
149
memory_writemax64
(
cpu
,
data
, len, odata);
150
151
return
1;
152
}
153
154
155
DEVINIT
(irqc)
156
{
157
struct
irqc_data
*d;
158
char
n[300];
159
int
i;
160
161
CHECK_ALLOCATION
(d = (
struct
irqc_data
*) malloc(
sizeof
(
struct
irqc_data
)));
162
memset(d, 0,
sizeof
(
struct
irqc_data
));
163
164
/* Connect to the CPU's interrupt pin: */
165
INTERRUPT_CONNECT
(
devinit
->
interrupt_path
, d->
irq
);
166
167
/* Register the interrupts: */
168
for
(i=0; i<
N_IRQC_INTERRUPTS
; i++) {
169
struct
interrupt
templ;
170
171
snprintf(n,
sizeof
(n),
"%s.irqc.%i"
,
172
devinit
->
interrupt_path
, i);
173
174
memset(&templ, 0,
sizeof
(templ));
175
templ.
line
= 1 << i;
/* Note: line contains the
176
_mask_, not line number. */
177
templ.
name
= n;
178
templ.
extra
= d;
179
templ.
interrupt_assert
=
irqc_interrupt_assert
;
180
templ.
interrupt_deassert
=
irqc_interrupt_deassert
;
181
interrupt_handler_register
(&templ);
182
}
183
184
/* Default to all interrupts enabled: */
185
d->
enabled
= 0xffffffff;
186
187
memory_device_register
(
devinit
->
machine
->
memory
,
devinit
->
name
,
188
devinit
->
addr
,
DEV_IRQC_LENGTH
, dev_irqc_access, d,
189
DM_DEFAULT
, NULL);
190
191
return
1;
192
}
193
data
u_short data
Definition:
siireg.h:79
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition:
interrupt.h:77
DEV_IRQC_UNMASK
#define DEV_IRQC_UNMASK
Definition:
dev_irqc.h:15
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition:
interrupt.h:74
interrupt::interrupt_deassert
void(* interrupt_deassert)(struct interrupt *)
Definition:
interrupt.h:39
irqc_data
Definition:
dev_irqc.cc:47
if
addr & if(addr >=0x24 &&page !=NULL)
Definition:
tmp_arm_multi.cc:56
devinit::addr
uint64_t addr
Definition:
device.h:46
memory_device_register
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition:
memory.cc:339
irqc_data::status
uint32_t status
Definition:
dev_irqc.cc:52
MEM_READ
#define MEM_READ
Definition:
memory.h:116
DM_DEFAULT
#define DM_DEFAULT
Definition:
memory.h:130
interrupt::extra
void * extra
Definition:
interrupt.h:59
devinit::machine
struct machine * machine
Definition:
device.h:41
DEV_IRQC_MASK
#define DEV_IRQC_MASK
Definition:
dev_irqc.h:14
device.h
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
devinit::interrupt_path
char * interrupt_path
Definition:
device.h:50
irqc_data::enabled
uint32_t enabled
Definition:
dev_irqc.cc:53
interrupt.h
fatal
void fatal(const char *fmt,...)
Definition:
main.cc:152
DEVICE_ACCESS
DEVICE_ACCESS(irqc)
Definition:
dev_irqc.cc:81
misc.h
dev_irqc.h
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition:
memory.cc:55
machine.h
devinit::name
char * name
Definition:
device.h:43
DEV_IRQC_LENGTH
#define DEV_IRQC_LENGTH
Definition:
dev_irqc.h:11
irqc_data::irq
struct interrupt irq
Definition:
dev_irqc.cc:48
devinit
Definition:
device.h:40
N_IRQC_INTERRUPTS
#define N_IRQC_INTERRUPTS
Definition:
dev_irqc.cc:45
cpu.h
machine::memory
struct memory * memory
Definition:
machine.h:126
irqc_interrupt_assert
void irqc_interrupt_assert(struct interrupt *interrupt)
Definition:
dev_irqc.cc:57
DEV_IRQC_IRQ
#define DEV_IRQC_IRQ
Definition:
dev_irqc.h:13
irqc_interrupt_deassert
void irqc_interrupt_deassert(struct interrupt *interrupt)
Definition:
dev_irqc.cc:69
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition:
interrupt.h:75
interrupt::line
uint32_t line
Definition:
interrupt.h:51
interrupt::interrupt_assert
void(* interrupt_assert)(struct interrupt *)
Definition:
interrupt.h:38
interrupt_handler_register
void interrupt_handler_register(struct interrupt *templ)
Definition:
interrupt.cc:81
interrupt::name
char * name
Definition:
interrupt.h:66
interrupt
Definition:
interrupt.h:36
DEVINIT
DEVINIT(irqc)
Definition:
dev_irqc.cc:155
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition:
memory.cc:89
irqc_data::asserted
int asserted
Definition:
dev_irqc.cc:50
cpu
Definition:
cpu.h:326
memory.h
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition:
misc.h:239
Generated on Tue Aug 25 2020 19:25:06 for GXemul by
1.8.18