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

View File

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

View File

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

View File

@ -1,4 +1,6 @@
//
// Original Uthernet ethernet card based on Cirrus Logic cs9800a
//
// Include dependency on S/W IP stack
//
import etherip
@ -33,7 +35,7 @@ byte pregdata
//
// 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
//

View File

@ -9,6 +9,7 @@ ED = ED\#FF2000
SB = SB\#FF2000
ROD = ROD\#FE1000
SIEVE = SIEVE\#FE1000
WIZNET = WIZNET\#FE1000
UTHERNET= UTHERNET\#FE1000
ETHERIP = ETHERIP\#FE1000
INET = INET\#FE1000
@ -45,7 +46,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#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:
-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
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)
./$(PLASM) -AM < libsrc/uthernet.pla > 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 defs = 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 char idconst_name[1024][17];
static int idconst_value[1024];

View File

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

View File

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

View File

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