dev_bebox.cc Source File
Back to the index.
src
devices
dev_bebox.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2005-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: BeBox motherboard registers and interrupt controller
29
*
30
* See the following URL for more information:
31
*
32
* http://www.bebox.nu/history.php?s=history/benews/benews27
33
*
34
* These interrupt numbers are from NetBSD's bebox/extint.c:
35
*
36
* serial3 6
37
* serial4 7
38
* midi1 8
39
* midi2 9
40
* scsi 10
41
* pci1 11
42
* pci2 12
43
* pci3 13
44
* sound 14
45
* 8259 26
46
* irda 27
47
* a2d 28
48
* geekport 29
49
*
50
* Note that these are in IBM order, i.e. reversed. So 8259 interrupts
51
* go to interrupt 31 - 26 = 5, when using normal numbers.
52
*
53
* Interrupt routing should work to both CPUs, but I've only ever seen the
54
* first CPU being used by NetBSD/bebox, so the second CPU is untested :-)
55
*/
56
57
#include <stdio.h>
58
#include <stdlib.h>
59
#include <string.h>
60
61
#include "
cpu.h
"
62
#include "
device.h
"
63
#include "
interrupt.h
"
64
#include "
machine.h
"
65
#include "
memory.h
"
66
#include "
misc.h
"
67
68
69
struct
bebox_data
{
70
struct
interrupt
cpu_irq
[2];
71
72
/* The 5 motherboard registers: */
73
uint32_t
cpu0_int_mask
;
74
uint32_t
cpu1_int_mask
;
75
uint32_t
int_status
;
76
uint32_t
xpi
;
77
uint32_t
resets
;
78
};
79
80
81
static
void
bebox_interrupt_assert(
struct
interrupt
*
interrupt
)
82
{
83
struct
bebox_data
*d = (
struct
bebox_data
*)
interrupt
->
extra
;
84
d->
int_status
|=
interrupt
->
line
;
85
86
/* printf("STATUS %08x CPU0 %08x CPU1 %08x\n",
87
d->int_status, d->cpu0_int_mask, d->cpu1_int_mask); */
88
89
if
(d->
int_status
& d->
cpu0_int_mask
)
90
INTERRUPT_ASSERT
(d->
cpu_irq
[0]);
91
if
(d->
int_status
& d->
cpu1_int_mask
)
92
INTERRUPT_ASSERT
(d->
cpu_irq
[1]);
93
}
94
static
void
bebox_interrupt_deassert(
struct
interrupt
*
interrupt
)
95
{
96
struct
bebox_data
*d = (
struct
bebox_data
*)
interrupt
->
extra
;
97
d->
int_status
&= ~
interrupt
->
line
;
98
99
if
(!(d->
int_status
& d->
cpu0_int_mask
))
100
INTERRUPT_DEASSERT
(d->
cpu_irq
[0]);
101
if
(!(d->
int_status
& d->
cpu1_int_mask
))
102
INTERRUPT_DEASSERT
(d->
cpu_irq
[1]);
103
}
104
105
106
/*
107
* check_cpu_masks():
108
*
109
* BeBox interrupt enable bits are not allowed to be present in
110
* both CPUs at the same time.
111
*/
112
static
void
check_cpu_masks(
struct
cpu
*
cpu
,
struct
bebox_data
*d)
113
{
114
d->
cpu0_int_mask
&= 0x7fffffff;
115
d->
cpu1_int_mask
&= 0x7fffffff;
116
if
((d->
cpu0_int_mask
| d->
cpu1_int_mask
) !=
117
(d->
cpu0_int_mask
^ d->
cpu1_int_mask
))
118
fatal
(
"check_cpu_masks(): BeBox cpu int masks collide!\n"
);
119
}
120
121
122
DEVICE_ACCESS
(bebox)
123
{
124
struct
bebox_data
*d = (
struct
bebox_data
*) extra;
125
uint64_t idata = 0, odata = 0;
126
127
if
(writeflag ==
MEM_WRITE
)
128
idata =
memory_readmax64
(
cpu
,
data
, len);
129
130
switch
(relative_addr) {
131
132
case
0x0f0:
133
if
(writeflag ==
MEM_READ
)
134
odata = d->
cpu0_int_mask
;
135
else
{
136
if
(idata & 0x80000000)
137
d->
cpu0_int_mask
|= idata;
138
else
139
d->
cpu0_int_mask
&= ~idata;
140
check_cpu_masks(
cpu
, d);
141
}
142
break
;
143
144
case
0x1f0:
145
if
(writeflag ==
MEM_READ
)
146
odata = d->
cpu1_int_mask
;
147
else
{
148
if
(idata & 0x80000000)
149
d->
cpu1_int_mask
|= idata;
150
else
151
d->
cpu1_int_mask
&= ~idata;
152
check_cpu_masks(
cpu
, d);
153
}
154
break
;
155
156
case
0x2f0:
157
if
(writeflag ==
MEM_READ
)
158
odata = d->
int_status
;
159
else
{
160
if
(idata & 0x80000000)
161
d->
int_status
|= idata;
162
else
163
d->
int_status
&= ~idata;
164
d->
int_status
&= 0x7fffffff;
165
}
166
break
;
167
168
case
0x3f0:
169
if
(writeflag ==
MEM_READ
) {
170
odata = d->
xpi
;
171
172
/* Bit 6 (counted from the left) is cpuid: */
173
odata &= ~0x02000000;
174
if
(
cpu
->
cpu_id
== 1)
175
odata |= 0x02000000;
176
}
else
{
177
fatal
(
"[ bebox: unimplemented write to 0x3f0:"
178
" 0x%08x ]\n"
, (
int
)idata);
179
}
180
break
;
181
default
:
182
if
(writeflag==
MEM_READ
) {
183
fatal
(
"[ bebox: unimplemented read from 0x%08lx ]\n"
,
184
(
long
)relative_addr);
185
}
else
{
186
fatal
(
"[ bebox: unimplemented write to 0x%08lx: 0x"
187
"%08x ]\n"
, (
long
)relative_addr, (
int
)idata);
188
}
189
}
190
191
if
(writeflag ==
MEM_READ
)
192
memory_writemax64
(
cpu
,
data
, len, odata);
193
194
return
1;
195
}
196
197
198
DEVINIT
(bebox)
199
{
200
struct
bebox_data
*d;
201
int
i;
202
char
n[300];
203
struct
machine
*
machine
=
devinit
->
machine
;
204
205
CHECK_ALLOCATION
(d = (
struct
bebox_data
*) malloc(
sizeof
(
struct
bebox_data
)));
206
memset(d, 0,
sizeof
(
struct
bebox_data
));
207
208
/* Connect to the two BeBox CPUs: */
209
for
(i=0; i<2; i++) {
210
if
(i >=
machine
->
ncpus
) {
211
fatal
(
"FATAL ERROR: The machine seem to be "
212
"lacking cpu nr %i (0-based)\n"
, i);
213
exit(1);
214
}
215
216
snprintf(n,
sizeof
(n),
"%s.cpu[%i]"
,
machine
->
path
, i);
217
INTERRUPT_CONNECT
(n, d->
cpu_irq
[i]);
218
}
219
220
/*
221
* Register the 32 BeBox interrupts:
222
*
223
* NOTE: They are registered on cpu[0], but the interrupt assert/
224
* deassert routines in this file make sure that the interrupts
225
* are routed to the correct cpu!
226
*/
227
for
(i=0; i<32; i++) {
228
struct
interrupt
templ;
229
snprintf(n,
sizeof
(n),
"%s.bebox.%i"
,
230
devinit
->
interrupt_path
, i);
231
memset(&templ, 0,
sizeof
(templ));
232
templ.
line
= 1 << i;
233
templ.
name
= n;
234
templ.
extra
= d;
235
templ.
interrupt_assert
= bebox_interrupt_assert;
236
templ.
interrupt_deassert
= bebox_interrupt_deassert;
237
interrupt_handler_register
(&templ);
238
}
239
240
memory_device_register
(
machine
->
memory
,
devinit
->
name
,
241
0x7ffff000, 0x500, dev_bebox_access, d,
DM_DEFAULT
, NULL);
242
243
devinit
->
return_ptr
= d;
244
245
return
1;
246
}
247
data
u_short data
Definition:
siireg.h:79
bebox_data::cpu0_int_mask
uint32_t cpu0_int_mask
Definition:
dev_bebox.cc:73
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition:
interrupt.h:77
cpu::cpu_id
int cpu_id
Definition:
cpu.h:359
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition:
interrupt.h:74
interrupt::interrupt_deassert
void(* interrupt_deassert)(struct interrupt *)
Definition:
interrupt.h:39
bebox_data::resets
uint32_t resets
Definition:
dev_bebox.cc:77
bebox_data
Definition:
dev_bebox.cc:69
if
addr & if(addr >=0x24 &&page !=NULL)
Definition:
tmp_arm_multi.cc:56
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
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
device.h
bebox_data::cpu1_int_mask
uint32_t cpu1_int_mask
Definition:
dev_bebox.cc:74
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
devinit::interrupt_path
char * interrupt_path
Definition:
device.h:50
interrupt.h
fatal
void fatal(const char *fmt,...)
Definition:
main.cc:152
misc.h
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition:
memory.cc:55
machine.h
machine
Definition:
machine.h:97
bebox_data::int_status
uint32_t int_status
Definition:
dev_bebox.cc:75
devinit::name
char * name
Definition:
device.h:43
devinit
Definition:
device.h:40
cpu.h
machine::path
char * path
Definition:
machine.h:108
machine::memory
struct memory * memory
Definition:
machine.h:126
devinit::return_ptr
void * return_ptr
Definition:
device.h:56
DEVINIT
DEVINIT(bebox)
Definition:
dev_bebox.cc:198
bebox_data::xpi
uint32_t xpi
Definition:
dev_bebox.cc:76
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition:
interrupt.h:75
bebox_data::cpu_irq
struct interrupt cpu_irq[2]
Definition:
dev_bebox.cc:70
interrupt::line
uint32_t line
Definition:
interrupt.h:51
DEVICE_ACCESS
DEVICE_ACCESS(bebox)
Definition:
dev_bebox.cc:122
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
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
memory.h
machine::ncpus
int ncpus
Definition:
machine.h:139
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition:
misc.h:239
Generated on Tue Mar 24 2020 14:04:48 for GXemul by
1.8.17