summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i82371eb_usb.cpp
blob: ce8a688cc7ee0944235eaee9c1e4621c110f75fe (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
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************

PIIX4E USB interface (UHCI)

TODO:
- Actual USB ports;
- SMI traps for legacy support;
- devcb for RTCIREN in PIIX4 ISA, cfr. specification update;

**************************************************************************************************/

#include "emu.h"
#include "i82371eb_usb.h"

#define VERBOSE (LOG_GENERAL)
//#define LOG_OUTPUT_FUNC osd_printf_info

#include "logmacro.h"

DEFINE_DEVICE_TYPE(I82371EB_USB, i82371eb_usb_device, "i82371eb_usb", "Intel 82371EB PIIX4E USB Host Controller")

// rev PIIX4E A-0 / PIIX4M A-0 = 0x01
// subvendor ID not given (assume blank)
// PIRQD# (0x04)
i82371eb_usb_device::i82371eb_usb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: usb_uhci_device(mconfig, I82371EB_USB, tag, owner, clock)
{
	set_ids(0x80867112, 0x01, 0x0c0300, 0x00000000);
	intr_pin = 0x04;
}

void i82371eb_usb_device::device_add_mconfig(machine_config &config)
{
	// 2 USB ports
}

void i82371eb_usb_device::device_start()
{
	usb_uhci_device::device_start();

	save_item(NAME(m_legsup));
	save_item(NAME(m_rtciren));
}


void i82371eb_usb_device::device_reset()
{
	usb_uhci_device::device_reset();

	command = 0x0000;
	// Can be bus master
	command_mask = 5;
	status = 0x0280;

	m_legsup = 0x2000;
	// indeterminate, may as well disable
	m_rtciren = false;
}

void i82371eb_usb_device::config_map(address_map &map)
{
	pci_device::config_map(map);
	// sbrnum - serial bus release number (1.0), 0x00 for "pre-release" 1.0
	map(0x60, 0x60).lr8(NAME([] () { return 0x10; }));
	// legsup - Legacy Support Register
	map(0xc0, 0xc1).lrw16(
		NAME([this] () { return m_legsup; }),
		NAME([this] (offs_t offset, u16 data, u16 mem_mask) {
			LOG("LEGSUP: %04x & %04x\n", data, mem_mask);
			if (ACCESSING_BITS_8_15)
			{
				// A20PTS
				if (BIT(data, 15))
					m_legsup &= ~(1 << 15);
				// USBPIRQDEN
				m_legsup &= ~(1 << 13);
				m_legsup |= (BIT(data, 13) << 13);
				// bit 12 (r/o) USBIRQS
				// TBY64W
				if (BIT(data, 11))
					m_legsup &= ~(1 << 11);
				// TBY64R
				if (BIT(data, 10))
					m_legsup &= ~(1 << 10);
				// TBY60W
				if (BIT(data, 9))
					m_legsup &= ~(1 << 9);
				// TBY60R
				if (BIT(data, 8))
					m_legsup &= ~(1 << 8);

				LOG("USBPIRQDEN %d ", BIT(data, 13));
			}
			if (ACCESSING_BITS_0_7)
			{
				// bit 6 PSS (r/o)
				m_legsup &= ~(0xbf);
				m_legsup |= (data & 0xbf);

				LOG("SMIEPTE %d A20PTEN %d USBSMIEN %d 64WEN %d 64REN %d 60WEN %d 60REN %d"
					, BIT(data, 7)
					, BIT(data, 5)
					, BIT(data, 4)
					, BIT(data, 3)
					, BIT(data, 2)
					, BIT(data, 1)
					, BIT(data, 0)
				);
			}
			LOG("\n");
		})
	);
	// MISCSUP
	// NOTE: byte access only
	map(0xff, 0xff).lrw8(
		NAME([this] () { return m_rtciren << 4; }),
		NAME([this] (offs_t offset, u8 data) {
			m_rtciren = !!BIT(data, 4);
			LOG("MISCSUP: %02x\n", data);
		})
	);
}

void i82371eb_usb_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
							uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
{
//  io_space->install_device(0, 0x03ff, *this, &i82371eb_usb_device::io_map);
}