From 00c336c255ca94a1d52d927ad4ea3e105d0fb12c Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 8 Jul 2022 04:49:34 -0400 Subject: [PATCH 1/6] Implement software loopback for PCNet driver. --- src/Home/Net/Drivers/PCNet.ZC | 14 +++++++++----- src/Home/Net/Protocols/ARP.ZC | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Home/Net/Drivers/PCNet.ZC b/src/Home/Net/Drivers/PCNet.ZC index 65826a15..3cf9f465 100755 --- a/src/Home/Net/Drivers/PCNet.ZC +++ b/src/Home/Net/Drivers/PCNet.ZC @@ -501,12 +501,21 @@ I64 PCNetTransmitPacketAllocate(U8 **packet_buffer_out, I64 length) return de_index; } +U8 *EthernetMACGet() +{ + return pcnet.mac_address; +} + U0 PCNetTransmitPacketFinish(I64 de_index) {/* Release ownership of the packet to the PCNet card by setting the OWN bit to 1. */ CPCNetDescriptorEntry *entry = &pcnet.tx_de_buffer[de_index * sizeof(CPCNetDescriptorEntry)]; + // check the TX packet MAC against local MAC, if they match: software loopback the TX packet to RX NetQueue + if (!MemCompare(EthernetMACGet(), pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, 6)) + NetQueuePush(pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, U16_MAX - (entry->status1 & 0xFFFF) + 1); + Bts(&entry->status1, PCNET_DESCRIPTORf_OWN); NetLog("PCNET FINISH TX PACKET: TX DE index: %X, OWN bit of entry at entry: %b.", de_index, Bt(&entry->status1, PCNET_DESCRIPTORf_OWN)); @@ -742,11 +751,6 @@ I64 EthernetFrameAllocate(U8 **packet_buffer_out, return de_index; } -U8 *EthernetMACGet() -{ - return pcnet.mac_address; -} - U0 NetStop() { // Halt network activity by setting STOP bit on Status CSR. U32 csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS); diff --git a/src/Home/Net/Protocols/ARP.ZC b/src/Home/Net/Protocols/ARP.ZC index 1a80cfb7..347b470c 100755 --- a/src/Home/Net/Protocols/ARP.ZC +++ b/src/Home/Net/Protocols/ARP.ZC @@ -127,9 +127,11 @@ CARPHash *ARPCachePut(U32 ip_address, U8 *mac_address) } U0 ARPLocalIPV4Set(U32 ip_address) -{ // takes in little endian IP, stores into globals as Big Endian +{ // takes in little endian IP, stores into arp_globals as Big Endian and into ARP cache as Little Endian arp_globals.local_ipv4 = EndianU32(ip_address); + ARPCachePut(ip_address, EthernetMACGet); + ARPSend(ARP_REPLY, ethernet_globals.ethernet_broadcast, EthernetMACGet, From 24e4ae8f2ebe93d14c66b306bf8e47352926ba2c Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 8 Jul 2022 18:08:30 -0400 Subject: [PATCH 2/6] Replace magic numbers with defines in Ethernet protocol code. --- src/Home/Net/Protocols/Ethernet.ZC | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Home/Net/Protocols/Ethernet.ZC b/src/Home/Net/Protocols/Ethernet.ZC index 801ac2aa..bcce3903 100755 --- a/src/Home/Net/Protocols/Ethernet.ZC +++ b/src/Home/Net/Protocols/Ethernet.ZC @@ -1,8 +1,8 @@ class CEthernetFrame { - U8 source_address[6]; + U8 source_address[MAC_ADDRESS_LENGTH]; U8 padding[2]; - U8 destination_address[6]; + U8 destination_address[MAC_ADDRESS_LENGTH]; U16 ethertype; U8 *data; @@ -12,15 +12,15 @@ class CEthernetFrame class CEthernetGlobals { - U8 ethernet_null[6]; - U8 ethernet_broadcast[6]; + U8 ethernet_null[MAC_ADDRESS_LENGTH]; + U8 ethernet_broadcast[MAC_ADDRESS_LENGTH]; } ethernet_globals; U0 EthernetGlobalsInit() { I64 i; - for (i = 0; i < 6; i++) + for (i = 0; i < MAC_ADDRESS_LENGTH; i++) { ethernet_globals.ethernet_null[i] = 0; ethernet_globals.ethernet_broadcast[i] = 0xFF; From 514cfe9f880857763c08483afa709cf2e5ff8c3d Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Sun, 10 Jul 2022 01:40:15 -0400 Subject: [PATCH 3/6] Implement initial driver-independent loopback networking. --- src/Home/Net/Drivers/PCNet.ZC | 20 ++++++++++++----- src/Home/Net/Drivers/VirtIONet.ZC | 35 ++++++++++++++++++++---------- src/Home/Net/Protocols/Ethernet.ZC | 10 +++++++++ 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/Home/Net/Drivers/PCNet.ZC b/src/Home/Net/Drivers/PCNet.ZC index 3cf9f465..861a269a 100755 --- a/src/Home/Net/Drivers/PCNet.ZC +++ b/src/Home/Net/Drivers/PCNet.ZC @@ -512,20 +512,28 @@ U0 PCNetTransmitPacketFinish(I64 de_index) CPCNetDescriptorEntry *entry = &pcnet.tx_de_buffer[de_index * sizeof(CPCNetDescriptorEntry)]; - // check the TX packet MAC against local MAC, if they match: software loopback the TX packet to RX NetQueue - if (!MemCompare(EthernetMACGet(), pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, 6)) - NetQueuePush(pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, U16_MAX - (entry->status1 & 0xFFFF) + 1); - Bts(&entry->status1, PCNET_DESCRIPTORf_OWN); NetLog("PCNET FINISH TX PACKET: TX DE index: %X, OWN bit of entry at entry: %b.", de_index, Bt(&entry->status1, PCNET_DESCRIPTORf_OWN)); } -U0 EthernetFrameFinish(I64 de_index) -{//Alias for driver Finish TX function. +U0 NetDriverTransmitPacketFinish(I64 de_index) +{//Alias for driver-specific Finish TX function. PCNetTransmitPacketFinish(de_index); } +I64 NetDriverPacketBufferGet(I64 de_index) +{ + return pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE; +} + +I64 NetDriverPacketLengthGet(I64 de_index) +{ + CPCNetDescriptorEntry *entry = &pcnet.tx_de_buffer[de_index * sizeof(CPCNetDescriptorEntry)]; + + return U16_MAX - (entry->status1 & 0xFFFF) + 1; +} + I64 PCNetPacketReceive(U8 **packet_buffer_out, U16 *packet_length_out) {/* Receives the packet at the current RX DE index. Parameters are both pointers, since we modify the value at the packet_buffer_out, diff --git a/src/Home/Net/Drivers/VirtIONet.ZC b/src/Home/Net/Drivers/VirtIONet.ZC index 31541648..a2010aa1 100755 --- a/src/Home/Net/Drivers/VirtIONet.ZC +++ b/src/Home/Net/Drivers/VirtIONet.ZC @@ -167,15 +167,15 @@ I64 EthernetFrameAllocate(U8 **buffer_out, U8 *src_addr, U8 *dst_addr, I64 index; - if (!MemCompare(dst_addr, &VirtioNet.mac, 6)) { - frame = loopback_frame; - loopback_length = length; - index = I64_MAX; - } else { +// if (!MemCompare(dst_addr, &VirtioNet.mac, 6)) { +// frame = loopback_frame; +// loopback_length = length; +// index = I64_MAX; +// } else { index = @virtio_net_alloc_tx_packet(&frame, 14 + length/*, flags*/); if (index < 0) return index; - } +// } MemCopy(frame + 0, dst_addr, 6); MemCopy(frame + 6, src_addr, 6); @@ -186,15 +186,26 @@ I64 EthernetFrameAllocate(U8 **buffer_out, U8 *src_addr, U8 *dst_addr, return index; } -I64 EthernetFrameFinish(I64 index) { - if (index == I64_MAX && loopback_frame && loopback_length) { - NetQueuePush(loopback_frame, loopback_length); - loopback_length = 0; - return 0; - } +//I64 EthernetFrameFinish(I64 index) { +I64 NetDriverTransmitPacketFinish(I64 index) { +// if (index == I64_MAX && loopback_frame && loopback_length) { +// NetQueuePush(loopback_frame, loopback_length); +// loopback_length = 0; +// return 0; +// } return @virtio_net_finish_tx_packet(index); } +I64 NetDriverPacketBufferGet(I64 de_index) +{ + return tx_buffers + de_index * ETHERNET_FRAME_SIZE; +} + +I64 NetDriverPacketLengthGet(I64 de_index) +{ // TODO: ... de_index in Alec's VirtIO-Net driver don't match up to any way to get packet length... + return 0; +} + U8 *EthernetMACGet() { return &VirtioNet.mac; } I64 @virtio_net_init() { diff --git a/src/Home/Net/Protocols/Ethernet.ZC b/src/Home/Net/Protocols/Ethernet.ZC index bcce3903..f2f75652 100755 --- a/src/Home/Net/Protocols/Ethernet.ZC +++ b/src/Home/Net/Protocols/Ethernet.ZC @@ -52,4 +52,14 @@ U0 EthernetFrameParse(CEthernetFrame *frame_out, U8 *frame, U16 length) frame_out->length = length - ETHERNET_MAC_HEADER_LENGTH - 4; // He has a comment literally just saying "??". + or - 4? } +U0 EthernetFrameFinish(I64 de_index) +{//Alias for generic driver Finish TX function. + + // check the TX packet MAC against local MAC, if they match: software loopback the TX packet to RX NetQueue + if (!MemCompare(EthernetMACGet(), NetDriverPacketBufferGet(de_index), MAC_ADDRESS_LENGTH)) + NetQueuePush(NetDriverPacketBufferGet(de_index), NetDriverPacketLengthGet(de_index)); + + NetDriverTransmitPacketFinish(de_index); +} + EthernetGlobalsInit; \ No newline at end of file From 57aaeebde1d8d4f4bf80d98e54f8df62835649d8 Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 23 Dec 2022 02:22:58 -0500 Subject: [PATCH 4/6] Fix loopback code using deprecated variable. --- src/Home/Net/Drivers/PCNet.ZC | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Home/Net/Drivers/PCNet.ZC b/src/Home/Net/Drivers/PCNet.ZC index 92825272..4f4c2bc1 100644 --- a/src/Home/Net/Drivers/PCNet.ZC +++ b/src/Home/Net/Drivers/PCNet.ZC @@ -585,7 +585,7 @@ U0 NetDriverTransmitPacketFinish(I64 de_index) I64 NetDriverPacketBufferGet(I64 de_index) { - return pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE; + return pcnet.tx_buffer_addr_phys + de_index * ETHERNET_FRAME_SIZE; } I64 NetDriverPacketLengthGet(I64 de_index) From ea9e921b627ea9e6b4042c7a36562f4699221aea Mon Sep 17 00:00:00 2001 From: GutPuncher Date: Fri, 8 Dec 2023 00:12:15 -0500 Subject: [PATCH 5/6] Fix loopback crashes. --- src/Home/Net/Programs/TCPChatClient.ZC | 4 ++-- src/Home/Net/Programs/TCPChatServer.ZC | 7 +++++-- src/Home/Net/Protocols/Ethernet.ZC | 13 ++++++++---- src/Home/Net/Utilities/NetQueue.ZC | 29 +++++++++++++++++++++++++- src/Kernel/KGlobals.ZC | 2 +- src/System/Define.ZC | 2 +- 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/Home/Net/Programs/TCPChatClient.ZC b/src/Home/Net/Programs/TCPChatClient.ZC index 2d8d6a68..4ae33e9f 100755 --- a/src/Home/Net/Programs/TCPChatClient.ZC +++ b/src/Home/Net/Programs/TCPChatClient.ZC @@ -24,8 +24,8 @@ U0 ChatMessageTask(I64) while (message = StrGet("> ",, SGF_SHIFT_ESC_EXIT)) { DocBottom(chat_display_task->put_doc); - DocPrint(chat_display_task->put_doc, - "$$BG,BLUE$$$$BLACK$$$$FG$$$$BG$$ %s\n", message); +// DocPrint(chat_display_task->put_doc, +// "$$BG,BLUE$$$$BLACK$$$$FG$$$$BG$$ %s\n", message); TCPSocketSendString(tcp, message); diff --git a/src/Home/Net/Programs/TCPChatServer.ZC b/src/Home/Net/Programs/TCPChatServer.ZC index db21e363..f7c2935c 100755 --- a/src/Home/Net/Programs/TCPChatServer.ZC +++ b/src/Home/Net/Programs/TCPChatServer.ZC @@ -37,7 +37,7 @@ U0 ChatServerBroadcast(CTCPSocket *tcp_socket, I64 length) { dest_socket = conn->socket; - if (dest_socket != tcp_socket) +// if (dest_socket != tcp_socket) { addr.address = EndianU32(dest_socket->destination_address(CSocketAddressIPV4).address.address); @@ -51,7 +51,10 @@ U0 ChatServerBroadcast(CTCPSocket *tcp_socket, I64 length) ip_string = NetworkToPresentation(AF_INET, &addr); // TODO: is NetworkToPresentation backwards? or, do socket addrs store BE or LE ? - message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s>$$FG$$$$BG$$ %%0%dts", ip_string, length); + if (dest_socket == tcp_socket) + message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s (you)>$$FG$$$$BG$$ %%0%dts", ip_string, length); + else + message_prefix = MStrPrint("$$BG,PURPLE$$$$BLACK$$<%s>$$FG$$$$BG$$ %%0%dts", ip_string, length); message = MStrPrint(message_prefix, buffer); diff --git a/src/Home/Net/Protocols/Ethernet.ZC b/src/Home/Net/Protocols/Ethernet.ZC index f2f75652..3a4de9f0 100755 --- a/src/Home/Net/Protocols/Ethernet.ZC +++ b/src/Home/Net/Protocols/Ethernet.ZC @@ -54,12 +54,17 @@ U0 EthernetFrameParse(CEthernetFrame *frame_out, U8 *frame, U16 length) U0 EthernetFrameFinish(I64 de_index) {//Alias for generic driver Finish TX function. + U8 *data = NetDriverPacketBufferGet(de_index); + I64 length = NetDriverPacketLengthGet(de_index); + U8 *mac = EthernetMACGet(); + Bool is_loopback = !MemCompare(mac, data, MAC_ADDRESS_LENGTH); // check the TX packet MAC against local MAC - // check the TX packet MAC against local MAC, if they match: software loopback the TX packet to RX NetQueue - if (!MemCompare(EthernetMACGet(), NetDriverPacketBufferGet(de_index), MAC_ADDRESS_LENGTH)) - NetQueuePush(NetDriverPacketBufferGet(de_index), NetDriverPacketLengthGet(de_index)); + // software loopback the TX packet to RX NetQueue if it's loopback + if (is_loopback) + NetQueueLazyPush(data, length); NetDriverTransmitPacketFinish(de_index); + } -EthernetGlobalsInit; \ No newline at end of file +EthernetGlobalsInit; diff --git a/src/Home/Net/Utilities/NetQueue.ZC b/src/Home/Net/Utilities/NetQueue.ZC index 1e709dda..c6eddb41 100755 --- a/src/Home/Net/Utilities/NetQueue.ZC +++ b/src/Home/Net/Utilities/NetQueue.ZC @@ -68,5 +68,32 @@ U0 NetQueuePush(U8 *data, I64 length) MPInt(I_NETHANDLER, INT_DEST_CPU); } +U0 NetQueueLazyPull() +{ + PUSHFD + CLI + + if (net_queue->next != net_queue) + { + NetLog("NETQUEUE LAZY PULL: Generating NetHandler interrupt."); + MPInt(I_NETHANDLER, INT_DEST_CPU); + } + + POPFD +} + +U0 NetQueueLazyPush(U8 *data, I64 length) +{ // Push into NetQueue, don't trigger interrupt in this func. + // Trigger interrupt by Spawn-ing another Task to check queue. + + CNetQueueEntry *entry = CAlloc(sizeof(CNetQueueEntry)); + + entry->packet_length = length; + MemCopy(entry->frame, data, length); + QueueInsert(entry, net_queue->last); + + Spawn(&NetQueueLazyPull,, "NetQueueLazyPull"); +} + +NetQueueInit; -NetQueueInit; \ No newline at end of file diff --git a/src/Kernel/KGlobals.ZC b/src/Kernel/KGlobals.ZC index c372e793..bc646ec1 100755 --- a/src/Kernel/KGlobals.ZC +++ b/src/Kernel/KGlobals.ZC @@ -14,7 +14,7 @@ U8 *rev_bits_table; //Table with U8 bits reversed CDate local_time_offset; F64 *pow10_I64, sys_os_version = 2.03; -U64 sys_os_version_sub = 107; +U64 sys_os_version_sub = 108; U8 *sys_os_version_str; U8 *sys_os_version_full; U8 *sys_os_version_nice; diff --git a/src/System/Define.ZC b/src/System/Define.ZC index 901ce1bc..d9411781 100755 --- a/src/System/Define.ZC +++ b/src/System/Define.ZC @@ -15,7 +15,7 @@ U0 LoadDocDefines() //$LK,"DD_BOOT_HIGH_LOC_DVD",A="FF:::/System/Boot/BootDVD.ZC,DD_BOOT_HIGH_LOC_DVD"$ $TR,"LineRep"$ -$ID,2$DefinePrint("DD_ZEALOS_LOC","98,756"); +$ID,2$DefinePrint("DD_ZEALOS_LOC","99,737"); $ID,-2$ DefinePrint("DD_MP_VECT", "%08X", MP_VECT_ADDR); DefinePrint("DD_MP_VECT_END", "%08X", MP_VECT_ADDR + COREAP_16BIT_INIT_END - COREAP_16BIT_INIT - 1); From 0cc6d4c112a269c69ece8b7da08dc632ffcc43f1 Mon Sep 17 00:00:00 2001 From: GutPuncher Date: Fri, 8 Dec 2023 00:22:59 -0500 Subject: [PATCH 6/6] Kludge VirtIONet driver loopback packet size. --- src/Home/Net/Drivers/VirtIONet.ZC | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Home/Net/Drivers/VirtIONet.ZC b/src/Home/Net/Drivers/VirtIONet.ZC index a2010aa1..c858eaf9 100755 --- a/src/Home/Net/Drivers/VirtIONet.ZC +++ b/src/Home/Net/Drivers/VirtIONet.ZC @@ -203,7 +203,7 @@ I64 NetDriverPacketBufferGet(I64 de_index) I64 NetDriverPacketLengthGet(I64 de_index) { // TODO: ... de_index in Alec's VirtIO-Net driver don't match up to any way to get packet length... - return 0; + return ETHERNET_FRAME_SIZE; } U8 *EthernetMACGet() { return &VirtioNet.mac; }