1 ;
2 ; TEXAS INSTRUMENTS TEXT FILE LICENSE
3 ;
4 ; Copyright (c) 2018-2019 Texas Instruments Incorporated
5 ;
6 ; All rights reserved not granted herein.
7 ;
8 ; Limited License.
9 ;
10 ; Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
11 ; license under copyrights and patents it now or hereafter owns or controls to
12 ; make, have made, use, import, offer to sell and sell ("Utilize") this software
13 ; subject to the terms herein. With respect to the foregoing patent license,
14 ; such license is granted solely to the extent that any such patent is necessary
15 ; to Utilize the software alone. The patent license shall not apply to any
16 ; combinations which include this software, other than combinations with devices
17 ; manufactured by or for TI (“TI Devices”). No hardware patent is licensed hereunder.
18 ;
19 ; Redistributions must preserve existing copyright notices and reproduce this license
20 ; (including the above copyright notice and the disclaimer and (if applicable) source
21 ; code license limitations below) in the documentation and/or other materials provided
22 ; with the distribution.
23 ;
24 ; Redistribution and use in binary form, without modification, are permitted provided
25 ; that the following conditions are met:
26 ; No reverse engineering, decompilation, or disassembly of this software is
27 ; permitted with respect to any software provided in binary form.
28 ; Any redistribution and use are licensed by TI for use only with TI Devices.
29 ; Nothing shall obligate TI to provide you with source code for the software
30 ; licensed and provided to you in object code.
31 ;
32 ; If software source code is provided to you, modification and redistribution of the
33 ; source code are permitted provided that the following conditions are met:
34 ; Any redistribution and use of the source code, including any resulting derivative
35 ; works, are licensed by TI for use only with TI Devices.
36 ; Any redistribution and use of any object code compiled from the source code
37 ; and any resulting derivative works, are licensed by TI for use only with TI Devices.
38 ;
39 ; Neither the name of Texas Instruments Incorporated nor the names of its suppliers
40 ; may be used to endorse or promote products derived from this software without
41 ; specific prior written permission.
42 ;
43 ; DISCLAIMER.
44 ;
45 ; THIS SOFTWARE IS PROVIDED BY TI AND TI’S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED
46 ; WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
47 ; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI’S
48 ; LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49 ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
50 ; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 ; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 ; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 ;-------------------------------------------------
56 ;---file: RTU_PSI.h
57 ;---purpose: utilities to manage PSI i/f for RTU
58 ;---------------------------------------------------
60 ;----------------------DEFINES------------------------
61 .include "rtu_psi_loopback.h"
63 ;global PSI state
64 .asg b0, ssmask ; mask of threads that are stalled.
65 .asg b1, sactive ; 0=thread0, 1=thread1, 2=thread2, 3=thread3
66 .asg b2, sreason ;2bits per thread give reason for stall (valid if smask bit is clear)
67 .asg b3, qlock ;bit n set => queue n locked
69 ; 2 bits/thread => 4 reasons why thread is stalled
70 ; b2
71 SR_RATE .set 0
72 SR_LOCK .set 1
73 SR_BUF .set 2
74 SR_QUEUE .set 3
76 ;---------------------------
77 ; Resource Lock Utility
78 ; QUICK Version
79 ; just 8 bits. no queue
80 ;----------------------------
81 ;init lock
82 QLOCK_INIT .macro
83 ldi GRrtu.ResLock, 0
84 .endm
86 ;get a lock or get stalled
87 ; 1 cycle no
88 ; 3 cycles yes
89 QLOCK_GET .macro r_res, queued_label,gotit_label
90 qbbs queued_label, GRrtu.ResLock, r_res
91 set GRrtu.ResLock, GRrtu.ResLock, r_res
92 jmp gotit_label
93 .endm
95 ;poll to see if we can have lock now
96 ; 1 cycles
97 QLOCK_POLL .macro r_res, gotit_label
98 qbbc gotit_label, GRrtu.ResLock, r_res
99 .endm
101 ;clear a lock
102 ; 1 cycles
103 QLOCK_CLR .macro r_res
104 clr GRrtu.ResLock, GRrtu.ResLock, r_res
105 .endm
107 ;-------Context save/restore---------------
108 ;park a thread context, case0
109 PARK_THREAD0 .macro slot, unstall_exit
110 zero &r2, 32
111 mov r2, RCtx.pix0
112 mov r3, RCtx.pix1
113 mov r4, RCtx.pix2
114 ldi r9, $code(unstall_exit)
115 PAGE_SAVE2_REG slot
116 .endm
118 ;park a thred context, case1
119 PARK_THREAD1 .macro slot, unstall_exit
120 mov r2, RCtx.pix0
121 mov r3, RCtx.pix1
122 mov r4, RCtx.pix2
123 mov r5, RCtx.pix3
124 mov r6, RCtx.pix4
125 ldi r9, $code(unstall_exit)
126 PAGE_SAVE2_REG slot
127 .endm
129 STALL_N_PARK .macro stall_reason, park_proc, unstall_label
130 clr GRrtu.StallMask, GRrtu.StallMask, GRrtu.ActThrdNum
131 add r11, GRrtu.ActThrdNum, PSI_CNTX0_SLOT
132 ldi r12, stall_reason
133 add r13, GRrtu.ActThrdNum, GRrtu.ActThrdNum
134 lsl r13, r13, 1
135 lsl r12, r12, r13
136 or GRrtu.StallReason, GRrtu.StallReason, r12
137 park_proc r11, unstall_label
138 .endm
140 ;-------------------------------------------
141 ;------------GLobal PSI SM-------------------
142 ;-------------------------------------------
143 ;macros to poll individual psi slots
144 RTU_POLL_SLOTx .macro slot
145 .newblock
146 $1: xin XID_PSI_S, &r1, 8
147 qbbs $2, r1, slot
148 CALL_SUB sstate_00, $1
149 jmp $1
150 $2:
151 .endm
153 ;State0: read in INFO WORD
154 ; 8 - 13 cycles..
155 ; r2-r5 hold info data
156 ; r1 - holds meta data
157 ; r0 - holds expected metadata
158 ;======================
159 ; INFO WORD KEY DATA
160 ; directed packet: r4.b2 (dst tag low)
161 ; crc provided by host: r2.t23
162 ; portq # provided by host in r4.b3 (dst tag high)
163 ; expected length:
164 ;======================
165 RTU_PSI_IN_S0 .macro err_exit, stall_exit, mgr_exit
166 .newblock
167 PSI_READ GRrtu.ActThrdNum, 20 ;read in info word
168 ldi32 r0, MD_INFO0
169 qbne $5, r1, r0
170 zero &RCtx.pix0, 20
172 ; check if the packet is management
173 and r12.b0, r2.b3, 0xf8
174 qbne $7, r12.b0, 0x80
175 jmp mgr_exit
177 ;see if host already put crc on pkt
178 ; todo : do we need to verify crc then on pkt
179 $7: qbbc $1, r2, 23 ; r2.t23
180 set Ctx.ippc_flags, Ctx.ippc_flags, f_crcinpkt
182 $1:
183 .if $isdefed("LOOPBACK_TEST")
184 set Ctx.ippc_flags, Ctx.ippc_flags, f_crcinpkt
185 .endif
186 .if $isdefed("LOOPBACK_TEST2")
187 clr Ctx.ippc_flags, Ctx.ippc_flags, f_crcinpkt ;crc not in pkt
188 .endif
190 set Ctx.ippc_forward, Ctx.ippc_forward, our_port ;to keep it local
191 ;//set portq
192 and Ctx.ippc_res, r4.b3, 0x07 ;ippc_res set to dst tag hi
193 mov Ctx.ippc_totlen, r3.w0 ;check rate
194 .if $isdefed("PSILOOP")
195 add Ctx.ippc_totlen, Ctx.ippc_totlen, 4 ;add 'crc' bytes
196 .endif
197 .if $isdefed("LOOPBACK_TEST")
198 mov Ctx.ippc_totlen, 512 ;hard code because it will be 0xffff
199 .endif
201 .if $isdefed("TX_RATE_LIMITER")
202 mov r3, GRrtu.ActThrdNum
203 qbbc $6, Ctx.he_flags, r3
204 TXRATE_CHK_AND_SOPv2 r3, r2, Ctx.ippc_totlen, $4
205 .endif
206 jmp $6
207 $4: jmp stall_exit
208 $5: jmp err_exit
209 $6: ; done
210 ;rate ok
211 .endm
213 ;process in Control Word
214 ; optional. note data already read in
215 ; assumes r1-r6 contains transfer
216 ;control fields of interest
217 ;word 0: time stam request 'cookie'
218 ;word 1: timestamp request (bit31)
219 ;word 2: udp chksum request
220 ;word 3: ignore
221 PSI_IN_CONTROL_PROC .macro
222 .newblock
223 ;Control words already in r1-r5
224 ;r2= cookie
225 ;r3= b31-> tx ts
226 ;r4= udp cs control: w0=#bytes, b3=loc of result (0rel), b2=start byte (0 rel)
227 ;r5= spare
228 qbbc $1, r3, 31 ;no_txts
229 set Ctx.ippc_flags, Ctx.ippc_flags, f_rts
230 ldi32 r10, FW_CONFIG + TX_TS_BASE
231 mov r4, r2 ; we need cookie after flags
232 sbbo &r3, r10, 8, 8 ; save cookie (r4) and flags (r3)
233 $1:
234 .endm
236 ;StateS1: read in 1st 16 data words
237 ; looking for 1st DATA or Control
238 ; Data in r2-r5, meta in r1
239 ; kick of fdb lookup. Note: we always do lookup, even for
240 ; directed pkt, to get vlan info
241 ; todo: optimization for non_vlan case: skip fdb
242 ;
243 RTU_PSI_IN_S1 .macro err_exit, control_exit
244 .newblock
245 PSI_READ GRrtu.ActThrdNum, 20
246 ldi32 r0, MD_CONTROL0
247 qbne $1, r1, r0
248 ;CONTROL DATA- so Process
249 PSI_IN_CONTROL_PROC
250 jmp control_exit
252 $1:
253 ;skip protocol info if present..
254 qbeq control_exit,r1.b2, PSI_DT_PROINFO
255 ;assume data...
256 qbne err_exit0?, r1.b2, 0x14
258 LEBE2_5_swap_6_9 ;shift r2-r5 to r6-r9
259 add r10, GRrtu.ActThrdNum, BS_SLOT_PSI0
260 PAGE_SAVEQ ;save off
261 jmp done?
262 err_exit0?: ;trampoline
263 jmp err_exit
264 done?:
265 .endm
267 branch_if_eop .macro label
268 qbbs label, r1, 4 ;r1.f_md_lastw
269 qbbs label, r1, 1 ;r1.f_md_eop
270 .endm
272 ;hard loop to process 64 bytes from PSI
273 ; eop_exitX: finished w/ data
274 ; X=1 => r1.b3 bytes of data need servicing
275 ; X=2 => 16+r1.b3 bytes of data need servicing
276 ; X=3 => 32+r1.b3 bytes of data need servicing
277 ; X=4 => 48+r1.b3 bytes of data need servicing
278 ; MACRO puts data in right order, ready to go, even for EOP
279 ; not going to check for errors...
280 RTU_PSI_READ_SR1_4 .macro slot, done_exit, eop_exit
281 .newblock
282 $1: xin XID_PSI_S, &r1, 8
283 qbbc $1, r1, GRrtu.ActThrdNum
284 PSI_READS slot, 20 ; Axxx
285 branch_if_eop $5
286 LEBE2_5_swap_6_9 ; xAxx
288 $2: xin XID_PSI_S, &r1, 8
289 qbbc $2, r1, GRrtu.ActThrdNum
290 PSI_READS slot, 20 ; BAxx
291 branch_if_eop $6
292 LEBE2_9_swap_10_17 ; xxAB
294 $3: xin XID_PSI_S, &r1, 8
295 qbbc $3, r1, GRrtu.ActThrdNum
296 PSI_READS slot, 20 ; CxAB
297 LEBE2_5_swap_6_9 ; xCAB
298 branch_if_eop $7
300 $4: xin XID_PSI_S, &r1, 8
301 qbbc $4, r1, GRrtu.ActThrdNum
302 PSI_READS slot, 20 ; DCAB
303 LEBE2_9_swap_10_17 ; BACD
304 LEBE2_5_swap_6_9 ; ABCD
305 branch_if_eop $8
306 jmp done_exit
308 $6: LEBE2_5_swap_6_9 ; ABxx
309 add r1.b3, r1.b3, 16
310 jmp eop_exit
312 $7: LEBE2_9_swap_10_17 ; BACx
313 LEBE2_5_swap_6_9 ; ABCx
314 add r1.b3, r1.b3, 32
315 jmp eop_exit
316 $8:
317 add r1.b3, r1.b3, 48
318 $5: jmp eop_exit
319 .endm
321 ;hard macro to process bytes 16-63 from PSI
322 ; (already read 1st 16)
323 ; will pad if EOP seen
324 ; assumption: if psi gives us N<16 as vaild, and we read in 16, that widget
325 ; zeros bytes n, n+1,.. 15 (0-rel)
326 RTU_PSI_READ_SR2_4 .macro slot, bslot, done_exit, eop_exit, eop_exit1
327 .newblock
328 zero &r2, 64
329 TM_DISABLE
330 PAGE_RESTORE2 bslot, 32
331 TM_ENABLE
332 ldi r10, 0
333 ;r5-r9 = 1st 16
334 $1: xin XID_PSI_S, &r1, 8
335 qbbc $1, r1, GRrtu.ActThrdNum
336 PSI_READS slot, 20
337 LEBE2_9_swap_10_17
338 branch_if_eop $4
340 $2: xin XID_PSI_S, &r1, 8
341 qbbc $2, r1, GRrtu.ActThrdNum
342 PSI_READS slot, 20
343 LEBE2_5_swap_6_9
344 branch_if_eop $5
346 $3: xin XID_PSI_S, &r1, 8
347 qbbc $3, r1, GRrtu.ActThrdNum
348 PSI_READS slot, 20
349 LEBE2_9_swap_10_17
350 LEBE2_5_swap_6_9
351 branch_if_eop $6
352 jmp done_exit
354 $4: ;< 32 byte packet
355 LEBE2_9_swap_10_17
356 LEBE2_5_swap_6_9
357 ldi r1.b3, 60
358 jmp eop_exit
359 $5: ;only 48 byte packet
360 LEBE2_9_swap_10_17
361 LEBE2_5_swap_6_9
362 ldi r1.b3, 60
363 jmp eop_exit
364 $6:
365 ;all should be lined up
366 add r1.b3, r1.b3, 48
367 qble eop_exit1, r1.b3, 60
368 ldi r1.b3, 60
369 jmp eop_exit
370 .endm
372 ;
373 ;Process fdb result to decide how to forward (part2)
374 ; r2 = xxMASK
375 RTU_PSI_IN_F0_PART2 .macro stall_exit_lock,stall_exit_buf
376 .newblock
377 ;now allocate buffer(s)
378 ;get a lock on the queue/buffer pools
379 QLOCK_GET Ctx.ippc_res, $1, $2
380 $1: jmp stall_exit_lock ;can't get lock
381 $2: ;lock_ok
382 add r1, Ctx.ippc_res, BP_SLOT0_RTU
383 CEIL64 r11.w2, Ctx.ippc_totlen
384 TM_DISABLE
385 BUFP_POP r1, r11.w2, Ctx.ippx_ptr0, $3
386 TM_ENABLE
387 jmp $9
388 $3: ;no_buffer0
389 TM_ENABLE
390 jmp stall_exit_buf
391 $9: ; done
392 .endm
394 ;write 64 bytes to one or both portq buffers
395 ;ADDR_LO needs to be set (r18) to r_pix3, rpix_4
396 ; aslo sets r19 to ADDR_HI
397 ; could be 15 cycles if 2x writes
398 DO_WRITE64 .macro unit, len
399 .newblock
400 LEBE_GO r2, 64 ;NEED_TO_FLIP
401 ldi r19, ADDR_HI
402 add r18, Ctx.ippx_ptr0, Ctx.ippc_curlen
403 xout unit, &r2, 64 + 8
404 add Ctx.ippc_curlen, Ctx.ippc_curlen, len
405 .endm
407 ;build descriptor
408 ;push descriptor onto port queue(s)
409 DO_EOP .macro stall_exit
410 ;build common parts of descriptor
411 mov r8.w0, Ctx.ippc_curlen ;len
412 .if $isdefed("PSILOOP")
413 add r8.w0, r8.w0, 4 ;include 'dummy' crc
414 .endif
415 ldi r8.b2, FROM_US_V
416 qbbs no_crc?, Ctx.ippc_flags, f_crcinpkt
417 set r8.t16 ;force tx to get hw to do crc
418 no_crc?:
419 add r8.b3, Ctx.ippc_res, BP_SLOT0_RTU ;b2 is 0-7. add RTU_BASE
420 qbbc no_tx_ts?, Ctx.ippc_flags, f_rts
421 set r8.t21
422 no_tx_ts?:
423 mov r7, Ctx.ippx_ptr0 ;ptr
424 add r2, Ctx.ippc_res, MQ_SLOT0_RTU ;queue
425 TM_DISABLE
426 MQ_PUSH r2, r7, fail?
427 set GRrtu.pqmap, GRrtu.pqmap, Ctx.ippc_res
428 TM_ENABLE
429 jmp done?
430 fail?:
431 TM_ENABLE
432 jmp stall_exit
434 done?: QLOCK_CLR Ctx.ippc_res ; success - release lock on queue/resources
435 .endm
437 ;wait for EOP on thread, tossing data
438 WAIT_EOP .macro
439 .newblock
440 qbeq $0, GRrtu.ActThrdNum, 0
441 qbeq $1, GRrtu.ActThrdNum, 1
442 qbeq $2, GRrtu.ActThrdNum, 2
443 $3
444 RTU_POLL_SLOTx 3
445 PSI_READS XID_PSI_R4, 20
446 qbbc $3, r1, 1 ;r1.f_md_eop
447 jmp $4
448 $2:
449 RTU_POLL_SLOTx 2
450 PSI_READS XID_PSI_R3, 20
451 qbbc $2, r1, 1 ;r1.f_md_eop
452 jmp $4
453 $1:
454 RTU_POLL_SLOTx 1
455 PSI_READS XID_PSI_R2, 20
456 qbbc $1, r1, 1 ;r1.f_md_eop
457 jmp $4
458 $0:
459 RTU_POLL_SLOTx 0
460 PSI_READS XID_PSI_R1, 20
461 qbbc $0, r1, 1 ;r1.f_md_eop
462 $4:
463 .endm
465 ;UNSTALL a thread
466 ; note: if can unstall, r9 from restored context has where to
467 ; r0.b0 clobbered
468 TRY_UNSTALL .macro thr, bs_slot, fail_exit
469 .newblock
470 ;restore state for this thread
471 TM_DISABLE
472 PAGE_RESTORE2_REG bs_slot, 32
473 TM_ENABLE
474 lsl r0.b1, thr, 2
475 lsr r0.b0, GRrtu.StallReason, r0.b1
476 and r0.b0, r0.b0, 0x3
477 qbeq try_us_rate?, r0.b0, SR_RATE
478 qbeq try_us_res?, r0.b0, SR_LOCK
479 qbeq try_us_buf?, r0.b0, SR_BUF
480 qbne fail_exit0?, r0.b0, SR_QUEUE
482 ;Stalled because portQ (or IPC Q) was full
483 ;try to unstall queue block (one or both qpushes failed)
484 ; simply jump to r9 (this will retry DO_EOP macro to close out pkt)
485 try_us_q?:
486 mov RCtx.pix0, r2
487 mov RCtx.pix1, r3
488 mov RCtx.pix2, r4
489 mov RCtx.pix3, r4
490 mov RCtx.pix4, r5
491 set GRrtu.StallMask, GRrtu.StallMask, thr
492 mov GRrtu.ActThrdNum, thr
493 jmp r9
495 ;Stalled because of rate limiter
496 ;so see if we have credits now
497 try_us_rate?:
498 mov r18, thr
499 TXRATE_CHK_AND_SOPV2 r18, r1, r2.w2, fail_exit0?
500 ;can unstall
501 set GRrtu.StallMask, GRrtu.StallMask, thr
502 mov GRrtu.ActThrdNum, thr
503 mov RCtx.pix0, r2
504 mov RCtx.pix1, r3
505 mov RCtx.pix2, r4
506 jmp r9
507 fail_exit0?: jmp fail_exit ;trampoline
509 ;Stalled because resource locked
510 ;so try and get lock for resource
511 try_us_res?:
512 QLOCK_POLL r3.b2, isuccess_exit1?
513 jmp fail_exit
514 isuccess_exit1?:
515 ;can unstall thread
516 mov RCtx.pix0, r2
517 mov RCtx.pix1, r3
518 mov RCtx.pix2, r4
519 set GRrtu.StallMask, GRrtu.StallMask, thr
520 mov GRrtu.ActThrdNum, thr
521 jmp r9
523 ;stalled becausec couldn't get buffer(s)
524 ;so try and get buffers
525 try_us_buf?:
526 TM_DISABLE
527 PAGE_RESTORE2_REG bs_slot, 32
528 TM_ENABLE
529 mov RCtx.pix0, r2
530 mov RCtx.pix1, r3
531 mov RCtx.pix2, r4
532 mov RCtx.pix3, r5
533 mov RCtx.pix4, r6
534 ;see if we need local pool
535 add r1, Ctx.ippc_res, BP_SLOT0_RTU
536 CEIL64 r11.w2,Ctx.ippc_totlen
537 TM_DISABLE
538 BUFP_POP r1, r11.w2, Ctx.ippx_ptr0, no_buffer0?
539 TM_ENABLE
540 ;success
541 set GRrtu.StallMask, GRrtu.StallMask, thr
542 mov GRrtu.ActThrdNum, thr
543 jmp r9
545 no_buffer0?:
546 TM_ENABLE
547 jmp fail_exit
548 .endm
550 MGR_SHUTDOWN .macro
551 .newblock
552 ; signal PRU we are going to stop
553 ldi32 r0, FW_CONFIG
554 ldi32 r1, RTU_STARTED_SHUTDOWN
555 sbbo &r1, r0, CFG_RTU_STATUS, 4
556 ; compete all ongoing PSI-L transfers
557 $1: ldi r7, 125 ; set 1 usec timeout
558 $2: xin XID_PSI_S, &r1, 8
559 mov r6, r1 ; save status at r6
560 and r6, r6, 0xf ;
561 qbne $3, r6, 0 ; we have active data
562 sub r7, r7, 1 ;
563 qbne $2, r7, 0 ;
564 jmp $7 ; timeout
566 $3 qbbc $4, r6, 0 ; read chunks from all threads if any
567 PSI_READS XID_PSI_R1, 20
568 $4: qbbc $5, r6, 1
569 PSI_READS XID_PSI_R2, 20
570 $5: qbbc $6, r6, 2
571 PSI_READS XID_PSI_R3, 20
572 $6: qbbc $1, r6, 3
573 PSI_READS XID_PSI_R4, 20
574 jmp $1
576 ; we don't care if TX queue is not empty. We are going to restart firmware anyways
577 ; and reinitialize all buffers and queues
579 ; wait for PRU complete
580 $7: ldi32 r0, FW_CONFIG
581 ldi32 r1, PRU_STOPPED
582 $8: add r0, r0, 0
583 lbbo &r9, r0, CFG_STATUS, 4
584 qbne $8, r9, r1
585 .endm