1 /////////////////////////////////////////////////////////////////////////
2 // $Id: uhci_core.h 14148 2021-02-16 17:04:04Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2009-2016  Benjamin D Lunt (fys [at] fysnet [dot] net)
6 //                2009-2021  The Bochs Project
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21 
22 #ifndef BX_IODEV_UHCI_CORE_H
23 #define BX_IODEV_UHCI_CORE_H
24 
25 #define USB_UHCI_PORTS 2
26 
27 typedef struct {
28   int    timer_index;
29 
30   // Registers
31   // Base + 0x00  Command register
32   // Base + 0x02  Status register
33   // Base + 0x04  Interrupt Enable register
34   // Base + 0x06  Frame Number register
35   // Base + 0x08  Frame Base Register (32-bit)
36   // Base + 0x0C  Start of Frame Modify register
37   // Base + 0x0D
38   // Base + 0x0E
39   // Base + 0x0F
40   // Base + 0x10  Eight(?) 16-bit ports (one for each port on hub)
41 
42   // Bit reps of registers above
43   // Command Register
44   //  Bits 15-8 are reserved
45   //  Bit 7 = Maximum packet size
46   //  Bit 6 = Host Controller has been configured (set by software)
47   //  Bit 5 = software debug mode
48   //  Bit 4 = force global resume
49   //  Bit 3 = enter global suspend mode
50   //  Bit 2 = global reset
51   //  Bit 1 = host controller reset
52   //  Bit 0 = run/stop schedule
53   struct {
54     bool  max_packet_size; //(bit 7) 0 = 32 bytes, 1 = 64 bytes
55     bool  configured;      //(bit 6)
56     bool  debug;           //(bit 5)
57     bool  resume;          //(bit 4)
58     bool  suspend;         //(bit 3)
59     bool  reset;           //(bit 2)
60     bool  host_reset;      //(bit 1)
61     bool  schedule;        //(bit 0) 0 = Stop, 1 = Run
62   } usb_command;
63 
64   // Status Register
65   //  Bits 15-6 are reserved
66   //  Bit 5 = Host controller halted
67   //  Bit 4 = Host controller process error
68   //  Bit 3 = PCI Bus error
69   //  Bit 2 = resume received
70   //  Bit 1 = USB error interrupt
71   //  Bit 0 = USB interrupt
72   struct {
73     bool  host_halted;     //(bit 5)
74     bool  host_error;      //(bit 4)
75     bool  pci_error;       //(bit 3)
76     bool  resume;          //(bit 2)
77     bool  error_interrupt; //(bit 1)
78     bool  interrupt;       //(bit 0)
79     Bit8u status2; // bit 0 and 1 are used to generate the interrupt
80   } usb_status;
81 
82   // Interrupt Enable Register
83   //  Bits 15-4 are reserved
84   //  Bit 3 = enable short packet interrupts
85   //  Bit 2 = enable interrupt On Complete
86   //  Bit 1 = enable resume
87   //  Bit 0 = enable timeout/crc
88   struct {
89     bool  short_packet; //(bit 3)
90     bool  on_complete;  //(bit 2)
91     bool  resume;       //(bit 1)
92     bool  timeout_crc;  //(bit 0)
93   } usb_enable;
94 
95   // Frame Number Register
96   //  Bits 15-11 are reserved
97   //  Bits 10-0  Frame List Current Index/Frame Number
98   struct {
99     Bit16u frame_num;
100   } usb_frame_num;
101 
102   // Frame List Base Address Register
103   //  Bits 31-12  Base
104   //  Bits 11-0   *must* be zeros when written to
105   struct {
106     Bit32u frame_base;
107   } usb_frame_base;
108 
109   // Start of Frame Modify Register
110   //  Bit    7 reserved
111   //  Bits 6-0 SOF timing value (default 64)
112   // SOF cycle time equals 11936+timing value
113   struct {
114     Bit8u sof_timing;
115   } usb_sof;
116 
117   // Port Register (0-1)
118   //  Bits 15-13  are reserved
119   //  Bit     12  suspend port
120   //  Bit  11-10  are reserved
121   //  Bit      9  port in reset state
122   //  Bit      8  low-speed device is attached (read-only)
123   //  Bit      7  reserved
124   //  Bit      6  resume detected (read-only)
125   //  Bit      5  line-status D+ (read-only)
126   //  Bit      4  line-status D- (read-only)
127   //  Bit      3  port enabled/disable status has changed
128   //               (write 1 to this bit to clear it)
129   //  Bit      2  port is enabled
130   //  Bit      1  connect status has changed
131   //               (write 1 to this bit to clear it)
132   //  Bit      0  current connect status (read-only)
133   //  Can only write in WORD sizes (Read in byte sizes???)
134   struct {
135     // our data
136     usb_device_c *device;   // device connected to this port
137 
138     // bit reps of actual port
139     bool suspend;
140     bool reset;
141     bool low_speed;
142     bool resume;
143     bool line_dminus;
144     bool line_dplus;
145     bool able_changed;
146     bool enabled;
147     bool connect_changed;
148     bool status;
149   } usb_port[USB_UHCI_PORTS];
150 
151   Bit8u  devfunc;
152 } bx_uhci_core_t;
153 
154 #pragma pack (push, 1)
155 struct TD {
156   Bit32u dword0;
157   Bit32u dword1;
158   Bit32u dword2;
159   Bit32u dword3;
160   Bit32u resv[4];
161 };
162 #pragma pack (pop)
163 
164 #define HC_HORZ    0x80
165 #define HC_VERT    0x81
166 struct HCSTACK {
167   Bit32u  next;
168   Bit8u   d;   // if queue, denotes VERT or HORZ
169   bool    q;
170   bool    t;
171 };
172 
173 class bx_uhci_core_c : public bx_pci_device_c {
174 public:
175   bx_uhci_core_c();
176   virtual ~bx_uhci_core_c();
177   virtual void init_uhci(Bit8u devfunc, Bit16u devid, Bit8u headt, Bit8u intp);
178   virtual void reset_uhci(unsigned);
179   void    uhci_register_state(bx_list_c *parent);
180   virtual void after_restore_state(void);
181   virtual void set_port_device(int port, usb_device_c *dev);
182   virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
183 
184   void event_handler(int event, USBPacket *packet, int port);
185 
186 protected:
187   bx_uhci_core_t hub;
188   Bit8u          global_reset;
189   bool           busy;
190 
191   USBAsync *packets;
192 
193   void update_irq(void);
194 
195   int  broadcast_packet(USBPacket *p);
196   bool set_connect_status(Bit8u port, bool connected);
197 
198   static void uhci_timer_handler(void *);
199   void uhci_timer(void);
200   bool DoTransfer(Bit32u address, Bit32u queue_num, struct TD *);
201   void set_status(struct TD *td, bool stalled, bool data_buffer_error, bool babble,
202     bool nak, bool crc_time_out, bool bitstuff_error, Bit16u act_len);
203 
204   static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
205   static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
206   Bit32u read(Bit32u address, unsigned io_len);
207   void   write(Bit32u address, Bit32u value, unsigned io_len);
208 };
209 
210 #endif
211