--- nono/vm/lance.cpp 2026/04/29 17:04:32 1.1.1.3 +++ nono/vm/lance.cpp 2026/04/29 17:04:45 1.1.1.7 @@ -1,15 +1,16 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "lance.h" -#include "config.h" #include "bus.h" -#include "mpu.h" -#include "romimg_luna.h" -#include "zram.h" +#include "config.h" +#include "interrupt.h" #include "mystring.h" +#include "mythread.h" +#include "zram.h" static void *lance_run(void *); @@ -19,7 +20,7 @@ LanceDevice::LanceDevice() devname = "Lance"; devaddr = 0xf1000000; - monitor.Init(80, 34); + monitor_size = nnSize(80, 34); rx_event.dev = this; rx_event.func = (DeviceCallback_t)&LanceDevice::Callback; @@ -50,9 +51,8 @@ LanceDevice::Init() return false; } - const ConfigItem& item = gConfig->Get("ethernet-macaddr"); + const ConfigItem& item = gConfig->Find("ethernet-macaddr"); const std::string& config_macaddr = item.AsString(); - macaddr_t macaddr; if (config_macaddr == "rom") { // ROM に書いてあるのを使うので、ここでは何もしなくていい } else { @@ -71,13 +71,7 @@ LanceDevice::Init() } } - putmsg(1, "macaddr=%s", macaddr.to_string().c_str()); - - // ROM に書き込む - if (gPROM->SetMacAddr(macaddr) == false) { - warnx("LanceDevice initialization failed: unexpected PROM"); - return false; - } + putmsg(1, "macaddr=%s", macaddr.to_string(':').c_str()); } // ワーカスレッド起動 @@ -163,8 +157,8 @@ LanceDevice::Peek(uint32 addr) __unreachable(); } -bool -LanceDevice::MonitorUpdate() +void +LanceDevice::MonitorUpdate(TextScreen& monitor) { /* CSR0: $1111 ERR BABL CERR MISS MERR RINT TINT IDON IADR:$123456 @@ -184,9 +178,7 @@ LADRF:$12345678_12345678 TDRP: // name を表示。(var & bit) ならオン(反転)表示。 // bitpos は 0..15 で [0] が MSB にあたる。 #define MonitorBit(var, bit, name) do { \ - monitor.Print(x, y, \ - (((var) & (bit)) ? TA::On : TA::Off), \ - "%s", name); \ + monitor.Puts(x, y, TA::OnOff((var) & (bit)), name); \ x += strlen(name) + 1; \ } while (0) @@ -202,8 +194,8 @@ LADRF:$12345678_12345678 TDRP: // CSR uint16 csr0 = reg.GetCSR0(); monitor.Print(0, y, "CSR0:$%04x", csr0); - MonitorReg(11, y, csr0 >> 8, csr0names); - MonitorReg(11, y + 1, csr0, csr0names + 8); + MonitorReg(monitor, 11, y, csr0 >> 8, csr0names); + MonitorReg(monitor, 11, y + 1, csr0, csr0names + 8); monitor.Print(54, y++, "IADR:$%06x", reg.iadr); monitor.Print(54, y, "CSR3:$%04x", reg.csr3); @@ -214,7 +206,7 @@ LADRF:$12345678_12345678 TDRP: MonitorBit(reg.csr3, AM7990::CSR3_BCON, csr3names[15]); y++; - monitor.Print(0, y, ""); + monitor.Puts(0, y, ""); y++; // MODE は bit15 と bit6-0 の8ビットだけ使われてるので // 途中を省略して 8ビットとして表示する @@ -255,7 +247,7 @@ LADRF:$12345678_12345678 TDRP: y++; // RMD - monitor.Print(0, y, ""); + monitor.Puts(0, y, ""); uint16 rmd[4]; uint32 rmd_addr; @@ -325,7 +317,7 @@ LADRF:$12345678_12345678 TDRP: y += 17; // TMD - monitor.Print(0, y, ""); + monitor.Puts(0, y, ""); uint16 tmd[4]; uint32 tmd_addr; @@ -388,19 +380,17 @@ LADRF:$12345678_12345678 TDRP: } } } - - return true; } // レジスタをビットごとに表示する。 // data は下位8ビットのみ使用し、上位は無視する。 void -LanceDevice::MonitorReg(int x, int y, uint32 data, const char * const *names) +LanceDevice::MonitorReg(TextScreen& monitor, + int x, int y, uint32 data, const char * const *names) { for (int i = 0; i < 8; i++) { bool b = data & (1 << (7 - i)); - uint attr = b ? TA::On : TA::Off; - monitor.Print(x + i * 5, y, attr, "%s", names[i]); + monitor.Puts(x + i * 5, y, TA::OnOff(b), names[i]); } } @@ -514,16 +504,11 @@ LanceDevice::WriteData(uint32 data) // INEA は %0 も %1 も書き込める // INEA は STOP 中は設定できない if (!reg.IsSTOP()) { - uint16 old_inea = reg.csr0 & AM7990::CSR0_INEA; - uint16 new_inea = data & AM7990::CSR0_INEA; reg.csr0 &= ~AM7990::CSR0_INEA; - reg.csr0 |= new_inea; - - // INEA が 0->1 に変化して、INTR 立ってたら割り込み上げる? - if (old_inea == 0 && new_inea != 0 && reg.IsINTR()) { - Interrupt(); - } + reg.csr0 |= data & AM7990::CSR0_INEA; } + + ChangeInterrupt(); break; } @@ -719,24 +704,22 @@ LanceDevice::ChipStop() RecvEnabled = false; } -// 割り込み要因を CSR0 にセットし、許可されていれば割り込みを上げる。 +// 割り込み要因を CSR0 にセットし、必要なら割り込みを上げる。 void LanceDevice::SetInterrupt(uint32 bit) { reg.csr0 |= bit; - - Interrupt(); + ChangeInterrupt(); } -// 許可されていれば割り込みを上げる。 +// 現状に合わせて割り込み信号線の状態を変える。 void -LanceDevice::Interrupt() +LanceDevice::ChangeInterrupt() { - if ((reg.csr0 & AM7990::CSR0_INEA)) { - putlog(2, "割り込み"); - gMPU->Interrupt(3); + if (reg.IsINTR() && (reg.csr0 & AM7990::CSR0_INEA)) { + gInterrupt->AssertINT(this); } else { - putlog(2, "割り込みはマスクされている"); + gInterrupt->NegateINT(this); } } @@ -744,9 +727,9 @@ LanceDevice::Interrupt() void * lance_run(void *dummy) { - pthread_setname_np("Lance worker"); + PTHREAD_SETNAME("Lance worker"); - dynamic_cast(gEthernet.get())->ThreadRun(); + gEthernet->ThreadRun(); return NULL; } @@ -785,11 +768,12 @@ LanceDevice::ThreadRun() } } -#define dispatch(flag, func) \ +#define dispatch(flag, func) do { \ if ((req & (flag))) { \ req &= ~(flag); \ (func)(); \ - } + } \ +} while (0) dispatch(REQ_TXIDLE, TXIdle); dispatch(REQ_TXCOPY, TXCopy); @@ -974,7 +958,7 @@ LanceDevice::TXNext() } // パケット受信。 -// これは mtx 取得状態で Nerdriver スレッドから呼ばれるので、 +// これは mtx 取得状態で Netdriver スレッドから呼ばれるので、 // パケットを手元にコピーして VM スレッドに通知を出すだけ。 bool LanceDevice::RecvPacket(qvector& buf) @@ -1180,12 +1164,12 @@ LanceDevice::RXMiss() // イベントハンドラ void -LanceDevice::Callback(int arg) +LanceDevice::Callback(Event& ev) { std::unique_lock lock(mtx); // ワーカスレッドにフェーズ遷移を伝えるだけ - request |= arg; + request |= ev.code; cv.notify_one(); }