openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

tuc24_ref.asm (10077B)


      1 ;
      2 ;
      3 ;
      4 ; This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5 ; 
      6 ; Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7 ; 
      8 ;
      9 ; This is the default program for the 5650 reference board (BCM95650R24)
     10 ;
     11 ; To start it, use the following commands from BCM:
     12 ;
     13 ;	0:led load tuc24_ref.hex
     14 ;	*:led start
     15 ;
     16 ;
     17 ; The BCM5650 reference board has 12 columns of 4 LEDs each, as shown below:
     18 ;
     19 ;       L02 L04 L06 L08 L10 L12 L14 L16 L18 L20 L22 L24
     20 ;       A02 A04 A06 A08 A10 A12 A14 A16 A18 A20 A22 A24
     21 ;       L01 L03 L05 L07 L09 L11 L13 L15 L17 L19 L21 L23
     22 ;       A01 A03 A05 A07 A09 A11 A13 A15 A17 A19 A21 A23
     23 ;
     24 ; For the FE ports, there are two bits per LED with the following colors:
     25 ;	ZERO, ZERO	Black
     26 ;	ZERO, ONE	Amber
     27 ;	ONE, ZERO	Green
     28 ;
     29 ; Also, there are 4 LEDs for the GE ports, as shown below:       
     30 ;       LG2 AG2   LG4 AG4
     31 ;       LG1 AG1   LG3 AG3
     32 ;
     33 ; For the GE ports, there is one bit per LED with the following colors:
     34 ;	ZERO		Green
     35 ;	ONE		Black
     36 ;
     37 ; The bits are shifted out in the following order:
     38 ;	A02, L02, A01, L01,..., A24, L24, A23, L23, LG1, AG1, ..., LG4, AG4
     39 ;
     40 ; Current implementation:
     41 ;
     42 ; L01 reflects port 1 link status
     43 ; A01 reflects port 1 activity
     44 ;
     45 ; Link up/down info cannot be derived from LINKEN or LINKUP, as the LED
     46 ; processor does not actually have access to link status.  This program
     47 ; assumes link status is kept current in bit 0 of RAM byte (0x80 + portnum).
     48 ; Generally, a program running on the main CPU must update these
     49 ; locations on link change; see linkscan callback in
     50 ; $SDK/src/appl/diag/ledproc.c.
     51 ;
     52 ; Current implementation:
     53 ;
     54 ; L01 reflects port 1 link status:
     55 ;	Black: no link
     56 ;	Amber: 10 Mb/s
     57 ;	Green: 100 Mb/s
     58 ;	Alternating green/amber: 1000 Mb/s
     59 ;	Very brief flashes of black at 1 Hz: half duplex
     60 ;	Longer periods of black: collisions in progress
     61 ;
     62 ; A01 reflects port 1 activity (even if port is down)
     63 ;	Black: idle
     64 ;	Green: RX (pulse extended to 1/3 sec)
     65 ;	Amber: TX (pulse extended to 1/3 sec, takes precedence over RX)
     66 ;	Green/Amber alternating at 6 Hz: both RX and TX
     67 ;
     68 ;
     69 ; Due to the different treatment and output ordering of the two types of
     70 ; ports, there are a number of complex transformations performed on the
     71 ; data.  In addition, the limited program space of the LED processor
     72 ; necessitates some optimizations for code length that make the following
     73 ; assembly somewhat unclear.  Comments have been added to clarify some of
     74 ; steps below.
     75 ;
     76 
     77 MIN_FE_PORT	EQU	0
     78 MAX_FE_PORT	EQU	23
     79 NUM_FE_PORT	EQU	24
     80 
     81 MIN_GE_PORT	EQU	24
     82 MAX_GE_PORT	EQU	27
     83 NUM_GE_PORT	EQU	4
     84 
     85 MIN_PORT	EQU	0
     86 MAX_PORT	EQU	27
     87 NUM_PORT	EQU	28
     88 
     89 PACK_SRC        EQU     0
     90 PACK_DST        EQU     128
     91 PACK_BITS       EQU     ((NUM_FE_PORT*4) + (NUM_GE_PORT*2))
     92 PACK_FE_NUM     EQU     (NUM_FE_PORT/2)
     93 PACK_NUM        EQU     (PACK_BITS/8)
     94 
     95 ; Instead of an enumeration, these values are the concatenation of the
     96 ; ONE/ZERO definitions at the bottom of the file.  This allows the
     97 ; "uncache" routine below to be more efficient.
     98         
     99 CACHE_BLACK     EQU     0xff
    100 CACHE_AMBER     EQU     0xfe
    101 CACHE_GREEN     EQU     0xef
    102         
    103 TICKS		EQU	1
    104 SECOND_TICKS	EQU	(30*TICKS)
    105 
    106 ; The TX/RX activity lights will be extended for ACT_EXT_TICKS
    107 ; so they will be more visible.
    108 
    109 ACT_EXT_TICKS	EQU	(SECOND_TICKS/3)
    110 HD_OFF_TICKS	EQU	(SECOND_TICKS/20)
    111 HD_ON_TICKS	EQU	(SECOND_TICKS-HD_ON_TICKS)
    112 TXRX_ALT_TICKS	EQU	(SECOND_TICKS/6)
    113 
    114 ;
    115 ; Main Update Routine
    116 ;
    117 ;  This routine is called once per tick.
    118 ;
    119 
    120 update:
    121 	sub	a,a		; ld a,MIN_FE_PORT (but only one instr)
    122 
    123 up1:
    124 	port	a
    125 	ld	(PORT_NUM),a
    126 
    127         cmp     a,MIN_GE_PORT
    128         jc      up_fe
    129         
    130 	call	link_status_ge	; First LED for this port
    131 	call	activity_ge	; Second LED for this port
    132 
    133         jmp     next_port
    134         
    135 up_fe:          
    136 	call	activity	; Lower LED for this port
    137 	call	link_status	; Upper LED for this port
    138 
    139         ; Copy from cache to pack location
    140         ld      a,(ACT_CACHE)
    141         call    uncache
    142         ld      a,(LINK_CACHE)
    143         call    uncache
    144         
    145 next_port:     
    146 	ld	a,(PORT_NUM)
    147 	inc	a
    148 	cmp	a,NUM_PORT
    149 	jnz	up1
    150 
    151 	; Update various timers
    152 
    153 	ld	b,HD_COUNT
    154 	inc	(b)
    155 	ld	a,(b)
    156 	cmp	a,HD_ON_TICKS+HD_OFF_TICKS
    157 	jc	up3
    158 	ld	(b),0
    159 up3:
    160 
    161 	ld	b,TXRX_ALT_COUNT
    162 	inc	(b)
    163 	ld	a,(b)
    164 	cmp	a,TXRX_ALT_TICKS
    165 	jc	up4
    166 	ld	(b),0
    167 up4:
    168 ;
    169 ; This bit is a workaround for a bug in the 5665 LED processor.
    170 ; 
    171 ; The pack instruction should put the data into data mem at 0x80.
    172 ; However, the internal register to store this address is only 7 bits.
    173 ; So the data is packed starting at address 0.
    174 ; This leads to two caveats:    
    175 ; 
    176 ; 1) Port 0 data _MUST_ be consumed before the first pack instruction.
    177 ; 
    178 ; 2) The output data must be moved from location 0 to location 128.
    179 ; 
    180 ; 
    181     
    182                 
    183         sub     b,b             ; ld b,PACK_SRC (but only one instr)
    184 
    185 packflip:       
    186         ld      a,(b)
    187         ror     a
    188         ror     a
    189         ror     a
    190         ror     a
    191         and     a,0xf
    192         ld      (PACKFLIP_CACHE),a
    193         ld      a,(b)
    194         rol     a
    195         rol     a
    196         rol     a
    197         rol     a
    198         and     a,0xf0
    199         or      a,(PACKFLIP_CACHE)
    200         ld      (b),a
    201           
    202         inc     b      
    203         cmp     b,PACK_FE_NUM
    204         jnz     packflip
    205         
    206         sub     b,b             ; ld b,PACK_SRC (but only one instr)
    207         ld      a,PACK_DST
    208 packmove:
    209         ld      (a),(b)
    210         inc     a
    211         inc     b
    212         cmp     b,PACK_NUM
    213         jnz     packmove
    214 
    215         send    PACK_BITS
    216 
    217 ;
    218 ; activity
    219 ;
    220 ;  This routine calculates the activity LED for the current port.
    221 ;  It extends the activity lights using timers (new activity overrides
    222 ;  and resets the timers).
    223 ;
    224 ;  Inputs: (PORT_NUM)
    225 ;  Outputs: Two bits sent to LED stream
    226 ;
    227 
    228 activity:
    229 	pushst	RX
    230 	pop
    231 	jnc	act1
    232 
    233 	ld	b,RX_TIMERS	; Start RX LED extension timer
    234 	add	b,(PORT_NUM)
    235 	ld	a,ACT_EXT_TICKS
    236 	ld	(b),a
    237 
    238 act1:
    239 	pushst	TX
    240 	pop
    241 	jnc	act2
    242 
    243 	ld	b,TX_TIMERS	; Start TX LED extension timer
    244 	add	b,(PORT_NUM)
    245 	ld	a,ACT_EXT_TICKS
    246 	ld	(b),a
    247 
    248 act2:
    249 	ld	b,TX_TIMERS	; Check TX LED extension timer
    250 	add	b,(PORT_NUM)
    251 
    252 	dec	(b)
    253 	jnc	act3		; TX active?
    254 	inc	(b)
    255 
    256 	ld	b,RX_TIMERS	; Check RX LED extension timer
    257 	add	b,(PORT_NUM)
    258 
    259 	dec	(b)		; Extend LED green if only RX active
    260         ld      a,ACT_CACHE
    261 	jnc	led_green
    262 	inc	(b)
    263 
    264 	jmp	led_black	; No activity
    265 
    266 act3:				; TX is active, see if RX also active
    267 	ld	b,RX_TIMERS
    268 	add	b,(PORT_NUM)
    269 
    270 	dec	(b)		; RX also active?
    271 	jnc	act4
    272 	inc	(b)
    273 
    274         ld      a,ACT_CACHE
    275 	jmp	led_amber	; Only TX active
    276 
    277 act4:				; Both TX and RX active
    278 	ld	b,(TXRX_ALT_COUNT)
    279 	cmp	b,TXRX_ALT_TICKS/2
    280         ld      a,ACT_CACHE
    281 	jc	led_amber	; Fast alternation of green/amber
    282 	jmp	led_green
    283 
    284 ;
    285 ; link_status
    286 ;
    287 ;  This routine calculates the link status LED for the current port.
    288 ;
    289 ;  Inputs: (PORT_NUM)
    290 ;  Outputs: Two bits sent to LED stream
    291 ;  Destroys: a, b
    292 ;
    293 
    294 link_status:
    295 	pushst	DUPLEX		; Skip blink code if full duplex
    296 	pop
    297 	jc	ls1
    298 
    299 	ld	a,(HD_COUNT)	; Provide blink for half duplex
    300 	cmp	a,HD_OFF_TICKS
    301         ld      a,LINK_CACHE    ; Cache address for led setting
    302 	jc	led_black
    303 
    304 ls1:
    305 	ld	a,(PORT_NUM)	; Check for link down
    306 	call	get_link
    307         ld      a,LINK_CACHE    ; Cache address for led setting
    308 	jnc	led_black
    309 
    310 	pushst	COLL		; Check for collision
    311 	pop
    312 	jc	led_black
    313 
    314 	pushst	SPEED_C		; Check for 100Mb speed
    315 	pop
    316 	jc	led_green       
    317 
    318 	pushst	SPEED_M		; Check for 10Mb (i.e. not 100 or 1000)
    319 	pop
    320 	jnc	led_amber
    321 
    322 
    323 ;
    324 ; get_link
    325 ;
    326 ;  This routine finds the link status LED for a port.
    327 ;  Link info is in bit 0 of the byte read from PORTDATA[port]
    328 ;
    329 ;  Inputs: Port number in a
    330 ;  Outputs: Carry flag set if link is up, clear if link is down.
    331 ;  Destroys: a, b
    332 ;
    333 
    334 get_link:
    335 	ld	b,PORTDATA
    336 	add	b,a
    337 	ld	b,(b)
    338 	tst	b,0
    339 	ret
    340 
    341 ;
    342 ; led_black, led_amber, led_green
    343 ;
    344 ;  Inputs: Cache address in a
    345 ;  Outputs: byte encoding two bits for color
    346 ;  Destroys: None
    347 ;
    348 
    349 led_black:
    350         ld (a),CACHE_BLACK
    351 	ret
    352 
    353 led_amber:
    354         ld (a),CACHE_AMBER
    355 	ret
    356 
    357 led_green:
    358         ld (a),CACHE_GREEN
    359 	ret
    360 
    361 
    362 
    363 ; uncache
    364 ;
    365 ; Inputs: LED bit pair byte-encoded in a
    366 ; Outputs: Two bits to the LED stream indicating color
    367 ; Destroys: None
    368 ;
    369 
    370 uncache:
    371         pushst  a
    372         pack
    373         ror     a
    374         ror     a
    375         ror     a
    376         ror     a
    377         pushst  a
    378         pack
    379         ret
    380 
    381 
    382 ; GE routines
    383 ;
    384 ; Inputs: LED bit pair in a
    385 ; Outputs: Two bits to the LED stream indicating color
    386 ; Destroys: None
    387 ;
    388 
    389 ; It is now safe to pack here, since the GE ports are beyond the pack area.
    390 
    391 
    392 activity_ge:
    393         ld      a,ZERO          ; On (ZERO)
    394         pushst  RX
    395         pop
    396         jc      act_led_set
    397 
    398         pushst  TX
    399         pop
    400         jc      act_led_set
    401 
    402         inc     a               ; On (ZERO) -> Off (ONE)
    403 
    404 act_led_set:
    405         pushst  a
    406         pack
    407         ret
    408 
    409 link_status_ge:
    410 
    411 	ld	a,(PORT_NUM)	; Check for link down
    412 	ld	b,PORTDATA
    413 	add	b,a
    414 	ld	b,(b)
    415 	tst	b,0
    416 
    417         ld      a,ONE           ; Off (ONE)
    418         jnc     ls_led_clear
    419 
    420         dec     a               ; Off (ONE) -> On (ZERO)
    421 
    422 ls_led_clear:
    423         pushst  a
    424         pack
    425         ret
    426 
    427 
    428 ; Variables (SDK software initializes LED memory from 0x80-0xff to 0)
    429 ;
    430 
    431 TXRX_ALT_COUNT	equ	0xff
    432 HD_COUNT	equ	0xfe
    433 
    434 PORT_NUM	equ	0xfc
    435 LINK_CACHE      equ     0xfb
    436 ACT_CACHE       equ     0xfa
    437 PACKFLIP_CACHE  equ     0xf9
    438 
    439 ;
    440 ; Port data, which must be updated continually by main CPU's
    441 ; linkscan task.  See $SDK/src/appl/diag/ledproc.c for examples.
    442 ; In this program, bit 0 is assumed to contain the link up/down status.
    443 ;
    444 
    445 PORTDATA	equ	0xa0	; Size 28 bytes
    446 
    447 ;
    448 ; LED extension timers
    449 ;
    450 
    451 RX_TIMERS	equ	0xc0+0			; NUM_PORT bytes
    452 TX_TIMERS	equ	0xc0+NUM_PORT		; NUM_PORT bytes
    453 
    454 ;
    455 ; Symbolic names for the bits of the port status fields
    456 ;
    457 
    458 RX		equ	0x0	; received packet
    459 TX		equ	0x1	; transmitted packet
    460 COLL		equ	0x2	; collision indicator
    461 SPEED_C		equ	0x3	; 100 Mbps
    462 SPEED_M		equ	0x4	; 1000 Mbps
    463 DUPLEX		equ	0x5	; half/full duplex
    464 FLOW		equ	0x6	; flow control capable
    465 LINKUP		equ	0x7	; link down/up status
    466 LINKEN		equ	0x8	; link disabled/enabled status
    467 ZERO		equ	0xE	; always 0
    468 ONE		equ	0xF	; always 1