]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
PCI bridge updates.
authorToni Wilen <twilen@winuae.net>
Mon, 6 Jul 2015 16:00:44 +0000 (19:00 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 6 Jul 2015 16:00:44 +0000 (19:00 +0300)
include/pci.h
include/pci_hw.h
pci.cpp
qemuvga/ne2000.cpp

index 1448362d6be8ef4fd47609f79a8eff39a8e363e3..63f0e6a67c0c7e79421f47abacced0fde841faa9 100644 (file)
@@ -1,6 +1,7 @@
 
 extern void pci_free(void);
 extern void pci_reset(void);
+extern void pci_hsync(void);
 extern void pci_rethink(void);
 extern void pci_dump(int);
 
index 3eecfd59208bb4b6afbfdcc78425d9f6b30ef772..c379c82ec17a3eafd02701395e718ac54225e4af 100644 (file)
@@ -8,6 +8,7 @@ typedef void (REGPARAM3 *pci_put_func)(struct pci_board_state*,uaecptr,uae_u32)
 typedef void (*pci_dev_irq)(struct pci_board_state*,bool);
 typedef bool(*pci_dev_init)(struct pci_board_state*);
 typedef void(*pci_dev_reset)(struct pci_board_state*);
+typedef void(*pci_dev_hsync)(struct pci_board_state*);
 typedef void(*pci_dev_free)(struct pci_board_state*);
 
 typedef struct
@@ -30,6 +31,8 @@ struct pci_config
        uae_u16 subsystenvendor;
        uae_u16 subsystem;
        uae_u8 interruptpin;
+       uae_u8 min_grant;
+       uae_u8 max_latency;
        uae_u32 bars[MAX_PCI_BARS];
 };
 
@@ -40,6 +43,7 @@ struct pci_board
        pci_dev_init init;
        pci_dev_free free;
        pci_dev_reset reset;
+       pci_dev_hsync hsync;
        pci_dev_irq irq;
        pci_addrbank bars[MAX_PCI_BARS];
 };
@@ -55,7 +59,8 @@ struct pci_board_state
        uae_u32 bar_size[MAX_PCI_BARS];
        int selected_bar;
        const struct pci_board *board;
-       int index;
+       int slot;
+       int func;
        bool memory_map_active;
        bool io_map_active;
        struct pci_bridge *bridge;
@@ -95,6 +100,7 @@ struct pci_bridge
        uae_u8 acmemory_2[128];
        struct romconfig *rc;
        uae_u16 window;
+       int slot_cnt;
 };
 
 extern void pci_free(void);
@@ -104,5 +110,11 @@ extern void pci_rethink(void);
 extern addrbank *dkb_wildfire_pci_init(struct romconfig *rc);
 
 extern void pci_irq_callback(struct pci_board_state *pcibs, bool irq);
+extern void pci_write_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8*, int size);
+extern void pci_read_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8*, int size);
 
 extern const struct pci_board ne2000_pci_board;
+extern const struct pci_board es1370_pci_board;
+extern const struct pci_board fm801_pci_board;
+extern const struct pci_board fm801_pci_board_func1;
+extern const struct pci_board solo1_pci_board;
diff --git a/pci.cpp b/pci.cpp
index 839c130109240ed67e8d66aa396344ee5912e349..83706c0ce4d6857678f5e11797878ba0515a19f7 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -27,6 +27,7 @@
 #include "uae.h"
 #include "rommgr.h"
 #include "cpuboard.h"
+#include "autoconf.h"
 
 #include "qemuvga/qemuuaeglue.h"
 #include "qemuvga/queue.h"
@@ -41,6 +42,7 @@
 
 static struct pci_bridge *bridges[PCI_BRIDGE_MAX + 1];
 static int last_bridge_index;
+static struct pci_board_state *hsyncs[MAX_PCI_BOARDS + 1];
 
 extern addrbank pci_config_bank, pci_io_bank, pci_mem_bank, pci_bridge_bank;
 
@@ -103,11 +105,13 @@ static struct pci_board *pci_board_alloc(struct pci_config *config)
        return pci;
 }
 
-static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int index)
+static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func)
 {
-       struct pci_board_state *pcibs = &pcib->boards[index];
+       struct pci_board_state *pcibs = &pcib->boards[pcib->slot_cnt];
+       pcib->slot_cnt++;
        pcibs->board = pci;
-       pcibs->index = index;
+       pcibs->slot = slot;
+       pcibs->func = func;
        pcibs->bridge = pcib;
        memset(pcibs->config_data, 0, sizeof pcibs->config_data);
        for (int i = 0; i < MAX_PCI_BARS; i++) {
@@ -115,6 +119,14 @@ static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci,
        }
        if (pci->init)
                pci->init(pcibs);
+       if (pci->hsync) {
+               for (int i = 0; i < MAX_PCI_BOARDS; i++) {
+                       if (hsyncs[i] == NULL) {
+                               hsyncs[i] = pcibs;
+                               break;
+                       }
+               }
+       }
 }
 
 void pci_free(void)
@@ -123,15 +135,27 @@ void pci_free(void)
                pci_bridge_free(bridges[i]);
                bridges[i] = NULL;
        }
+       for (int i = 0; i < MAX_PCI_BOARDS; i++) {
+               hsyncs[i] = NULL;
+       }
+       uae_int_requested &= ~(0x10 | 0x100);
 }
-
 void pci_reset(void)
 {
        pci_free();
 }
 
+void pci_hsync(void)
+{
+       for (int i = 0; i < MAX_PCI_BOARDS; i++) {
+               if (hsyncs[i])
+                       hsyncs[i]->board->hsync(hsyncs[i]);
+       }
+}
+
 void pci_rethink(void)
 {
+       uae_int_requested &= ~(0x10 | 0x100);
        for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
                struct pci_bridge *pcib = bridges[i];
                if (!pcib)
@@ -143,13 +167,14 @@ void pci_rethink(void)
                                const struct pci_config *c = pcibs->board->config;
                                if (c->interruptpin) {
                                        if ((pcibs->config_data[5] & (1 << 3)) && !(pcibs->config_data[6] & (1 << (10 - 8)))) {
-                                               pcib->irq |= 1 << (pcibs->board->config->interruptpin - 1);
+                                               pcib->irq |= 1 << (c->interruptpin - 1);
                                        }
                                }
                        }
                }
-               if (pcib->irq & pcib->intena)
-                       INTREQ_0(0x8000 | pcib->intreq_mask);
+               if (pcib->irq & pcib->intena) {
+                       uae_int_requested |= pcib->intreq_mask;
+               }
        }
 }
 
@@ -192,6 +217,8 @@ static void create_config_data(struct pci_board_state *s)
        d[0x2e] = c->subsystenvendor >> 8;
        d[0x2f] = c->subsystenvendor;
 
+       d[0x3c] = c->max_latency;
+       d[0x3d] = c->min_grant;
        d[0x3e] = c->interruptpin;
 }
 
@@ -255,14 +282,14 @@ static struct pci_board_state *get_pci_board_state_config(struct pci_bridge *pci
        int idx = pcib->get_index(addr);
        if (idx < 0)
                return NULL;
-       struct pci_board_state *pcibs = &pcib->boards[idx];
-       if (!pcibs->board) {
-#if PCI_DEBUG_CONFIG
-               write_log(_T("- Empty slot %d\n"), idx);
-#endif
-               return NULL;
+       int slot = idx & 0xff;
+       int func = (idx >> 8) & 0xff;
+       for (int i = 0; i < MAX_PCI_BOARDS; i++) {
+               struct pci_board_state *pcibs = &pcib->boards[i];
+               if (pcibs->slot == slot && pcibs->func == func && pcibs->board)
+                       return pcibs;
        }
-       return pcibs;
+       return NULL;
 }
 
 static int stored_board, stored_bar;
@@ -280,7 +307,7 @@ static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaec
        for (int i = 0; i < MAX_PCI_BOARDS; i++) {
                struct pci_board_state *pcibs = &pcib->boards[i];
                for (int j = 0; j < MAX_PCI_BARS; j++) {
-                       if (pcibs2->bar_enabled[j] && addr2 >= pcibs->bar_start[j] && addr2 <= pcibs->bar_end[j]) {
+                       if (pcibs->bar_enabled[j] && addr2 >= pcibs->bar_start[j] && addr2 <= pcibs->bar_end[j]) {
                                *bar = j;
                                stored_board = i;
                                stored_bar = j;
@@ -307,7 +334,7 @@ static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **p
        addr -= pcib->io_offset;
        addr &= (pcibs->bar_size[bar] & ~1) - 1;
 #if PCI_DEBUG_IO
-       write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x\n"), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC);
+       write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x "), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC);
 #endif
        *addrp = addr;
        return &pcibs->board->bars[bar];
@@ -355,7 +382,7 @@ static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap
                return NULL;
        *endianswap = pcib->endian_swap_config;
 #if PCI_DEBUG_CONFIG
-       write_log(_T("- Board %d (%s)\n"), pcibs->index, pcibs->board->label);
+       write_log(_T("- Board %d/%d (%s)\n"), pcibs->slot, pcibs->func, pcibs->board->label);
 #endif
        create_config_data(pcibs);
        return pcibs->config_data;
@@ -376,14 +403,14 @@ static void map_pci_banks(struct pci_board_state *pcibs, int type, bool enable)
                        pcibs->bar_enabled[i] = true;
 #if PCI_DEBUG_CONFIG
                        if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
-                               write_log(_T("Board %d ('%s') BAR%d: %08x-%08x\n"), pcibs->index, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
+                               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]);
                        }
 #endif
                } else {
                        pcibs->bar_enabled[i] = false;
 #if PCI_DEBUG_CONFIG
                        if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
-                               write_log(_T("Board %d ('%s') BAR%d: %08x-%08x\n"), pcibs->index, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
+                               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]);
                        }
 #endif
                }
@@ -582,8 +609,15 @@ static uae_u32 REGPARAM2 pci_io_lget(uaecptr addr)
        const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 4);
        if (a && a->lget) {
                v = a->lget(pcibs, addr);
+#if PCI_DEBUG_IO
+               write_log(_T("-> %08x\n"), v);
+#endif
                if (endianswap)
                        v = endianswap_long(v);
+       } else {
+#if PCI_DEBUG_IO
+               write_log(_T("-> X\n"), v);
+#endif
        }
        return v;
 }
@@ -599,10 +633,20 @@ static uae_u32 REGPARAM2 pci_io_wget(uaecptr addr)
        if (a && a->wget) {
                if (endianswap) {
                        v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
+#if PCI_DEBUG_IO
+                       write_log(_T("-> %04x\n"), v);
+#endif
                        v = endianswap_word(v);
                } else {
                        v = a->wget(pcibs, addr);
+#if PCI_DEBUG_IO
+                       write_log(_T("-> %04x\n"), v);
+#endif
                }
+       } else {
+#if PCI_DEBUG_IO
+               write_log(_T("-> X\n"), v);
+#endif
        }
        return v;
 }
@@ -618,9 +662,19 @@ static uae_u32 REGPARAM2 pci_io_bget(uaecptr addr)
        if (a && a->bget) {
                if (endianswap) {
                        v = a->bget(pcibs, beswap(endianswap, addr));
+#if PCI_DEBUG_IO
+                       write_log(_T("-> %02x\n"), v);
+#endif
                } else {
                        v = a->bget(pcibs, addr);
+#if PCI_DEBUG_IO
+                       write_log(_T("-> %02x\n"), v);
+#endif
                }
+       } else {
+#if PCI_DEBUG_IO
+               write_log(_T("-> X\n"), v);
+#endif
        }
        return v;
 }
@@ -637,6 +691,9 @@ static void REGPARAM2 pci_io_lput(uaecptr addr, uae_u32 b)
                        b = endianswap_long(b);
                a->lput(pcibs, addr, b);
        }
+#if PCI_DEBUG_IO
+       write_log(_T("<- %08x\n"), b);
+#endif
 }
 static void REGPARAM2 pci_io_wput(uaecptr addr, uae_u32 b)
 {
@@ -654,6 +711,9 @@ static void REGPARAM2 pci_io_wput(uaecptr addr, uae_u32 b)
                        a->wput(pcibs, addr, b);
                }
        }
+#if PCI_DEBUG_IO
+       write_log(_T("<- %04x\n"), b);
+#endif
 }
 static void REGPARAM2 pci_io_bput(uaecptr addr, uae_u32 b)
 {
@@ -670,6 +730,9 @@ static void REGPARAM2 pci_io_bput(uaecptr addr, uae_u32 b)
                        a->bput(pcibs, addr, b);
                }
        }
+#if PCI_DEBUG_IO
+       write_log(_T("<- %02x\n"), b);
+#endif
 }
 
 static uae_u32 REGPARAM2 pci_mem_lget(uaecptr addr)
@@ -987,7 +1050,7 @@ static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       uae_u8 v = 0;
+       uae_u8 v = 0xff;
        struct pci_bridge *pcib = get_pci_bridge_2(addr);
        if (!pcib)
                return v;
@@ -1001,13 +1064,17 @@ static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
                        int offset = addr & 0x7fffff;
                        if (offset == 0) {
                                v = pcib->window;
+                               v |= 8; // id
                        }
                        if (offset == 4) {
                                v = pcib->irq | (pcib->intena << 4);
                        }
                } else {
-                       int offset = addr & 0xffff;
-                       if (offset == 11) {
+                       int offset = addr & 0x1f;
+                       v = 0;
+                       if (offset == 2) {
+                               v = 0x20;
+                       } else if (offset == 11) {
                                v = pcib->irq | (pcib->intena << 4);
                        }
                }
@@ -1022,7 +1089,7 @@ static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       uae_u16 v = 0;
+       uae_u16 v = 0xffff;
 #if PCI_DEBUG_BRIDGE
        write_log(_T("pci_bridge_wget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
 #endif
@@ -1031,9 +1098,12 @@ static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
                return v;
        if (pcib->configured_2) {
                if (pcib->bank_2_zorro == 2) {
-                       int offset = addr & 0xffff;
+                       int offset = addr & 0x1f;
+                       v = 0;
                        if (offset == 2) {
-                               v = pcib->window;
+                               v = 0x2080; // id
+                       } else if (offset == 10) {
+                               v = pcib->irq | (pcib->intena << 4);
                        }
                }
        }
@@ -1044,7 +1114,7 @@ static uae_u32 REGPARAM2 pci_bridge_lget_2(uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       uae_u32 v = 0;
+       uae_u32 v = 0xffffffff;
 #if PCI_DEBUG_BRIDGE
        write_log(_T("pci_bridge_lget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
 #endif
@@ -1208,6 +1278,18 @@ addrbank pci_bridge_bank_2 = {
        pci_bridge_lget_2, pci_bridge_wget_2, ABFLAG_IO | ABFLAG_SAFE
 };
 
+void pci_write_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
+{
+}
+void pci_read_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
+{
+       while (size > 0) {
+               *p++ = get_byte(addr);
+               addr++;
+               size--;
+       }
+}
+
 static void pci_dump_out(const TCHAR *txt, int log)
 {
        if (log > 0)
@@ -1221,7 +1303,7 @@ static void pci_dump_memio_region(struct pci_bridge *pcib, uaecptr start, uaecpt
        for (int i = 0; i < MAX_PCI_BOARDS; i++) {
                struct pci_board_state *pcibs = &pcib->boards[i];
                for (int j = 0; j < MAX_PCI_BARS; j++) {
-                       if (pcibs->bar_size[i] && (pcibs->bar_start[j] || pcibs->bar_end[j]) && (pcibs->bar_size[j] & 1) == type) {
+                       if (pcibs->bar_size[j] && (pcibs->bar_start[j] || pcibs->bar_end[j]) && (pcibs->bar_size[j] & 1) == type) {
                                TCHAR txt[256];
                                _stprintf(txt, _T("        - %08X - %08X: BAR%d %s\n"), pcibs->bar_start[j], pcibs->bar_end[j], j, pcibs->board->label);
                                pci_dump_out(txt, log);
@@ -1249,7 +1331,6 @@ void pci_dump(int log)
 {
        for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
                TCHAR txt[256];
-               uae_u8 slots[MAX_PCI_BOARDS] = { 0 };
                uaecptr start, end;
                struct pci_bridge *pcib = bridges[i];
                if (!pcib)
@@ -1258,24 +1339,24 @@ void pci_dump(int log)
                pci_dump_out(txt, log);
                pci_dump_region(&pci_config_bank, &start, &end);
                if (start) {
+                       struct pci_board_state *oldpcibs = NULL;
                        int previdx = -1;
                        _stprintf(txt, _T("%08X - %08X: Configuration space\n"), start, end - 1);
                        pci_dump_out(txt, log);
                        while (start < end) {
-                               int idx = pcib->get_index(start);
-                               if (idx >= 0 && idx != previdx && slots[idx] == 0) {
-                                       struct pci_board_state *pcibs = &pcib->boards[idx];
+                               struct pci_board_state *pcibs = get_pci_board_state_config(pcib, start);
+                               if (pcibs && pcibs != oldpcibs) {
                                        const struct pci_board *pci = pcibs->board;
                                        if (pcibs->board) {
-                                               _stprintf(txt, _T("        - Slot %d: [%04X/%04X] %s IO=%d MEM=%d\n"),
-                                                       idx, pci->config->vendor, pci->config->device, pci->label,
+                                               _stprintf(txt, _T(" - %08x Card %d/%d: [%04X/%04X] %s IO=%d MEM=%d\n"),
+                                                       start, pcibs->slot, pcibs->func, pci->config->vendor, pci->config->device, pci->label,
                                                        pcibs->io_map_active, pcibs->memory_map_active);
                                        } else {
-                                               _stprintf(txt, _T("        - Slot %d: <none>\n"), idx);
+                                               int idx = pcib->get_index(start);
+                                               _stprintf(txt, _T("        - Slot %d: <none>\n"), idx & 0xff);
                                        }
                                        pci_dump_out(txt, log);
-                                       previdx = idx;
-                                       slots[idx] = 1;
+                                       oldpcibs = pcibs;
                                }
                                start += 256;
                        }
@@ -1407,12 +1488,12 @@ void pci_irq_callback(struct pci_board_state *pcibs, bool irq)
 
 static const struct pci_config ncr_53c815_pci_config =
 {
-       0x1000, 0x0004, 0, 0, 0, 0x010000, 0, 0, 0, 1, { 256 | 1, 1024 | 0, 0, 0, 0, 0, 32768 | 0 }
+       0x1000, 0x0004, 0, 0, 0, 0x010000, 0, 0, 0, 1, 0, 0, { 256 | 1, 1024 | 0, 0, 0, 0, 0, 32768 | 0 }
 };
 static const struct pci_board ncr_53c815_pci_board =
 {
        _T("NCR53C815"),
-       &ncr_53c815_pci_config, NULL, NULL, NULL, pci_irq_callback,
+       &ncr_53c815_pci_config, NULL, NULL, NULL, NULL, pci_irq_callback,
        {
                { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput },
                { wildfire_lget, wildfire_wget, wildfire_bget, wildfire_lput, wildfire_wput, wildfire_bput },
@@ -1426,10 +1507,25 @@ static const struct pci_board ncr_53c815_pci_board =
 
 static void add_pci_devices(struct pci_bridge *pcib)
 {
-       if (currprefs.ne2000pciname[0])
-               pci_board_add(pcib, &ne2000_pci_board, 0);
-       
-       //pci_board_add(pcib, &ncr_53c815_pci_board, 1);
+       int slot = 0;
+
+       if (currprefs.ne2000pciname[0]) {
+               pci_board_add(pcib, &ne2000_pci_board, slot++, 0);
+       }
+
+       if (currprefs.sound_fm801) {
+               pci_board_add(pcib, &fm801_pci_board, slot, 0);
+               pci_board_add(pcib, &fm801_pci_board_func1, slot, 1);
+               slot++;
+       }
+
+       if (currprefs.sound_es1370) {
+               pci_board_add(pcib, &es1370_pci_board, slot++, 0);
+       }
+
+       //pci_board_add(pcib, &solo1_pci_board, slot++, 0);
+
+       //pci_board_add(pcib, &ncr_53c815_pci_board, 1, 0);
 }
 
 // Wildfire
@@ -1450,12 +1546,12 @@ addrbank *dkb_wildfire_pci_init(struct romconfig *rc)
        pcib->endian_swap_io = 0;
        pcib->endian_swap_memory = 0;
        pcib->intena = 0xff; // controlled by bridge config bits, bit unknown.
-       pcib->intreq_mask = 0x2000;
+       pcib->intreq_mask = 0x100;
        pcib->get_index = dkb_wildfire_get_index;
        pcib->baseaddress = 0x80000000;
        pcib->baseaddress_end = 0xffffffff;
        pcib->configured = -1;
-       pci_board_add(pcib, &ncr_53c815_pci_board, 0);
+       pci_board_add(pcib, &ncr_53c815_pci_board, 0, 0);
        map_banks(&pci_config_bank, 0x80000000 >> 16, 0x10000000 >> 16, 0);
        map_banks(&pci_mem_bank, 0x90000000 >> 16, 0x30000000 >> 16, 0);
        map_banks(&pci_io_bank, 0xc0000000 >> 16, 0x30000000 >> 16, 0);
@@ -1488,7 +1584,8 @@ static int prometheus_get_index(uaecptr addr)
                return -1;
        int slot = (addr & 0xf000) >> 13;
        if (slot > 3)
-               slot = -1;
+               return -1;
+       slot |= ((addr >> 8) & 7) << 8;
        return slot;
 }
 
@@ -1502,7 +1599,7 @@ static addrbank *prometheus_pci_init(struct romconfig *rc)
        pcib->endian_swap_io = -1;
        pcib->endian_swap_memory = -1;
        pcib->intena = 0xff;
-       pcib->intreq_mask = 0x0008;
+       pcib->intreq_mask = 0x10;
        pcib->get_index = prometheus_get_index;
        pcib->bank = &pci_bridge_bank;
        pcib->bank_zorro = 3;
@@ -1523,9 +1620,10 @@ static int grex_get_index(uaecptr addr)
        int slot = -1;
        struct pci_bridge *pcib = get_pci_bridge(addr);
 
-       if ((addr & 0xfffc0700) == 0xfffc0000) {
+       if ((addr & 0xfffc1000) == 0xfffc0000) {
                int v = (addr & 0x3f000) >> 13;
                slot = countbit(v);
+               slot |= ((addr >> 8) & 7) << 8;
        }
        return slot;
 }
@@ -1537,7 +1635,7 @@ static addrbank *grex_pci_init(struct romconfig *rc)
        bridges[PCI_BRIDGE_GREX] = pcib;
        pcib->label = _T("G-REX");
        pcib->intena = 0;
-       pcib->intreq_mask = 0x0008;
+       pcib->intreq_mask = 0x10;
        pcib->get_index = grex_get_index;
        pcib->baseaddress = 0x80000000;
        pcib->baseaddress_end = 0xffffffff;
@@ -1570,7 +1668,7 @@ static addrbank *cbvision(struct romconfig *rc)
        bridges[PCI_BRIDGE_XVISION] = pcib;
        pcib->label = _T("CBVision");
        pcib->intena = 0;
-       pcib->intreq_mask = 0x0008;
+       pcib->intreq_mask = 0x10;
        pcib->get_index = xvision_get_index;
        pcib->baseaddress = 0xe0000000;
        pcib->baseaddress_end = 0xffffffff;
@@ -1586,14 +1684,40 @@ static addrbank *cbvision(struct romconfig *rc)
 
 // Mediator
 
+// Mediator 4000MK2
 static const uae_u8 autoconfig_mediator_4000mk2_256m[16] = { 0x84,0xa1,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 static const uae_u8 autoconfig_mediator_4000mk2_512m[16] = { 0x85,0xa1,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 static const uae_u8 autoconfig_mediator_4000mk2_2[16] = { 0x88,0x21,0x20,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 
+// Mediator 1200 TX
 static const uae_u8 autoconfig_mediator_1200tx_1[16] = { 0xca,0x3c,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 static const uae_u8 autoconfig_mediator_1200tx_2_4m[16] = { 0xc7,0xbc,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 static const uae_u8 autoconfig_mediator_1200tx_2_8m[16] = { 0xc0,0xbc,0x00,0x00,0x08,0x9e,0x00,0x00,0x00,0x00,0x00,0x00 };
 
+// Mediator 1200
+static const uae_u8 autoconfig_mediator_1200_1[16] = { 0xca, 0x20, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uae_u8 autoconfig_mediator_1200_2_4m[16] = { 0xcf, 0xa0, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uae_u8 autoconfig_mediator_1200_2_8m[16] = { 0xc8, 0xa0, 0x00, 0x00, 0x08, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+struct mediator_autoconfig
+{
+       const uae_u8 *io;
+       const uae_u8 *mem_small;
+       const uae_u8 *mem_large;
+};
+
+#define MED_1200 0
+#define MED_1200TX 1
+#define MED_4000MK2 2
+
+static struct mediator_autoconfig mediator_ac[] =
+{
+       { autoconfig_mediator_1200_1, autoconfig_mediator_1200_2_4m, autoconfig_mediator_1200_2_8m },
+       { autoconfig_mediator_1200tx_1, autoconfig_mediator_1200tx_2_4m, autoconfig_mediator_1200tx_2_8m },
+       { autoconfig_mediator_4000mk2_2, autoconfig_mediator_4000mk2_256m, autoconfig_mediator_4000mk2_512m }
+};
+
+
 static int mediator_get_index_1200(uaecptr addr)
 {
        struct pci_bridge *pcib = get_pci_bridge(addr);
@@ -1605,7 +1729,8 @@ static int mediator_get_index_1200(uaecptr addr)
        offset -= 0x10000;
        int slot = offset / 0x800;
        if (slot >= 6)
-               slot = -1;
+               return -1;
+       slot |= ((offset >> 8) & 7) << 8;
        return slot;
 }
 
@@ -1620,7 +1745,8 @@ static int mediator_get_index_4000(uaecptr addr)
        offset -= 0x800000;
        int slot = offset / 0x800;
        if (slot >= 6)
-               slot = -1;
+               return -1;
+       slot |= ((offset >> 8) & 7) << 8;
        return slot;
 }
 
@@ -1631,7 +1757,7 @@ static void mediator_pci_init_1200(struct pci_bridge *pcib)
        pcib->endian_swap_io = -1;
        pcib->endian_swap_memory = -1;
        pcib->intena = 0;
-       pcib->intreq_mask = 0x0008;
+       pcib->intreq_mask = 0x10;
        pcib->get_index = mediator_get_index_1200;
        pcib->bank = &pci_bridge_bank;
        pcib->bank_2 = &pci_bridge_bank_2;
@@ -1640,7 +1766,7 @@ static void mediator_pci_init_1200(struct pci_bridge *pcib)
        mediator_set_window_offset(pcib, 0);
 }
 
-static addrbank *mediator_pci_init_1200_1(struct romconfig *rc)
+static addrbank *mediator_pci_init_1200_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 2)) {
@@ -1656,13 +1782,13 @@ static addrbank *mediator_pci_init_1200_1(struct romconfig *rc)
                        return &expamem_null;
        }
        memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
-       for (int i = 0; i < sizeof autoconfig_mediator_1200tx_1; i++) {
-               ew(pcib->acmemory_2, i * 4, autoconfig_mediator_1200tx_1[i]);
+       for (int i = 0; i < 16; i++) {
+               ew(pcib->acmemory_2, i * 4, m_ac->io[i]);
        }
        return &pci_bridge_bank_2;
 }
 
-static addrbank *mediator_pci_init_1200_2(struct romconfig *rc)
+static addrbank *mediator_pci_init_1200_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 2)) {
@@ -1679,7 +1805,7 @@ static addrbank *mediator_pci_init_1200_2(struct romconfig *rc)
                add_pci_devices(pcib);
        }
        memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
-       const uae_u8 *ac = (rc->device_settings & 1) ? autoconfig_mediator_1200tx_2_8m : autoconfig_mediator_1200tx_2_4m;
+       const uae_u8 *ac = (rc->device_settings & 1) ? m_ac->mem_large : m_ac->mem_small;
        for (int i = 0; i < 16; i++) {
                ew(pcib->acmemory, i * 4, ac[i]);
        }
@@ -1693,7 +1819,7 @@ static void mediator_pci_init_4000(struct pci_bridge *pcib)
        pcib->endian_swap_io = -1;
        pcib->endian_swap_memory = -1;
        pcib->intena = 0;
-       pcib->intreq_mask = 0x0008;
+       pcib->intreq_mask = 0x10;
        pcib->get_index = mediator_get_index_4000;
        pcib->bank = &pci_bridge_bank;
        pcib->bank_2 = &pci_bridge_bank_2;
@@ -1702,7 +1828,7 @@ static void mediator_pci_init_4000(struct pci_bridge *pcib)
        mediator_set_window_offset(pcib, 0);
 }
 
-static addrbank *mediator_pci_init_4000_1(struct romconfig *rc)
+static addrbank *mediator_pci_init_4000_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 2)) {
@@ -1718,12 +1844,12 @@ static addrbank *mediator_pci_init_4000_1(struct romconfig *rc)
                        return &expamem_null;
        }
        memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
-       for (int i = 0; i < sizeof autoconfig_mediator_4000mk2_2; i++) {
-               ew(pcib->acmemory_2, i * 4, autoconfig_mediator_4000mk2_2[i]);
+       for (int i = 0; i < 16; i++) {
+               ew(pcib->acmemory_2, i * 4, m_ac->io[i]);
        }
        return &pci_bridge_bank_2;
 }
-static addrbank *mediator_pci_init_4000_2(struct romconfig *rc)
+static addrbank *mediator_pci_init_4000_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 2)) {
@@ -1741,7 +1867,7 @@ static addrbank *mediator_pci_init_4000_2(struct romconfig *rc)
                add_pci_devices(pcib);
        }
        memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
-       const uae_u8 *ac = (rc->device_settings & 1) ? autoconfig_mediator_4000mk2_512m : autoconfig_mediator_4000mk2_256m;
+       const uae_u8 *ac = (rc->device_settings & 1) ? m_ac->mem_large : m_ac->mem_small;
        for (int i = 0; i < 16; i++) {
                ew(pcib->acmemory, i * 4, ac[i]);
        }
@@ -1750,36 +1876,54 @@ static addrbank *mediator_pci_init_4000_2(struct romconfig *rc)
 
 addrbank *mediator_init(struct romconfig *rc)
 {
+       struct mediator_autoconfig *ac;
        switch (rc->subtype)
        {
                case 0:
+               ac = &mediator_ac[MED_1200];
                if (rc->device_settings & 2)
-                       return mediator_pci_init_1200_2(rc);
+                       return mediator_pci_init_1200_2(rc, ac);
                else
-                       return mediator_pci_init_1200_1(rc);
+                       return mediator_pci_init_1200_1(rc, ac);
                case 1:
+               ac = &mediator_ac[MED_1200TX];
+               if (rc->device_settings & 2)
+                       return mediator_pci_init_1200_2(rc, ac);
+               else
+                       return mediator_pci_init_1200_1(rc, ac);
+               case 2:
+               ac = &mediator_ac[MED_4000MK2];
                if (rc->device_settings & 2)
-                       return mediator_pci_init_4000_2(rc);
+                       return mediator_pci_init_4000_2(rc, ac);
                else
-                       return mediator_pci_init_4000_1(rc);
+                       return mediator_pci_init_4000_1(rc, ac);
        }
        return &expamem_null;
 }
 
 addrbank *mediator_init2(struct romconfig *rc)
 {
+       struct mediator_autoconfig *ac;
        switch (rc->subtype)
        {
                case 0:
+               ac = &mediator_ac[MED_1200];
                if (rc->device_settings & 2)
-                       return mediator_pci_init_1200_1(rc);
+                       return mediator_pci_init_1200_1(rc, ac);
                else
-                       return mediator_pci_init_1200_2(rc);
+                       return mediator_pci_init_1200_2(rc, ac);
                case 1:
+               ac = &mediator_ac[MED_1200TX];
+               if (rc->device_settings & 2)
+                       return mediator_pci_init_1200_1(rc, ac);
+               else
+                       return mediator_pci_init_1200_2(rc, ac);
+               case 2:
+               ac = &mediator_ac[MED_4000MK2];
                if (rc->device_settings & 2)
-                       return mediator_pci_init_4000_1(rc);
+                       return mediator_pci_init_4000_1(rc, ac);
                else
-                       return mediator_pci_init_4000_2(rc);
+                       return mediator_pci_init_4000_2(rc, ac);
        }
        return &expamem_null;
 }
index 2e99bcd5ac41e625761951b9a3f9504e46f6fbd8..891d2fac247c3dab060f61bd884596eb65741ba9 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "qemuuaeglue.h"
 #include "queue.h"
+#include "threaddep/thread.h"
 
 struct NetClientState
 {
@@ -376,8 +377,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
             s->isr &= ~ENISR_RESET;
             /* test specific case: zero length transfer */
-            if ((val & (E8390_RREAD | E8390_RWRITE)) &&
-                s->tcnt == 0) {
+            if ((val & (E8390_RREAD | E8390_RWRITE)) && s->tcnt == 0) {
                 s->isr |= ENISR_RDC;
                 ne2000_update_irq(s);
             }
@@ -477,7 +477,6 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         }
     }
-       ne2000_receive_check();
 }
 
 static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
@@ -557,7 +556,6 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
             break;
         }
     }
-       ne2000_receive_check();
 #ifdef DEBUG_NE2000
     write_log("NE2000: read reg=0x%x val=0x%02x\n", offset, ret);
 #endif
@@ -723,6 +721,7 @@ static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
     return 0;
 }
 
+#if 0
 static int ne2000_post_load(void* opaque, int version_id)
 {
     NE2000State* s = (NE2000State*)opaque;
@@ -733,7 +732,6 @@ static int ne2000_post_load(void* opaque, int version_id)
     return 0;
 }
 
-#if 0
 const VMStateDescription vmstate_ne2000 = {
     .name = "ne2000",
     .version_id = 2,
@@ -937,10 +935,11 @@ type_init(ne2000_register_types)
 #define MAX_RECEIVE_BUFFER_INDEX 256
 static int receive_buffer_index;
 static uae_u8 *receive_buffer;
-static int receive_buffer_read, receive_buffer_write;
+static volatile int receive_buffer_read, receive_buffer_write;
 static int receive_buffer_size[MAX_RECEIVE_BUFFER_INDEX];
+static uae_sem_t ne2000_sem;
 
-static void ne2000_receive_check(void)
+static void ne2000_receive_check2(void)
 {
        if (receive_buffer_read != receive_buffer_write) {
                if (ne2000state.isr & ENISR_RX)
@@ -955,6 +954,19 @@ static void ne2000_receive_check(void)
        }
 }
 
+static void ne2000_receive_check(void)
+{
+       if (receive_buffer_read != receive_buffer_write) {
+               uae_sem_wait(&ne2000_sem);
+               if (receive_buffer_read != receive_buffer_write) {
+                       uae_sem_post(&ne2000_sem);
+                       ne2000_receive_check2();
+               } else {
+                       uae_sem_post(&ne2000_sem);
+               }
+       }
+}
+
 static void gotfunc(void *devv, const uae_u8 *databuf, int len)
 {
 #ifdef DEBUG_NE2000
@@ -963,7 +975,10 @@ static void gotfunc(void *devv, const uae_u8 *databuf, int len)
        ne2000_receive_check();
        if (len > MAX_PACKET_SIZE) 
                return;
-       if (((receive_buffer_write + 1) & (MAX_RECEIVE_BUFFER_INDEX - 1)) == receive_buffer_read) {
+       uae_sem_wait(&ne2000_sem);
+       int nextwrite = (receive_buffer_write + 1) & (MAX_RECEIVE_BUFFER_INDEX - 1);
+       if (nextwrite == receive_buffer_read) {
+               uae_sem_post(&ne2000_sem);
                write_log("NE2000: receive buffer full\n");
                return;
        }
@@ -971,9 +986,14 @@ static void gotfunc(void *devv, const uae_u8 *databuf, int len)
        receive_buffer_size[receive_buffer_write] = len;
        receive_buffer_write++;
        receive_buffer_write &= (MAX_RECEIVE_BUFFER_INDEX - 1);
-       ne2000_receive_check();
+       uae_sem_post(&ne2000_sem);
 }      
 
+static void ne2000_hsync_handler(struct pci_board_state *pcibs)
+{
+       ne2000_receive_check();
+}
+
 static void REGPARAM2 ne2000_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
 {
        ne2000_write(ncs.ne2000state, addr, b & 0xff, 1);
@@ -1016,6 +1036,7 @@ static void ne2000_free(struct pci_board_state *pcibs)
        sysdata = NULL;
        xfree(receive_buffer);
        receive_buffer = NULL;
+       uae_sem_destroy(&ne2000_sem);
 }
 
 static bool ne2000_init(struct pci_board_state *pcibs)
@@ -1026,6 +1047,7 @@ static bool ne2000_init(struct pci_board_state *pcibs)
        ncs.ne2000state = &ne2000state;
        memset(&ne2000state, 0, sizeof ne2000state);
 
+       uae_sem_init(&ne2000_sem, 0, 1);
        if (!receive_buffer) {
                receive_buffer = xcalloc(uae_u8, MAX_PACKET_SIZE * MAX_RECEIVE_BUFFER_INDEX);
        }
@@ -1069,13 +1091,13 @@ static bool ne2000_init(struct pci_board_state *pcibs)
 
 static const struct pci_config ne2000_pci_config =
 {
-       0x10ec, 0x8029, 0, 0, 0, 0x020000, 0, 0x10ec, 0x8029, 1, { 0x20 | 1, 0, 0, 0, 0, 0, 0 }
+       0x10ec, 0x8029, 0, 0, 0, 0x020000, 0, 0x10ec, 0x8029, 1, 0, 0, { 0x20 | 1, 0, 0, 0, 0, 0, 0 }
 };
 
 const struct pci_board ne2000_pci_board =
 {
        _T("RTL8029"),
-       &ne2000_pci_config, ne2000_init, ne2000_free, ne2000_reset, pci_irq_callback,
+       &ne2000_pci_config, ne2000_init, ne2000_free, ne2000_reset, ne2000_hsync_handler, pci_irq_callback,
        {
                { ne2000_lget, ne2000_wget, ne2000_bget, ne2000_lput, ne2000_wput, ne2000_bput },
                { NULL },