--- nono/vm/ethernet.cpp 2026/04/29 17:05:10 1.1.1.6 +++ nono/vm/ethernet.cpp 2026/04/29 17:05:21 1.1.1.8 @@ -9,15 +9,13 @@ // #include "ethernet.h" +#include "config.h" #include "hostnet.h" #include "scheduler.h" -// グローバル参照用 -EthernetDevice *gEthernet; - // コンストラクタ -EthernetDevice::EthernetDevice(const std::string& objname_) - : inherited(objname_) +EthernetDevice::EthernetDevice(int objid_) + : inherited(objid_) { } @@ -25,9 +23,8 @@ EthernetDevice::EthernetDevice(const std EthernetDevice::~EthernetDevice() { if ((bool)hostnet) { - hostnet->SetCallbackDevice(NULL); + hostnet->SetRxCallback(NULL); } - gEthernet = NULL; } // 動的なコンストラクション @@ -35,10 +32,10 @@ bool EthernetDevice::Create() { // ホストドライバを作成してこのデバイスと紐付ける - hostnet.reset(new HostNetDevice()); + int n = GetId() - OBJ_ETHERNET0; + hostnet.reset(new HostNetDevice(this, n)); hostnet->SetRxCallback(ToDeviceCallback(&EthernetDevice::HostRxCallback)); - hostnet->SetCallbackDevice(this); return true; } @@ -48,5 +45,54 @@ void EthernetDevice::HostRxCallback() { // スレッドを超えるためにメッセージを投げる - gScheduler->SendMessage(MessageID::HOSTNET_RX); + int n = GetId() - OBJ_ETHERNET0; + scheduler->SendMessage(MessageID::HOSTNET_RX(n)); +} + +// 設定ファイルから MAC アドレスを読み込む。 +// MAC アドレスを保持するデバイスが呼び出すこと。MAC アドレスを保持する +// デバイスがイーサネットデバイスとは限らず、例えば LANCE を採用している +// 機種ではたいてい ROM か誰かが MAC アドレスを持っている。 +// +// 引数 accept_rom が true なら、設定 ethernet-macaddr=rom を許可する。 +// これは (お手持ちの実機) ROM イメージが MAC アドレスを保持しているため、 +// 指定(や生成)不要なケースで指定できる (prom.cpp 参照)。 +// 引数 accept_rom が false で、設定値に "rom" が指定されるとエラーにする。 +// +// "rom" が指定されて許可されている場合 mac は触らず true を返す。 +// MAC アドレスが指定されているか自動生成したかで取得できれば mac に格納して +// true を返す。それ以外の場合は、エラーメッセージを表示して false を返す。 +/*static*/ bool +EthernetDevice::GetConfigMacAddr(int n, macaddr_t *mac, bool accept_rom) +{ + std::string keyname = string_format("ethernet%d-macaddr", n); + const ConfigItem& item = gConfig->Find(keyname); + const std::string& val = item.AsString(); + + if (val == "rom") { + // ROM に書いてあるのを使う。 + if (accept_rom) { + return true; + } else { + item.Err("\"rom\" cannot be specified in this vmtype"); + return false; + } + } else { + if (val == "auto") { + // 自動生成。 + // 出来れば生成したのを覚えといて、次からそれを使いたい。 + if (0) { + } else { + mac->Generate(); + } + } else { + // ユーザ指定 + if (mac->FromString(val) == false) { + item.Err("Invalid MAC address"); + return false; + } + } + } + + return true; }