changtimwu / changtimwu.github.com

Tim's testing/practice notes
7 stars 2 forks source link

peridot notes #22

Open changtimwu opened 9 years ago

changtimwu commented 9 years ago
/* RMU Mode: R28.10:8=00 choose P0 for Peridot */
RW U1 P27 R28 H00C0   /* switch global registers, global control 2 */
/* R4.9:8=01(std DSA) Port0*/
RW U1 P0 R4 H017f     /* switch registers, port 0, port control */
changtimwu commented 9 years ago
changtimwu commented 9 years ago
changtimwu commented 9 years ago

first 11 bytes of eeprom -- 9 bytes are easy to understand

changtimwu commented 9 years ago

ram 0x0000 裡面第一行指令一定是 jp 80, 因為前面要放很多東西包括 isr table application 0x80~0xe000

.org  0x0000  ;start of SRAM space - interrupt tables
rst0:
  jp  start   ;

.org  0x0080    ;start of code space - enter code here
start:

the memory layout of first 128 bytes

;====================================================================
;     restart table
;
; The restart table must start at address 0x0000 as this is where the
; rst x commands call to.
;====================================================================
int040:       ;org 0x0040
  call  h_defInt  ;default handler w/caller ID on the stack (i.e., old PC)

This implies

intnmi:       ;org 0x0066
  call  h_defInt  ;default handler w/caller ID on the stack (i.e., old PC)

z80 nmi ISR 固定要放在 0x0066

0x58 ~ 0x63 沒浪費, 放了 Manufacturer modifiable parameters , code 會讀來用?

;       ;org 0x0058
s_smiDevAddr: .db 0x00  ;1 byte SMI Device Addr for s_tbl2switch routine
        ;b7=P, 1=phy 0=switch
        ;  if b7=1: b6=C22, 1=Clause 22, 0=Clause 45
        ;  if b7=1: b5=Ext, 1=external, 0=internal
        ;b4:0=SMI Dev Addr
;
miscInfo: .db 0x01  ;Device Features Control Byte
        ;b7:2=reserved
        ;b1=Enable EEE on AVB ports with reservations
        ;b0=Enable EEE
switchMac0: .dw 0x0050  ;1st two bytes of the switch's MAC address
switchMac2: .dw 0x4300  ;2nd two bytes of the switch's MAC address
switchMac4: .dw 0x0003  ;3rd two bytes of the switch's MAC address
stpPorts: .dw 0xF7FF  ;b15:12 - CLI enabled on port(s), 0xF=disabled, 0xE=all ports
        ;b11 - reserved 
        ;b10:0 - bit vector of active switch ports for STP
ptpPorts: .dw 0xFFFF  ;b15:12 - forced Slave Port if <> 0xF
        ;b11 - 1=Grand Master capable
        ;b10:0 - bit vector of active switch ports for PTP
srpPorts: .dw 0x07FF  ;b15:11 - reserved
        ;b10:0 - bit vector of active switch ports for SRP

0x67 ~ 0x7f 沒用, 未來可以放

changtimwu commented 9 years ago

CPU interrupt mode 都是用 mode 2, 用 im 2 指令達成.

I/O registers related to interrupts: 0x07 -- interrupt source 0x08~0x0e -- act registers, interrupt vector table 固定在這

NMI 就是不能mask掉, 連 DI(disable interrupt)指令也不能關掉

changtimwu commented 9 years ago

In mode 2, ISR 可以在 ram 內的任何 address, I REG 決定 high byte, act register 決定

meaning of ack register 0 -- disable this interrupt 1 -- it's NMI and ISR is fixed at <I REG>0066 2~0xff -- low byte of ISR entry point. This also defines priority. The lower address the higher priority.

two level interrupts: When serving a interrupt( running inside of an ISR), all other INTs are masked(不會觸發) out except NMI. NMI 永遠不會被遮罩.

所有 ISRs 的 code 不能超過 256 byte( in the same page)? No, the page which <I REG> assigns would be just a JUMP table. or (Branch table)

;====================================================================
;     Z80 mode 2 interrupt table
;
; Z80 Mode 2 interrupts support a jump table that can be anywhere as long as the
; entire table is in the same page (i.e., the upper 8 addr bits are the same).
; This table is placed here so the previously listed restarts can be used for
; code size optimization (if needed).  For this to work the interrupt
; controller needs to put the Z80 into Mode 2 & configure the I-Reg
; & interrupt controller to point to these addresses (it is the job of each
; interrupt from the controller to supply the lower 8 addr bits).
;
; input:  nothing
; output: Top of Stack=value indicating the interrupt # (these are calls)
; effect: nothing destroyed 
; note:   before the interrupt service routine returns it must 
;   pop all the saved registers off the stack (like this extra call)
; 0x0066 - 0x0069 Z80 NMI branch table
; 0x0058 - 0x0065 Manufacturer modifiable parameter table from EEPROM
; 0x0040 - 0x0057 Z80 Mode 2 Interrupt branch table
;     Use this to support all 8 interrupts w/separate vectors
;
changtimwu commented 9 years ago

http://z80-heaven.wikidot.com/interrupts

main:
 bcall(_ClrLCDFull)  ; 清除螢幕
; disable interrupts while we're install ours
 di
; set up the interrupt jump table to jump to $9A9A
 ld a,$9A  ;  把 0x9a 填滿整個 mem 0x99xx
 ld ($9900),a 
 ld hl,$9900
 ld de,$9901
 ld bc,256
 ldir
; copy our interrupt to $9A9A  ; ISR copy 到 9a9a
 ld hl,interruptStart
 ld de,$9A9A
 ld bc,interruptEnd - interruptStart
 ldir
; set $99 into I  ;  日後 isr routine entry 都是 0x99xx
 ld a,$99
 ld I,a
; set interrupt mode 2
 im 2
loop:
; re-enable interrupts
 ei
; rest of our program ; 一直印 counter 看看timer interrupt  是不是真的固定把它累加.
 ld hl,0
 ld (curRow),hl
 ld hl,(counter)
 bcall(_DispHl)
 jr loop

interruptStart:
; disable interrupts during our interrupt
 di
; swap registers
 ex AF,AF'
 exx
; our interrupt code
 ld hl,(counter)
 inc hl
 ld (counter),hl

; swap back registers
 ex AF,AF'
 exx
; re-enable interrupts and return
 ei
 ret
interruptEnd:

counter:
.dw 0

ISR 最後一行要下 ei !!

changtimwu commented 9 years ago

RST 稱之為 Restart, sometimes are referred as software interrupt, 前面 0x00~0x3f 放的是 restart table, 一個 rst 指令就可以進去, 跟call指令的差別在, rst 只需要 1 byte,適合拿來放frequently called routines.

changtimwu commented 9 years ago

trace the ethernet command of impMonMain.s

changtimwu commented 9 years ago

to save memory the monitor program use table to store reg read/writes. How much can this save when comparing with directly read write with instruction?

halInitTbl:     ;halInit switch configuration
;       ;Enable below commands for debugging
; .db setDisout   ;enable debug messages
; .db 0x00      ;with this zero byte

;       ;Do Global 2 work
  .db smiDevOp+G2   ;modify Global 2

;       ;Set GPIO 12 to be output
  .db regWtOp+0x1A    ;modify Global 2 offset 0x1A
  .dw 0xE3EF      ;sets GPIO 12 to output
; the above equals to WriteReg( 0x1c, 0x1a, 0xe3ef)

;       ;Set features (only works on unprogrammed parts)
  .db regWtOp+0x1A    ;modify Global 2 offset 0x1A
  .dw 0xF940      ;override the automotive mode
;the above equals to WriteReg( 0x1c, 0x1a, 0xf940)

;       ;and set PHYs Auto-neg (only needed on unprogrammed parts)
  .db mulWtOp+v8    ;multiple dev write
  .db v7to1     ;on ports 8 to 1
  .db phyOp+c22int+0x00 ;to internal C22 PHYs offset 0x00
  .dw 0x9100      ;reset the PHY w/Auto-neg enabled
; the above equals to 
;  for (i=1;i<=8;i++)
;    WritePhy( i, 0, 0x9100);

;       ;Turn on the LEDs (they are off while fast booting)
  .db smiDevOp+p0   ;modify Port 0
  .db regWtOp+0x16    ;offset 0x16
  .dw 0x8000      ;turn on the LEDs
;the above equals to WriteReg( 0x00, 0x16, 0x8000);

  .db stop      ;end of this command list
; 
;
c_ePairTbl:
;       ;Enable below commands for debugging
; .db setDisout   ;enable debug messages
; .db 0x00      ;with this zero byte

;Turn off learning on Ports 0 to 9
  .db mulWtOp+v8+v9   ;write to multiple ports  
  .db v7to0     ;ports 0 to 9
  .db swOp+0x0B   ;write to Switch Port offset 0x0B   ;
  .dw 0x0000      ;value to turn off learning
; equals to
;  for (i=0;i<=9;i++){
;    WriteReg( i, 0x0b, 0x0000);
; } 

;       ;Configure Ports 0 to 9 to trap SA Misses
  .db mulWtOp+v8+v9   ;write to multiple ports
  .db v7to0     ;ports 0 to 9
  .db swOp+0x0D   ;write to Switch Port offset 0x0D
  .dw 0x0040      ;value to trap SA Misses
; equals to
;  for (i=0;i<=9;i++){
;    WriteReg( i, 0x0d, 0x0040);
; } 

;       ;Configure IMP port for Header+ETDSA+Forwarding
  .db smiDevOp+IMP    ;configure the IMP's port
  .db regWtOp+0x04    ;write to Port offset 0x04
  .dw 0x0B7F      ;value for Header+ETDSA+Forwarding
; this equals to WriteReg( 0x1e, 0x04, 0x0b7f)

;       ;Configure CPUDest ==> IMP port
  .db smiDevOp+G1   ;modify Global 1
  .db regWtOp+0x1A    ;offset 0x1A
  .dw 0xB0FE      ;value to point CPUDest to port 0x1E (the IMP)
; this equals to WriteReg( 0x1b, 0x1a, 0xb0fe)

  .db stop      ;end of the table
changtimwu commented 9 years ago

device table

p0  = 0x00  ;SMI Dev vector for Port 0
p1  = 0x01  ;SMI Dev vector for Port 1
p2  = 0x02  ;SMI Dev vector for Port 2
p3  = 0x03  ;SMI Dev vector for Port 3
p4  = 0x04  ;SMI Dev vector for Port 4
p5  = 0x05  ;SMI Dev vector for Port 5
p6  = 0x06  ;SMI Dev vector for Port 6
p7  = 0x07  ;SMI Dev vector for Port 7
p8  = 0x08  ;SMI Dev vector for Port 8
p9  = 0x09  ;SMI Dev vector for Port 9
p10 = 0x0A  ;SMI Dev vector for Port 10
p11 = 0x0B  ;SMI Dev vector for Port 11
G1  = 0x1B  ;SMI Dev for Global 1
G2  = 0x1C  ;SMI Dev for Global 2
IMP = 0x1E  ;SMI Dev for Z80 CPU
tcam  = 0x1F  ;SMI Dev for the TCAM
setPhyMd =  0x01  ;Set PHY Access mode opcode
setDisout = 0x02  ;Set c_disout mode opcode
setSingStep = 0x03  ;Set single step mode opcode
smiDevOp =  0x20  ;Set SMI Dev Addr opcode
c45WtAddr = 0x40  ;Set Clause 45 register address
regWtOp = 0x60  ;Register Write opcode
mulWtOp = 0x80  ;Multiple Device Write opcode
phyOp = 0x80  ;indicates operation is to a PHY reg
rmwOp = 0xC0  ;Read Modify Write opcode
waitOp  = 0xE0  ;Wait on Bit opcode
swOp  = 0x40  ;indicates operation is to a Switch reg
;
c22int  = 0x40  ;PHY access mode value for Clause 22 Internal access
c22ext  = 0x60  ;PHY access mode value for Clause 22 Internal access
c45int  = 0x00  ;PHY access mode value for Clause 45 Internal access
c45ext  = 0x20  ;PHY access mode value for Clause 45 Internal access
;
changtimwu commented 9 years ago

The internal PHY and SERDES registers are only accessible via the SMI PHY command and Data registers(Global 2, offset 0x18 & 0x19) using SMIFunc set for Internal Access mode. The internal Port 1 to Port 8 PHYs are mapped at SMI device address 0x01 to 0x08 respectively. The internal SERDES on Ports 9 and Port 10 are mapped at SMI device addreses 0x09 and 0x0a respectively.

changtimwu commented 9 years ago

Table 136, Index: 0x30 of Monitor & MGMT Control _Many modes of frame processing need to know where the CPU is located. Theses modes are

  1. When IGMP/MLD frame is received and Snooping is enabled on the port(Port offset 0x04)
  2. When this port is configured as a DSA Port and it receives a TO_CPU frame
  3. When a Rsvd2CPU frames enters the port (Global 2 offset 0x05)
  4. When the port's SA Filtering mode is Drop to CPU(Port offset 0x04)
  5. When any of the port's Policy Options(Port offset 0x0e) trap the frame to the CPU
  6. When the ingressing frame is a ARP and ARP mirroring is enabled on the port (Port offset 0x08)
  7. When any of the port's Miss Traps occur that are enabled(Port offset 0x0D) In all cases, except for ARP, the frames that meet the enabled criteria are mapped to the port defined by this register only, overriding where the frame would normally go._
changtimwu commented 9 years ago

page 39, Table 24: Port Control Register, Offset 0x04 Field SA Filtering Description(key field for 802.1x) Source Address Filtering controls These bits select the SA filtering method to be used on the port 0x03 = Drop to CPU.
Ingressing frames will be mapped to the CPUDest(Global offset 0x1a) if their SA field is in the ATU's address database as a Static entry with a port vector of all zeros and the frame is not otherwise filtered. Otherwise, the frames will be discarded if their SA field is not in the ATU's address database(i.e., it's a new or unknown source address).

This mode is a form of MAC based 802.1X where some frames can be forced to the CPU for further authentication prior to full authorization.

changtimwu commented 9 years ago

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF257897

changtimwu commented 9 years ago

page 58 Port E Type offset 0x0f 2015-09-09 10 02 50

page 29 Port control offset 0x04 2015-09-08 4 15 40 2015-09-08 4 15 29

2015-09-08 4 17 51

G2(0x1b) offset 0x1c , page 134 2015-09-08 3 51 27

changtimwu commented 9 years ago

G1(0x1b) offset 0x1a, index 0x30, page 131

the value 0xb0fe

2015-09-08 4 39 14

changtimwu commented 9 years ago

The extra data placed in the frame is needed to support the Spanning Tree Protocol(STP) as well as cross-chip features like LAGs, Mirrors. etc. Ports that are interconnected together to form a larger switch ports connected to the management CPU must use this mode.

所以 STD DSA mode 是指, 只有control packet才會塞DSA?

changtimwu commented 9 years ago

https://github.com/contiki-os/contiki/blob/master/doc/pt-doc.txt A protothread runs within a single C function and cannot span over other functions.

even though having such a limitation, contiki still intensively use protothread in his net implementation ex. https://github.com/contiki-os/contiki/blob/master/core/net/http-socket/http-socket.c

it also demonstrate how to use multiple pt when thread has deep calls.e

sdcc seems implement setjmp/longjmp for z80. out a lot coroutine implementations out there
http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/489 http://fanf.livejournal.com/105413.html

changtimwu commented 9 years ago

https://github.com/adamdunkels/uip uip 1.0 has integrated tuntap.