dev_kn02.cc Source File
Back to the index.
src
devices
dev_kn02.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2003-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: DEC KN02 mainbus (TurboChannel interrupt controller)
29
*
30
* Used in DECstation type 2 ("3MAX"). See include/dec_kn02.h for more info.
31
*/
32
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include "
cpu.h
"
38
#include "
device.h
"
39
#include "
interrupt.h
"
40
#include "
machine.h
"
41
#include "
memory.h
"
42
#include "
misc.h
"
43
44
#include "
thirdparty/dec_kn02.h
"
45
46
47
#define DEV_KN02_LENGTH 0x1000
48
49
50
struct
kn02_data
{
51
uint8_t
csr
[
sizeof
(uint32_t)];
52
53
/* Dummy fill bytes, so dyntrans can be used: */
54
uint8_t
filler
[
DEV_KN02_LENGTH
-
sizeof
(uint32_t)];
55
56
struct
interrupt
irq
;
57
int
int_asserted
;
58
};
59
60
61
/*
62
* kn02_interrupt_assert(), kn02_interrupt_deassert():
63
*
64
* Called whenever a KN02 (TurboChannel) interrupt is asserted/deasserted.
65
*/
66
void
kn02_interrupt_assert
(
struct
interrupt
*
interrupt
)
67
{
68
struct
kn02_data
*d = (
struct
kn02_data
*)
interrupt
->
extra
;
69
d->
csr
[0] |=
interrupt
->
line
;
70
if
(d->
csr
[0] & d->
csr
[2] && !d->
int_asserted
) {
71
d->
int_asserted
= 1;
72
INTERRUPT_ASSERT
(d->
irq
);
73
}
74
}
75
void
kn02_interrupt_deassert
(
struct
interrupt
*
interrupt
)
76
{
77
struct
kn02_data
*d = (
struct
kn02_data
*)
interrupt
->
extra
;
78
d->
csr
[0] &= ~
interrupt
->
line
;
79
if
(!(d->
csr
[0] & d->
csr
[2]) && d->
int_asserted
) {
80
d->
int_asserted
= 0;
81
INTERRUPT_DEASSERT
(d->
irq
);
82
}
83
}
84
85
86
DEVICE_ACCESS
(kn02)
87
{
88
struct
kn02_data
*d = (
struct
kn02_data
*) extra;
89
uint64_t idata = 0, odata = 0;
90
91
if
(writeflag ==
MEM_WRITE
)
92
idata =
memory_readmax64
(
cpu
,
data
, len);
93
94
switch
(relative_addr) {
95
case
0:
96
if
(writeflag==
MEM_READ
) {
97
odata = d->
csr
[0] + (d->
csr
[1] << 8) +
98
(d->
csr
[2] << 16) + (d->
csr
[3] << 24);
99
100
/* debug("[ kn02: read from CSR: 0x%08x ]\n", odata); */
101
}
else
{
102
/*
103
* Only bits 23..8 are considered writable. The
104
* lowest 8 bits are actually writable, but don't
105
* affect the interrupt I/O bits; the low 8 bits
106
* on write turn on and off LEDs. (There are no
107
* LEDs in the emulator, so those bits are just
108
* ignored.)
109
*/
110
int
old_assert = (d->
csr
[0] & d->
csr
[2])? 1 : 0;
111
int
new_assert;
112
/* fatal("[ kn02: write to CSR: 0x%08x ]\n", idata); */
113
114
d->
csr
[1] = (idata >> 8) & 255;
115
d->
csr
[2] = (idata >> 16) & 255;
116
117
/* Recalculate interrupt assertions: */
118
new_assert = (d->
csr
[0] & d->
csr
[2])? 1 : 0;
119
if
(new_assert != old_assert) {
120
if
(new_assert) {
121
INTERRUPT_ASSERT
(d->
irq
);
122
d->
int_asserted
= 1;
123
}
else
{
124
INTERRUPT_DEASSERT
(d->
irq
);
125
d->
int_asserted
= 0;
126
}
127
}
128
}
129
break
;
130
default
:
131
if
(writeflag==
MEM_READ
) {
132
debug
(
"[ kn02: read from 0x%08lx ]\n"
,
133
(
long
)relative_addr);
134
}
else
{
135
debug
(
"[ kn02: write to 0x%08lx: 0x%08x ]\n"
,
136
(
long
)relative_addr, (
int
)idata);
137
}
138
}
139
140
if
(writeflag ==
MEM_READ
)
141
memory_writemax64
(
cpu
,
data
, len, odata);
142
143
return
1;
144
}
145
146
147
DEVINIT
(kn02)
148
{
149
struct
kn02_data
*d;
150
uint32_t
csr
;
151
int
i;
152
153
CHECK_ALLOCATION
(d = (
struct
kn02_data
*) malloc(
sizeof
(
struct
kn02_data
)));
154
memset(d, 0,
sizeof
(
struct
kn02_data
));
155
156
/* Connect the KN02 to a specific MIPS CPU interrupt line: */
157
INTERRUPT_CONNECT
(
devinit
->
interrupt_path
, d->
irq
);
158
159
/* Register the 8 possible TurboChannel interrupts: */
160
for
(i=0; i<8; i++) {
161
struct
interrupt
templ;
162
char
tmpstr[300];
163
snprintf(tmpstr,
sizeof
(tmpstr),
"%s.kn02.%i"
,
164
devinit
->
interrupt_path
, i);
165
memset(&templ, 0,
sizeof
(templ));
166
templ.
line
= 1 << i;
167
templ.
name
= tmpstr;
168
templ.
extra
= d;
169
templ.
interrupt_assert
=
kn02_interrupt_assert
;
170
templ.
interrupt_deassert
=
kn02_interrupt_deassert
;
171
interrupt_handler_register
(&templ);
172
}
173
174
/*
175
* Set initial value of the CSR. Note: If the KN02_CSR_NRMMOD bit
176
* is not set, the 5000/200 PROM image loops forever.
177
*/
178
csr
=
KN02_CSR_NRMMOD
;
179
d->
csr
[0] =
csr
;
180
d->
csr
[1] =
csr
>> 8;
181
d->
csr
[2] =
csr
>> 16;
182
d->
csr
[3] =
csr
>> 24;
183
184
memory_device_register
(
devinit
->
machine
->
memory
,
devinit
->
name
,
185
devinit
->
addr
,
DEV_KN02_LENGTH
, dev_kn02_access, d,
186
DM_DYNTRANS_OK
, &d->
csr
[0]);
187
188
return
1;
189
}
190
kn02_data
Definition:
dev_kn02.cc:50
data
u_short data
Definition:
siireg.h:79
kn02_interrupt_assert
void kn02_interrupt_assert(struct interrupt *interrupt)
Definition:
dev_kn02.cc:66
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition:
interrupt.h:77
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition:
interrupt.h:74
kn02_data::int_asserted
int int_asserted
Definition:
dev_kn02.cc:57
interrupt::interrupt_deassert
void(* interrupt_deassert)(struct interrupt *)
Definition:
interrupt.h:39
DEVICE_ACCESS
DEVICE_ACCESS(kn02)
Definition:
dev_kn02.cc:86
debug
#define debug
Definition:
dev_adb.cc:57
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
kn02_data::csr
uint8_t csr[sizeof(uint32_t)]
Definition:
dev_kn02.cc:51
MEM_READ
#define MEM_READ
Definition:
memory.h:116
kn02_data::irq
struct interrupt irq
Definition:
dev_kn02.cc:56
interrupt::extra
void * extra
Definition:
interrupt.h:59
devinit::machine
struct machine * machine
Definition:
device.h:41
KN02_CSR_NRMMOD
#define KN02_CSR_NRMMOD
Definition:
dec_kn02.h:196
kn02_data::filler
uint8_t filler[DEV_KN02_LENGTH - sizeof(uint32_t)]
Definition:
dev_kn02.cc:54
device.h
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
devinit::interrupt_path
char * interrupt_path
Definition:
device.h:50
interrupt.h
misc.h
kn02_interrupt_deassert
void kn02_interrupt_deassert(struct interrupt *interrupt)
Definition:
dev_kn02.cc:75
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
devinit
Definition:
device.h:40
cpu.h
machine::memory
struct memory * memory
Definition:
machine.h:126
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition:
interrupt.h:75
DEV_KN02_LENGTH
#define DEV_KN02_LENGTH
Definition:
dev_kn02.cc:47
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
dec_kn02.h
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition:
memory.cc:89
cpu
Definition:
cpu.h:326
DM_DYNTRANS_OK
#define DM_DYNTRANS_OK
Definition:
memory.h:131
DEVINIT
DEVINIT(kn02)
Definition:
dev_kn02.cc:147
csr
u_short csr
Definition:
siireg.h:69
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