Previous 15994 Revisions Next

r15467 Friday 15th June, 2012 at 14:34:43 UTC by Miodrag Milanović
pci wip (nw)
[src/emu/machine]pci.c pci.h
[src/mess/drivers]at.c bebox.c

src/emu/machine/pci.c
r15466r15467
7070***************************************************************************/
7171
7272#include "emu.h"
73#include "devconv.h"
7473#include "machine/pci.h"
7574
7675#define LOG_PCI   0
7776
78typedef struct _pci_bus_state pci_bus_state;
79struct _pci_bus_state
80{
81   device_t *   busdevice;
82   const pci_bus_config *   config;
83   device_t *   device[32];
84   pci_bus_state *      siblings[8];
85   UINT8            siblings_busnum[8];
86   int               siblings_count;
87   offs_t               address;
88   INT8               devicenum; // device number we are addressing
89   INT8               busnum; // pci bus number we are addressing
90   pci_bus_state *      busnumaddr; // pci bus we are addressing
91};
77//**************************************************************************
78//  GLOBAL VARIABLES
79//**************************************************************************
9280
81const device_type PCI_BUS = &device_creator<pci_bus_device>;
9382
83//**************************************************************************
84//  LIVE DEVICE
85//**************************************************************************
9486
87//-------------------------------------------------
88//  pci_bus_device - constructor
89//-------------------------------------------------
90pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
91        device_t(mconfig, PCI_BUS, "PCI Bus", tag, owner, clock),
92      m_father(NULL)
93{
94   for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) {
95      m_devtag[i]= NULL;
96      m_read_callback[i] = NULL;
97      m_write_callback[i] = NULL;
98   }
99   m_siblings_count = 0;
100}
101
95102/***************************************************************************
96103    INLINE FUNCTIONS
97104***************************************************************************/
98105
99/*-------------------------------------------------
100    get_safe_token - makes sure that the passed
101    in device is, in fact, a PCI bus
102-------------------------------------------------*/
103
104INLINE pci_bus_state *get_safe_token(device_t *device)
106READ32_MEMBER( pci_bus_device::read )
105107{
106   assert(device != NULL);
107   assert(device->type() == PCI_BUS);
108
109   return (pci_bus_state *)downcast<legacy_device_base *>(device)->token();
110}
111
112
113
114READ32_DEVICE_HANDLER( pci_32le_r )
115{
116   pci_bus_state *pcibus = get_safe_token(device);
117108   UINT32 result = 0xffffffff;
118109   int function, reg;
119110
r15466r15467
122113   switch (offset)
123114   {
124115      case 0:
125         result = pcibus->address;
116         result = m_address;
126117         break;
127118
128119      case 1:
129         if (pcibus->devicenum != -1)
120         if (m_devicenum != -1)
130121         {
131            pci_read_func read = pcibus->busnumaddr->config->device[pcibus->devicenum].read_callback;
122            pci_read_func read = m_busnumaddr->m_read_callback[m_devicenum];
132123            if (read != NULL)
133124            {
134               function = (pcibus->address >> 8) & 0x07;
135               reg = (pcibus->address >> 0) & 0xfc;
136               result = (*read)(pcibus->busnumaddr->busdevice, pcibus->busnumaddr->device[pcibus->devicenum], function, reg, mem_mask);
125               function = (m_address >> 8) & 0x07;
126               reg = (m_address >> 0) & 0xfc;
127               result = (*read)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, mem_mask);
137128            }
138129         }
139130         break;
140131   }
141132
142133   if (LOG_PCI)
143      logerror("pci_32le_r('%s'): offset=%d result=0x%08X\n", device->tag(), offset, result);
134      logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result);
144135
145136   return result;
146137}
147138
148139
149140
150static pci_bus_state *pci_search_bustree(int busnum, int devicenum, pci_bus_state *pcibus)
141pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus)
151142{
152int a;
153pci_bus_state *ret;
143   int a;
144   pci_bus_device *ret;
154145
155   if (pcibus->config->busnum == busnum)
146   if (pcibus->m_busnum == busnum)
156147   {
157148      return pcibus;
158149   }
159   for (a = 0; a < pcibus->siblings_count; a++)
150   for (a = 0; a < pcibus->m_siblings_count; a++)
160151   {
161      ret = pci_search_bustree(busnum, devicenum, pcibus->siblings[a]);
152      ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]);
162153      if (ret != NULL)
163154         return ret;
164155   }
r15466r15467
167158
168159
169160
170WRITE32_DEVICE_HANDLER( pci_32le_w )
161WRITE32_MEMBER( pci_bus_device::write )
171162{
172   pci_bus_state *pcibus = get_safe_token(device);
173
174163   offset %= 2;
175164
176165   if (LOG_PCI)
177      logerror("pci_32le_w('%s'): offset=%d data=0x%08X\n", device->tag(), offset, data);
166      logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data);
178167
179168   switch (offset)
180169   {
181170      case 0:
182         pcibus->address = data;
171         m_address = data;
183172
184173         /* lookup current device */
185         if (pcibus->address & 0x80000000)
174         if (m_address & 0x80000000)
186175         {
187            int busnum = (pcibus->address >> 16) & 0xff;
188            int devicenum = (pcibus->address >> 11) & 0x1f;
189            pcibus->busnumaddr = pci_search_bustree(busnum, devicenum, pcibus);
190            if (pcibus->busnumaddr != NULL)
176            int busnum = (m_address >> 16) & 0xff;
177            int devicenum = (m_address >> 11) & 0x1f;
178            m_busnumaddr = pci_search_bustree(busnum, devicenum, this);
179            if (m_busnumaddr != NULL)
191180            {
192               pcibus->busnum = busnum;
193               pcibus->devicenum = devicenum;
181               m_busnumber = busnum;
182               m_devicenum = devicenum;
194183            }
195184            else
196               pcibus->devicenum = -1;
185               m_devicenum = -1;
197186            if (LOG_PCI)
198187               logerror("  bus:%d device:%d\n", busnum, devicenum);
199188         }
200189         break;
201190
202191      case 1:
203         if (pcibus->devicenum != -1)
192         if (m_devicenum != -1)
204193         {
205            pci_write_func write = pcibus->busnumaddr->config->device[pcibus->devicenum].write_callback;
194            pci_write_func write = m_busnumaddr->m_write_callback[m_devicenum];
206195            if (write != NULL)
207196            {
208               int function = (pcibus->address >> 8) & 0x07;
209               int reg = (pcibus->address >> 0) & 0xfc;
210               (*write)(pcibus->busnumaddr->busdevice, pcibus->busnumaddr->device[pcibus->devicenum], function, reg, data, mem_mask);
197               int function = (m_address >> 8) & 0x07;
198               int reg = (m_address >> 0) & 0xfc;
199               (*write)(m_busnumaddr, m_busnumaddr->m_device[m_devicenum], function, reg, data, mem_mask);
211200            }
212201            if (LOG_PCI)
213               logerror("  function:%d register:%d\n", (pcibus->address >> 8) & 0x07, (pcibus->address >> 0) & 0xfc);
202               logerror("  function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc);
214203         }
215204         break;
216205   }
r15466r15467
218207
219208
220209
221READ64_DEVICE_HANDLER(pci_64be_r) { return read64be_with_32le_device_handler(pci_32le_r, device, offset, mem_mask); }
222WRITE64_DEVICE_HANDLER(pci_64be_w) { write64be_with_32le_device_handler(pci_32le_w, device, offset, data, mem_mask); }
210READ64_MEMBER(pci_bus_device::read_64be)
211{
212   UINT64 result = 0;
213   mem_mask = FLIPENDIAN_INT64(mem_mask);
214   if (ACCESSING_BITS_0_31)
215      result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0;
216   if (ACCESSING_BITS_32_63)
217      result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32;
218   return FLIPENDIAN_INT64(result);
219}
223220
221WRITE64_MEMBER(pci_bus_device::write_64be)
222{
223   data = FLIPENDIAN_INT64(data);
224   mem_mask = FLIPENDIAN_INT64(mem_mask);
225   if (ACCESSING_BITS_0_31)
226      write(space, offset * 2 + 0, data >> 0, mem_mask >> 0);
227   if (ACCESSING_BITS_32_63)
228      write(space, offset * 2 + 1, data >> 32, mem_mask >> 32);
229}
224230
225int pci_add_sibling( running_machine &machine, char *pcitag, char *sibling )
226{
227   device_t *device1 = machine.device(pcitag);
228   device_t *device2 = machine.device(sibling);
229   pci_bus_state *pcibus1 = get_safe_token(device1);
230   pci_bus_state *pcibus2 = get_safe_token(device2);
231   pci_bus_config *config2;
232231
233   if ((device1 == NULL) || (device2 == NULL) || (pcibus1 == NULL) || (pcibus2 == NULL))
234      return 0;
235   if (pcibus1->siblings_count == 8)
236      return 0;
237   config2 = (pci_bus_config *)downcast<const legacy_device_base *>(device2)->inline_config();
238   pcibus1->siblings[pcibus1->siblings_count] = get_safe_token(device2);
239   pcibus1->siblings_busnum[pcibus1->siblings_count] = config2->busnum;
240   pcibus1->siblings_count++;
241   return 1;
232void pci_bus_device::add_sibling(pci_bus_device *sibling, int busnum)
233{
234   m_siblings[m_siblings_count] = sibling;
235   m_siblings_busnum[m_siblings_count] = busnum;
236   m_siblings_count++;
242237}
243238
244239
245/***************************************************************************
246    DEVICE INTERFACE
247***************************************************************************/
240//-------------------------------------------------
241//  device_post_load - handle updating after a
242//  restore
243//-------------------------------------------------
248244
249
250static void pci_bus_postload(pci_bus_state *pcibus)
245void pci_bus_device::device_post_load()
251246{
252   if (pcibus->devicenum != -1)
247   if (m_devicenum != -1)
253248   {
254      pcibus->busnumaddr = pci_search_bustree(pcibus->busnum, pcibus->devicenum, pcibus);
249      m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this);
255250   }
256251}
257252
253//-------------------------------------------------
254//  device_start - device-specific startup
255//-------------------------------------------------
258256
259/*-------------------------------------------------
260    device start callback
261-------------------------------------------------*/
262
263static DEVICE_START( pci_bus )
257void pci_bus_device::device_start()
264258{
265   pci_bus_state *pcibus = get_safe_token(device);
266   int devicenum;
267
268   /* validate some basic stuff */
269   assert(device != NULL);
270   assert(device->static_config() == NULL);
271   assert(downcast<const legacy_device_base *>(device)->inline_config() != NULL);
272
273259   /* store a pointer back to the device */
274   pcibus->config = (const pci_bus_config *)downcast<const legacy_device_base *>(device)->inline_config();
275   pcibus->busdevice = device;
276   pcibus->devicenum = -1;
260   m_devicenum = -1;
277261
278262   /* find all our devices */
279   for (devicenum = 0; devicenum < ARRAY_LENGTH(pcibus->device); devicenum++)
280      if (pcibus->config->device[devicenum].devtag != NULL)
281         pcibus->device[devicenum] = device->machine().device(pcibus->config->device[devicenum].devtag);
263   for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++)
264      if (m_devtag[i] != NULL)
265         m_device[i] = machine().device(m_devtag[i]);
282266
283   if (pcibus->config->father != NULL)
284      pci_add_sibling(device->machine(), (char *)pcibus->config->father, (char *)device->tag());
267   if (m_father != NULL) {
268      pci_bus_device *father = machine().device<pci_bus_device>(m_father);
269      if (father)
270         father->add_sibling(this, m_busnum);
271   }
285272
286273   /* register pci states */
287   device->save_item(NAME(pcibus->address));
288   device->save_item(NAME(pcibus->devicenum));
289   device->save_item(NAME(pcibus->busnum));
290
291   device->machine().save().register_postload(save_prepost_delegate(FUNC(pci_bus_postload), pcibus));
274   save_item(NAME(m_address));
275   save_item(NAME(m_devicenum));
276   save_item(NAME(m_busnum));
292277}
293278
294279
295/*-------------------------------------------------
296    device reset callback
297-------------------------------------------------*/
280//-------------------------------------------------
281//  device_reset - device-specific reset
282//-------------------------------------------------
298283
299static DEVICE_RESET( pci_bus )
284void pci_bus_device::device_reset()
300285{
301   pci_bus_state *pcibus = get_safe_token(device);
302
303286   /* reset the drive state */
304   pcibus->devicenum = -1;
305   pcibus->address = 0;
287   m_devicenum = -1;
288   m_address = 0;
306289}
307
308
309/*-------------------------------------------------
310    device get info callback
311-------------------------------------------------*/
312
313DEVICE_GET_INFO( pci_bus )
314{
315   switch (state)
316   {
317      /* --- the following bits of info are returned as 64-bit signed integers --- */
318      case DEVINFO_INT_TOKEN_BYTES:         info->i = sizeof(pci_bus_state);      break;
319      case DEVINFO_INT_INLINE_CONFIG_BYTES:   info->i = sizeof(pci_bus_config);      break;
320
321      /* --- the following bits of info are returned as pointers to data or functions --- */
322      case DEVINFO_FCT_START:               info->start = DEVICE_START_NAME(pci_bus); break;
323      case DEVINFO_FCT_RESET:               info->reset = DEVICE_RESET_NAME(pci_bus);break;
324
325      /* --- the following bits of info are returned as NULL-terminated strings --- */
326      case DEVINFO_STR_NAME:               strcpy(info->s, "PCI Bus");            break;
327      case DEVINFO_STR_FAMILY:            strcpy(info->s, "Peripherial Bus");      break;
328      case DEVINFO_STR_VERSION:            strcpy(info->s, "1.0");               break;
329      case DEVINFO_STR_SOURCE_FILE:         strcpy(info->s, __FILE__);            break;
330      case DEVINFO_STR_CREDITS:            strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
331   }
332}
333
334
335DEFINE_LEGACY_DEVICE(PCI_BUS, pci_bus);
src/emu/machine/pci.h
r15466r15467
99#ifndef PCI_H
1010#define PCI_H
1111
12#include "devlegcy.h"
12//**************************************************************************
13//  TYPE DEFINITIONS
14//**************************************************************************
1315
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
1916typedef UINT32 (*pci_read_func)(device_t *pcibus, device_t *device, int function, int reg, UINT32 mem_mask);
2017typedef void (*pci_write_func)(device_t *pcibus, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask);
2118
22typedef struct _pci_device_entry pci_device_entry;
23struct _pci_device_entry
19// ======================> ttl74145_device
20
21class pci_bus_device :  public device_t
2422{
25   const char *      devtag;
26   pci_read_func      read_callback;
27   pci_write_func      write_callback;
28};
23public:
24    // construction/destruction
25    pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2926
30typedef struct _pci_bus_config pci_bus_config;
31struct _pci_bus_config
32{
33   UINT8            busnum;
34   pci_device_entry   device[32];
35   const char *      father;
27   DECLARE_READ32_MEMBER( read );
28   DECLARE_WRITE32_MEMBER( write );
29
30   DECLARE_READ64_MEMBER( read_64be );
31   DECLARE_WRITE64_MEMBER( write_64be );
32   
33   void set_busnum(int busnum) { m_busnum = busnum; }
34   void set_device(int num, const char *tag, pci_read_func read_func, pci_write_func write_func) {
35      m_devtag[num] = tag; m_read_callback[num] = read_func; m_write_callback[num] = write_func; }
36     
37   pci_bus_device *pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus);
38   void add_sibling(pci_bus_device *sibling, int busnum);
39   
40protected:
41    // device-level overrides
42    virtual void device_start();
43   virtual void device_reset();
44    virtual void device_post_load();
45
46private:
47   UINT8            m_busnum;
48   const char *      m_devtag[32];
49   pci_read_func      m_read_callback[32];
50   pci_write_func      m_write_callback[32];
51   const char *      m_father;
52   device_t *         m_device[32];
53   pci_bus_device *   m_siblings[8];
54   UINT8            m_siblings_busnum[8];
55   int               m_siblings_count;
56   
57   offs_t            m_address;
58   INT8            m_devicenum; // device number we are addressing
59   INT8            m_busnumber; // pci bus number we are addressing
60   pci_bus_device *   m_busnumaddr; // pci bus we are addressing
3661};
3762
63// device type definition
64extern const device_type PCI_BUS;
3865
3966
4067/***************************************************************************
r15466r15467
4370
4471#define MCFG_PCI_BUS_ADD(_tag, _busnum) \
4572   MCFG_DEVICE_ADD(_tag, PCI_BUS, 0) \
46   MCFG_DEVICE_CONFIG_DATA32(pci_bus_config, busnum, _busnum)
73   downcast<pci_bus_device *>(device)->set_busnum(_busnum); \
4774
4875#define MCFG_PCI_BUS_DEVICE(_devnum, _devtag, _configread, _configwrite) \
49   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(pci_bus_config, device, _devnum, pci_device_entry, devtag, _devtag) \
50   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(pci_bus_config, device, _devnum, pci_device_entry, read_callback, _configread) \
51   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(pci_bus_config, device, _devnum, pci_device_entry, write_callback, _configwrite)
76   downcast<pci_bus_device *>(device)->set_device(_devnum, _devtag,_configread,_configwrite); \
5277
5378#define MCFG_PCI_BUS_SIBLING(_father_tag) \
54   MCFG_DEVICE_CONFIG_DATAPTR(pci_bus_config, father, _father_tag)
79   downcast<pci_bus_device *>(device)->set_father(_father_tag); \
5580
5681
57/***************************************************************************
58    FUNCTION PROTOTYPES
59***************************************************************************/
60
61READ32_DEVICE_HANDLER( pci_32le_r );
62WRITE32_DEVICE_HANDLER( pci_32le_w );
63
64READ64_DEVICE_HANDLER( pci_64be_r );
65WRITE64_DEVICE_HANDLER( pci_64be_w );
66
67int pci_add_sibling( running_machine &machine, char *pcitag, char *sibling );
68
69/* ----- device interface ----- */
70
71DECLARE_LEGACY_DEVICE(PCI_BUS, pci_bus);
72
7382#endif /* PCI_H */
src/mess/drivers/at.c
r15466r15467
217217   AM_RANGE(0x00a0, 0x00bf) AM_DEVREADWRITE8_LEGACY("pic8259_slave", pic8259_r, pic8259_w, 0xffffffff)
218218   AM_RANGE(0x00c0, 0x00df) AM_READWRITE8(at_dma8237_2_r, at_dma8237_2_w, 0xffffffff)
219219   AM_RANGE(0x00e0, 0x00ef) AM_NOP // used for timing?
220   AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE_LEGACY("pcibus", pci_32le_r, pci_32le_w)
220   AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_device, read, write)     
221221ADDRESS_MAP_END
222222
223223static ADDRESS_MAP_START( megapc_io, AS_IO, 32, at_state )
src/mess/drivers/bebox.c
r15466r15467
6262   AM_RANGE(0x800003F0, 0x800003F7) AM_READWRITE_LEGACY(bebox_800003F0_r, bebox_800003F0_w )
6363   AM_RANGE(0x800003F8, 0x800003FF) AM_DEVREADWRITE8( "ns16550_0",ns16550_device,  ins8250_r, ins8250_w, U64(0xffffffffffffffff) )
6464   AM_RANGE(0x80000480, 0x8000048F) AM_READWRITE8_LEGACY(bebox_80000480_r, bebox_80000480_w, U64(0xffffffffffffffff) )
65   AM_RANGE(0x80000CF8, 0x80000CFF) AM_DEVREADWRITE_LEGACY("pcibus", pci_64be_r, pci_64be_w )
65   AM_RANGE(0x80000CF8, 0x80000CFF) AM_DEVREADWRITE("pcibus", pci_bus_device, read_64be, write_64be )
6666   AM_RANGE(0x800042E8, 0x800042EF) AM_DEVWRITE8_LEGACY("cirrus", cirrus_42E8_w, U64(0xffffffffffffffff) )
6767
6868   AM_RANGE(0xBFFFFFF0, 0xBFFFFFFF) AM_READ_LEGACY(bebox_interrupt_ack_r )
r15466r15467
7676
7777static READ64_HANDLER(bb_slave_64be_r)
7878{
79   device_t *device = space->machine().device("pcibus");
79   pci_bus_device *device = space->machine().device<pci_bus_device>("pcibus");
8080
8181   // 2e94 is the real address, 2e84 is where the PC appears to be under full DRC
8282   if ((cpu_get_pc(&space->device()) == 0xfff02e94) || (cpu_get_pc(&space->device()) == 0xfff02e84))
r15466r15467
8484      return 0x108000ff;   // indicate slave CPU
8585   }
8686
87   return pci_64be_r(device, offset, mem_mask);
87   return device->read_64be(*space, offset, mem_mask);
8888}
8989
9090static ADDRESS_MAP_START( bebox_slave_mem, AS_PROGRAM, 64, bebox_state )
9191   AM_RANGE(0x80000cf8, 0x80000cff) AM_READ_LEGACY(bb_slave_64be_r)
92   AM_RANGE(0x80000cf8, 0x80000cff) AM_DEVWRITE_LEGACY("pcibus", pci_64be_w )
92   AM_RANGE(0x80000cf8, 0x80000cff) AM_DEVWRITE("pcibus", pci_bus_device, write_64be )
9393   AM_IMPORT_FROM(bebox_mem)
9494ADDRESS_MAP_END
9595

Previous 15994 Revisions Next


© 1998-2018 The MESS Team