Skip to content

Commit

Permalink
Handle attach/detach, send set_address packet
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Feb 15, 2024
1 parent d655268 commit b155a0a
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 226 deletions.
4 changes: 2 additions & 2 deletions include/vcml.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@
#include "vcml/models/sd/card.h"
#include "vcml/models/sd/sdhci.h"

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

#include "vcml/models/pci/device.h"
#include "vcml/models/pci/host.h"
Expand Down
5 changes: 3 additions & 2 deletions include/vcml/models/usb/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@
namespace vcml {
namespace usb {

class device : public module, public usb_host
class device : public module, public usb_dev_if
{
public:
device(const sc_module_name& nm);
virtual ~device();
VCML_KIND(usb::device);

protected:
virtual void usb_reset(int ep) override;
virtual void usb_reset_device() override;
virtual void usb_reset_endpoint(int ep) override;
virtual void usb_transport(usb_packet& p) override;
};

Expand Down
18 changes: 12 additions & 6 deletions include/vcml/models/usb/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
namespace vcml {
namespace usb {

class xhci : public peripheral
class xhci : public peripheral, public usb_host_if
{
public:
static constexpr size_t MAX_SLOTS = 64;
Expand Down Expand Up @@ -130,17 +130,18 @@ class xhci : public peripheral

bool fetch_transfer(const trigger& ev);

u32 cmd_noop(trb& cmd);
u32 cmd_enable_slot(trb& cmd, u32& slotid);
u32 cmd_disable_slot(trb& cmd, u32& slotid);
u32 cmd_address_device(trb& cmd, u32& slotid);

bool fetch_command(trb& cmd, u64& addr);
void execute_command(trb& cmd, u64 addr);

void command_thread();
void transfer_thread();

void do_noop(trb& cmd, u64 addr);
void do_enable_slot(trb& cmd, u64 addr);
void do_disable_slot(trb& cmd, u64 addr);
void do_address_device(trb& cmd, u64 addr);

bool port_connected(size_t port);
void port_notify(size_t port, u32 mask);
void port_reset(size_t port, bool warm);
void port_update(size_t port, bool attach);
Expand Down Expand Up @@ -178,12 +179,17 @@ class xhci : public peripheral
tlm_target_socket in;
tlm_initiator_socket dma;
gpio_initiator_socket irq;
usb_initiator_array usb_out;

xhci(const sc_module_name& name);
virtual ~xhci();
VCML_KIND(usb::xhci);

virtual void reset() override;

protected:
virtual void usb_attach(usb_initiator_socket& socket) override;
virtual void usb_detach(usb_initiator_socket& socket) override;
};

} // namespace usb
Expand Down
6 changes: 4 additions & 2 deletions include/vcml/protocols/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ class socket_array : public sc_object
if (socket)
return *socket;

VCML_ERROR_ON(idx >= m_max, "socket out of bounds: %zu", idx);
if (idx >= m_max)
VCML_ERROR("socket index out of bounds: %s[%zu]", name(), idx);

hierarchy_guard guard(this);
string nm = mkstr("%s[%zu]", basename(), idx);
socket = new SOCKET(nm.c_str(), m_space);
Expand All @@ -200,7 +202,7 @@ class socket_array : public sc_object

SOCKET& operator[](size_t idx) { return get(idx); }
const SOCKET& operator[](size_t idx) const {
VCML_ERROR_ON(!exists(idx), "socket %zu not found", idx);
VCML_ERROR_ON(!exists(idx), "socket %s[%zu] not found", name(), idx);
return *m_sockets.at(idx);
}

Expand Down
53 changes: 38 additions & 15 deletions include/vcml/protocols/usb_sockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,24 @@ class usb_target_socket;
class usb_initiator_stub;
class usb_target_stub;

class usb_host
class usb_host_if
{
public:
usb_host() = default;
virtual ~usb_host() = default;
usb_host_if() = default;
virtual ~usb_host_if() = default;

virtual void usb_reset(int ep);
virtual void usb_attach(usb_initiator_socket& s);
virtual void usb_detach(usb_initiator_socket& s);
};

class usb_dev_if
{
public:
usb_dev_if() = default;
virtual ~usb_dev_if() = default;

virtual void usb_reset_device();
virtual void usb_reset_endpoint(int ep);
virtual void usb_transport(const usb_target_socket& s, usb_packet& p);
virtual void usb_transport(usb_packet& p);
};
Expand All @@ -40,16 +51,16 @@ class usb_fw_transport_if : public sc_core::sc_interface
public:
typedef usb_packet protocol_types;

virtual usb_speed usb_get_speed() = 0;
virtual void usb_reset(int ep) = 0;

virtual void usb_transport(usb_packet& p) = 0;
};

class usb_bw_transport_if : public sc_core::sc_interface
{
public:
typedef usb_packet protocol_types;

virtual void usb_connection_update(usb_speed speed) = 0;
};

typedef base_initiator_socket<usb_fw_transport_if, usb_bw_transport_if>
Expand Down Expand Up @@ -92,38 +103,46 @@ using usb_base_target_array = socket_array<usb_base_target_socket>;
class usb_initiator_socket : public usb_base_initiator_socket
{
private:
usb_host* m_host;
usb_host_if* m_host;
usb_speed m_speed;

struct usb_bw_transport : usb_bw_transport_if {
usb_initiator_socket* socket;
usb_bw_transport(usb_initiator_socket* s):
usb_bw_transport_if(), socket(s) {}
virtual ~usb_bw_transport() = default;
virtual void usb_connection_update(usb_speed speed) override {
socket->usb_connection_update(speed);
}
} m_transport;

void usb_connection_update(usb_speed speed);

public:
usb_initiator_socket(const char* name, address_space = VCML_AS_DEFAULT);
virtual ~usb_initiator_socket() = default;
VCML_KIND(usb_initiator_socket);

constexpr usb_speed connection_speed() const { return m_speed; }
constexpr bool is_connected() const { return m_speed != USB_SPEED_NONE; }

void send(usb_packet& p);
void reset_device();
void reset_endpoint(int ep);
};

class usb_target_socket : public usb_base_target_socket
{
private:
usb_host* m_host;
usb_dev_if* m_dev;
usb_speed m_speed;

struct usb_fw_transport : usb_fw_transport_if {
usb_target_socket* socket;
usb_fw_transport(usb_target_socket* t):
usb_fw_transport_if(), socket(t) {}
virtual ~usb_fw_transport() = default;

virtual usb_speed usb_get_speed() override { return socket->speed; }

virtual void usb_reset(int ep) override { socket->usb_reset(ep); }

virtual void usb_transport(usb_packet& p) override {
socket->usb_transport(p);
}
Expand All @@ -133,15 +152,20 @@ class usb_target_socket : public usb_base_target_socket
void usb_transport(usb_packet& p);

public:
usb_speed speed;

usb_target_socket(const char* name, address_space as = VCML_AS_DEFAULT);
virtual ~usb_target_socket() = default;
VCML_KIND(usb_target_socket);

bool is_attached() const { return m_speed != USB_SPEED_NONE; }
void attach(usb_speed speed);
void detach();
};

class usb_initiator_stub : private usb_bw_transport_if
{
private:
virtual void usb_connection_update(usb_speed speed) override;

public:
usb_base_initiator_socket usb_out;
usb_initiator_stub(const char* nm);
Expand All @@ -151,7 +175,6 @@ class usb_initiator_stub : private usb_bw_transport_if
class usb_target_stub : private usb_fw_transport_if
{
private:
virtual usb_speed usb_get_speed() override;
virtual void usb_reset(int ep) override;
virtual void usb_transport(usb_packet& p) override;

Expand Down
4 changes: 4 additions & 0 deletions include/vcml/protocols/usb_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ struct usb_packet {

ostream& operator<<(ostream& os, const usb_packet& p);

usb_packet usb_packet_setup(u32 addr, void* data, size_t len);
usb_packet usb_packet_out(u32 addr, u32 epno, const void* data, size_t len);
usb_packet usb_packet_in(u32 addr, u32 epno, void* data, size_t len);

constexpr bool success(const usb_packet& p) {
return success(p.result);
}
Expand Down
13 changes: 7 additions & 6 deletions src/vcml/models/usb/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
namespace vcml {
namespace usb {

device::device(const sc_module_name& nm): module(nm), usb_host() {
device::device(const sc_module_name& nm): module(nm), usb_dev_if() {
// nothing to do
}

device::~device() {
// nothing to do
}

void device::usb_reset(int ep) {
if (ep < 0)
log_info("reset usb device");
else
log_info("reset usb endpoint %d", ep);
void device::usb_reset_device() {
log_info("usb reset device");
}

void device::usb_reset_endpoint(int ep) {
log_info("usb reset endpoint %d", ep);
}

void device::usb_transport(usb_packet& p) {
Expand Down
Loading

0 comments on commit b155a0a

Please sign in to comment.