1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * PCI Bridge board emulation
5 *
6 * Copyright 2015 Toni Wilen
7 * Hardware information by Radoslaw Kujawa
8 *
9 */
10
11 #define PCI_DEBUG_IO 0
12 #define PCI_DEBUG_MEMORY 0
13 #define PCI_DEBUG_CONFIG 1
14 #define PCI_DEBUG_BRIDGE 0
15
16 #include "sysconfig.h"
17 #include "sysdeps.h"
18
19 #include "options.h"
20 #include "custom.h"
21 #include "memory.h"
22 #include "debug.h"
23 #include "pci_hw.h"
24 #include "pci.h"
25 #include "ncr_scsi.h"
26 #include "newcpu.h"
27 #include "uae.h"
28 #include "rommgr.h"
29 #include "cpuboard.h"
30 #include "autoconf.h"
31
32 #include "qemuvga/qemuuaeglue.h"
33 #include "qemuvga/queue.h"
34 #include "qemuvga/scsi/scsi.h"
35
36 #define PCI_BRIDGE_WILDFIRE 0
37 #define PCI_BRIDGE_GREX (PCI_BRIDGE_WILDFIRE + 1)
38 #define PCI_BRIDGE_XVISION (PCI_BRIDGE_GREX + 1)
39 #define PCI_BRIDGE_PROMETHEUS (PCI_BRIDGE_XVISION + 1)
40 #define PCI_BRIDGE_MEDIATOR (PCI_BRIDGE_PROMETHEUS * MAX_DUPLICATE_EXPANSION_BOARDS)
41 #define PCI_BRIDGE_MAX (PCI_BRIDGE_MEDIATOR * MAX_DUPLICATE_EXPANSION_BOARDS + 1)
42
43 static struct pci_bridge *bridges[PCI_BRIDGE_MAX + 1];
44 static int last_bridge_index;
45 static struct pci_board_state *hsyncs[MAX_PCI_BOARDS + 1];
46
47 extern addrbank pci_config_bank, pci_io_bank, pci_mem_bank, pci_bridge_bank;
48
pci_board_free(struct pci_board_state * pcibs)49 static void pci_board_free(struct pci_board_state *pcibs)
50 {
51 if (!pcibs || !pcibs->board)
52 return;
53 if (pcibs->board->free)
54 pcibs->board->free(pcibs);
55 }
56
pci_bridge_alloc(void)57 static struct pci_bridge *pci_bridge_alloc(void)
58 {
59 struct pci_bridge *pcib = xcalloc(struct pci_bridge, 1);
60 last_bridge_index = 0;
61 return pcib;
62 };
63
pci_bridge_get_zorro(struct romconfig * rc)64 static struct pci_bridge *pci_bridge_get_zorro(struct romconfig *rc)
65 {
66 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
67 if (bridges[i] && bridges[i]->rc == rc) {
68 return bridges[i];
69 }
70 }
71 return NULL;
72 }
73
pci_bridge_alloc_zorro(int offset,struct romconfig * rc)74 static struct pci_bridge *pci_bridge_alloc_zorro(int offset, struct romconfig *rc)
75 {
76 struct pci_bridge *pcib = pci_bridge_alloc();
77 for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
78 if (bridges[i + offset] == NULL) {
79 bridges[i + offset] = pcib;
80 pcib->rc = rc;
81 pcib->type = offset;
82 return pcib;
83 }
84 }
85 return NULL;
86 }
87
88
pci_bridge_free(struct pci_bridge * pcib)89 static void pci_bridge_free(struct pci_bridge *pcib)
90 {
91 if (!pcib)
92 return;
93 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
94 pci_board_free(&pcib->boards[i]);
95 }
96 last_bridge_index = 0;
97 xfree(pcib->data);
98 xfree(pcib);
99 }
100
pci_board_alloc(struct pci_config * config)101 static struct pci_board *pci_board_alloc(struct pci_config *config)
102 {
103 struct pci_board *pci = xcalloc(struct pci_board, 1);
104 pci->config = config;
105 return pci;
106 }
107
pci_board_add(struct pci_bridge * pcib,const struct pci_board * pci,int slot,int func)108 static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func)
109 {
110 struct pci_board_state *pcibs = &pcib->boards[pcib->slot_cnt];
111 pcib->slot_cnt++;
112 pcibs->board = pci;
113 pcibs->slot = slot;
114 pcibs->func = func;
115 pcibs->bridge = pcib;
116 memset(pcibs->config_data, 0, sizeof pcibs->config_data);
117 for (int i = 0; i < MAX_PCI_BARS; i++) {
118 pcibs->bar_size[i] = pci->config->bars[i];
119 }
120 if (pci->init)
121 pci->init(pcibs);
122 if (pci->hsync) {
123 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
124 if (hsyncs[i] == NULL) {
125 hsyncs[i] = pcibs;
126 break;
127 }
128 }
129 }
130 }
131
pci_free(void)132 void pci_free(void)
133 {
134 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
135 pci_bridge_free(bridges[i]);
136 bridges[i] = NULL;
137 }
138 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
139 hsyncs[i] = NULL;
140 }
141 uae_int_requested &= ~(0x10 | 0x100);
142 }
pci_reset(void)143 void pci_reset(void)
144 {
145 pci_free();
146 }
147
pci_hsync(void)148 void pci_hsync(void)
149 {
150 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
151 if (hsyncs[i])
152 hsyncs[i]->board->hsync(hsyncs[i]);
153 }
154 }
155
pci_rethink(void)156 void pci_rethink(void)
157 {
158 uae_int_requested &= ~(0x10 | 0x100);
159 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
160 struct pci_bridge *pcib = bridges[i];
161 if (!pcib)
162 continue;
163 pcib->irq = 0;
164 for (int j = 0; j < MAX_PCI_BOARDS; j++) {
165 struct pci_board_state *pcibs = &pcib->boards[j];
166 if (pcibs->board) {
167 const struct pci_config *c = pcibs->board->config;
168 if (c->interruptpin) {
169 if ((pcibs->config_data[5] & (1 << 3)) && !(pcibs->config_data[6] & (1 << (10 - 8)))) {
170 pcib->irq |= 1 << (c->interruptpin - 1);
171 }
172 }
173 }
174 }
175 if (pcib->irq & pcib->intena) {
176 uae_int_requested |= pcib->intreq_mask;
177 }
178 }
179 }
180
set_pci_irq(struct pci_bridge * pcib,struct pci_board_state * pcibs,bool active)181 static void set_pci_irq(struct pci_bridge *pcib, struct pci_board_state *pcibs, bool active)
182 {
183 pcibs->config_data[5] &= ~(1 << 3);
184 if (active)
185 pcibs->config_data[5] |= (1 << 3);
186 pci_rethink();
187 }
188
create_config_data(struct pci_board_state * s)189 static void create_config_data(struct pci_board_state *s)
190 {
191 uae_u8 *d = s->config_data;
192 const struct pci_config *c = s->board->config;
193
194 // big endian, get/put functions will swap if needed.
195 d[0] = c->device >> 8;
196 d[1] = c->device;
197 d[2] = c->vendor >> 8;
198 d[3] = c->vendor;
199
200 d[8] = c->deviceclass >> 16;
201 d[9] = c->deviceclass >> 8;
202 d[10] = c->deviceclass;
203 d[11] = c->revision;
204
205 d[13] = c->header;
206
207 for (int i = 0; i < MAX_PCI_BARS; i++) {
208 int off = i == MAX_PCI_BARS - 1 ? 0x30 : 0x10 + i * 4;
209 d[off + 0] = s->bar[i] >> 24;
210 d[off + 1] = s->bar[i] >> 16;
211 d[off + 2] = s->bar[i] >> 8;
212 d[off + 3] = s->bar[i] >> 0;
213 }
214
215 d[0x2c] = c->subsystem >> 8;
216 d[0x2d] = c->subsystem;
217 d[0x2e] = c->subsystenvendor >> 8;
218 d[0x2f] = c->subsystenvendor;
219
220 d[0x3c] = c->max_latency;
221 d[0x3d] = c->min_grant;
222 d[0x3e] = c->interruptpin;
223 }
224
get_pci_bridge(uaecptr addr)225 static struct pci_bridge *get_pci_bridge(uaecptr addr)
226 {
227 if (addr < 0x10000 || (addr & 0xffff0000) == 0xe80000 || (addr & 0xff000000) == 0xff000000) {
228 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
229 struct pci_bridge *pcib = bridges[i];
230 if (pcib && pcib->configured == 0) {
231 return pcib;
232 }
233 }
234 }
235 struct pci_bridge *pcib = bridges[last_bridge_index];
236 if (pcib) {
237 if (addr >= pcib->baseaddress && addr < pcib->baseaddress_end)
238 return pcib;
239 if (pcib->configured_2 && addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2)
240 return pcib;
241 }
242 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
243 struct pci_bridge *pcib = bridges[i];
244 if (pcib) {
245 if ((addr >= pcib->baseaddress && addr < pcib->baseaddress_end) ||
246 (pcib->configured_2 && addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2)) {
247 last_bridge_index = i;
248 return pcib;
249 }
250 }
251 }
252 return NULL;
253 }
254
get_pci_bridge_2(uaecptr addr)255 static struct pci_bridge *get_pci_bridge_2(uaecptr addr)
256 {
257 if (addr < 0x10000 || (addr & 0xffff0000) == 0xe80000 || (addr & 0xff000000) == 0xff000000) {
258 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
259 struct pci_bridge *pcib = bridges[i];
260 if (pcib && pcib->configured_2 == 0) {
261 return pcib;
262 }
263 }
264 }
265 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
266 struct pci_bridge *pcib = bridges[i];
267 if (pcib && pcib->configured_2) {
268 if (addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2) {
269 last_bridge_index = i;
270 return pcib;
271 }
272 }
273 }
274 return NULL;
275 }
276
get_pci_board_state_config(struct pci_bridge * pcib,uaecptr addr)277 static struct pci_board_state *get_pci_board_state_config(struct pci_bridge *pcib, uaecptr addr)
278 {
279 if (!pcib)
280 return NULL;
281 // get slot
282 int idx = pcib->get_index(addr);
283 if (idx < 0)
284 return NULL;
285 int slot = idx & 0xff;
286 int func = (idx >> 8) & 0xff;
287 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
288 struct pci_board_state *pcibs = &pcib->boards[i];
289 if (pcibs->slot == slot && pcibs->func == func && pcibs->board)
290 return pcibs;
291 }
292 return NULL;
293 }
294
295 static int stored_board, stored_bar;
296
get_pci_board_state(struct pci_bridge * pcib,uaecptr addr,int * bar)297 static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaecptr addr, int *bar)
298 {
299 uaecptr addr2 = addr - pcib->io_offset;
300 struct pci_board_state *pcibs2 = &pcib->boards[stored_board];
301 if (pcibs2) {
302 if (pcibs2->bar_enabled[stored_bar] && addr2 >= pcibs2->bar_start[stored_bar] && addr2 <= pcibs2->bar_end[stored_bar]) {
303 *bar = stored_bar;
304 return pcibs2;
305 }
306 }
307 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
308 struct pci_board_state *pcibs = &pcib->boards[i];
309 for (int j = 0; j < MAX_PCI_BARS; j++) {
310 if (pcibs->bar_enabled[j] && addr2 >= pcibs->bar_start[j] && addr2 <= pcibs->bar_end[j]) {
311 *bar = j;
312 stored_board = i;
313 stored_bar = j;
314 return pcibs;
315 }
316 }
317 }
318 return NULL;
319 }
320
get_pci_io(uaecptr * addrp,struct pci_board_state ** pcibsp,int * endianswap,int size)321 static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **pcibsp, int *endianswap, int size)
322 {
323 uaecptr addr = *addrp;
324 int bar;
325 struct pci_bridge *pcib = get_pci_bridge(addr);
326 if (!pcib)
327 return NULL;
328 struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, &bar);
329 if (!pcibs)
330 return NULL;
331 *pcibsp = pcibs;
332 pcibs->selected_bar = bar;
333 *endianswap = pcib->endian_swap_io;
334 addr -= pcib->io_offset;
335 addr &= (pcibs->bar_size[bar] & ~1) - 1;
336 #if PCI_DEBUG_IO
337 write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x "), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC);
338 #endif
339 *addrp = addr;
340 return &pcibs->board->bars[bar];
341 }
342
get_pci_mem(uaecptr * addrp,struct pci_board_state ** pcibsp,int * endianswap)343 static const pci_addrbank *get_pci_mem(uaecptr *addrp, struct pci_board_state **pcibsp, int *endianswap)
344 {
345 uaecptr addr = *addrp;
346 int bar;
347 #if PCI_DEBUG_MEMORY
348 write_log(_T("get_pci_mem %08x %08x\n"), addr, M68K_GETPC);
349 #endif
350 struct pci_bridge *pcib = get_pci_bridge(addr);
351 if (!pcib)
352 return NULL;
353 struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, &bar);
354 if (!pcibs)
355 return NULL;
356 *pcibsp = pcibs;
357 pcibs->selected_bar = bar;
358 *endianswap = pcib->endian_swap_memory;
359 addr &= pcibs->bar_size[bar] - 1;
360 addr -= pcib->memory_offset;
361 *addrp = addr;
362 return &pcibs->board->bars[bar];
363 }
364
get_pci_config(uaecptr addr,int size,uae_u32 v,int * endianswap)365 static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap)
366 {
367 #if PCI_DEBUG_CONFIG
368 if (size < 0) {
369 size = -size;
370 write_log(_T("PCI Config Space %s READ %08x PC=%08x\n"),
371 size == 4 ? _T("LONG") : (size == 2 ? _T("WORD") : _T("BYTE")), addr, M68K_GETPC);
372 } else {
373 write_log(_T("PCI Config Space %s WRITE %08x = %08x PC=%08x\n"),
374 size == 4 ? _T("LONG") : (size == 2 ? _T("WORD") : _T("BYTE")), addr, v, M68K_GETPC);
375 }
376 #endif
377 struct pci_bridge *pcib = get_pci_bridge(addr);
378 if (!pcib)
379 return NULL;
380 struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr);
381 if (!pcibs)
382 return NULL;
383 *endianswap = pcib->endian_swap_config;
384 #if PCI_DEBUG_CONFIG
385 write_log(_T("- Board %d/%d (%s)\n"), pcibs->slot, pcibs->func, pcibs->board->label);
386 #endif
387 create_config_data(pcibs);
388 return pcibs->config_data;
389 }
390
map_pci_banks(struct pci_board_state * pcibs,int type,bool enable)391 static void map_pci_banks(struct pci_board_state *pcibs, int type, bool enable)
392 {
393 const struct pci_board *pci = pcibs->board;
394 uae_u32 mask = type ? 3 : 15;
395 for (int i = 0; i < MAX_PCI_BARS; i++) {
396 if (pcibs->bar_size[i] == 0)
397 continue;
398 if ((pcibs->bar_size[i] & 1) != type)
399 continue;
400 pcibs->bar_start[i] = (pcibs->bar[i] & ~mask) + pcibs->bridge->baseaddress_offset;
401 pcibs->bar_end[i] = pcibs->bar_start[i] + (pcibs->bar_size[i] & ~1) - 1;
402 if (enable && pcibs->bar[i] < 0xffff0000) {
403 pcibs->bar_enabled[i] = true;
404 #if PCI_DEBUG_CONFIG
405 if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
406 write_log(_T("Board %d/%d ('%s') BAR%d: %08x-%08x\n"), pcibs->slot, pcibs->func, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
407 }
408 #endif
409 } else {
410 pcibs->bar_enabled[i] = false;
411 #if PCI_DEBUG_CONFIG
412 if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
413 write_log(_T("Board %d/%d ('%s') BAR%d: %08x-%08x\n"), pcibs->slot, pcibs->func, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
414 }
415 #endif
416 }
417 pcibs->bar_old[i] = pcibs->bar_start[i];
418 }
419 }
420
update_pci_config(uaecptr addr)421 static void update_pci_config(uaecptr addr)
422 {
423 struct pci_bridge *pcib = get_pci_bridge(addr);
424 if (!pcib)
425 return;
426 struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr);
427 if (!pcibs)
428 return;
429 uae_u8 *d = pcibs->config_data;
430 const struct pci_config *c = pcibs->board->config;
431 for (int i = 0; i < MAX_PCI_BARS; i++) {
432 int off = i == MAX_PCI_BARS - 1 ? 0x30 : 0x10 + i * 4;
433 if (pcibs->bar_size[i]) {
434 pcibs->bar[i] = d[off + 0] << 24;
435 pcibs->bar[i] |= d[off + 1] << 16;
436 pcibs->bar[i] |= d[off + 2] << 8;
437 pcibs->bar[i] |= d[off + 3] << 0;
438 pcibs->bar[i] &= ~((pcibs->bar_size[i] & ~1) - 1);
439 pcibs->bar[i] |= (pcibs->bar_size[i] & 1);
440 } else {
441 pcibs->bar[i] = 0;
442 }
443 }
444 create_config_data(pcibs);
445 pcibs->io_map_active = (d[7] & 1) != 0;
446 pcibs->memory_map_active = (d[7] & 2) != 0;
447 map_pci_banks(pcibs, 1, pcibs->io_map_active);
448 map_pci_banks(pcibs, 0, pcibs->memory_map_active);
449 }
450
451
beswap(int endianswap,uaecptr addr)452 static uaecptr beswap(int endianswap, uaecptr addr)
453 {
454 if (endianswap > 0)
455 return (addr & ~3) | (3 - (addr & 3));
456 return addr;
457 }
458
pci_config_lget(uaecptr addr)459 static uae_u32 REGPARAM2 pci_config_lget(uaecptr addr)
460 {
461 uae_u32 v = 0xffffffff;
462 int endianswap;
463 uae_u8 *config = get_pci_config(addr, -4, 0, &endianswap);
464 if (config) {
465 uae_u32 offset = addr & 0xff;
466 if (!endianswap) {
467 v = config[offset + 0] << 24;
468 v |= config[offset + 1] << 16;
469 v |= config[offset + 2] << 8;
470 v |= config[offset + 3] << 0;
471 } else {
472 v = config[offset + 3] << 24;
473 v |= config[offset + 2] << 16;
474 v |= config[offset + 1] << 8;
475 v |= config[offset + 0] << 0;
476 }
477 #if PCI_DEBUG_CONFIG
478 write_log(_T("- %08x\n"), v);
479 #endif
480 }
481 return v;
482 }
pci_config_wget(uaecptr addr)483 static uae_u32 REGPARAM2 pci_config_wget(uaecptr addr)
484 {
485 uae_u32 v = 0xffff;
486 int endianswap;
487 uae_u8 *config = get_pci_config(addr, -2, 0, &endianswap);
488 if (config) {
489 uae_u32 offset = addr & 0xff;
490 if (!endianswap) {
491 v = config[offset + 0] << 8;
492 v |= config[offset + 1] << 0;
493 } else {
494 v = config[(offset ^ (endianswap > 0 ? 2 : 0)) + 1] << 8;
495 v |= config[(offset ^ (endianswap > 0 ? 2 : 0)) + 0] << 0;
496 }
497 #if PCI_DEBUG_CONFIG
498 write_log(_T("- %04x\n"), v);
499 #endif
500 }
501 return v;
502 }
pci_config_bget(uaecptr addr)503 static uae_u32 REGPARAM2 pci_config_bget(uaecptr addr)
504 {
505 uae_u8 v = 0xff;
506 int endianswap;
507 uae_u8 *config = get_pci_config(addr, -1, 0, &endianswap);
508 if (config) {
509 uae_u32 offset = addr & 0xff;
510 if (!endianswap) {
511 v = config[offset + 0];
512 } else {
513 v = config[beswap(endianswap, offset)];
514 }
515 #if PCI_DEBUG_CONFIG
516 write_log(_T("- %02x\n"), v);
517 #endif
518 }
519 return v;
520 }
pci_config_lput(uaecptr addr,uae_u32 b)521 static void REGPARAM2 pci_config_lput(uaecptr addr, uae_u32 b)
522 {
523 int endianswap;
524 uae_u8 *config = get_pci_config(addr, 4, b, &endianswap);
525 if (config) {
526 uae_u32 offset = addr & 0xff;
527 if (!endianswap) {
528 config[offset + 0] = b >> 24;
529 config[offset + 1] = b >> 16;
530 config[offset + 2] = b >> 8;
531 config[offset + 3] = b >> 0;
532 } else {
533 config[offset + 3] = b >> 24;
534 config[offset + 2] = b >> 16;
535 config[offset + 1] = b >> 8;
536 config[offset + 0] = b >> 0;
537 }
538 update_pci_config(addr);
539 }
540 }
pci_config_wput(uaecptr addr,uae_u32 b)541 static void REGPARAM2 pci_config_wput(uaecptr addr, uae_u32 b)
542 {
543 int endianswap;
544 uae_u8 *config = get_pci_config(addr, 2, b, &endianswap);
545 if (config) {
546 uae_u32 offset = addr & 0xff;
547 if (!endianswap) {
548 config[offset + 0] = b >> 8;
549 config[offset + 1] = b >> 0;
550 } else {
551 config[(offset ^ (endianswap > 0 ? 2 : 0)) + 1] = b >> 8;
552 config[(offset ^ (endianswap > 0 ? 2 : 0)) + 0] = b >> 0;
553 }
554 update_pci_config(addr);
555 }
556 }
pci_config_bput(uaecptr addr,uae_u32 b)557 static void REGPARAM2 pci_config_bput(uaecptr addr, uae_u32 b)
558 {
559 int endianswap;
560 uae_u8 *config = get_pci_config(addr, 1, b, &endianswap);
561 if (config) {
562 uae_u32 offset = addr & 0xff;
563 if (!endianswap) {
564 config[offset] = b;
565 } else {
566 config[beswap(endianswap, offset)] = b;
567 }
568 update_pci_config(addr);
569 }
570 }
571
endianswap_long(uae_u32 v)572 static uae_u32 endianswap_long(uae_u32 v)
573 {
574 v = (v >> 24) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | (v << 24);
575 return v;
576 }
endianswap_word(uae_u16 v)577 static uae_u16 endianswap_word(uae_u16 v)
578 {
579 v = (v >> 8) | (v << 8);
580 return v;
581 }
582
pci_io_lget(uaecptr addr)583 static uae_u32 REGPARAM2 pci_io_lget(uaecptr addr)
584 {
585 uae_u32 v = 0xffffffff;
586 int endianswap;
587 struct pci_board_state *pcibs;
588 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 4);
589 if (a && a->lget) {
590 v = a->lget(pcibs, addr);
591 #if PCI_DEBUG_IO
592 write_log(_T("-> %08x\n"), v);
593 #endif
594 if (endianswap)
595 v = endianswap_long(v);
596 } else {
597 #if PCI_DEBUG_IO
598 write_log(_T("-> X\n"), v);
599 #endif
600 }
601 return v;
602 }
pci_io_wget(uaecptr addr)603 static uae_u32 REGPARAM2 pci_io_wget(uaecptr addr)
604 {
605 uae_u32 v = 0xffff;
606 int endianswap;
607 struct pci_board_state *pcibs;
608 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 2);
609 if (a && a->wget) {
610 if (endianswap) {
611 v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
612 #if PCI_DEBUG_IO
613 write_log(_T("-> %04x\n"), v);
614 #endif
615 v = endianswap_word(v);
616 } else {
617 v = a->wget(pcibs, addr);
618 #if PCI_DEBUG_IO
619 write_log(_T("-> %04x\n"), v);
620 #endif
621 }
622 } else {
623 #if PCI_DEBUG_IO
624 write_log(_T("-> X\n"), v);
625 #endif
626 }
627 return v;
628 }
pci_io_bget(uaecptr addr)629 static uae_u32 REGPARAM2 pci_io_bget(uaecptr addr)
630 {
631 uae_u32 v = 0xff;
632 int endianswap;
633 struct pci_board_state *pcibs;
634 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 1);
635 if (a && a->bget) {
636 if (endianswap) {
637 v = a->bget(pcibs, beswap(endianswap, addr));
638 #if PCI_DEBUG_IO
639 write_log(_T("-> %02x\n"), v);
640 #endif
641 } else {
642 v = a->bget(pcibs, addr);
643 #if PCI_DEBUG_IO
644 write_log(_T("-> %02x\n"), v);
645 #endif
646 }
647 } else {
648 #if PCI_DEBUG_IO
649 write_log(_T("-> X\n"), v);
650 #endif
651 }
652 return v;
653 }
pci_io_lput(uaecptr addr,uae_u32 b)654 static void REGPARAM2 pci_io_lput(uaecptr addr, uae_u32 b)
655 {
656 int endianswap;
657 struct pci_board_state *pcibs;
658 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -4);
659 if (a && a->lput) {
660 if (endianswap)
661 b = endianswap_long(b);
662 a->lput(pcibs, addr, b);
663 }
664 #if PCI_DEBUG_IO
665 write_log(_T("<- %08x\n"), b);
666 #endif
667 }
pci_io_wput(uaecptr addr,uae_u32 b)668 static void REGPARAM2 pci_io_wput(uaecptr addr, uae_u32 b)
669 {
670 int endianswap;
671 struct pci_board_state *pcibs;
672 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -2);
673 if (a && a->wput) {
674 if (endianswap) {
675 b = endianswap_word(b);
676 a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
677 } else {
678 a->wput(pcibs, addr, b);
679 }
680 }
681 #if PCI_DEBUG_IO
682 write_log(_T("<- %04x\n"), b);
683 #endif
684 }
pci_io_bput(uaecptr addr,uae_u32 b)685 static void REGPARAM2 pci_io_bput(uaecptr addr, uae_u32 b)
686 {
687 int endianswap;
688 struct pci_board_state *pcibs;
689 const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -1);
690 if (a && a->bput) {
691 if (endianswap) {
692 a->bput(pcibs, beswap(endianswap, addr), b);
693 } else {
694 a->bput(pcibs, addr, b);
695 }
696 }
697 #if PCI_DEBUG_IO
698 write_log(_T("<- %02x\n"), b);
699 #endif
700 }
701
pci_mem_lget(uaecptr addr)702 static uae_u32 REGPARAM2 pci_mem_lget(uaecptr addr)
703 {
704 uae_u32 v = 0xffffffff;
705 int endianswap;
706 struct pci_board_state *pcibs;
707 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
708 if (a && a->lget) {
709 v = a->lget(pcibs, addr);
710 if (endianswap)
711 v = endianswap_long(v);
712 }
713 return v;
714 }
pci_mem_wget(uaecptr addr)715 static uae_u32 REGPARAM2 pci_mem_wget(uaecptr addr)
716 {
717 uae_u32 v = 0xffff;
718 int endianswap;
719 struct pci_board_state *pcibs;
720 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
721 if (a && a->wget) {
722 if (endianswap) {
723 v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
724 v = endianswap_word(v);
725 } else {
726 v = a->wget(pcibs, addr);
727 }
728 }
729 return v;
730 }
pci_mem_bget(uaecptr addr)731 static uae_u32 REGPARAM2 pci_mem_bget(uaecptr addr)
732 {
733 uae_u32 v = 0xff;
734 int endianswap;
735 struct pci_board_state *pcibs;
736 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
737 if (a && a->bget) {
738 if (endianswap) {
739 v = a->bget(pcibs, beswap(endianswap, addr));
740 } else {
741 v = a->bget(pcibs, addr);
742 }
743 }
744 return v;
745 }
pci_mem_lput(uaecptr addr,uae_u32 b)746 static void REGPARAM2 pci_mem_lput(uaecptr addr, uae_u32 b)
747 {
748 int endianswap;
749 struct pci_board_state *pcibs;
750 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
751 if (a && a->lput) {
752 if (endianswap)
753 b = endianswap_long(b);
754 a->lput(pcibs, addr, b);
755 }
756 }
pci_mem_wput(uaecptr addr,uae_u32 b)757 static void REGPARAM2 pci_mem_wput(uaecptr addr, uae_u32 b)
758 {
759 int endianswap;
760 struct pci_board_state *pcibs;
761 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
762 if (a && a->wput) {
763 if (endianswap) {
764 b = endianswap_word(b);
765 a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
766 } else {
767 a->wput(pcibs, addr, b);
768 }
769 }
770 }
pci_mem_bput(uaecptr addr,uae_u32 b)771 static void REGPARAM2 pci_mem_bput(uaecptr addr, uae_u32 b)
772 {
773 int endianswap;
774 struct pci_board_state *pcibs;
775 const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
776 if (a && a->bput) {
777 if (endianswap) {
778 a->bput(pcibs, beswap(endianswap, addr), b);
779 } else {
780 a->bput(pcibs, addr, b);
781 }
782 }
783 }
784
pci_bridge_lget(uaecptr addr)785 static uae_u32 REGPARAM2 pci_bridge_lget(uaecptr addr)
786 {
787 uae_u32 v = 0;
788 struct pci_bridge *pcib = get_pci_bridge(addr);
789 if (!pcib)
790 return v;
791 if (pcib == bridges[PCI_BRIDGE_GREX] || pcib == bridges[PCI_BRIDGE_XVISION]) {
792 int reg = (addr & 0xf0) >> 4;
793 switch(reg)
794 {
795 case 0:
796 v = pcib->endian_swap_io ? 2 : 0;
797 v |= pcib->config[0];
798 if (pcib == bridges[PCI_BRIDGE_GREX])
799 v |= 0x02000000;
800 if (!pcib->irq)
801 v |= 0x80000000;
802 if (!pcib->intena)
803 v |= 0x00000020;
804 break;
805 case 1:
806 v = pcib->intena ? 1 : 0;
807 break;
808 case 2:
809 break;
810 case 3:
811 break;
812 case 4:
813 break;
814 }
815 }
816 #if PCI_DEBUG_BRIDGE
817 write_log(_T("pci_bridge_lget %08x=%08x PC=%08x\n"), addr, v, M68K_GETPC);
818 #endif
819 return v;
820 }
pci_bridge_wget(uaecptr addr)821 static uae_u32 REGPARAM2 pci_bridge_wget(uaecptr addr)
822 {
823 uae_u16 v = 0;
824 #if PCI_DEBUG_BRIDGE
825 write_log(_T("pci_bridge_wget %08x PC=%08x\n"), addr, M68K_GETPC);
826 #endif
827 return v;
828 }
pci_bridge_bget(uaecptr addr)829 static uae_u32 REGPARAM2 pci_bridge_bget(uaecptr addr)
830 {
831 uae_u8 v = 0;
832 struct pci_bridge *pcib = get_pci_bridge(addr);
833 if (!pcib)
834 return v;
835 if (!pcib->configured) {
836 uaecptr offset = addr & 65535;
837 if (offset >= sizeof pcib->acmemory)
838 return 0;
839 return pcib->acmemory[offset];
840
841 } else if (pcib == bridges[PCI_BRIDGE_WILDFIRE]) {
842 int offset = addr & 15;
843 v = pcib->config[offset / 4];
844 }
845 #if PCI_DEBUG_BRIDGE
846 write_log(_T("pci_bridge_bget %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
847 #endif
848 return v;
849 }
pci_bridge_lput(uaecptr addr,uae_u32 b)850 static void REGPARAM2 pci_bridge_lput(uaecptr addr, uae_u32 b)
851 {
852 #if PCI_DEBUG_BRIDGE
853 write_log(_T("pci_bridge_lput %08x %08x PC=%08x\n"), addr, b, M68K_GETPC);
854 #endif
855 struct pci_bridge *pcib = get_pci_bridge(addr);
856 if (!pcib)
857 return;
858 if (pcib == bridges[PCI_BRIDGE_GREX] || pcib == bridges[PCI_BRIDGE_XVISION]) {
859 int reg = (addr & 0xf0) >> 4;
860 switch (reg)
861 {
862 case 0:
863 pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0 ? -1 : 0;
864 break;
865 case 1:
866 pcib->intena = (b & 1) ? 0xff : 0x00;
867 break;
868 case 3:
869 pcib->config[0] = b & 1;
870 pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0 ? -1 : 0;
871 break;
872 }
873 }
874 }
pci_bridge_wput(uaecptr addr,uae_u32 b)875 static void REGPARAM2 pci_bridge_wput(uaecptr addr, uae_u32 b)
876 {
877 struct pci_bridge *pcib = get_pci_bridge(addr);
878 if (!pcib)
879 return;
880 if (!pcib->configured) {
881 uaecptr offset = addr & 65535;
882 if (pcib->bank_zorro == 3) {
883 switch (offset)
884 {
885 case 0x44:
886 if (pcib->type == PCI_BRIDGE_PROMETHEUS) {
887 if (validate_banks_z3(&pci_io_bank, (expamem_z3_pointer) >> 16, expamem_z3_size >> 16)) {
888 map_banks_z3(&pci_io_bank, (expamem_z3_pointer) >> 16, 0xf0000 >> 16);
889 map_banks_z3(&pci_mem_bank, (expamem_z3_pointer + 0x100000) >> 16, (511 * 1024 * 1024) >> 16);
890 map_banks_z3(&pci_config_bank, (expamem_z3_pointer + 0xf0000) >> 16, 0x10000 >> 16);
891 }
892 pcib->baseaddress_offset = pcib->baseaddress;
893 pcib->io_offset = expamem_z3_pointer;
894 } else if (pcib->type == PCI_BRIDGE_MEDIATOR) {
895 map_banks_z3(&pci_mem_bank, expamem_z3_pointer >> 16, expamem_z3_size >> 16);
896 pcib->baseaddress_offset = 0;
897 }
898 pcib->baseaddress = expamem_z3_pointer;
899 pcib->board_size = expamem_z3_size;
900 pcib->baseaddress_end = pcib->baseaddress + pcib->board_size;
901 pcib->configured = 1;
902 expamem_next(pcib->bank, NULL);
903 break;
904 }
905 }
906 }
907 #if PCI_DEBUG_BRIDGE
908 write_log(_T("pci_bridge_wput %08x %04x PC=%08x\n"), addr, b & 0xffff, M68K_GETPC);
909 #endif
910 }
pci_bridge_bput(uaecptr addr,uae_u32 b)911 static void REGPARAM2 pci_bridge_bput(uaecptr addr, uae_u32 b)
912 {
913 struct pci_bridge *pcib = get_pci_bridge(addr);
914 if (!pcib)
915 return;
916 #if PCI_DEBUG_BRIDGE
917 write_log(_T("pci_bridge_bput %08x %02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
918 #endif
919 if (!pcib->configured) {
920 uaecptr offset = addr & 65535;
921 if (pcib->bank_zorro == 2) {
922 switch (offset)
923 {
924 case 0x48:
925 // Mediator 1200
926 map_banks_z2(&pci_mem_bank, b, expamem_z2_size >> 16);
927 pcib->baseaddress = b << 16;
928 pcib->board_size = expamem_z2_size;
929 pcib->baseaddress_end = pcib->baseaddress + pcib->board_size;
930 pcib->configured = 1;
931 expamem_next(pcib->bank, NULL);
932 break;
933 case 0x4c:
934 pcib->configured = -1;
935 expamem_shutup(pcib->bank);
936 break;
937 }
938 }
939 }
940 if (pcib == bridges[PCI_BRIDGE_WILDFIRE]) {
941 addr &= 15;
942 if (addr == 0) {
943 cpuboard_set_flash_unlocked((b & 4) != 0);
944 } else if (addr == 8) {
945 pcib->config[2] = b;
946 if (b & 1) {
947 write_log(_T("Wildfire 68000 mode!\n"));
948 cpu_halt(CPU_HALT_ACCELERATOR_CPU_FALLBACK);
949 }
950 }
951 }
952 }
953
954
mediator_set_window_offset(struct pci_bridge * pcib,uae_u16 v)955 static void mediator_set_window_offset(struct pci_bridge *pcib, uae_u16 v)
956 {
957 uae_u32 offset = pcib->memory_offset;
958 if (pcib->bank_2_zorro == 3) {
959 // 4000
960 uae_u8 mask = pcib->board_size == 256 * 1024 * 1024 ? 0xf0 : 0xe0;
961 pcib->window = v & mask;
962 pcib->memory_offset = pcib->window << 18;
963 } else {
964 // 1200
965 uae_u16 mask = pcib->board_size == 4 * 1024 * 1024 ? 0xffc0 : 0xff80;
966 pcib->window = v & mask;
967 pcib->memory_offset = pcib->window << 16;
968 }
969 pcib->memory_offset -= pcib->baseaddress;
970 #if PCI_DEBUG_BRIDGE
971 if (pcib->memory_offset != offset) {
972 write_log(_T("Mediator window: %08x offset: %08x\n"),
973 pcib->memory_offset + pcib->baseaddress, pcib->memory_offset);
974 }
975 #endif
976 }
977
pci_bridge_bget_2(uaecptr addr)978 static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
979 {
980 uae_u8 v = 0xff;
981 struct pci_bridge *pcib = get_pci_bridge_2(addr);
982 if (!pcib)
983 return v;
984 if (!pcib->configured_2) {
985 uaecptr offset = addr & 65535;
986 if (offset >= sizeof pcib->acmemory_2)
987 return 0;
988 return pcib->acmemory_2[offset];
989 } else {
990 if (pcib->bank_2_zorro == 3) {
991 int offset = addr & 0x7fffff;
992 if (offset == 0) {
993 v = pcib->window;
994 v |= 8; // id
995 }
996 if (offset == 4) {
997 v = pcib->irq | (pcib->intena << 4);
998 }
999 } else {
1000 int offset = addr & 0x1f;
1001 v = 0;
1002 if (offset == 2) {
1003 v = 0x20;
1004 } else if (offset == 11) {
1005 v = pcib->irq | (pcib->intena << 4);
1006 }
1007 }
1008 }
1009 #if PCI_DEBUG_BRIDGE
1010 write_log(_T("pci_bridge_bget_2 %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
1011 #endif
1012 return v;
1013 }
pci_bridge_wget_2(uaecptr addr)1014 static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
1015 {
1016 uae_u16 v = 0xffff;
1017 #if PCI_DEBUG_BRIDGE
1018 write_log(_T("pci_bridge_wget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
1019 #endif
1020 struct pci_bridge *pcib = get_pci_bridge_2(addr);
1021 if (!pcib)
1022 return v;
1023 if (pcib->configured_2) {
1024 if (pcib->bank_2_zorro == 2) {
1025 int offset = addr & 0x1f;
1026 v = 0;
1027 if (offset == 2) {
1028 v = 0x2080; // id
1029 } else if (offset == 10) {
1030 v = pcib->irq | (pcib->intena << 4);
1031 }
1032 }
1033 }
1034 return v;
1035 }
pci_bridge_lget_2(uaecptr addr)1036 static uae_u32 REGPARAM2 pci_bridge_lget_2(uaecptr addr)
1037 {
1038 uae_u32 v = 0xffffffff;
1039 #if PCI_DEBUG_BRIDGE
1040 write_log(_T("pci_bridge_lget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
1041 #endif
1042 struct pci_bridge *pcib = get_pci_bridge_2(addr);
1043 if (!pcib)
1044 return v;
1045 v = pci_bridge_wget_2(addr + 0) << 16;
1046 v |= pci_bridge_wget_2(addr + 2);
1047 return v;
1048 }
1049
pci_bridge_bput_2(uaecptr addr,uae_u32 b)1050 static void REGPARAM2 pci_bridge_bput_2(uaecptr addr, uae_u32 b)
1051 {
1052 struct pci_bridge *pcib = get_pci_bridge_2(addr);
1053 if (!pcib)
1054 return;
1055 #if PCI_DEBUG_BRIDGE
1056 write_log(_T("pci_bridge_bput_2 %08x %02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
1057 #endif
1058 if (!pcib->configured_2) {
1059 uaecptr offset = addr & 65535;
1060 if (pcib->bank_2_zorro == 2) {
1061 switch (offset)
1062 {
1063 case 0x48:
1064 // Mediator 1200 IO
1065 pcib->baseaddress_2 = b << 16;
1066 pcib->baseaddress_end_2 = (b << 16) + expamem_z2_size;
1067 map_banks_z2(pcib->bank_2, pcib->baseaddress_2 >> 16, 0x10000 >> 16);
1068 map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, (expamem_z2_size - 0x10000) >> 16);
1069 pcib->configured_2 = 1;
1070 pcib->io_offset = pcib->baseaddress_2 + 0x10000;
1071 expamem_next(pcib->bank_2, NULL);
1072 break;
1073 case 0x4c:
1074 pcib->configured_2 = -1;
1075 expamem_shutup(pcib->bank_2);
1076 break;
1077 }
1078 }
1079 } else {
1080 if (pcib->bank_2_zorro == 2) {
1081 // Mediator 1200
1082 int offset = addr & 0xffff;
1083 if (offset == 7) {
1084 // config/io mapping
1085 if (b & 0x20) {
1086 if (b & 0x80) {
1087 map_banks_z2(&pci_config_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
1088 } else {
1089 map_banks_z2(&pci_io_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
1090 }
1091 } else {
1092 map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
1093 }
1094 } else if (offset == 11) {
1095 pcib->intena = b >> 4;
1096 } else if (offset == 0x40) {
1097 // power off
1098 uae_quit();
1099 }
1100 }
1101 if (pcib->bank_2_zorro == 3) {
1102 // Mediator 4000 window
1103 int offset = addr & 0x7fffff;
1104 if (offset == 0) {
1105 mediator_set_window_offset(pcib, b);
1106 } else if (offset == 4) {
1107 pcib->intena = b >> 4;
1108 }
1109 }
1110 }
1111 }
pci_bridge_wput_2(uaecptr addr,uae_u32 b)1112 static void REGPARAM2 pci_bridge_wput_2(uaecptr addr, uae_u32 b)
1113 {
1114 struct pci_bridge *pcib = get_pci_bridge_2(addr);
1115 if (!pcib)
1116 return;
1117 if (!pcib->configured_2) {
1118 uaecptr offset = addr & 65535;
1119 if (pcib->bank_2_zorro == 3) {
1120 switch (offset)
1121 {
1122 case 0x44:
1123 // Mediator 4000 IO
1124 if (validate_banks_z3(&pci_io_bank, expamem_z3_pointer >> 16, expamem_z3_size >> 16)) {
1125 map_banks(pcib->bank_2, expamem_z3_pointer >> 16, 0x800000 >> 16, 0);
1126 map_banks(&pci_config_bank, (expamem_z3_pointer + 0x800000) >> 16, 0x400000 >> 16, 0);
1127 map_banks(&pci_io_bank, (expamem_z3_pointer + 0xc00000) >> 16, 0x400000 >> 16, 0);
1128 }
1129 pcib->baseaddress_2 = expamem_z3_pointer;
1130 pcib->baseaddress_end_2 = expamem_z3_pointer + expamem_z3_size;
1131 pcib->board_size_2 = expamem_z3_size;
1132 pcib->configured_2 = 1;
1133 pcib->io_offset = (expamem_z3_pointer + 0xc00000);
1134 expamem_next(pcib->bank, NULL);
1135 break;
1136 }
1137 }
1138 } else {
1139 if (pcib->bank_2_zorro == 2) {
1140 // Mediator 1200 window
1141 int offset = addr & 0xffff;
1142 if (offset == 2) {
1143 mediator_set_window_offset(pcib, b);
1144 }
1145 }
1146 }
1147 #if PCI_DEBUG_BRIDGE
1148 write_log(_T("pci_bridge_wput_2 %08x %04x PC=%08x\n"), addr, b & 0xffff, M68K_GETPC);
1149 #endif
1150 }
pci_bridge_lput_2(uaecptr addr,uae_u32 b)1151 static void REGPARAM2 pci_bridge_lput_2(uaecptr addr, uae_u32 b)
1152 {
1153 #if PCI_DEBUG_BRIDGE
1154 write_log(_T("pci_bridge_lput_2 %08x %08x PC=%08x\n"), addr, b, M68K_GETPC);
1155 #endif
1156 struct pci_bridge *pcib = get_pci_bridge_2(addr);
1157 if (!pcib)
1158 return;
1159 pci_bridge_wput_2(addr + 0, b >> 16);
1160 pci_bridge_wput_2(addr + 2, b >> 0);
1161 }
1162
1163
1164 addrbank pci_config_bank = {
1165 pci_config_lget, pci_config_wget, pci_config_bget,
1166 pci_config_lput, pci_config_wput, pci_config_bput,
1167 default_xlate, default_check, NULL, NULL, _T("PCI CONFIG"),
1168 pci_config_lget, pci_config_wget,
1169 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1170 };
1171 addrbank pci_io_bank = {
1172 pci_io_lget, pci_io_wget, pci_io_bget,
1173 pci_io_lput, pci_io_wput, pci_io_bput,
1174 default_xlate, default_check, NULL, NULL, _T("PCI IO"),
1175 pci_io_lget, pci_io_wget,
1176 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1177 };
1178 addrbank pci_mem_bank = {
1179 pci_mem_lget, pci_mem_wget, pci_mem_bget,
1180 pci_mem_lput, pci_mem_wput, pci_mem_bput,
1181 default_xlate, default_check, NULL, NULL, _T("PCI MEMORY"),
1182 pci_mem_lget, pci_mem_wget,
1183 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1184 };
1185 addrbank pci_bridge_bank = {
1186 pci_bridge_lget, pci_bridge_wget, pci_bridge_bget,
1187 pci_bridge_lput, pci_bridge_wput, pci_bridge_bput,
1188 default_xlate, default_check, NULL, NULL, _T("PCI BRIDGE"),
1189 pci_bridge_lget, pci_bridge_wget,
1190 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1191 };
1192 addrbank pci_bridge_bank_2 = {
1193 pci_bridge_lget_2, pci_bridge_wget_2, pci_bridge_bget_2,
1194 pci_bridge_lput_2, pci_bridge_wput_2, pci_bridge_bput_2,
1195 default_xlate, default_check, NULL, NULL, _T("PCI BRIDGE #2"),
1196 pci_bridge_lget_2, pci_bridge_wget_2,
1197 ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
1198 };
1199
validate_pci_dma(struct pci_board_state * pcibs,uaecptr addr,int size)1200 static bool validate_pci_dma(struct pci_board_state *pcibs, uaecptr addr, int size)
1201 {
1202 struct pci_bridge *pcib = pcibs->bridge;
1203 addrbank *ab = &get_mem_bank(addr);
1204 if (ab == &dummy_bank)
1205 return false;
1206 if (pcib->pcipcidma) {
1207 if (ab == &pci_mem_bank && &get_mem_bank(addr + size - 1) == &pci_mem_bank)
1208 return true;
1209 }
1210 if (pcib->amigapicdma) {
1211 if ((ab->flags & ABFLAG_RAM) && ab->check(addr, size))
1212 return true;
1213 }
1214 return false;
1215 }
1216
pci_write_dma(struct pci_board_state * pcibs,uaecptr addr,uae_u8 * p,int size)1217 void pci_write_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
1218 {
1219 if (validate_pci_dma(pcibs, addr, size)) {
1220 while (size > 0) {
1221 put_byte(addr, *p++);
1222 addr++;
1223 size--;
1224 }
1225 } else {
1226 write_log(_T("pci_write_dma invalid address %08x, size %d\n"), addr, size);
1227 while (size > 0) {
1228 put_byte(addr, uaerand());
1229 addr++;
1230 size--;
1231 }
1232 }
1233 }
pci_read_dma(struct pci_board_state * pcibs,uaecptr addr,uae_u8 * p,int size)1234 void pci_read_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
1235 {
1236 if (validate_pci_dma(pcibs, addr, size)) {
1237 while (size > 0) {
1238 *p++ = get_byte(addr);
1239 addr++;
1240 size--;
1241 }
1242 } else {
1243 write_log(_T("pci_read_dma invalid address %08x, size %d\n"), addr, size);
1244 while (size > 0) {
1245 *p++ = uaerand();
1246 addr++;
1247 size--;
1248 }
1249 }
1250 }
1251
pci_dump_out(const TCHAR * txt,int log)1252 static void pci_dump_out(const TCHAR *txt, int log)
1253 {
1254 if (log > 0)
1255 write_log(_T("%s"), txt);
1256 else if (log == 0)
1257 console_out(txt);
1258 }
1259
pci_dump_memio_region(struct pci_bridge * pcib,uaecptr start,uaecptr end,int type,int log)1260 static void pci_dump_memio_region(struct pci_bridge *pcib, uaecptr start, uaecptr end, int type, int log)
1261 {
1262 for (int i = 0; i < MAX_PCI_BOARDS; i++) {
1263 struct pci_board_state *pcibs = &pcib->boards[i];
1264 for (int j = 0; j < MAX_PCI_BARS; j++) {
1265 if (pcibs->bar_size[j] && (pcibs->bar_start[j] || pcibs->bar_end[j]) && (pcibs->bar_size[j] & 1) == type) {
1266 TCHAR txt[256];
1267 _stprintf(txt, _T(" - %08X - %08X: BAR%d %s\n"), pcibs->bar_start[j], pcibs->bar_end[j], j, pcibs->board->label);
1268 pci_dump_out(txt, log);
1269 }
1270 }
1271 }
1272 }
1273
pci_dump_region(addrbank * bank,uaecptr * start,uaecptr * end)1274 static void pci_dump_region(addrbank *bank, uaecptr *start, uaecptr *end)
1275 {
1276 *start = 0;
1277 *end = 0;
1278 for (int i = 0; i < 65536 + 1; i++) {
1279 addrbank *a = mem_banks[i];
1280 if (*start == 0 && a == bank)
1281 *start = i << 16;
1282 if (*start && a != bank) {
1283 *end = i << 16;
1284 return;
1285 }
1286 }
1287 }
1288
pci_dump(int log)1289 void pci_dump(int log)
1290 {
1291 for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
1292 TCHAR txt[256];
1293 uaecptr start, end;
1294 struct pci_bridge *pcib = bridges[i];
1295 if (!pcib)
1296 continue;
1297 _stprintf(txt, _T("PCI bridge '%s'\n"), pcib->label);
1298 pci_dump_out(txt, log);
1299 pci_dump_region(&pci_config_bank, &start, &end);
1300 if (start) {
1301 struct pci_board_state *oldpcibs = NULL;
1302 int previdx = -1;
1303 _stprintf(txt, _T("%08X - %08X: Configuration space\n"), start, end - 1);
1304 pci_dump_out(txt, log);
1305 while (start < end) {
1306 struct pci_board_state *pcibs = get_pci_board_state_config(pcib, start);
1307 if (pcibs && pcibs != oldpcibs) {
1308 const struct pci_board *pci = pcibs->board;
1309 if (pcibs->board) {
1310 _stprintf(txt, _T(" - %08x Card %d/%d: [%04X/%04X] %s IO=%d MEM=%d\n"),
1311 start, pcibs->slot, pcibs->func, pci->config->vendor, pci->config->device, pci->label,
1312 pcibs->io_map_active, pcibs->memory_map_active);
1313 } else {
1314 int idx = pcib->get_index(start);
1315 _stprintf(txt, _T(" - Slot %d: <none>\n"), idx & 0xff);
1316 }
1317 pci_dump_out(txt, log);
1318 oldpcibs = pcibs;
1319 }
1320 start += 256;
1321 }
1322 }
1323 pci_dump_region(&pci_io_bank, &start, &end);
1324 if (start) {
1325 _stprintf(txt, _T("%08X - %08X: IO space\n"), start, end - 1);
1326 pci_dump_out(txt, log);
1327 pci_dump_memio_region(pcib, start, end, 1, log);
1328 }
1329 pci_dump_region(&pci_mem_bank, &start, &end);
1330 if (start) {
1331 _stprintf(txt, _T("%08X - %08X: Memory space\n"), start, end - 1);
1332 pci_dump_out(txt, log);
1333 pci_dump_memio_region(pcib, start, end, 0, log);
1334 }
1335 }
1336 }
1337
countbit(int mask)1338 static int countbit(int mask)
1339 {
1340 int found = -1;
1341 for (int i = 0; i < 15; i++) {
1342 if (mask & (1 << i)) {
1343 if (found >= 0)
1344 return -1;
1345 found = i;
1346 }
1347 }
1348 return found;
1349 }
1350
1351 /* DKB Wildfire */
1352
1353 #define WILDFIRE_CONFIG_MASK 32767
1354
wildfire_bput(struct pci_board_state * pcibs,uaecptr addr,uae_u32 b)1355 static void REGPARAM2 wildfire_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
1356 {
1357 // BAR6 = "ROM"
1358 if (pcibs->selected_bar == 6) {
1359 bridges[PCI_BRIDGE_WILDFIRE]->data[addr & WILDFIRE_CONFIG_MASK] = b;
1360 } else {
1361 ncr815_io_bput_wildfire(addr, b);
1362 }
1363 }
wildfire_wput(struct pci_board_state * pcibs,uaecptr addr,uae_u32 b)1364 static void REGPARAM2 wildfire_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
1365 {
1366 if (pcibs->selected_bar == 6) {
1367 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 0) & WILDFIRE_CONFIG_MASK] = b >> 8;
1368 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 1) & WILDFIRE_CONFIG_MASK] = b;
1369 } else {
1370 ncr815_io_bput_wildfire(addr + 1, b >> 0);
1371 ncr815_io_bput_wildfire(addr + 0, b >> 8);
1372 }
1373 }
wildfire_lput(struct pci_board_state * pcibs,uaecptr addr,uae_u32 b)1374 static void REGPARAM2 wildfire_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
1375 {
1376 if (pcibs->selected_bar == 6) {
1377 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 0) & WILDFIRE_CONFIG_MASK] = b >> 24;
1378 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 1) & WILDFIRE_CONFIG_MASK] = b >> 16;
1379 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 2) & WILDFIRE_CONFIG_MASK] = b >> 8;
1380 bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 3) & WILDFIRE_CONFIG_MASK] = b >> 0;
1381 } else {
1382 ncr815_io_bput_wildfire(addr + 3, b >> 0);
1383 ncr815_io_bput_wildfire(addr + 2, b >> 8);
1384 ncr815_io_bput_wildfire(addr + 1, b >> 16);
1385 ncr815_io_bput_wildfire(addr + 0, b >> 24);
1386 }
1387 }
wildfire_bget(struct pci_board_state * pcibs,uaecptr addr)1388 static uae_u32 REGPARAM2 wildfire_bget(struct pci_board_state *pcibs, uaecptr addr)
1389 {
1390 uae_u32 v = 0;
1391 if (pcibs->selected_bar == 6) {
1392 v = bridges[PCI_BRIDGE_WILDFIRE]->data[addr & WILDFIRE_CONFIG_MASK];
1393 } else {
1394 v = ncr815_io_bget_wildfire(addr);
1395 }
1396 return v;
1397 }
wildfire_wget(struct pci_board_state * pcibs,uaecptr addr)1398 static uae_u32 REGPARAM2 wildfire_wget(struct pci_board_state *pcibs, uaecptr addr)
1399 {
1400 uae_u32 v = 0;
1401 if (pcibs->selected_bar == 6) {
1402 v = bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 0) & WILDFIRE_CONFIG_MASK] << 8;
1403 v |= bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 1) & WILDFIRE_CONFIG_MASK];
1404 } else {
1405 v = ncr815_io_bget_wildfire(addr + 1) << 0;
1406 v |= ncr815_io_bget_wildfire(addr + 0) << 8;
1407 }
1408 return v;
1409 }
wildfire_lget(struct pci_board_state * pcibs,uaecptr addr)1410 static uae_u32 REGPARAM2 wildfire_lget(struct pci_board_state *pcibs, uaecptr addr)
1411 {
1412 uae_u32 v = 0;
1413 if (pcibs->selected_bar == 6) {
1414 v = bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 0) & WILDFIRE_CONFIG_MASK] << 24;
1415 v |= bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 1) & WILDFIRE_CONFIG_MASK] << 16;
1416 v |= bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 2) & WILDFIRE_CONFIG_MASK] << 8;
1417 v |= bridges[PCI_BRIDGE_WILDFIRE]->data[(addr + 3) & WILDFIRE_CONFIG_MASK];
1418 } else {
1419 v = ncr815_io_bget_wildfire(addr + 3) << 0;
1420 v |= ncr815_io_bget_wildfire(addr + 2) << 8;
1421 v |= ncr815_io_bget_wildfire(addr + 1) << 16;
1422 v |= ncr815_io_bget_wildfire(addr + 0) << 24;
1423 }
1424 return v;
1425 }
1426
dkb_wildfire_get_index(uaecptr addr)1427 static int dkb_wildfire_get_index(uaecptr addr)
1428 {
1429 int idx = 0;
1430 int slot = -1;
1431 for (int i = 0x0800; i <= 0x10000000; i <<= 1, idx++) {
1432 if (addr & i) {
1433 if (slot >= 0)
1434 return -1;
1435 slot = idx;
1436 }
1437 }
1438 if (slot > 5)
1439 slot = -1;
1440 return slot;
1441 }
1442
pci_irq_callback(struct pci_board_state * pcibs,bool irq)1443 void pci_irq_callback(struct pci_board_state *pcibs, bool irq)
1444 {
1445 set_pci_irq(pcibs->bridge, pcibs, irq);
1446 }
1447
1448 static const struct pci_config ncr_53c815_pci_config =
1449 {
1450 0x1000, 0x0004, 0, 0, 0, 0x010000, 0, 0, 0, 1, 0, 0, { 256 | 1, 1024 | 0, 0, 0, 0, 0, 32768 | 0 }
1451 };
1452 static const struct pci_board ncr_53c815_pci_board =
1453 {
1454 _T("NCR53C815"),
1455 &ncr_53c815_pci_config, NULL, NULL, NULL, NULL, pci_irq_callback,
1456 {
1457 { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput },
1458 { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput },
1459 { NULL },
1460 { NULL },
1461 { NULL },
1462 { NULL },
1463 { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput }
1464 }
1465 };
1466
add_pci_devices(struct pci_bridge * pcib)1467 static void add_pci_devices(struct pci_bridge *pcib)
1468 {
1469 int slot = 0;
1470
1471 if (currprefs.ne2000pciname[0]) {
1472 pci_board_add(pcib, &ne2000_pci_board, slot++, 0);
1473 }
1474
1475 if (currprefs.sound_fm801) {
1476 pci_board_add(pcib, &fm801_pci_board, slot, 0);
1477 pci_board_add(pcib, &fm801_pci_board_func1, slot, 1);
1478 slot++;
1479 }
1480
1481 if (currprefs.sound_es1370) {
1482 pci_board_add(pcib, &es1370_pci_board, slot++, 0);
1483 }
1484
1485 //pci_board_add(pcib, &solo1_pci_board, slot++, 0);
1486
1487 //pci_board_add(pcib, &ncr_53c815_pci_board, 1, 0);
1488 }
1489
1490 // Wildfire
1491
wildfire_ncr815_irq(int v)1492 void wildfire_ncr815_irq(int v)
1493 {
1494 struct pci_board_state *pcibs = &bridges[PCI_BRIDGE_WILDFIRE]->boards[0];
1495 set_pci_irq(bridges[PCI_BRIDGE_WILDFIRE], pcibs, v != 0);
1496 }
1497
dkb_wildfire_pci_init(struct romconfig * rc)1498 addrbank *dkb_wildfire_pci_init(struct romconfig *rc)
1499 {
1500 struct pci_bridge *pcib = pci_bridge_alloc();
1501
1502 bridges[PCI_BRIDGE_WILDFIRE] = pcib;
1503 pcib->label = _T("Wildfire");
1504 pcib->endian_swap_config = 0;
1505 pcib->endian_swap_io = 0;
1506 pcib->endian_swap_memory = 0;
1507 pcib->intena = 0xff; // controlled by bridge config bits, bit unknown.
1508 pcib->intreq_mask = 0x100;
1509 pcib->get_index = dkb_wildfire_get_index;
1510 pcib->baseaddress = 0x80000000;
1511 pcib->baseaddress_end = 0xffffffff;
1512 pcib->configured = -1;
1513 pcib->pcipcidma = true;
1514 pcib->amigapicdma = true;
1515 pci_board_add(pcib, &ncr_53c815_pci_board, 0, 0);
1516 map_banks(&pci_config_bank, 0x80000000 >> 16, 0x10000000 >> 16, 0);
1517 map_banks(&pci_mem_bank, 0x90000000 >> 16, 0x30000000 >> 16, 0);
1518 map_banks(&pci_io_bank, 0xc0000000 >> 16, 0x30000000 >> 16, 0);
1519 map_banks(&pci_bridge_bank, 0xffff0000 >> 16, 0x10000 >> 16, 0);
1520 pcib->data = xcalloc(uae_u8, 32768);
1521 return &expamem_null;
1522 }
1523
1524 // Prometheus: 44359/1
1525
1526 static const uae_u8 prometheus_autoconfig[16] = { 0x85, 0x01, 0x30, 0x00, 0xad, 0x47, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1527
ew(uae_u8 * acmemory,int addr,uae_u8 value)1528 static void ew(uae_u8 *acmemory, int addr, uae_u8 value)
1529 {
1530 if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
1531 acmemory[addr] = (value & 0xf0);
1532 acmemory[addr + 2] = (value & 0x0f) << 4;
1533 } else {
1534 acmemory[addr] = ~(value & 0xf0);
1535 acmemory[addr + 2] = ~((value & 0x0f) << 4);
1536 }
1537 }
1538
prometheus_get_index(uaecptr addr)1539 static int prometheus_get_index(uaecptr addr)
1540 {
1541 struct pci_bridge *pcib = get_pci_bridge(addr);
1542
1543 addr -= pcib->baseaddress;
1544 if ((addr & 0xffff0f00) != 0x000f0000)
1545 return -1;
1546 int slot = (addr & 0xf000) >> 13;
1547 if (slot > 3)
1548 return -1;
1549 slot |= ((addr >> 8) & 7) << 8;
1550 return slot;
1551 }
1552
prometheus_pci_init(struct romconfig * rc)1553 static addrbank *prometheus_pci_init(struct romconfig *rc)
1554 {
1555 struct pci_bridge *pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_PROMETHEUS, rc);
1556 if (!pcib)
1557 return &expamem_null;
1558 pcib->label = _T("Prometheus");
1559 pcib->endian_swap_config = 1;
1560 pcib->endian_swap_io = -1;
1561 pcib->endian_swap_memory = -1;
1562 pcib->intena = 0xff;
1563 pcib->intreq_mask = 0x10;
1564 pcib->get_index = prometheus_get_index;
1565 pcib->bank = &pci_bridge_bank;
1566 pcib->bank_zorro = 3;
1567 pcib->pcipcidma = true;
1568 if (rc->device_settings & 1)
1569 pcib->amigapicdma = true;
1570
1571 add_pci_devices(pcib);
1572
1573 memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
1574 for (int i = 0; i < sizeof prometheus_autoconfig; i++) {
1575 ew(pcib->acmemory, i * 4, prometheus_autoconfig[i]);
1576 }
1577 return pcib->bank;
1578 }
1579
1580 // G-REX
1581
grex_get_index(uaecptr addr)1582 static int grex_get_index(uaecptr addr)
1583 {
1584 int slot = -1;
1585 struct pci_bridge *pcib = get_pci_bridge(addr);
1586
1587 if ((addr & 0xfffc1000) == 0xfffc0000) {
1588 int v = (addr & 0x3f000) >> 13;
1589 slot = countbit(v);
1590 slot |= ((addr >> 8) & 7) << 8;
1591 }
1592 return slot;
1593 }
1594
grex_pci_init(struct romconfig * rc)1595 static addrbank *grex_pci_init(struct romconfig *rc)
1596 {
1597 struct pci_bridge *pcib = pci_bridge_alloc();
1598
1599 bridges[PCI_BRIDGE_GREX] = pcib;
1600 pcib->label = _T("G-REX");
1601 pcib->intena = 0;
1602 pcib->intreq_mask = 0x10;
1603 pcib->get_index = grex_get_index;
1604 pcib->baseaddress = 0x80000000;
1605 pcib->baseaddress_end = 0xffffffff;
1606 pcib->configured = -1;
1607 pcib->pcipcidma = true;
1608 pcib->amigapicdma = true;
1609
1610 add_pci_devices(pcib);
1611
1612 map_banks(&pci_config_bank, 0xfffc0000 >> 16, 0x20000 >> 16, 0);
1613 map_banks(&pci_mem_bank, 0x80000000 >> 16, 0x78000000 >> 16, 0);
1614 map_banks(&pci_io_bank, 0xfffa0000 >> 16, 0x20000 >> 16, 0);
1615 map_banks(&pci_bridge_bank, 0xfffe0000 >> 16, 0x10000 >> 16, 0);
1616 pcib->io_offset = 0xfffa0000;
1617 return &expamem_null;
1618 }
1619
1620 // CyberVision/BlizzardVision without VGA chip...
1621
xvision_get_index(uaecptr addr)1622 static int xvision_get_index(uaecptr addr)
1623 {
1624 struct pci_bridge *pcib = get_pci_bridge(addr);
1625 if ((addr & 0xfffcf700) == 0xfffc0000)
1626 return 0;
1627 return -1;
1628 }
1629
cbvision(struct romconfig * rc)1630 static addrbank *cbvision(struct romconfig *rc)
1631 {
1632 struct pci_bridge *pcib = pci_bridge_alloc();
1633
1634 bridges[PCI_BRIDGE_XVISION] = pcib;
1635 pcib->label = _T("CBVision");
1636 pcib->intena = 0;
1637 pcib->intreq_mask = 0x10;
1638 pcib->get_index = xvision_get_index;
1639 pcib->baseaddress = 0xe0000000;
1640 pcib->baseaddress_end = 0xffffffff;
1641 pcib->configured = -1;
1642 pcib->pcipcidma = true;
1643 pcib->amigapicdma = true;
1644
1645 map_banks(&pci_config_bank, 0xfffc0000 >> 16, 0x20000 >> 16, 0);
1646 map_banks(&pci_mem_bank, 0xe0000000 >> 16, 0x10000000 >> 16, 0);
1647 map_banks(&pci_io_bank, 0xfffa0000 >> 16, 0x20000 >> 16, 0);
1648 map_banks(&pci_bridge_bank, 0xfffe0000 >> 16, 0x10000 >> 16, 0);
1649 pcib->io_offset = 0xfffa0000;
1650 return &expamem_null;
1651 }
1652
1653 // Mediator
1654
1655 // Mediator 4000MK2
1656 static const uae_u8 autoconfig_mediator_4000mk2_256m[16] = { 0x84,0xa1,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1657 static const uae_u8 autoconfig_mediator_4000mk2_512m[16] = { 0x85,0xa1,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1658 static const uae_u8 autoconfig_mediator_4000mk2_2[16] = { 0x88,0x21,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1659
1660 // Mediator 1200 TX
1661 static const uae_u8 autoconfig_mediator_1200tx_1[16] = { 0xca,0x3c,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1662 static const uae_u8 autoconfig_mediator_1200tx_2_4m[16] = { 0xc7,0xbc,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1663 static const uae_u8 autoconfig_mediator_1200tx_2_8m[16] = { 0xc0,0xbc,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1664
1665 // Mediator 1200 SX
1666 static const uae_u8 autoconfig_mediator_1200sx_1[16] = { 0xca,0x28,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1667 static const uae_u8 autoconfig_mediator_1200sx_2_4m[16] = { 0xc7,0xa8,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1668 static const uae_u8 autoconfig_mediator_1200sx_2_8m[16] = { 0xc0,0xa8,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
1669
1670 // Mediator 1200
1671 static const uae_u8 autoconfig_mediator_1200_1[16] = { 0xca, 0x20, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1672 static const uae_u8 autoconfig_mediator_1200_2_4m[16] = { 0xcf, 0xa0, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1673 static const uae_u8 autoconfig_mediator_1200_2_8m[16] = { 0xc8, 0xa0, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1674
1675 struct mediator_autoconfig
1676 {
1677 const uae_u8 *io;
1678 const uae_u8 *mem_small;
1679 const uae_u8 *mem_large;
1680 };
1681
1682 #define MED_1200 0
1683 #define MED_1200SX 1
1684 #define MED_1200TX 2
1685 #define MED_4000MK2 3
1686
1687 static struct mediator_autoconfig mediator_ac[] =
1688 {
1689 { autoconfig_mediator_1200_1, autoconfig_mediator_1200_2_4m, autoconfig_mediator_1200_2_8m },
1690 { autoconfig_mediator_1200sx_1, autoconfig_mediator_1200sx_2_4m, autoconfig_mediator_1200sx_2_8m },
1691 { autoconfig_mediator_1200tx_1, autoconfig_mediator_1200tx_2_4m, autoconfig_mediator_1200tx_2_8m },
1692 { autoconfig_mediator_4000mk2_2, autoconfig_mediator_4000mk2_256m, autoconfig_mediator_4000mk2_512m }
1693 };
1694
1695
mediator_get_index_1200(uaecptr addr)1696 static int mediator_get_index_1200(uaecptr addr)
1697 {
1698 struct pci_bridge *pcib = get_pci_bridge(addr);
1699 if (!pcib)
1700 return -1;
1701 uae_u32 offset = addr - pcib->baseaddress_2;
1702 if (offset < 0x10000)
1703 return -1;
1704 offset -= 0x10000;
1705 int slot = offset / 0x800;
1706 if (slot >= 6)
1707 return -1;
1708 slot |= ((offset >> 8) & 7) << 8;
1709 return slot;
1710 }
1711
mediator_get_index_4000(uaecptr addr)1712 static int mediator_get_index_4000(uaecptr addr)
1713 {
1714 struct pci_bridge *pcib = get_pci_bridge(addr);
1715 if (!pcib)
1716 return -1;
1717 uae_u32 offset = addr - pcib->baseaddress_2;
1718 if (offset < 0x800000 || offset >= 0xc00000)
1719 return -1;
1720 offset -= 0x800000;
1721 int slot = offset / 0x800;
1722 if (slot >= 6)
1723 return -1;
1724 slot |= ((offset >> 8) & 7) << 8;
1725 return slot;
1726 }
1727
mediator_pci_init_1200(struct pci_bridge * pcib)1728 static void mediator_pci_init_1200(struct pci_bridge *pcib)
1729 {
1730 pcib->label = _T("Mediator 1200");
1731 pcib->endian_swap_config = -1;
1732 pcib->endian_swap_io = -1;
1733 pcib->endian_swap_memory = -1;
1734 pcib->intena = 0;
1735 pcib->intreq_mask = 0x10;
1736 pcib->get_index = mediator_get_index_1200;
1737 pcib->bank = &pci_bridge_bank;
1738 pcib->bank_2 = &pci_bridge_bank_2;
1739 pcib->bank_zorro = 2;
1740 pcib->bank_2_zorro = 2;
1741 pcib->pcipcidma = true;
1742 if (pcib->rc->device_settings & 1)
1743 pcib->amigapicdma = true;
1744 mediator_set_window_offset(pcib, 0);
1745 }
1746
mediator_pci_init_1200_1(struct romconfig * rc,struct mediator_autoconfig * m_ac)1747 static addrbank *mediator_pci_init_1200_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
1748 {
1749 struct pci_bridge *pcib;
1750 if (!(rc->device_settings & 4)) {
1751 // io first
1752 pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
1753 if (!pcib)
1754 return &expamem_null;
1755 mediator_pci_init_1200(pcib);
1756 add_pci_devices(pcib);
1757 } else {
1758 pcib = pci_bridge_get_zorro(rc);
1759 if (!pcib)
1760 return &expamem_null;
1761 }
1762 memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
1763 for (int i = 0; i < 16; i++) {
1764 ew(pcib->acmemory_2, i * 4, m_ac->io[i]);
1765 }
1766 return &pci_bridge_bank_2;
1767 }
1768
mediator_pci_init_1200_2(struct romconfig * rc,struct mediator_autoconfig * m_ac)1769 static addrbank *mediator_pci_init_1200_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
1770 {
1771 struct pci_bridge *pcib;
1772 if (!(rc->device_settings & 4)) {
1773 // memory last
1774 pcib = pci_bridge_get_zorro(rc);
1775 if (!pcib)
1776 return &expamem_null;
1777 } else {
1778 // memory first
1779 pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
1780 if (!pcib)
1781 return &expamem_null;
1782 mediator_pci_init_1200(pcib);
1783 add_pci_devices(pcib);
1784 }
1785 memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
1786 const uae_u8 *ac = (rc->device_settings & 2) ? m_ac->mem_large : m_ac->mem_small;
1787 for (int i = 0; i < 16; i++) {
1788 ew(pcib->acmemory, i * 4, ac[i]);
1789 }
1790 return &pci_bridge_bank;
1791 }
1792
mediator_pci_init_4000(struct pci_bridge * pcib)1793 static void mediator_pci_init_4000(struct pci_bridge *pcib)
1794 {
1795 pcib->label = _T("Mediator 4000");
1796 pcib->endian_swap_config = -1;
1797 pcib->endian_swap_io = -1;
1798 pcib->endian_swap_memory = -1;
1799 pcib->intena = 0;
1800 pcib->intreq_mask = 0x10;
1801 pcib->get_index = mediator_get_index_4000;
1802 pcib->bank = &pci_bridge_bank;
1803 pcib->bank_2 = &pci_bridge_bank_2;
1804 pcib->bank_zorro = 3;
1805 pcib->bank_2_zorro = 3;
1806 pcib->pcipcidma = true;
1807 if (pcib->rc->device_settings & 1)
1808 pcib->amigapicdma = true;
1809 mediator_set_window_offset(pcib, 0);
1810 }
1811
mediator_pci_init_4000_1(struct romconfig * rc,struct mediator_autoconfig * m_ac)1812 static addrbank *mediator_pci_init_4000_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
1813 {
1814 struct pci_bridge *pcib;
1815 if (!(rc->device_settings & 4)) {
1816 // io first
1817 pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
1818 if (!pcib)
1819 return &expamem_null;
1820 mediator_pci_init_4000(pcib);
1821 add_pci_devices(pcib);
1822 } else {
1823 pcib = pci_bridge_get_zorro(rc);
1824 if (!pcib)
1825 return &expamem_null;
1826 }
1827 memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
1828 for (int i = 0; i < 16; i++) {
1829 ew(pcib->acmemory_2, i * 4, m_ac->io[i]);
1830 }
1831 return &pci_bridge_bank_2;
1832 }
mediator_pci_init_4000_2(struct romconfig * rc,struct mediator_autoconfig * m_ac)1833 static addrbank *mediator_pci_init_4000_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
1834 {
1835 struct pci_bridge *pcib;
1836 if (!(rc->device_settings & 4)) {
1837 // memory last
1838 pcib = pci_bridge_get_zorro(rc);
1839 if (!pcib)
1840 return &expamem_null;
1841 } else {
1842 // memory first
1843 pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
1844 if (!pcib)
1845 return &expamem_null;
1846
1847 mediator_pci_init_4000(pcib);
1848 add_pci_devices(pcib);
1849 }
1850 memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
1851 const uae_u8 *ac = (rc->device_settings & 2) ? m_ac->mem_large : m_ac->mem_small;
1852 for (int i = 0; i < 16; i++) {
1853 ew(pcib->acmemory, i * 4, ac[i]);
1854 }
1855 return &pci_bridge_bank;
1856 }
1857
mediator_init(struct romconfig * rc)1858 addrbank *mediator_init(struct romconfig *rc)
1859 {
1860 struct mediator_autoconfig *ac;
1861 switch (rc->subtype)
1862 {
1863 case 0:
1864 ac = &mediator_ac[MED_1200];
1865 if (rc->device_settings & 4)
1866 return mediator_pci_init_1200_2(rc, ac);
1867 else
1868 return mediator_pci_init_1200_1(rc, ac);
1869 case 1:
1870 ac = &mediator_ac[MED_1200SX];
1871 if (rc->device_settings & 4)
1872 return mediator_pci_init_1200_2(rc, ac);
1873 else
1874 return mediator_pci_init_1200_1(rc, ac);
1875 case 2:
1876 ac = &mediator_ac[MED_1200TX];
1877 if (rc->device_settings & 4)
1878 return mediator_pci_init_1200_2(rc, ac);
1879 else
1880 return mediator_pci_init_1200_1(rc, ac);
1881 case 3:
1882 ac = &mediator_ac[MED_4000MK2];
1883 if (rc->device_settings & 4)
1884 return mediator_pci_init_4000_2(rc, ac);
1885 else
1886 return mediator_pci_init_4000_1(rc, ac);
1887 }
1888 return &expamem_null;
1889 }
1890
mediator_init2(struct romconfig * rc)1891 addrbank *mediator_init2(struct romconfig *rc)
1892 {
1893 struct mediator_autoconfig *ac;
1894 switch (rc->subtype)
1895 {
1896 case 0:
1897 ac = &mediator_ac[MED_1200];
1898 if (rc->device_settings & 4)
1899 return mediator_pci_init_1200_1(rc, ac);
1900 else
1901 return mediator_pci_init_1200_2(rc, ac);
1902 case 1:
1903 ac = &mediator_ac[MED_1200SX];
1904 if (rc->device_settings & 4)
1905 return mediator_pci_init_1200_1(rc, ac);
1906 else
1907 return mediator_pci_init_1200_2(rc, ac);
1908 case 2:
1909 ac = &mediator_ac[MED_1200TX];
1910 if (rc->device_settings & 4)
1911 return mediator_pci_init_1200_1(rc, ac);
1912 else
1913 return mediator_pci_init_1200_2(rc, ac);
1914 case 3:
1915 ac = &mediator_ac[MED_4000MK2];
1916 if (rc->device_settings & 4)
1917 return mediator_pci_init_4000_1(rc, ac);
1918 else
1919 return mediator_pci_init_4000_2(rc, ac);
1920 }
1921 return &expamem_null;
1922 }
1923
prometheus_init(struct romconfig * rc)1924 addrbank *prometheus_init(struct romconfig *rc)
1925 {
1926 return prometheus_pci_init(rc);
1927 }
1928
cbvision_init(struct romconfig * rc)1929 addrbank *cbvision_init(struct romconfig *rc)
1930 {
1931 return cbvision(rc);
1932 }
1933
grex_init(struct romconfig * rc)1934 addrbank *grex_init(struct romconfig *rc)
1935 {
1936 return grex_pci_init(rc);
1937 }
1938