Skip to content

Commit

Permalink
Adding usb support
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Feb 25, 2024
1 parent 18f6a51 commit 80b1b1f
Show file tree
Hide file tree
Showing 29 changed files with 4,583 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ setup.sh
.vs/
CMakeSettings.json

# Language Server
.clangd
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ add_library(vcml STATIC
${src}/vcml/protocols/pci.cpp
${src}/vcml/protocols/eth.cpp
${src}/vcml/protocols/can.cpp
${src}/vcml/protocols/usb_types.cpp
${src}/vcml/protocols/usb_sockets.cpp
${src}/vcml/protocols/serial.cpp
${src}/vcml/protocols/virtio.cpp
${src}/vcml/models/generic/clock.cpp
Expand Down Expand Up @@ -156,6 +158,9 @@ add_library(vcml STATIC
${src}/vcml/models/spi/ocspi.cpp
${src}/vcml/models/sd/card.cpp
${src}/vcml/models/sd/sdhci.cpp
${src}/vcml/models/usb/device.cpp
${src}/vcml/models/usb/keyboard.cpp
${src}/vcml/models/usb/xhci.cpp
${src}/vcml/models/pci/device.cpp
${src}/vcml/models/pci/host.cpp
${src}/vcml/models/virtio/mmio.cpp
Expand Down
5 changes: 5 additions & 0 deletions include/vcml.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "vcml/protocols/pci_ids.h"
#include "vcml/protocols/eth.h"
#include "vcml/protocols/can.h"
#include "vcml/protocols/usb.h"
#include "vcml/protocols/serial.h"
#include "vcml/protocols/virtio.h"

Expand Down Expand Up @@ -116,6 +117,10 @@
#include "vcml/models/sd/card.h"
#include "vcml/models/sd/sdhci.h"

#include "vcml/models/usb/xhci.h"
#include "vcml/models/usb/device.h"
#include "vcml/models/usb/keyboard.h"

#include "vcml/models/pci/device.h"
#include "vcml/models/pci/host.h"

Expand Down
13 changes: 13 additions & 0 deletions include/vcml/core/register.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ class reg : public reg_base, public property<DATA, N>
void on_write_mask(DATA mask);
void on_write_mask(const array<DATA, N>& mask);

void read_zero();
void ignore_write();

bool is_banked() const { return m_banked; }
void set_banked(bool set = true) { m_banked = set; }

Expand Down Expand Up @@ -319,6 +322,16 @@ void reg<DATA, N>::on_write_mask(const array<DATA, N>& mask) {
});
}

template <typename DATA, size_t N>
void reg<DATA, N>::read_zero() {
on_read([]() -> DATA { return 0; });
}

template <typename DATA, size_t N>
void reg<DATA, N>::ignore_write() {
on_read([](DATA val) -> void { return; });
}

template <typename DATA, size_t N>
const DATA& reg<DATA, N>::bank(int bk) const {
return bank(bk, 0);
Expand Down
133 changes: 133 additions & 0 deletions include/vcml/models/usb/device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/******************************************************************************
* *
* Copyright (C) 2024 MachineWare GmbH *
* All Rights Reserved *
* *
* This is work is licensed under the terms described in the LICENSE file *
* found in the root directory of this source tree. *
* *
******************************************************************************/

#ifndef VCML_USB_DEVICE_H
#define VCML_USB_DEVICE_H

#include "vcml/core/types.h"
#include "vcml/core/systemc.h"
#include "vcml/core/module.h"
#include "vcml/core/model.h"

#include "vcml/protocols/usb.h"

namespace vcml {
namespace usb {

struct endpoint_desc {
u8 address;
u8 attributes;
u16 max_packet_size;
u8 interval;
u8 refresh;
u8 sync_address;
vector<u8> extra;
};

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:
u32 m_address;
bool m_stalled;

enum device_state {
STATE_DEFAULT = 0,
STATE_ADDRESSED = 1,
STATE_CONFIGURED = 2,
};

device_state m_state;

enum control_state {
STATE_SETUP,
STATE_DATA,
STATE_STATUS,
};

struct ep0 {
u16 req;
u16 val;
u16 idx;
u16 len;
size_t pos;
usb_result res;
control_state state;
u8* ptr;
u8 buf[1024];
} m_ep0;

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, 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_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;
virtual void usb_transport(usb_packet& p) override;
};

} // namespace usb
} // namespace vcml

#endif
87 changes: 87 additions & 0 deletions include/vcml/models/usb/keyboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/******************************************************************************
* *
* Copyright (C) 2024 MachineWare GmbH *
* All Rights Reserved *
* *
* This is work is licensed under the terms described in the LICENSE file *
* found in the root directory of this source tree. *
* *
******************************************************************************/

#ifndef VCML_USB_KEYBOARD_H
#define VCML_USB_KEYBOARD_H

#include "vcml/core/types.h"
#include "vcml/core/systemc.h"
#include "vcml/core/module.h"
#include "vcml/core/model.h"

#include "vcml/ui/input.h"
#include "vcml/ui/keymap.h"
#include "vcml/ui/console.h"

#include "vcml/protocols/usb.h"
#include "vcml/models/usb/device.h"

namespace vcml {
namespace usb {

class keyboard : public device
{
private:
u8 m_leds;
vector<u8> m_keys;

ui::keyboard m_keyboard;
ui::console m_console;

void poll_modifier_keys(u8& data);
void poll_standard_keys(u8* data, size_t len);
void poll_keys(u8* data, size_t len);

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;
property<u16> productid;

property<string> manufacturer;
property<string> product;
property<string> serialno;
property<string> keymap;

usb_target_socket usb_in;

keyboard(const sc_module_name& nm);
virtual ~keyboard();
VCML_KIND(usb::keyboard);

protected:
virtual void start_of_simulation() override;
virtual void end_of_simulation() 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
} // namespace vcml

#endif
Loading

0 comments on commit 80b1b1f

Please sign in to comment.