1 // license:BSD-3-Clause
2 // copyright-holders:Samuele Zannoli
3 #ifndef MAME_INCLUDES_XBOX_PCI_H
4 #define MAME_INCLUDES_XBOX_PCI_H
5 
6 #pragma once
7 
8 #include "machine/pit8253.h"
9 #include "xbox_nv2a.h"
10 #include "xbox_usb.h"
11 
12 /*
13  * Host
14  */
15 
16 class nv2a_host_device : public pci_host_device {
17 public:
18 	template <typename T>
nv2a_host_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,T && cpu_tag)19 	nv2a_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
20 		: nv2a_host_device(mconfig, tag, owner, clock)
21 	{
22 		set_ids_host(0x10de02a5, 0, 0);
23 		set_cpu_tag(std::forward<T>(cpu_tag));
24 	}
25 	nv2a_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
26 	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
27 			uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
set_cpu_tag(T && cpu_tag)28 	template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
29 
30 protected:
31 	virtual void device_start() override;
32 	virtual void device_reset() override;
33 
34 private:
35 	required_device<device_memory_interface> cpu;
36 };
37 
DECLARE_DEVICE_TYPE(NV2A_HOST,nv2a_host_device)38 DECLARE_DEVICE_TYPE(NV2A_HOST, nv2a_host_device)
39 
40 /*
41  * Ram
42  */
43 
44 class nv2a_ram_device : public pci_device {
45 public:
46 	nv2a_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int memory_size)
47 		: nv2a_ram_device(mconfig, tag, owner, clock)
48 	{
49 		ram_size = memory_size;
50 	}
51 	nv2a_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
52 
53 	virtual void config_map(address_map &map) override;
54 
55 	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
56 		uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
57 
58 protected:
59 	virtual void device_start() override;
60 
61 	uint32_t config_register_r();
62 	void config_register_w(uint32_t data);
63 
64 private:
65 	int ram_size;
66 	std::vector<uint32_t> ram;
67 };
68 
DECLARE_DEVICE_TYPE(NV2A_RAM,nv2a_ram_device)69 DECLARE_DEVICE_TYPE(NV2A_RAM, nv2a_ram_device)
70 
71 /*
72  * LPC Bus
73  */
74 
75 class lpcbus_host_interface {
76 public:
77 	virtual void set_virtual_line(int line, int state) = 0;
78 	virtual void remap() = 0;
79 };
80 
81 class lpcbus_device_interface {
82 public:
83 	virtual void map_extra(address_space *memory_space, address_space *io_space) = 0;
84 	virtual void set_host(int index, lpcbus_host_interface *host) = 0;
85 };
86 
87 class mcpx_isalpc_device : public pci_device, public lpcbus_host_interface {
88 public:
89 	mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
90 	mcpx_isalpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
91 
smi()92 	auto smi() { return m_smi_callback.bind(); }
interrupt_output()93 	auto interrupt_output() { return m_interrupt_output.bind(); }
boot_state_hook()94 	auto boot_state_hook() { return m_boot_state_hook.bind(); }
95 
96 	uint32_t acknowledge();
97 	void debug_generate_irq(int irq, int state);
98 
99 	virtual void set_virtual_line(int line, int state) override;
100 	virtual void remap() override;
101 
102 	uint32_t acpi_r(offs_t offset, uint32_t mem_mask = ~0);
103 	void acpi_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
104 	void boot_state_w(uint8_t data);
105 
106 	DECLARE_WRITE_LINE_MEMBER(irq1);
107 	DECLARE_WRITE_LINE_MEMBER(irq3);
108 	DECLARE_WRITE_LINE_MEMBER(irq11);
109 	DECLARE_WRITE_LINE_MEMBER(irq10);
110 	DECLARE_WRITE_LINE_MEMBER(irq14);
111 	DECLARE_WRITE_LINE_MEMBER(irq15);
112 
113 protected:
114 	virtual void device_start() override;
115 	virtual void device_reset() override;
116 	virtual void device_add_mconfig(machine_config &config) override;
117 	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
118 		uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
119 
120 	DECLARE_WRITE_LINE_MEMBER(interrupt_ouptut_changed);
121 	uint8_t get_slave_ack(offs_t offset);
122 	DECLARE_WRITE_LINE_MEMBER(pit8254_out0_changed);
123 	DECLARE_WRITE_LINE_MEMBER(pit8254_out1_changed);
124 	DECLARE_WRITE_LINE_MEMBER(pit8254_out2_changed);
125 
126 private:
127 	void internal_io_map(address_map &map);
128 	void lpc_io(address_map &map);
129 	void update_smi_line();
130 	void speaker_set_spkrdata(uint8_t data);
131 
132 	uint8_t portb_r();
133 	void portb_w(uint8_t data);
134 
135 	devcb_write_line m_smi_callback;
136 	devcb_write_line m_interrupt_output;
137 	devcb_write8 m_boot_state_hook;
138 	required_device<pic8259_device> pic8259_1;
139 	required_device<pic8259_device> pic8259_2;
140 	required_device<pit8254_device> pit8254;
141 
142 	uint16_t m_pm1_status;
143 	uint16_t m_pm1_enable;
144 	uint16_t m_pm1_control;
145 	uint16_t m_pm1_timer;
146 	uint16_t m_gpe0_status;
147 	uint16_t m_gpe0_enable;
148 	uint16_t m_global_smi_control;
149 	uint8_t m_smi_command_port;
150 	uint8_t m_gpio_mode[26];
151 	lpcbus_device_interface *lpcdevices[16];
152 	uint8_t m_speaker;
153 	bool m_refresh;
154 	uint8_t m_pit_out2;
155 	uint8_t m_spkrdata;
156 	uint8_t m_channel_check;
157 };
158 
DECLARE_DEVICE_TYPE(MCPX_ISALPC,mcpx_isalpc_device)159 DECLARE_DEVICE_TYPE(MCPX_ISALPC, mcpx_isalpc_device)
160 
161 /*
162  * SMBus
163  */
164 
165 class smbus_interface {
166 public:
167 	virtual int execute_command(int command, int rw, int data) = 0;
168 };
169 
170 class mcpx_smbus_device : public pci_device {
171 public:
172 	mcpx_smbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
173 	mcpx_smbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
174 
interrupt_handler()175 	auto interrupt_handler() { return m_interrupt_handler.bind(); }
176 
177 	uint32_t smbus0_r(offs_t offset, uint32_t mem_mask = ~0);
178 	void smbus0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
179 	uint32_t smbus1_r(offs_t offset, uint32_t mem_mask = ~0);
180 	void smbus1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
181 
182 protected:
183 	virtual void device_start() override;
184 	virtual void device_reset() override;
185 
186 	virtual void config_map(address_map &map) override;
187 
188 private:
189 	devcb_write_line m_interrupt_handler;
190 	struct smbus_state {
191 		int status;
192 		int control;
193 		int address;
194 		int data;
195 		int command;
196 		int rw;
197 		smbus_interface *devices[128];
198 		uint32_t words[256 / 4];
199 	} smbusst[2];
200 	void smbus_io0(address_map &map);
201 	void smbus_io1(address_map &map);
202 	void smbus_io2(address_map &map);
203 	uint32_t smbus_read(int bus, offs_t offset, uint32_t mem_mask);
204 	void smbus_write(int bus, offs_t offset, uint32_t data, uint32_t mem_mask);
minimum_grant_r()205 	uint8_t minimum_grant_r() { return 3; }
maximum_latency_r()206 	uint8_t maximum_latency_r() { return 1; }
207 };
208 
DECLARE_DEVICE_TYPE(MCPX_SMBUS,mcpx_smbus_device)209 DECLARE_DEVICE_TYPE(MCPX_SMBUS, mcpx_smbus_device)
210 
211 /*
212  * OHCI USB Controller
213  */
214 class usb_function_device;
215 class mcpx_ohci_device : public pci_device {
216 public:
217 	mcpx_ohci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
218 	mcpx_ohci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
219 	void set_hack_callback(std::function<void(void)> hack) { hack_callback = hack; }
220 	void plug_usb_device(int port, device_usb_ohci_function_interface *function);
221 
222 	auto interrupt_handler() { return m_interrupt_handler.bind(); }
223 
224 	uint32_t ohci_r(offs_t offset);
225 	void ohci_w(offs_t offset, uint32_t data);
226 
227 protected:
228 	virtual void device_start() override;
229 	virtual void device_reset() override;
230 	virtual void device_config_complete() override;
231 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
232 
233 	virtual void config_map(address_map &map) override;
234 
235 private:
236 	ohci_usb_controller *ohci_usb;
237 	devcb_write_line m_interrupt_handler;
238 	emu_timer *timer;
239 	required_device<cpu_device> maincpu;
240 	std::function<void(void)> hack_callback;
241 	void ohci_mmio(address_map &map);
242 	struct dev_t {
243 		device_usb_ohci_function_interface *dev;
244 		int port;
245 	} connecteds[4];
246 	int connecteds_count;
247 	uint8_t minimum_grant_r() { return 3; }
248 	uint8_t maximum_latency_r() { return 1; }
249 };
250 
DECLARE_DEVICE_TYPE(MCPX_OHCI,mcpx_ohci_device)251 DECLARE_DEVICE_TYPE(MCPX_OHCI, mcpx_ohci_device)
252 
253 /*
254  * Ethernet
255  */
256 
257 class mcpx_eth_device : public pci_device {
258 public:
259 	mcpx_eth_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
260 
261 	uint32_t eth_r();
262 	void eth_w(uint32_t data);
263 	uint32_t eth_io_r();
264 	void eth_io_w(uint32_t data);
265 
266 protected:
267 	virtual void device_start() override;
268 	virtual void device_reset() override;
269 
270 private:
271 	void eth_mmio(address_map &map);
272 	void eth_io(address_map &map);
273 };
274 
DECLARE_DEVICE_TYPE(MCPX_ETH,mcpx_eth_device)275 DECLARE_DEVICE_TYPE(MCPX_ETH, mcpx_eth_device)
276 
277 /*
278  * Audio Processing Unit
279  */
280 
281 class mcpx_apu_device : public pci_device {
282 public:
283 	template <typename T>
284 	mcpx_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id, T &&cpu_tag)
285 		: mcpx_apu_device(mconfig, tag, owner, clock)
286 	{
287 		set_ids(0x10de01b0, 0xc2, 0x040100, subsystem_id);
288 		set_cpu_tag(std::forward<T>(cpu_tag));
289 	}
290 	mcpx_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
291 	template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
292 
293 	uint32_t apu_r(offs_t offset, uint32_t mem_mask = ~0);
294 	void apu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
295 
296 protected:
297 	virtual void device_start() override;
298 	virtual void device_reset() override;
299 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
300 
301 	virtual void config_map(address_map &map) override;
302 
303 private:
304 	required_device<device_memory_interface> cpu;
305 	// APU contains 3 dsps: voice processor (VP) global processor (GP) encode processor (EP)
306 	struct apu_state {
307 		uint32_t memory[0x60000 / 4];
308 		uint32_t gpdsp_sgaddress; // global processor scatter-gather
309 		uint32_t gpdsp_sgblocks;
310 		uint32_t gpdsp_address;
311 		uint32_t epdsp_sgaddress; // encoder processor scatter-gather
312 		uint32_t epdsp_sgblocks;
313 		uint32_t epdsp_sgaddress2;
314 		uint32_t epdsp_sgblocks2;
315 		int voice_number;
316 		uint32_t voices_heap_blockaddr[1024];
317 		uint64_t voices_active[4]; //one bit for each voice: 1 playing 0 not
318 		uint32_t voicedata_address;
319 		int voices_frequency[256]; // sample rate
320 		int voices_position[256]; // position in samples * 1000
321 		int voices_position_start[256]; // position in samples * 1000
322 		int voices_position_end[256]; // position in samples * 1000
323 		int voices_position_increment[256]; // position increment every 1ms * 1000
324 		emu_timer *timer;
325 		address_space *space;
326 	} apust;
327 	void apu_mmio(address_map &map);
328 	uint8_t minimum_grant_r() { return 1; }
329 	uint8_t maximum_latency_r() { return 0xc; }
330 };
331 
DECLARE_DEVICE_TYPE(MCPX_APU,mcpx_apu_device)332 DECLARE_DEVICE_TYPE(MCPX_APU, mcpx_apu_device)
333 
334 /*
335  * AC97 Audio Controller
336  */
337 
338 class mcpx_ac97_audio_device : public pci_device {
339 public:
340 	mcpx_ac97_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
341 	mcpx_ac97_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
342 
343 	uint32_t ac97_audio_r(offs_t offset, uint32_t mem_mask = ~0);
344 	void ac97_audio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
345 	uint32_t ac97_audio_io0_r();
346 	void ac97_audio_io0_w(uint32_t data);
347 	uint32_t ac97_audio_io1_r();
348 	void ac97_audio_io1_w(uint32_t data);
349 
350 protected:
351 	virtual void device_start() override;
352 	virtual void device_reset() override;
353 
354 	virtual void config_map(address_map &map) override;
355 
356 private:
357 	struct ac97_state {
358 		uint32_t mixer_regs[0x84 / 4];
359 		uint32_t controller_regs[0x40 / 4];
360 	} ac97st;
361 	void ac97_mmio(address_map &map);
362 	void ac97_io0(address_map &map);
363 	void ac97_io1(address_map &map);
364 	uint8_t minimum_grant_r() { return 2; }
365 	uint8_t maximum_latency_r() { return 5; }
366 };
367 
DECLARE_DEVICE_TYPE(MCPX_AC97_AUDIO,mcpx_ac97_audio_device)368 DECLARE_DEVICE_TYPE(MCPX_AC97_AUDIO, mcpx_ac97_audio_device)
369 
370 /*
371  * AC97 Modem Controller
372  */
373 
374 class mcpx_ac97_modem_device : public pci_device {
375 public:
376 	mcpx_ac97_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
377 };
378 
DECLARE_DEVICE_TYPE(MCPX_AC97_MODEM,mcpx_ac97_modem_device)379 DECLARE_DEVICE_TYPE(MCPX_AC97_MODEM, mcpx_ac97_modem_device)
380 
381 /*
382  * IDE Controller
383  */
384 
385 class mcpx_ide_device : public pci_device {
386 public:
387 	mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subsystem_id);
388 	mcpx_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
389 
390 	auto pri_interrupt_handler() { return m_pri_interrupt_handler.bind(); }
391 	auto sec_interrupt_handler() { return m_sec_interrupt_handler.bind(); }
392 
393 	void class_rev_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
394 	uint8_t pri_read_cs1_r();
395 	void pri_write_cs1_w(uint8_t data);
396 	uint8_t sec_read_cs1_r();
397 	void sec_write_cs1_w(uint8_t data);
398 
399 protected:
400 	virtual void device_start() override;
401 	virtual void device_reset() override;
402 	virtual void device_add_mconfig(machine_config &config) override;
403 	virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
404 		uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
405 
406 	virtual void config_map(address_map &map) override;
407 
408 private:
409 	required_device<bus_master_ide_controller_device> m_pri;
410 	required_device<bus_master_ide_controller_device> m_sec;
411 	devcb_write_line m_pri_interrupt_handler;
412 	devcb_write_line m_sec_interrupt_handler;
413 	void ide_pri_command(address_map &map);
414 	void ide_pri_control(address_map &map);
415 	void ide_sec_command(address_map &map);
416 	void ide_sec_control(address_map &map);
417 	void ide_io(address_map &map);
418 	DECLARE_WRITE_LINE_MEMBER(ide_pri_interrupt);
419 	DECLARE_WRITE_LINE_MEMBER(ide_sec_interrupt);
420 	uint8_t minimum_grant_r() { return 3; }
421 	uint8_t maximum_latency_r() { return 1; }
422 };
423 
DECLARE_DEVICE_TYPE(MCPX_IDE,mcpx_ide_device)424 DECLARE_DEVICE_TYPE(MCPX_IDE, mcpx_ide_device)
425 
426 
427 /*
428  * AGP Bridge
429  */
430 
431 class nv2a_agp_device : public agp_bridge_device {
432 public:
433 	nv2a_agp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t main_id, uint32_t revision)
434 		: nv2a_agp_device(mconfig, tag, owner, clock)
435 	{
436 		set_ids_bridge(main_id, revision);
437 	}
438 	nv2a_agp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
439 
440 	void config_map(address_map& map) override;
441 
442 	uint32_t unknown_r(offs_t offset, uint32_t mem_mask = ~0);
443 	void unknown_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
444 
445 protected:
446 	virtual void device_start() override;
447 	virtual void device_reset() override;
448 };
449 
DECLARE_DEVICE_TYPE(NV2A_AGP,nv2a_agp_device)450 DECLARE_DEVICE_TYPE(NV2A_AGP, nv2a_agp_device)
451 
452 /*
453  * NV2A 3D Accelerator
454  */
455 
456 class nv2a_gpu_device : public agp_device {
457 public:
458 	template <typename T>
459 	nv2a_gpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
460 		: nv2a_gpu_device(mconfig, tag, owner, clock)
461 	{
462 		set_cpu_tag(std::forward<T>(cpu_tag));
463 	}
464 	nv2a_gpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
465 	template <typename T> void set_cpu_tag(T &&cpu_tag) { cpu.set_tag(std::forward<T>(cpu_tag)); }
466 	nv2a_renderer *debug_get_renderer() { return nvidia_nv2a; }
467 
468 	auto interrupt_handler() { return m_interrupt_handler.bind(); }
469 
470 	uint32_t geforce_r(offs_t offset, uint32_t mem_mask = ~0);
471 	void geforce_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
472 	uint32_t nv2a_mirror_r(offs_t offset, uint32_t mem_mask = ~0);
473 	void nv2a_mirror_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
474 
475 protected:
476 	virtual void device_start() override;
477 	virtual void device_reset() override;
478 
479 private:
480 	nv2a_renderer *nvidia_nv2a;
481 	required_device<device_memory_interface> cpu;
482 	devcb_write_line m_interrupt_handler;
483 	address_space *m_program;
484 	void nv2a_mmio(address_map &map);
485 	void nv2a_mirror(address_map &map);
486 };
487 
488 DECLARE_DEVICE_TYPE(NV2A_GPU, nv2a_gpu_device)
489 
490 #endif // MAME_INCLUDES_XBOX_PCI_H
491