diff --git a/Sources/Application/Application.swift b/Sources/Application/Application.swift index 2dfc1e3..fec8c6b 100644 --- a/Sources/Application/Application.swift +++ b/Sources/Application/Application.swift @@ -1611,6 +1611,18 @@ struct Application { uartPutDec(UInt64(kernel_genet33_tflush())) uartPuts("\n") + // Runtime V138: EXT RGMII OOB_DISABLE writeback. UART token only. + // No boot event emit. No DMA / unpark. No EL0 enter after GENET. + uartPuts("runtime v138: GENET EXT OOB\n") + let genet34_ok_boot = kernel_genet34_selftest() + uartPuts("genet34 ok=") + uartPutDec(UInt64(genet34_ok_boot)) + uartPuts(" version=138 oob=") + uartPutDec(UInt64(kernel_genet34_oob())) + uartPuts(" restore=") + uartPutDec(UInt64(kernel_genet34_restore())) + uartPuts("\n") + kernel_event_emit(KERNEL_EVENT_KIND_SELFTEST, 22, UInt(kernel_pool_selftest()), UInt(kernel_pool_count())) kernel_event_emit(KERNEL_EVENT_KIND_SELFTEST, 23, UInt(heap_fragmentation_selftest()), UInt(kernel_pool_pressure_selftest())) kernel_event_emit(KERNEL_EVENT_KIND_SELFTEST, 24, UInt(kernel_driver_registry_selftest()), UInt(kernel_driver_count())) diff --git a/Sources/Application/UARTShell.swift b/Sources/Application/UARTShell.swift index 91cfd1b..7f4fe68 100644 --- a/Sources/Application/UARTShell.swift +++ b/Sources/Application/UARTShell.swift @@ -100,7 +100,7 @@ func uartPutShellBufferSlice(_ start: UInt32, _ len: UInt32) { } let SHELL_COMMAND_LIST = - "commands=help,protocol,status,heap,queues,tasks,tasks2,kobjects,drivers,drivercheck,mailboxes,sendtest,supervisor,health,handlecheck,capcheck,events,runtime,agent,certificate,sched,sched2,sched3,sched4,sched5,sched6,sched7,sched8,sched9,sched10,sched11,sched12,cores,locks,runqueues,diag,irqs,timers,memcheck,faults,retained,retained-clear,memmap,mmu,pools,poolcheck,heapfrag,poolstats,frames,heapcheck,framecheck,stress,frameprobe,bootcert,canceltest,taskcheck,channeltest,bootcheck,soak,heap-invalid-free-test,heap-double-free-test,panic-test,fault-test,reboot,vmm,asplit,el0,syscall,uaccess,usermode,process,loader,multiprocess,sdhci,card,block,fat32,mailbox,framebuf,console,pcie,vl805,xhci,genet,genet2,genet3,genet4,gpio,genet5,genet6,genet7,genet8,genet9,genet10,genet11,genet12,i2c,pwm,i2c2,spi2,stimer,sdload,sdls,sdfile,sdovl,sdovf,sdiss,gpio2,stimer2,pwm2,gpio3,stimer3,mboxt,mboxc,wdog2,mboxv,rng,dma2,sdwr,sdmk,sdrd,sdst,sdscr,sdss,sdbus,sdmb,sdsw,sdmw,sdbc,sdfi,sdfb,sdfm,sdrm,genet13,genet14,genet15,genet16,genet17,genet18,genet19,genet20,genet21,genet22,genet23,genet24,genet25,genet26,genet27,genet28,genet29,genet30,genet31,genet32,genet33" + "commands=help,protocol,status,heap,queues,tasks,tasks2,kobjects,drivers,drivercheck,mailboxes,sendtest,supervisor,health,handlecheck,capcheck,events,runtime,agent,certificate,sched,sched2,sched3,sched4,sched5,sched6,sched7,sched8,sched9,sched10,sched11,sched12,cores,locks,runqueues,diag,irqs,timers,memcheck,faults,retained,retained-clear,memmap,mmu,pools,poolcheck,heapfrag,poolstats,frames,heapcheck,framecheck,stress,frameprobe,bootcert,canceltest,taskcheck,channeltest,bootcheck,soak,heap-invalid-free-test,heap-double-free-test,panic-test,fault-test,reboot,vmm,asplit,el0,syscall,uaccess,usermode,process,loader,multiprocess,sdhci,card,block,fat32,mailbox,framebuf,console,pcie,vl805,xhci,genet,genet2,genet3,genet4,gpio,genet5,genet6,genet7,genet8,genet9,genet10,genet11,genet12,i2c,pwm,i2c2,spi2,stimer,sdload,sdls,sdfile,sdovl,sdovf,sdiss,gpio2,stimer2,pwm2,gpio3,stimer3,mboxt,mboxc,wdog2,mboxv,rng,dma2,sdwr,sdmk,sdrd,sdst,sdscr,sdss,sdbus,sdmb,sdsw,sdmw,sdbc,sdfi,sdfb,sdfm,sdrm,genet13,genet14,genet15,genet16,genet17,genet18,genet19,genet20,genet21,genet22,genet23,genet24,genet25,genet26,genet27,genet28,genet29,genet30,genet31,genet32,genet33,genet34" func printShellReady() { uartPuts("shell ready \(SHELL_COMMAND_LIST)\n") @@ -3064,6 +3064,17 @@ func printGenet33() { uartPuts("\n") } +func printGenet34() { + _ = kernel_genet34_selftest() + uartPuts("genet34 ok=") + uartPutDec(UInt64(kernel_genet34_ok())) + uartPuts(" version=138 oob=") + uartPutDec(UInt64(kernel_genet34_oob())) + uartPuts(" restore=") + uartPutDec(UInt64(kernel_genet34_restore())) + uartPuts("\n") +} + func printPoolName(_ pool: UInt32) { var i: UInt32 = 0 let n = kernel_pool_name_len(pool) @@ -4078,6 +4089,8 @@ func dispatchShellCommand(_ commandStart: UInt32, _ commandLen: UInt32, _ reques printGenet32() } else if shellBufferSliceEquals(commandStart, commandLen, "genet33") { printGenet33() + } else if shellBufferSliceEquals(commandStart, commandLen, "genet34") { + printGenet34() } else if shellBufferSliceEquals(commandStart, commandLen, "pools") { printPools() } else if shellBufferSliceEquals(commandStart, commandLen, "poolcheck") { diff --git a/Sources/Support/include/Support.h b/Sources/Support/include/Support.h index 3d112a3..d4a798d 100644 --- a/Sources/Support/include/Support.h +++ b/Sources/Support/include/Support.h @@ -1579,6 +1579,12 @@ int kernel_genet33_ok(void); unsigned int kernel_genet33_rflush(void); unsigned int kernel_genet33_tflush(void); +// V138: EXT RGMII OOB_DISABLE writeback. No DMA. No EL0. +int kernel_genet34_selftest(void); +int kernel_genet34_ok(void); +unsigned int kernel_genet34_oob(void); +unsigned int kernel_genet34_restore(void); + // V80: BSC1 + SPI0 register probe. Read-only. No boot event emit. int kernel_i2c_selftest(void); int kernel_i2c_ok(void); diff --git a/Sources/Support/kernel_genet.c b/Sources/Support/kernel_genet.c index d722005..c4b4296 100644 --- a/Sources/Support/kernel_genet.c +++ b/Sources/Support/kernel_genet.c @@ -18,6 +18,7 @@ #define EXT_OFF 0x0080U #define EXT_RGMII_OOB_CTRL (EXT_OFF + 0x000CU) #define RGMII_LINK (1U << 4) +#define OOB_DISABLE (1U << 5) #define UMAC_OFF 0x0800U #define UMAC_CMD (UMAC_OFF + 0x008U) @@ -5048,3 +5049,52 @@ int kernel_genet33_selftest(void) { int kernel_genet33_ok(void) { return genet33_ok_val; } unsigned int kernel_genet33_rflush(void) { return genet33_rflush_val; } unsigned int kernel_genet33_tflush(void) { return genet33_tflush_val; } + +// V138: EXT RGMII OOB_DISABLE writeback (Linux EXT_RGMII_OOB_CTRL). +// Unused EXT-block mechanism — not a UMAC/RBUF/TBUF/HFB/MIB/SYS-flush +// clone, not BMSR/link MDIO, not TX csum / 64B descriptors, not +// local loopback. Clear then set bit 5, restore leftover. No DMA. +// No EL0. UART token only. +int kernel_genet34_selftest(void); + +static int genet34_probed; +static int genet34_ok_val; +static unsigned int genet34_oob_val; +static unsigned int genet34_restore_val; + +int kernel_genet34_selftest(void) { + uint32_t saved; + uint32_t got; + + if (genet34_probed) return genet34_ok_val; + genet34_probed = 1; + genet34_ok_val = 0; + genet34_oob_val = 0; + genet34_restore_val = 0; + + if (!kernel_genet33_selftest()) return 0; + + saved = G32(EXT_RGMII_OOB_CTRL); + if (saved == 0xDEADDEADU || saved == 0xFFFFFFFFU) return 0; + + genet_wr32(EXT_RGMII_OOB_CTRL, saved & ~OOB_DISABLE); + got = G32(EXT_RGMII_OOB_CTRL); + if (got == 0xDEADDEADU || got == 0xFFFFFFFFU) return 0; + if ((got & OOB_DISABLE) != 0U) return 0; + + genet_wr32(EXT_RGMII_OOB_CTRL, saved | OOB_DISABLE); + got = G32(EXT_RGMII_OOB_CTRL); + if (got == 0xDEADDEADU || got == 0xFFFFFFFFU) return 0; + if ((got & OOB_DISABLE) == 0U) return 0; + genet34_oob_val = 1; + + genet_wr32(EXT_RGMII_OOB_CTRL, saved); + if (G32(EXT_RGMII_OOB_CTRL) != saved) return 0; + genet34_restore_val = 1; + genet34_ok_val = 1; + return 1; +} + +int kernel_genet34_ok(void) { return genet34_ok_val; } +unsigned int kernel_genet34_oob(void) { return genet34_oob_val; } +unsigned int kernel_genet34_restore(void) { return genet34_restore_val; } diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index a2746bf..4063ff2 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -135,6 +135,7 @@ Turn the static identity-map MMU into a real virtual-memory system and run code - [x] V135 HFB filter-0 enable after GENET (`genet31 ok=1 version=135 hfb=`). Fail-closed `HFB_FLT_ENABLE` bit-0 clear/set + leftover restore; does not set `RBUF_HFB_EN`; no DMA; no EL0. Not an RBUF/TBUF/UMAC poke or TX csum / 64B-descriptor clone. - [x] V136 UMAC TX MIB reset after GENET (`genet32 ok=1 version=136 rst=1 zero=1`). Fail-closed leftover `tx.pok`/`tx.bytes` non-zero, `UMAC_MIB_CTRL` `UMAC_MIB_RESET_TX` pulse, counters == 0; no DMA; no EL0. Not an RBUF/TBUF/HFB-enable writeback or TX csum / 64B-descriptor clone. - [x] V137 SYS RBUF/TBUF flush after GENET (`genet33 ok=1 version=137 rflush=1 tflush=1`). Fail-closed `SYS_RBUF_FLUSH_CTRL` + `SYS_TBUF_FLUSH_CTRL` bit-0 pulse + leftover restore; no DMA; no EL0. Not a UMAC/RBUF/TBUF/HFB/MIB enable writeback or TX csum / 64B-descriptor clone. +- [x] V138 EXT RGMII OOB after GENET (`genet34 ok=1 version=138 oob=1 restore=1`). Fail-closed `EXT_RGMII_OOB_CTRL` `OOB_DISABLE` clear/set + leftover restore; no DMA; no EL0. Not a UMAC/RBUF/TBUF/HFB/MIB/SYS-flush writeback, BMSR/link MDIO, loopback, or TX csum / 64B-descriptor clone. - Minimal TCP/IP: ARP, IPv4, ICMP (ping), UDP, then TCP. - A tiny socket API exposed as syscalls. (EL0 `sys_socket` after genet12 I-aborts `esr=0xbf000002` and watchdog-resets; deferred.) - *First proof:* the kernel answers an ICMP ping from the host over its OWN driver diff --git a/scripts/netboot/net-iterate.sh b/scripts/netboot/net-iterate.sh index 506e8ca..29a674e 100755 --- a/scripts/netboot/net-iterate.sh +++ b/scripts/netboot/net-iterate.sh @@ -489,6 +489,8 @@ PY && printf '%s' "$serial_delta" | grep -qa "genet32 ok=1 version=136 rst=" \ && printf '%s' "$serial_delta" | grep -qa "runtime v137: GENET SYS flush" \ && printf '%s' "$serial_delta" | grep -qa "genet33 ok=1 version=137 rflush=" \ + && printf '%s' "$serial_delta" | grep -qa "runtime v138: GENET EXT OOB" \ + && printf '%s' "$serial_delta" | grep -qa "genet34 ok=1 version=138 oob=" \ && printf '%s' "$serial_delta" | grep -qa "vmmcheck ok=1" \ && printf '%s' "$serial_delta" | grep -qa "asplit ok=1 version=46" \ && printf '%s' "$serial_delta" | grep -qa "el0 ok=1 version=47" \ @@ -806,6 +808,8 @@ PY probe_shell "genet32" "^genet32 ok=1 version=136 rst=" # V137: SYS rbuf/tbuf flush pulse. No DMA. No EL0. probe_shell "genet33" "^genet33 ok=1 version=137 rflush=" + # V138: EXT RGMII OOB_DISABLE writeback. No DMA. No EL0. + probe_shell "genet34" "^genet34 ok=1 version=138 oob=" # probe shell: req-status probe_shell "req id=25 cmd=status" "^resp id=25 ok=1 cmd=status end" # probe shell: canceltest diff --git a/scripts/netboot/netboot-doctor.sh b/scripts/netboot/netboot-doctor.sh index dfb9c36..a51dbe0 100755 --- a/scripts/netboot/netboot-doctor.sh +++ b/scripts/netboot/netboot-doctor.sh @@ -349,6 +349,8 @@ while [ "$SECONDS" -lt "$deadline" ]; do && printf '%s' "$serial_delta" | grep -q "genet32 ok=1 version=136 rst=" \ && printf '%s' "$serial_delta" | grep -q "runtime v137: GENET SYS flush" \ && printf '%s' "$serial_delta" | grep -q "genet33 ok=1 version=137 rflush=" \ + && printf '%s' "$serial_delta" | grep -q "runtime v138: GENET EXT OOB" \ + && printf '%s' "$serial_delta" | grep -q "genet34 ok=1 version=138 oob=" \ && printf '%s' "$serial_delta" | grep -q "vmmcheck ok=1" \ && printf '%s' "$serial_delta" | grep -q "asplit ok=1 version=46" \ && printf '%s' "$serial_delta" | grep -q "el0 ok=1 version=47" \ diff --git a/tests/test_runtime_genet_v138_contract.py b/tests/test_runtime_genet_v138_contract.py new file mode 100644 index 0000000..971d53a --- /dev/null +++ b/tests/test_runtime_genet_v138_contract.py @@ -0,0 +1,89 @@ +"""EPIC F V138: GENET EXT RGMII OOB writeback. No EL0.""" + +import pathlib + + +ROOT = pathlib.Path(__file__).resolve().parents[1] + + +def read_repo(path: str) -> str: + return (ROOT / path).read_text() + + +def _selftest_body(genet: str, name: str) -> str: + key = f"int {name}(void) {{" + chunk = genet.split(key, 1)[1] + nxt = chunk.find("\nint kernel_genet") + return chunk if nxt < 0 else chunk[:nxt] + + +def test_genet34_ext_rgmii_oob_without_el0() -> None: + genet = read_repo("Sources/Support/kernel_genet.c") + support = read_repo("Sources/Support/include/Support.h") + app = read_repo("Sources/Application/Application.swift") + shell = read_repo("Sources/Application/UARTShell.swift") + iterate = read_repo("scripts/netboot/net-iterate.sh") + scheduler = read_repo("Sources/Support/kernel_scheduler.c") + roadmap = read_repo("docs/ROADMAP.md") + + assert "kernel_genet34_selftest" in genet + g34 = genet.split("kernel_genet34_selftest", 1)[1] + body34 = _selftest_body(genet, "kernel_genet34_selftest") + assert "EXT_RGMII_OOB_CTRL" in genet + assert "OOB_DISABLE" in genet + assert "EXT_RGMII_OOB_CTRL" in body34 + assert "OOB_DISABLE" in body34 + assert "kernel_genet33_selftest" in body34 + assert "CMD_LCL_LOOP_EN" not in genet + assert "SYS_RBUF_FLUSH_CTRL" not in body34 + assert "SYS_TBUF_FLUSH_CTRL" not in body34 + assert "UMAC_MIB_CTRL" not in body34 + assert "UMAC_MIB_RESET_TX" not in body34 + assert "UMAC_MIB_RESET_RX" not in body34 + assert "HFB_FLT_ENABLE" not in body34 + assert "HFB_FLT0_EN" not in body34 + assert "RBUF_HFB_EN" not in body34 + assert "TBUF_ENERGY_CTRL" not in body34 + assert "TBUF_EEE_EN" not in body34 + assert "RBUF_CHK_CTRL" not in body34 + assert "RBUF_RXCHK_EN" not in body34 + assert "UMAC_MDF_CTRL" not in body34 + assert "UMAC_MAX_FRAME_LEN" not in body34 + assert "DMA_TX_DO_CSUM" not in body34 + assert "RBUF_64B_EN" not in body34 + assert "MII_BMSR" not in body34 + assert "BMSR_LSTATUS" not in body34 + assert "MII_BMCR" not in body34 + assert "RGMII_LINK" not in body34 + assert "kernel_genet13_selftest" not in body34 + assert "kernel_genet21_selftest" not in body34 + assert "genet10_unpark" not in body34 + assert "genet10_park" not in body34 + assert "GIC" not in g34 + assert "kernel_enter_el0_and_wait" not in g34 + assert "kernel_event_emit" not in g34 + assert "watchdog_reset_now" not in g34 + assert "M-SEARCH" not in g34 + assert "HTTP/1.0" not in g34 + assert "200000" not in genet + assert "static unsigned long alloc_dma" not in genet + assert "int kernel_genet34_selftest(void);" in support + assert 'uartPuts("runtime v138: GENET EXT OOB\\n")' in app + assert 'uartPuts("genet34 ok=")' in app + assert "kernel_event_emit(KERNEL_EVENT_KIND_SELFTEST, 138" not in app + assert "func printGenet34()" in shell + assert 'shellBufferSliceEquals(commandStart, commandLen, "genet34")' in shell + assert ",genet33,genet34" in shell + assert 'grep -qa "genet34 ok=1 version=138 oob="' in iterate + assert 'probe_shell "genet34" "^genet34 ok=1 version=138 oob="' in iterate + assert "V138 EXT RGMII OOB" in roadmap + assert "CONFIG.TXT" not in g34 + assert "AETHER.TMP" not in g34 + assert "ping -c 2" in iterate + assert "SOCK_STREAM" in iterate + assert "sched12" in iterate + assert "kernel_genet34_selftest" not in scheduler + after = app.split("kernel_genet12_selftest", 1)[1] + assert "kernel_enter_el0_and_wait" not in after + assert "kernel_socket_selftest" not in after + assert "kernel_genet34_selftest" in after