proc do { cmd } { global ser set ser [open "com1:" {RDWR}] fconfigure $ser -mode 9600,n,8,1 fconfigure $ser -blocking 0 -translation binary -buffersize 1024 puts -nonewline $ser "\r$cmd\r" flush $ser set s "" set t [clock clicks] incr t 1000 while { [clock clicks]<$t } { append s [read $ser] if { [regexp ">$cmd\r(.*)>" $s tout r] } { break } } close $ser string trim $r } proc @ { address args } { if { [llength $args] } { set data [lindex $args 0] set r [do [format "m 0x%08lx 0x%08lx" $address $data]] } { set r [do [format "m 0x%08lx" $address]] regexp {=(.*)$} $r tout data } return $data } proc pci { b d f o {data {}}} { set r [do "p $b $d $f $o $data"] regexp {=(.*)$} $r tout data set data } proc cacheFlush {} { do cacheFlush } proc cacheInvalidate {} { do cacheInvalidate } set eepromErase 0x7000000 set eepromEral 0x4800000 set eepromEwds 0x4000000 set eepromEwen 0x4c00000 set eepromRead 0x6000000 set eepromWrite 0x5000000 set eepromWral 0x4400000 set cmd 0x6000000 set data 0 set address 0 set len 27 proc eepromCmd { cmd {len 11} {address 0} {data 0}} { global base set eectrl $base incr eectrl 0x0c set other [@ $eectrl] set other [expr $other & ~0xffff0000] incr cmd [expr ($address<<16)|$data] set data 0 set bit 27 while { $len } { incr len -1 incr bit -1 # cs set reg [expr $other | 0xa0000] # and data in accordingly if { $cmd&(1<<$bit) } { incr reg 0x40000 } set reg [@ $eectrl $reg] # do clock incr reg 0x10000 set reg [@ $eectrl $reg] # undo clock incr reg -0x10000 set reg [@ $eectrl $reg] set reg [@ $eectrl] #read data out if { $reg&0x80000 } { incr data [expr 1<<$bit] } } set reg [expr $other] @ [expr $base+0x0c] $reg return $data } proc mdi { regAddr {args {}}} { global base global phyAddr set mdiReg $base incr mdiReg 0x10 if { [llength $args] } { set data [lindex $args 0] set cmd [expr (1<<26)|($phyAddr<<21)|($regAddr<<16)|$data] } { set cmd [expr (2<<26)|($phyAddr<<21)|($regAddr<<16)] } @ $mdiReg $cmd set t [clock clicks] incr t 2000 while { [clock clicks]<$t } { set r [@ $mdiReg] if { $r&(1<<28) } break } expr $r&0xffff } set base 0xe0000000 return pci 0 11 0 0x00 pci 0 11 0 0x10 $base pci 0 11 0 0x04 0x00000006 set phyAddr 0 mdi 0 0x400 set phyAddr 1 mdi 0 0x2100 mdi 0 0x0400 return do "pd 0" set phyAddr 1 set phyAddr 0 set phyAddr 0 mdi 0 0x400 set phyAddr 1 mdi 0 0x1000 mdi 0 0x1200 mdi 0 0x2100 mdi 1 mdi 1 @ [expr $base+0x1c] eepromCmd $eepromRead 27 0 eepromCmd $eepromRead 27 1 eepromCmd $eepromRead 27 2 eepromCmd $eepromRead 27 0x10 eepromCmd $eepromWrite 27 0 0xaabb eepromCmd $eepromEwen 11 eepromCmd $eepromEral 11 eepromCmd $eepromWrite 27 0x00 0xaa00 eepromCmd $eepromWrite 27 0x01 0x0000 eepromCmd $eepromWrite 27 0x02 0x0000 eepromCmd $eepromWrite 27 0x10 0x4080 set ias 0x190000 @ [expr $ias+0x00] 0xc0010000 @ [expr $ias+0x04] 0x00000000 @ [expr $ias+0x08] 0x0000aa00 @ [expr $ias+0x0c] 0x00000000 cacheFlush @ [expr $base+4] $ias set cuc 1 set ruc 0 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ $base @ $base [expr (1<<24)|($cuc<<13)] @ $base set config 0x190000 @ [expr $config+0x00] 0xc0020000 @ [expr $config+0x04] 0x00000000 @ [expr $config+0x08] 0x00008816 @ [expr $config+0x0c] 0x01300000 ; #0x03300000 !broadcast @ [expr $config+0x10] 0x002e0001 @ [expr $config+0x14] 0x48f20060 @ [expr $config+0x18] 0x00f24000 @ [expr $config+0x1c] 0x00000d3f cacheFlush @ [expr $base+4] $config set cuc 1 set ruc 0 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ $base @ $base [expr (1<<24)|($cuc<<13)] @ $base set rfd [@ [expr $base+4]] set rfd 0x180000 @ [expr $rfd+0x000] 0x00000000 @ [expr $rfd+0x004] [expr $rfd+0x800] @ [expr $rfd+0x008] 0xffffffff @ [expr $rfd+0x00c] [expr 256<<16] @ [expr $rfd+0x800] 0x00000000 @ [expr $rfd+0x804] $rfd @ [expr $rfd+0x808] 0xffffffff @ [expr $rfd+0x80c] [expr 256<<16] cacheFlush @ [expr $base+4] $rfd set cuc 0 set ruc 1 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ $base @ $base [expr (1<<24)|(1<<4)] set cuc 0 set ruc 4 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ $base [expr (1<<24)|0xffff] @ $base @ [expr $base+4] 0 set cuc 0 set ruc 6 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ [expr $base+4] 0 set cuc 6 set ruc 0 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] set rfd [@ [expr $base+4]] @ [expr $rfd+0x0] @ [expr $rfd+0x4] @ [expr $rfd+0x8] @ [expr $rfd+0xc] set rfd 0x0018be48 set base [@ 0x00188000] proc getTrame { rfd } { set status [@ $rfd] if { ($status&0xa000)==0xa000 } { set len [expr [@ [expr $rfd+0xc]]&0x3fff] } { set len 0 } set ints [list] set address $rfd incr address 0x10 set cnt [expr ($len+3)>>2] while { $cnt } { lappend ints [@ $address] incr address 4 incr cnt -1 } binary format a[set len] [binary format i* $ints] } set trame [getTrame $rfd] set trame [getTrame [expr $rfd+0x800]] string length $trame dump 0 $trame proc handleTrame { trame } { binary scan $trame c6c6S1 dst src type set src set dst set type if { $type==0x806 } { binary scan $trame @14S1S1 dst src type } } set ints [list] for { set offset 0; set address [expr $rfd+0x000] } { $offset<64 } { incr address 4; incr offset 4 } { lappend ints [expr [@ $address]] } set trame [binary format i* $ints] dump 0 $trame for { set offset 0; set address [expr $rfd+0x800] } { $offset<64 } { incr address 4; incr offset 4 } { @ $address 0 } @ [expr $rfd+0x10] 0 @ [expr $rfd+0x14] 0 @ [expr $rfd+0x18] 0 @ [expr $rfd+0x1c] 0 @ [expr $rfd+0x810] 0 @ [expr $rfd+0x814] 0 @ [expr $rfd+0x818] 0 @ [expr $rfd+0x81c] 0 proc ipAddress { ip } { set v 0 foreach b [split $ip .] { set v [expr ($v<<8)|$b] } set v } ipAddress 90.0.0.3 set data "une chaine de caractere" set id 12345 set frag 0 set ttl 128 set prot 0x11 set ipchksum 0 set ipsrc [ipAddress 90.0.0.30] set ipdst [ipAddress 90.0.0.31] set portsrc 60000 set portdst 80 set udpchksum 0 set trame [binary format H12H12S1c1c1S1S1S1c1c1S1I1I1S1S1S1S1a* "00c0a87c3cec" "00aa00000000" 0x0800 0x45 0x00 \ [expr [string length $data]+28] $id $frag $ttl $prot $ipchksum \ $ipsrc $ipdst $portsrc $portdst [expr [string length $data]+8] $udpchksum \ $data] set ipchksum 0 binary scan $trame @14S10 words foreach word $words { incr ipchksum $word } set ipchksum [expr 0xfffe-$ipchksum] set trame [binary format a*@24S1 $trame $ipchksum] dump 0 $trame set tcb 0x00188820 set tcb 0x00190000 @ [expr $tcb+0x0] 0xc0040000 @ [expr $tcb+0x4] 0x00000000 @ [expr $tcb+0x8] 0xffffffff @ [expr $tcb+0xc] [expr (1<<16)|(1<<15)|[string length $trame]] binary scan [set trame]\0\0\0 i* ints set address $tcb incr address 0x10 foreach int $ints { @ $address $int incr address 4 } @ [expr $tcb+0x0] 0xc0040000 @ [expr $base+4] $tcb set cuc 1 set ruc 0 @ $base [expr (1<<24)|($cuc<<20)|($ruc<<16)] @ $base 00b0048000000000ffffffff2c800100 \ set trame [binary format H*H*H* \ 00c0a87c3cec0030590163d10800 \ 4500002c24520000801162325a00001e5a00001f \ 005009a700180000 \ 74686965727279206c61726d6f697265 \ ] set mac 00-30-59-01-63-d1 exec arp -s "90.0.0.30" $mac exec arp -a set sock [socket 90.0.0.31 80] puts $sock "GET / HTTP/1.1" close $sock