summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/gt64xxx.h
blob: 6433dcbabde24e0e4fd956a5778c860b66bb7920 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
// license:BSD-3-Clause
// copyright-holders: Aaron Giles, Ted Green
// Galileo GT-64xxx System Controller
// Skeleton code based off seattle machine driver.
// TODO:
// Need PCI to be able to have a target delay (pci bus stall) a dma transfer
// Configurable byte swapping on cpu and pci busses.

#ifndef GT64XXX_H
#define GT64XXX_H

#include "pci.h"
#include "cpu/mips/mips3.h"

// Supports R4600/4650/4700/R5000 CPUs
#define MCFG_GT64010_ADD(_tag,  _cpu_tag, _clock, _irq_num) \
	MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x014611ab, 0x03, 0x00000000) \
	downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
	downcast<gt64xxx_device *>(device)->set_clock(_clock); \
	downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);

// Supports the following 32-bit bus CPUs:
// IDT RC4640 and RC4650 (in 32-bit mode)
// QED RM523X
// NEC/Toshiba VR4300
#define MCFG_GT64111_ADD(_tag,  _cpu_tag, _clock, _irq_num) \
	MCFG_PCI_DEVICE_ADD(_tag, GT64XXX, 0x414611ab, 0x10, 0x058000, 0x00000000) \
	downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
	downcast<gt64xxx_device *>(device)->set_clock(_clock); \
	downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);

#define MCFG_GT64XXX_SET_BE_CPU(_be) \
	downcast<gt64xxx_device *>(device)->set_be(_be);

#define MCFG_GT64XXX_IRQ_ADD(_irq_num) \
	downcast<gt64xxx_device *>(device)->set_irq_info(_irq_num);

#define MCFG_GT64XXX_SET_CS(_cs_num, _map) \
	downcast<gt64xxx_device *>(device)->set_cs_map(_cs_num, ADDRESS_MAP_NAME(_map), #_map, owner);

/*************************************
 *
 *  Galileo constants
 *
 *************************************/

#define TIMER_PERIOD            attotime::from_hz(m_clock)
#define PCI_BUS_CLOCK        33000000
// Number of dma words to transfer at a time, real hardware configurable between 8-32
#define DMA_BURST_SIZE       32
#define DMA_TIMER_PERIOD     attotime::from_hz(PCI_BUS_CLOCK / 48)

/* Galileo registers - 0x000-0x3ff */
#define GREG_CPU_CONFIG     (0x000/4)
#define GREG_RAS_1_0_LO     (0x008/4)
#define GREG_RAS_1_0_HI     (0x010/4)
#define GREG_RAS_3_2_LO     (0x018/4)
#define GREG_RAS_3_2_HI     (0x020/4)
#define GREG_CS_2_0_LO      (0x028/4)
#define GREG_CS_2_0_HI      (0x030/4)
#define GREG_CS_3_BOOT_LO   (0x038/4)
#define GREG_CS_3_BOOT_HI   (0x040/4)
#define GREG_PCI_IO_LO      (0x048/4)
#define GREG_PCI_IO_HI      (0x050/4)
#define GREG_PCI_MEM0_LO    (0x058/4)
#define GREG_PCI_MEM0_HI    (0x060/4)
#define GREG_INTERNAL_SPACE (0x068/4)
#define GREG_BUSERR_LO      (0x070/4)
#define GREG_BUSERR_HI      (0x078/4)
// GT-64111 only
#define GREG_PCI_MEM1_LO    (0x080/4)
#define GREG_PCI_MEM1_HI    (0x088/4)

/* Galileo registers - 0x400-0x7ff */
#define GREG_RAS0_LO        (0x400/4)
#define GREG_RAS0_HI        (0x404/4)
#define GREG_RAS1_LO        (0x408/4)
#define GREG_RAS1_HI        (0x40c/4)
#define GREG_RAS2_LO        (0x410/4)
#define GREG_RAS2_HI        (0x414/4)
#define GREG_RAS3_LO        (0x418/4)
#define GREG_RAS3_HI        (0x41c/4)
#define GREG_CS0_LO         (0x420/4)
#define GREG_CS0_HI         (0x424/4)
#define GREG_CS1_LO         (0x428/4)
#define GREG_CS1_HI         (0x42c/4)
#define GREG_CS2_LO         (0x430/4)
#define GREG_CS2_HI         (0x434/4)
#define GREG_CS3_LO         (0x438/4)
#define GREG_CS3_HI         (0x43c/4)
#define GREG_CSBOOT_LO      (0x440/4)
#define GREG_CSBOOT_HI      (0x444/4)
#define GREG_DRAM_CONFIG    (0x448/4)
#define GREG_DRAM_BANK0     (0x44c/4)
#define GREG_DRAM_BANK1     (0x450/4)
#define GREG_DRAM_BANK2     (0x454/4)
#define GREG_DRAM_BANK3     (0x458/4)
#define GREG_DEVICE_BANK0   (0x45c/4)
#define GREG_DEVICE_BANK1   (0x460/4)
#define GREG_DEVICE_BANK2   (0x464/4)
#define GREG_DEVICE_BANK3   (0x468/4)
#define GREG_DEVICE_BOOT    (0x46c/4)
#define GREG_ADDRESS_ERROR  (0x470/4)

/* Galileo registers - 0x800-0xbff */
#define GREG_DMA0_COUNT     (0x800/4)
#define GREG_DMA1_COUNT     (0x804/4)
#define GREG_DMA2_COUNT     (0x808/4)
#define GREG_DMA3_COUNT     (0x80c/4)
#define GREG_DMA0_SOURCE    (0x810/4)
#define GREG_DMA1_SOURCE    (0x814/4)
#define GREG_DMA2_SOURCE    (0x818/4)
#define GREG_DMA3_SOURCE    (0x81c/4)
#define GREG_DMA0_DEST      (0x820/4)
#define GREG_DMA1_DEST      (0x824/4)
#define GREG_DMA2_DEST      (0x828/4)
#define GREG_DMA3_DEST      (0x82c/4)
#define GREG_DMA0_NEXT      (0x830/4)
#define GREG_DMA1_NEXT      (0x834/4)
#define GREG_DMA2_NEXT      (0x838/4)
#define GREG_DMA3_NEXT      (0x83c/4)
#define GREG_DMA0_CONTROL   (0x840/4)
#define GREG_DMA1_CONTROL   (0x844/4)
#define GREG_DMA2_CONTROL   (0x848/4)
#define GREG_DMA3_CONTROL   (0x84c/4)
#define GREG_TIMER0_COUNT   (0x850/4)
#define GREG_TIMER1_COUNT   (0x854/4)
#define GREG_TIMER2_COUNT   (0x858/4)
#define GREG_TIMER3_COUNT   (0x85c/4)
#define GREG_DMA_ARBITER    (0x860/4)
#define GREG_TIMER_CONTROL  (0x864/4)

/* Galileo registers - 0xc00-0xfff */
#define GREG_PCI_COMMAND    (0xc00/4)
#define GREG_PCI_TIMEOUT    (0xc04/4)
#define GREG_PCI_RAS_1_0    (0xc08/4)
#define GREG_PCI_RAS_3_2    (0xc0c/4)
#define GREG_PCI_CS_2_0     (0xc10/4)
#define GREG_PCI_CS_3_BOOT  (0xc14/4)
#define GREG_INT_STATE      (0xc18/4)
#define GREG_INT_MASK       (0xc1c/4)
#define GREG_PCI_INT_MASK   (0xc24/4)
#define GREG_CONFIG_ADDRESS (0xcf8/4)
#define GREG_CONFIG_DATA    (0xcfc/4)

/* Galileo interrupts */
#define GINT_SUMMARY_SHIFT  (0)
#define GINT_MEMOUT_SHIFT   (1)
#define GINT_DMAOUT_SHIFT   (2)
#define GINT_CPUOUT_SHIFT   (3)
#define GINT_DMA0COMP_SHIFT (4)
#define GINT_DMA1COMP_SHIFT (5)
#define GINT_DMA2COMP_SHIFT (6)
#define GINT_DMA3COMP_SHIFT (7)
#define GINT_T0EXP_SHIFT    (8)
#define GINT_T1EXP_SHIFT    (9)
#define GINT_T2EXP_SHIFT    (10)
#define GINT_T3EXP_SHIFT    (11)
#define GINT_MASRDERR_SHIFT (12)
#define GINT_SLVWRERR_SHIFT (13)
#define GINT_MASWRERR_SHIFT (14)
#define GINT_SLVRDERR_SHIFT (15)
#define GINT_ADDRERR_SHIFT  (16)
#define GINT_MEMERR_SHIFT   (17)
#define GINT_MASABORT_SHIFT (18)
#define GINT_TARABORT_SHIFT (19)
#define GINT_RETRYCTR_SHIFT (20)


/*************************************
 *  Structures
 *************************************/
struct galileo_timer
{
	emu_timer *     timer;
	UINT32          count;
	UINT8           active;
};

struct galileo_addr_map
{
	UINT32 low_addr;
	UINT32 high_addr;
	address_space* space;
	galileo_addr_map() : low_addr(0xffffffff), high_addr(0x0) {}
};

struct galileo_device_map
{
	bool enable;
	const char *name;
	device_t *device;
	address_map_constructor map;
	galileo_device_map() : enable(false), device(nullptr) {}
};

class gt64xxx_device : public pci_host_device {
public:
	gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	virtual void reset_all_mappings() override;
	virtual void map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space,
							UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) override;

	void set_cpu_tag(const char *tag) { cpu_tag = tag;}
	void set_clock(const UINT32 clock) {m_clock = clock;}
	void set_be(const int be) {m_be = be;}
	void set_autoconfig(const int autoconfig) {m_autoconfig = autoconfig;}
	void set_irq_num(const int irq_num) {m_irq_num = irq_num;}
	virtual DECLARE_ADDRESS_MAP(config_map, 32) override;

	DECLARE_WRITE_LINE_MEMBER(pci_stall);

	// pci bus
	DECLARE_READ32_MEMBER(  pci_config_r);
	DECLARE_WRITE32_MEMBER( pci_config_w);

	// cpu bus
	DECLARE_READ32_MEMBER (cpu_if_r);
	DECLARE_WRITE32_MEMBER(cpu_if_w);

	DECLARE_READ32_MEMBER (master_mem0_r);
	DECLARE_WRITE32_MEMBER(master_mem0_w);

	DECLARE_READ32_MEMBER (master_mem1_r);
	DECLARE_WRITE32_MEMBER(master_mem1_w);

	DECLARE_READ32_MEMBER (master_io_r);
	DECLARE_WRITE32_MEMBER(master_io_w);

	// devices
	DECLARE_READ32_MEMBER (ras_0_r);
	DECLARE_WRITE32_MEMBER(ras_0_w);
	DECLARE_READ32_MEMBER(ras_1_r);
	DECLARE_WRITE32_MEMBER(ras_1_w);
	DECLARE_READ32_MEMBER(ras_2_r);
	DECLARE_WRITE32_MEMBER(ras_2_w);
	DECLARE_READ32_MEMBER(ras_3_r);
	DECLARE_WRITE32_MEMBER(ras_3_w);
	DECLARE_READ32_MEMBER (cs_0_r);
	DECLARE_WRITE32_MEMBER(cs_0_w);

	// Enums
	enum proc_addr_bank {ADDR_RAS1_0, ADDR_RAS3_2, ADDR_CS2_0, ADDR_CS3_BCS, ADDR_PCI_IO, ADDR_PCI_MEM0, ADDR_PCI_MEM1, ADDR_NUM};

	void set_cs_map(int id, address_map_constructor map, const char *name, device_t *device);

protected:
	address_space *m_cpu_space;
	virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
	virtual void device_start() override;
	virtual void device_reset() override;


private:
	mips3_device *m_cpu;
	const char *cpu_tag;
	UINT32 m_clock;
	int m_be, m_autoconfig;
	int m_irq_num;

	int m_pci_stall_state;
	int m_retry_count;
	int m_pci_cpu_stalled;
	UINT32 m_cpu_stalled_offset;
	UINT32 m_cpu_stalled_data;
	UINT32 m_cpu_stalled_mem_mask;

	address_space_config m_mem_config, m_io_config;

	required_memory_region m_romRegion;
	optional_memory_region m_updateRegion;

	DECLARE_ADDRESS_MAP(cpu_map, 32);

	void map_cpu_space();

	UINT32 m_prev_addr;
	/* raw register data */
	UINT32          m_reg[0xd00/4];

	/* timer info */
	galileo_timer   m_timer[4];
	TIMER_CALLBACK_MEMBER(timer_callback);

	/* DMA info */
	INT8            m_dma_active;

	// Ram
	std::vector<UINT32> m_ram[4];

	// Chip Select
	std::vector<galileo_device_map> m_cs_map;

	template<int id> void map_trampoline(::address_map &map, device_t &device) {
		m_cs_map[id].map(map, *m_cs_map[id].device);
	}
	template <typename T> void install_cs_map(offs_t addrstart, offs_t addrend, void (T::*map)(::address_map &map, device_t &device), const char *name) {
		//address_map_delegate delegate(map, name, static_cast<T *>(this));
		address_map_delegate delegate(map, name, static_cast<T *>(this));
		m_cpu_space->install_device_delegate(addrstart, addrend, *this, delegate);
	}

	void update_irqs();

	int m_last_dma;
	emu_timer* m_dma_timer;
	std::vector<galileo_addr_map> dma_addr_map;
	int dma_fetch_next(address_space &space, int which);
	TIMER_CALLBACK_MEMBER(perform_dma);
	address_space* dma_decode_address(UINT32 &addr);

};

extern const device_type GT64XXX;

#endif