Skip to content

Commit

Permalink
Adding HID descriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Feb 22, 2024
1 parent 431e104 commit c439b04
Show file tree
Hide file tree
Showing 8 changed files with 572 additions and 236 deletions.
64 changes: 52 additions & 12 deletions include/vcml/models/usb/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,46 @@
namespace vcml {
namespace usb {

struct endpoint_desc {
u8 address;
u8 attributes;
u16 max_packet_size;
u8 interval;
u8 refresh;
u8 sync_address;
};

struct interface_desc {
u8 alternate_setting;
u8 ifxclass;
u8 subclass;
u8 protocol;
vector<endpoint_desc> endpoints;
vector<u8> extra;
};

struct config_desc {
u8 value;
u8 attributes;
u8 max_power;
vector<interface_desc> interfaces;
};

struct device_desc {
u16 bcd_usb;
u8 device_class;
u8 device_subclass;
u8 device_protocol;
u8 max_packet_size0;
u16 vendor_id;
u16 product_id;
u16 bcd_device;
string manufacturer;
string product;
string serial_number;
vector<config_desc> configs;
};

class device : public module, public usb_dev_if
{
private:
Expand Down Expand Up @@ -49,37 +89,37 @@ class device : public module, public usb_dev_if
size_t pos;
usb_result res;
control_state state;
u8* ptr;
u8 buf[1024];
} m_ep0;

usb_result load_config_descriptors(u8* data, size_t idx);

public:
bool is_addressed() const { return m_state >= STATE_ADDRESSED; }
bool is_configured() const { return m_state >= STATE_CONFIGURED; }

u32 get_address() const { return m_address; }

device(const sc_module_name& nm);
device(const sc_module_name& nm, const device_desc& desc);
virtual ~device();
VCML_KIND(usb::device);

protected:
device_desc m_desc;
size_t m_cur_config;
size_t m_cur_iface;

virtual usb_result get_data(u32 ep, u8* data, size_t len);
virtual usb_result set_data(u32 ep, const u8* data, size_t len);

virtual usb_result get_configuration(u8& config);
virtual usb_result set_configuration(u8 config);

virtual usb_result get_desc(usb_device_desc& desc) = 0;
virtual usb_result get_desc(usb_config_desc& desc, size_t idx) = 0;
virtual usb_result get_desc(usb_interface_desc& desc, size_t idx,
size_t cfg) = 0;
virtual usb_result get_desc(usb_endpoint_desc& desc, size_t idx,
size_t ifx, size_t cfg) = 0;
virtual usb_result get_desc(usb_string_desc& str, size_t idx) = 0;
virtual usb_result get_desc(usb_bos_desc& desc) = 0;
virtual usb_result get_interface(u8& interface);
virtual usb_result get_descriptor(u8 type, u8 idx, u8* data, size_t size);

virtual usb_result handle_control(u16 req, u16 val, u16 idx, u8* data,
size_t length);
virtual usb_result handle_ep0(usb_packet& p);
virtual usb_result handle_data(usb_packet& p);

virtual void usb_reset_device() override;
virtual void usb_reset_endpoint(int ep) override;
Expand Down
28 changes: 20 additions & 8 deletions include/vcml/models/usb/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,21 @@ namespace usb {
class keyboard : public device
{
private:
u8 m_leds;
ui::keyboard m_keyboard;
ui::console m_console;

public:
enum led_type {
LED_NUM_LOCK = bit(0),
LED_CAPS_LOCK = bit(1),
LED_SCROLL_LOCK = bit(2),
LED_COMPOSE = bit(3),
LED_KANA = bit(4),
};

constexpr bool get_led(led_type type) const { return m_leds & type; }

property<bool> usb3;

property<u16> vendorid;
Expand All @@ -52,14 +63,15 @@ class keyboard : public device
virtual void start_of_simulation() override;
virtual void end_of_simulation() override;

virtual usb_result get_desc(usb_device_desc& desc) override;
virtual usb_result get_desc(usb_config_desc& desc, size_t idx) override;
virtual usb_result get_desc(usb_interface_desc& desc, size_t idx,
size_t cfg) override;
virtual usb_result get_desc(usb_endpoint_desc& desc, size_t idx,
size_t ifx, size_t cfg) override;
virtual usb_result get_desc(usb_string_desc& desc, size_t idx) override;
virtual usb_result get_desc(usb_bos_desc& desc) override;
virtual usb_result get_report(u8* data, size_t size);
virtual usb_result set_report(u8* data, size_t size);

virtual usb_result get_data(u32 ep, u8* data, size_t len) override;

usb_result get_interface_descriptor(u8 type, u8 idx, u8* data, size_t sz);

virtual usb_result handle_control(u16 req, u16 val, u16 idx, u8* data,
size_t length) override;
};

} // namespace usb
Expand Down
3 changes: 2 additions & 1 deletion include/vcml/models/usb/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class xhci : public peripheral, public usb_host_if

void send_event(size_t intr, trb& event);
void send_cc_event(size_t intr, u32 ccode, u32 slotid, u64 addr);
void send_tr_event(size_t intr, u32 ccode, u32 slotid, u64 addr);
void send_tr_event(size_t intr, u32 ccode, u32 slotid, u32 ep, u64 addr);
void send_port_event(size_t intr, u32 ccode, u64 portid);

bool get_transfer(u32& slotid, u32& epid);
Expand All @@ -135,6 +135,7 @@ class xhci : public peripheral, public usb_host_if
u32 cmd_evaluate_context(trb& cmd, u32& slotid);
u32 cmd_reset_endpoint(trb& cmd, u32& slotid);
u32 cmd_stop_endpoint(trb& cmd, u32& slotid);
u32 cmd_set_tr_dequeue_pointer(trb& cmd, u32& slotid);

bool fetch_command(trb& cmd, u64& addr);
void execute_command(trb& cmd, u64 addr);
Expand Down
48 changes: 27 additions & 21 deletions include/vcml/protocols/usb_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,30 @@ constexpr bool failed(const usb_packet& p) {
}

enum usb_request : u16 {
USB_REQ_DEVICE = 0x00,
USB_REQ_INTERFACE = 0x01,
USB_REQ_ENDPOINT = 0x02,
USB_REQ_OTHER = 0x03,

USB_REQ_OUT = 0x00,
USB_REQ_IN = 0x80,

USB_REQ_GET_STATUS = 0x00 << 8,
USB_REQ_CLEAR_FEATURE = 0x01 << 8,
USB_REQ_SET_FEATURE = 0x03 << 8,
USB_REQ_SET_ADDRESS = 0x05 << 8,
USB_REQ_GET_DESCRIPTOR = 0x06 << 8,
USB_REQ_SET_DESCRIPTOR = 0x07 << 8,
USB_REQ_GET_CONFIGURATION = 0x08 << 8,
USB_REQ_SET_CONFIGURATION = 0x09 << 8,
USB_REQ_GET_INTERFACE = 0x0a << 8,
USB_REQ_SET_INTERFACE = 0x0b << 8,
USB_REQ_SYNCH_FRAME = 0x0c << 8,
USB_REQ_SET_SEL = 0x30 << 8,
USB_REQ_SET_ISOCH_DELAY = 0x31 << 8,
USB_REQ_DEVICE = 0x0000,
USB_REQ_IFACE = 0x0100,
USB_REQ_ENDPOINT = 0x0200,
USB_REQ_OTHER = 0x0300,

USB_REQ_CLASS = 0x2000,
USB_REQ_VENDOR = 0x4000,

USB_REQ_OUT = 0x0000,
USB_REQ_IN = 0x8000,

USB_REQ_GET_STATUS = 0x00,
USB_REQ_CLEAR_FEATURE = 0x01,
USB_REQ_SET_FEATURE = 0x03,
USB_REQ_SET_ADDRESS = 0x05,
USB_REQ_GET_DESCRIPTOR = 0x06,
USB_REQ_SET_DESCRIPTOR = 0x07,
USB_REQ_GET_CONFIGURATION = 0x08,
USB_REQ_SET_CONFIGURATION = 0x09,
USB_REQ_GET_INTERFACE = 0x0a,
USB_REQ_SET_INTERFACE = 0x0b,
USB_REQ_SYNCH_FRAME = 0x0c,
USB_REQ_SET_SEL = 0x30,
USB_REQ_SET_ISOCH_DELAY = 0x31,
};

enum usb_descriptor_type : u8 {
Expand All @@ -114,6 +117,9 @@ enum usb_descriptor_type : u8 {
USB_DT_INTERFACE_ASSOC = 0x0b,
USB_DT_BOS = 0x0f,
USB_DT_DEVICE_CAPABILITY = 0x10,
USB_DT_HID = 0x21,
USB_DT_REPORT = 0x22,
USB_DT_PHYSICAL = 0x23,
USB_DT_CS_INTERFACE = 0x24,
USB_DT_CS_ENDPOINT = 0x25,
USB_DT_ENDPOINT_COMPANION = 0x30,
Expand Down
Loading

0 comments on commit c439b04

Please sign in to comment.