1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-07-08 09:28:57 +00:00

fix dynamic driver laoding and wiznet WIP

This commit is contained in:
dschmenk 2015-02-03 08:56:44 -08:00
parent bd32c162b9
commit 5651c0b125
9 changed files with 145 additions and 104 deletions

View File

@ -8,13 +8,14 @@ import cmdsys
byte MACHID byte MACHID
end end
import inet import inet
byte localha, localip, subnet, gateway predef swab, sendUDP, openUDP, closeUDP, serviceIP
predef swab, sendUDP, listenUDP, hangupUDP, serviceIP predef setInterfaceIP, getInterfaceHA
end end
// //
// Needed to init subnet // Needed to init subnet
// //
const IP_BROADCAST = $FFFF const IP_BROADCAST = $FFFF
const IP4ADR_SIZE = 4
// //
// DHCP message // DHCP message
// //
@ -54,6 +55,15 @@ byte stateDHCP, retry, timeout
// //
const DHCP_CLIENT_PORT = 68 const DHCP_CLIENT_PORT = 68
const DHCP_SERVER_PORT = 67 const DHCP_SERVER_PORT = 67
word portDHCP
byte[4] zeros
byte[4] ones = $FF, $FF, $FF, $FF
//
// Default static net IP addresses
//
byte localgw = 192,168,123,1
byte localip = 192,168,123,10
byte localnet = 255,255,255,0
// //
// Pre-configured DHCP packet // Pre-configured DHCP packet
// //
@ -134,7 +144,7 @@ def dumpdhcp(pkt)
putip(@pkt->dhcp_yourip);putln putip(@pkt->dhcp_yourip);putln
putip(@pkt->dhcp_serverip);putln putip(@pkt->dhcp_serverip);putln
putip(@pkt->dhcp_gatewayip);putln putip(@pkt->dhcp_gatewayip);putln
dumpbytes(@pkt->dhcp_opts, 32);putln dumpbytes(@pkt->dhcp_opts, 48);putln
end end
def parseopts(opts, match) def parseopts(opts, match)
byte i byte i
@ -151,10 +161,11 @@ def parseopts(opts, match)
loop loop
return -1 return -1
end end
def servdhcp(remip, remport, lclport, pkt, len, param) def recvDHCP(remip, remport, pkt, len, param)
word optofst word optofst, maskopts, gwopts
//putip(remip);putc(':');puti(remport);putln //putip(remip);putc(':');puti(remport);putln
//dumpdhcp(pkt)
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 = $0403 if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 = $0403
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2] when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
is DHCP_OFFER is DHCP_OFFER
@ -167,21 +178,23 @@ def servdhcp(remip, remport, lclport, pkt, len, param)
memcpy(@optsDHCP.5, @pkt->dhcp_yourip, 4) memcpy(@optsDHCP.5, @pkt->dhcp_yourip, 4)
memcpy(@optsDHCP.11, @pkt->dhcp_serverip, 4) memcpy(@optsDHCP.11, @pkt->dhcp_serverip, 4)
memcpy(@DHCP.dhcp_serverip, @pkt->dhcp_serverip, 4) memcpy(@DHCP.dhcp_serverip, @pkt->dhcp_serverip, 4)
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp) sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
break break
is DHCP_ACK is DHCP_ACK
stateDHCP = DHCP_ACK stateDHCP = DHCP_ACK
//
// Stop listening to UDP port
//
hangupUDP(DHCP_CLIENT_PORT)
//puts(@ackstr) //puts(@ackstr)
// //
// Copy parameters to working copy // Copy parameters to working copy
// //
memcpy(@localip, @pkt->dhcp_yourip, 4) memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE)
memcpy(@subnet, @pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 1) + 2], 4) maskopts = parseopts(@pkt->dhcp_opts, 1) + 2
puts(@boundstr);putip(@localip);putc('/');putip(@subnet);putln if maskopts >= 0
memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE)
fin
gwopts = parseopts(@pkt->dhcp_opts, 3) + 2
if gwopts >= 0
memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE)
fin
break break
otherwise otherwise
dumpdhcp(pkt) dumpdhcp(pkt)
@ -191,39 +204,40 @@ end
// //
// Get the local hardware address into the DHCP packet // Get the local hardware address into the DHCP packet
// //
memcpy(@DHCP.dhcp_clientha, @localha, 6) getInterfaceHA(@DHCP.dhcp_clientha)
// //
// Clear our local IP address // Clear our local IP address
// //
memset(@localip, 0, 4) setInterfaceIP(@zeros,@ones, @zeros)
//
// Set subnet mask to all 1's
//
memset(@subnet, IP_BROADCAST, 4)
// //
// Prepare to receive DHCP packets from a server // Prepare to receive DHCP packets from a server
// //
listenUDP(DHCP_CLIENT_PORT, @servdhcp, 0) portDHCP = openUDP(DHCP_CLIENT_PORT, @recvDHCP, 0)
// //
// Service IP // Service IP
// //
while retry < 3 while retry < 3 and stateDHCP <> DHCP_ACK
// //
// Broadcast DHCP DISCOVER message // Broadcast DHCP DISCOVER message
// //
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp) sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
for timeout = 1 to 1000 for timeout = 1 to 1000
serviceIP serviceIP
if stateDHCP == DHCP_ACK if stateDHCP == DHCP_ACK
return 0 break
fin fin
next next
retry = retry + 1 retry = retry + 1
loop loop
closeUDP(portDHCP)
setInterfaceIP(@localip, @localnet, @localgw)
puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
// //
// Nobody answered // Service IP
// //
hangupUDP(DHCP_CLIENT_PORT) repeat
return -1 serviceIP
until ^$C000 > 127
^$C010
done done

View File

@ -1,5 +1,6 @@
import cmdsys import cmdsys
predef syscall, call, getc, gets, putc, puts, putln predef syscall, call, getc, gets, putc, puts, putln
predef isugt, isuge, isult, isule
predef memset, memcpy, modaddr, modexec predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID byte MACHID
@ -39,7 +40,7 @@ const PAYLOAD_ARP = $0608 // BE format
// //
// IP datagram header // IP datagram header
// //
const IPADR_SIZE = 4 const IP4ADR_SIZE = 4
struc t_iphdr struc t_iphdr
byte ip_vers_hlen byte ip_vers_hlen
byte ip_service byte ip_service
@ -49,8 +50,8 @@ struc t_iphdr
byte ip_ttl byte ip_ttl
byte ip_proto byte ip_proto
word ip_chksm word ip_chksm
byte[IPADR_SIZE] ip_src byte[IP4ADR_SIZE] ip_src
byte[IPADR_SIZE] ip_dst byte[IP4ADR_SIZE] ip_dst
byte[] ip_options byte[] ip_options
end end
const t_ethriphdr = t_ethrhdr + t_iphdr const t_ethriphdr = t_ethrhdr + t_iphdr
@ -77,8 +78,8 @@ end
// UDP IPv4 psuedo header // UDP IPv4 psuedo header
// //
struc t_piphdr struc t_piphdr
byte[IPADR_SIZE] pip_src byte[IP4ADR_SIZE] pip_src
byte[IPADR_SIZE] pip_dst byte[IP4ADR_SIZE] pip_dst
byte pip_zero byte pip_zero
byte pip_proto byte pip_proto
word pip_len word pip_len
@ -115,9 +116,9 @@ struc t_arp
byte arp_plen byte arp_plen
word arp_op word arp_op
byte[MAC_SIZE] arp_senderha byte[MAC_SIZE] arp_senderha
byte[IPADR_SIZE] arp_senderip byte[IP4ADR_SIZE] arp_senderip
byte[MAC_SIZE] arp_targha byte[MAC_SIZE] arp_targha
byte[IPADR_SIZE] arp_targip byte[IP4ADR_SIZE] arp_targip
end end
const t_earp = t_ethrhdr+t_arp const t_earp = t_ethrhdr+t_arp
// //
@ -142,19 +143,19 @@ word ePayload = PAYLOAD_ARP
word ARP = HW_ETHER // HW TYPE word ARP = HW_ETHER // HW TYPE
word = ARP_PROTO // PROTO TYPE word = ARP_PROTO // PROTO TYPE
byte = MAC_SIZE // HLEN byte = MAC_SIZE // HLEN
byte = IPADR_SIZE // PLEN byte = IP4ADR_SIZE // PLEN
word opARP // OP word opARP // OP
export byte[MAC_SIZE] localha export byte[MAC_SIZE] localha
export byte[IPADR_SIZE] localip export byte[IP4ADR_SIZE] localip
byte[MAC_SIZE] remoteha byte[MAC_SIZE] remoteha
byte[IPADR_SIZE] remoteip byte[IP4ADR_SIZE] remoteip
// //
// Local network parameters // Local network parameters
// //
export byte[IPADR_SIZE] subnet byte[IP4ADR_SIZE] subnet
export byte[IPADR_SIZE] gateway byte[IP4ADR_SIZE] gateway
const MAX_UDP_NOTIFIES = 16 const MAX_UDP_NOTIFIES = 4
const MAX_TCP_NOTIFIES = 8 const MAX_TCP_NOTIFIES = 4
// //
// Notify callbacks // Notify callbacks
// //
@ -163,8 +164,8 @@ struc t_notify
word notify_func word notify_func
word notify_parm word notify_parm
end end
word portsUDP byte[t_notify * MAX_UDP_NOTIFIES] portsUDP
word portsTCP byte[t_notify * MAX_TCP_NOTIFIES] portsTCP
// //
// Service ICMP hook // Service ICMP hook
// //
@ -254,12 +255,12 @@ export def sendIP(ipdst, proto, seglist, size)
hdr.ip_ttl = 10 // Is this reasonable? hdr.ip_ttl = 10 // Is this reasonable?
hdr.ip_proto = proto hdr.ip_proto = proto
hdr:ip_chksm = 0 hdr:ip_chksm = 0
memcpy(@hdr.ip_src, @localip, IPADR_SIZE) memcpy(@hdr.ip_src, @localip, IP4ADR_SIZE)
if !ipdst // IP_BROADCAST if !ipdst // IP_BROADCAST
memset(@hdr.ip_dst, IP_BROADCAST, IPADR_SIZE) memset(@hdr.ip_dst, IP_BROADCAST, IP4ADR_SIZE)
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE) memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
else else
memcpy(@hdr.ip_dst, ipdst, IPADR_SIZE) memcpy(@hdr.ip_dst, ipdst, IP4ADR_SIZE)
retry = 0 retry = 0
while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2 while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2
if retry >= 3 if retry >= 3
@ -268,7 +269,7 @@ export def sendIP(ipdst, proto, seglist, size)
retry = retry + 1 retry = retry + 1
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE) memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
memset(@remoteha, 0, MAC_SIZE) memset(@remoteha, 0, MAC_SIZE)
memcpy(@remoteip, @hdr.ip_dst, IPADR_SIZE) memcpy(@remoteip, @hdr.ip_dst, IP4ADR_SIZE)
ePayload = PAYLOAD_ARP ePayload = PAYLOAD_ARP
opARP = ARP_REQST opARP = ARP_REQST
setFrameLen(t_earp) setFrameLen(t_earp)
@ -311,11 +312,11 @@ end
// //
// Send UDP datagram // Send UDP datagram
// //
export def sendUDP(ipdst, portdst, portsrc, data, len) export def sendUDP(port, ipdst, portdst, data, len)
word[8] seglist // list of data and header segments word[8] seglist // list of data and header segments
byte[t_udphdr] hdr byte[t_udphdr] hdr
hdr:udp_src = swab(portsrc) hdr:udp_src = swab(port=>notify_port)
hdr:udp_dst = swab(portdst) hdr:udp_dst = swab(portdst)
hdr:udp_len = swab(t_udphdr + len) hdr:udp_len = swab(t_udphdr + len)
hdr:udp_chksm = 0 hdr:udp_chksm = 0
@ -328,62 +329,56 @@ end
// //
// Notify on UDP datagram received // Notify on UDP datagram received
// //
export def listenUDP(localport, callback, param) export def openUDP(localport, callback, param)
word port word port
byte i byte i
if !localport; return -1; fin // invalid port if !localport; return -1; fin // invalid port
// //
// Allocate the port notify array if needed
//
if !portsUDP
portsUDP = heapalloc(MAX_UDP_NOTIFIES * t_notify)
if !portsUDP; return -1; fin
memset(portsUDP, 0, MAX_UDP_NOTIFIES * t_notify)
fin
//
// Look for an existing notification on localport // Look for an existing notification on localport
// //
port = portsUDP port = @portsUDP
for i = 1 to MAX_UDP_NOTIFIES for i = 1 to MAX_UDP_NOTIFIES
if port=>notify_port == localport if port=>notify_port == localport
port=>notify_func = callback port=>notify_func = callback
port=>notify_parm = param port=>notify_parm = param
return 0 return port
fin fin
port = port + t_notify
next next
// //
// Add notification on localport if room // Add notification on localport if room
// //
port = portsUDP port = @portsUDP
for i = 1 to MAX_UDP_NOTIFIES for i = 1 to MAX_UDP_NOTIFIES
if !port=>notify_port if !port=>notify_port
port=>notify_port = localport port=>notify_port = localport
port=>notify_func = callback port=>notify_func = callback
port=>notify_parm = param port=>notify_parm = param
return 0 return port
fin fin
port = port + t_notify
next next
return -1
end end
// //
// Clear notify on UDP port // Clear notify on UDP port
// //
export def hangupUDP(localport) export def closeUDP(port)
word port word port
byte i byte i
if !localport; return -1; fin // invalid port if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
// //
// Look for an existing notification on localport // Clear notiications on this port
// //
port = portsUDP if port=>notify_port
for i = 1 to MAX_UDP_NOTIFIES port=>notify_port = 0
if port=>notify_port == localport
port=>notify_port = 0
return 0 return 0
fin fin
next fin
//
// Invalid port
//
return -1 return -1
end end
// //
@ -446,12 +441,12 @@ export def serviceIP
// //
when iphdr->ip_proto when iphdr->ip_proto
is IP_PROTO_UDP is IP_PROTO_UDP
port = portsUDP port = @portsUDP
if port if port
lclport = swab(rxptr=>udp_dst) lclport = swab(rxptr=>udp_dst)
for i = 1 to MAX_UDP_NOTIFIES for i = 1 to MAX_UDP_NOTIFIES
if port=>notify_port == lclport) if port=>notify_port == lclport)
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),lclport,rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm) port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm)
break break
fin fin
port = port + t_notify port = port + t_notify
@ -518,5 +513,20 @@ export def setEtherDriver(MAC, getlen, readframe, setlen, writeframe)
setFrameLen = setlen setFrameLen = setlen
writeFrame = writeframe writeFrame = writeframe
end end
//
// Set the local IP addresses
//
export def setInterfaceIP(newIP, newSubnet, newGateway)
if newIP; memcpy(@localip, newIP, IP4ADR_SIZE); fin
if newSubnet; memcpy(@subnet, newSubnet, IP4ADR_SIZE); fin
if newGateway; memcpy(@gateway, newGateway, IP4ADR_SIZE); fin
end
//
// Get the interface hardware address
//
export def getInterfaceHA(ha)
if ha; memcpy(ha, @myMAC, MAC_SIZE); fin
return MAC_SIZE
end
done done

View File

@ -4,32 +4,33 @@ import cmdsys
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID byte MACHID
end end
import uthernet //
byte localip, subnet, gateway // List of loadable network device drivers
predef serviceIP //
end byte netDrivers = "WIZNET"
byte = "UTHERNET"
byte = ""
word driver = @netDrivers
//
// DHCP module to load
//
byte dhcp = "DHCP" byte dhcp = "DHCP"
//
byte serverip = 192,168,123,1 // Look for net hardware
byte staticip = 192,168,123,10 //
byte staticmask = 255,255,255,0 while ^driver
puts(driver);putln
if modexec(@dhcp) < 0 if modexec(driver) >= 0
// break
// Set our local IP address fin
// driver = driver + ^driver + 1
memcpy(@localip, @staticip, 4) loop
memcpy(@subnet, @staticmask, 4) if !^driver
memcpy(@gateway, @serverip, 4) return -1
fin fin
// //
// Service IP // Get an IP address
// //
repeat modexec(@dhcp)
serviceIP
until ^$C000 > 127
^$C010
done done

View File

@ -1,4 +1,6 @@
// //
// Original Uthernet ethernet card based on Cirrus Logic cs9800a
//
// Include dependency on S/W IP stack // Include dependency on S/W IP stack
// //
import etherip import etherip
@ -33,7 +35,7 @@ byte pregdata
// //
// Uthernet MAC address // Uthernet MAC address
// //
byte[6] utherMAC = $00,$0A,$99,$1E,$02,$00 byte[6] utherMAC = $00,$0A,$99,$1E,$02,$A0
// //
// Defines for ASM routines // Defines for ASM routines
// //

View File

@ -9,6 +9,7 @@ ED = ED\#FF2000
SB = SB\#FF2000 SB = SB\#FF2000
ROD = ROD\#FE1000 ROD = ROD\#FE1000
SIEVE = SIEVE\#FE1000 SIEVE = SIEVE\#FE1000
WIZNET = WIZNET\#FE1000
UTHERNET= UTHERNET\#FE1000 UTHERNET= UTHERNET\#FE1000
ETHERIP = ETHERIP\#FE1000 ETHERIP = ETHERIP\#FE1000
INET = INET\#FE1000 INET = INET\#FE1000
@ -45,7 +46,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000 #SYSTYPE = \#FF2000
#TXTTYPE = \#040000 #TXTTYPE = \#040000
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(SB) $(MON) $(ROD) $(SIEVE) $(WIZNET) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1)
clean: clean:
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
@ -122,6 +123,10 @@ $(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/sieve.pla > samplesrc/sieve.a ./$(PLASM) -AM < samplesrc/sieve.pla > samplesrc/sieve.a
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
$(WIZNET): libsrc/wiznet.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/wiznet.pla > libsrc/wiznet.a
acme --setpc 4094 -o $(WIZNET) libsrc/wiznet.a
$(UTHERNET): libsrc/uthernet.pla $(PLVM02) $(PLASM) $(UTHERNET): libsrc/uthernet.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/uthernet.pla > libsrc/uthernet.a ./$(PLASM) -AM < libsrc/uthernet.pla > libsrc/uthernet.a
acme --setpc 4094 -o $(UTHERNET) libsrc/uthernet.a acme --setpc 4094 -o $(UTHERNET) libsrc/uthernet.a

View File

@ -14,7 +14,7 @@ static int locals = 0;
static int predefs = 0; static int predefs = 0;
static int defs = 0; static int defs = 0;
static int asmdefs = 0; static int asmdefs = 0;
static int codetags = 0; static int codetags = 1; // Fix check for break_tag and cont_tag
static int fixups = 0; static int fixups = 0;
static char idconst_name[1024][17]; static char idconst_name[1024][17];
static int idconst_value[1024]; static int idconst_value[1024];

View File

@ -910,6 +910,9 @@ def loadmod(mod)
fixup = 0 fixup = 0
if init if init
fixup = adddef(init - defofst + bytecode, @deflast)() fixup = adddef(init - defofst + bytecode, @deflast)()
if fixup < 0
perr = -fixup
fin
if !(systemflags & modinitkeep) if !(systemflags & modinitkeep)
modend = init - defofst + bytecode modend = init - defofst + bytecode
fin fin
@ -978,7 +981,7 @@ def execmod(modfile)
^lastsym = 0 ^lastsym = 0
systemflags = saveflags systemflags = saveflags
fin fin
return perr return -perr
end end
// //
// Get heap start. // Get heap start.

View File

@ -1075,6 +1075,9 @@ def loadmod(mod)
else else
modend = init - defofst + defaddr modend = init - defofst + defaddr
fin fin
if fixup < 0
perr = -fixup
fin
else else
fixup = fixup & ~modinitkeep fixup = fixup & ~modinitkeep
fin fin
@ -1264,7 +1267,7 @@ def execmod(modfile)
^lastsym = 0 ^lastsym = 0
systemflags = saveflags systemflags = saveflags
fin fin
return perr return -perr
end end
// //
// Get heap start. // Get heap start.

View File

@ -1114,6 +1114,9 @@ def loadmod(mod)
fixup = 0 fixup = 0
if init if init
fixup = adddef(defext, init - defofst + defaddr, @deflast)() fixup = adddef(defext, init - defofst + defaddr, @deflast)()
if fixup < 0
perr = -fixup
fin
fin fin
return fixup return fixup
end end
@ -1262,7 +1265,7 @@ def execmod(modfile)
xpokeb(symtbl.0, lastsym, 0) xpokeb(symtbl.0, lastsym, 0)
systemflags = saveflags systemflags = saveflags
fin fin
return perr return -perr
end end
// //
// Init console. // Init console.