--- nono/vm/ethernet.h 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/ethernet.h 2026/04/29 17:04:55 1.1.1.7 @@ -1,17 +1,17 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #pragma once +#include "device.h" +#include "qvector.h" #include -#include #include +#include #include -#include "device.h" -#include "mystring.h" -#include "qvector.h" // IODevice // | @@ -24,14 +24,14 @@ // (LUNA, AM7990) (X68000, RTL8019) // // これ自体は IODevice である必要はないが、LanceDevice などの親になるため -// IODevice にしてある。(多重継承はしない) +// IODevice にしてある。(多重継承はしない) class NetDriver; // MAC アドレス格納用のクラス class macaddr_t : public std::array { - typedef std::array inherited; + using inherited = std::array; public: // この MAC アドレスが 00:00:00:00:00:00 なら true bool empty() const { @@ -43,50 +43,68 @@ class macaddr_t : public std::array>; +// 受信パケットキュー用 +using RXPacketQueue = std::queue; + class EthernetDevice : public IODevice { - typedef IODevice inherited; + using inherited = IODevice; protected: - EthernetDevice(); + EthernetDevice(const std::string& objname_); public: - virtual ~EthernetDevice(); + virtual ~EthernetDevice() override; - virtual bool Create(); - virtual bool Init(); + bool Create() override; // パケットを受信した。 // ホストネットワークドライバから呼ばれる。 - // ホストネットワークスレッドで mtx 取得状態で呼ばれるので、 // バッファをコピーしてこちらのスレッドに処理を引き渡すところまでを行う。 - // buf はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、 + // packet はプリアンブルを含まず、イーサネットフレームヘッダ(14バイト)、 // データ(46-1500バイト)、FCS(CRC) (4バイト) からなる。 - virtual bool RecvPacket(qvector& buf) = 0; + // 渡されたパケットの所有権はこちらで引き取る。 + bool RecvPacket(RXPacket packet); - // パケット受信許可。 - // true の場合のみホストドライバは RecvPacket() をコールしてよい。 - bool RecvEnabled = false; + // MAC アドレスを取得 + macaddr_t GetMacAddr() const { + return macaddr; + } + // 統計情報の取得 + uint64 GetTXPkts() const { return tx_pkts; } + uint64 GetRXPkts() const { return rx_pkts; } + + protected: // このデバイスと継承デバイスのメンバ変数を読み書きする場合は // 必ずこのロックを取得する。? - // cv もこのロックを使う。 std::mutex mtx {}; - // ワーカスレッドへ指示を出すための条件変数 - std::condition_variable cv {}; - // ワーカスレッドへのリクエストフラグ - uint32 request = 0; - protected: + // パケット受信許可。 + bool RecvEnabled {}; + // MAC アドレスを生成する static void GenerateMacAddr(macaddr_t *addr); @@ -95,6 +113,28 @@ class EthernetDevice : public IODevice // パケットを送信する bool SendPacket(const std::vector& buf); + + // 継承クラスはこのメソッドをオーバーライドして、受信に対する処理を行う。 + // パケットを受信してキューに投入した後に呼び出される。 + virtual void NotifyRecvPacket() = 0; + + // MAC アドレス + macaddr_t macaddr {}; + + // 受信パケットキュー + // VMとホストの通信速度調停のためキューが必要。 + RXPacketQueue rxq {}; + + // 統計情報 + uint64 tx_pkts {}; + uint64 rx_pkts {}; + + private: + // Create() の下請け + bool CreateNone(); + bool CreateAFPacket(); + bool CreateTap(); + bool CreateBPF(); }; extern std::unique_ptr gEthernet;