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);
}
|