feat(ttl): Add the Diag / SONiC BER cycle macro

6_Blanton_Script_BER_Cycle.ttl is a standalone macro, not part of A/B/C.
Each cycle measures PRBS BER on unit 0 in the Diag OS, cold-boots into
SONiC by writing the CB FPGA, measures again, and cold-boots back; while
1, no end. The boot target is chosen in the BIOS Boot Manager ("USB
Device" = Diag, "Hard Drive" = SONiC) and confirmed by the boot
signature. The log goes to Logs\Blanton_BER_Cycle_<ts>.log.

prbsstat runs with Interval=30 and the BER is read after sleep 40. The
sleep has to be longer than the interval: checked against the error
counts 'prbs get' reports in the same cycle, sleep 10 read Diag ~60x and
SONiC ~40x low, and sleep 30 still read Diag ~60x low because its Ber is
sent 30.15 s after STArt, before the first interval is published.
Interval=30 + sleep 40 matched on both sides over 73 cycles.

Known limits: the SONiC -> Diag boot writes a hard-coded BDF
(0000:05:00.0); the prompts assume the hostname 'sonic'; the fan is set
to 30 % on the SONiC side only; the password is the placeholder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd
This commit is contained in:
2026-10-01 13:32:14 +08:00
co-authored by Claude Opus 5.5
parent ebb2260798
commit 7937ade30e
@@ -0,0 +1,315 @@
;================================================================
; Prompt Definitions
;================================================================
prompt_login = "sonic login:"
prompt_sonic = "admin@sonic:~$"
prompt_sonic_root = "root@sonic:~#"
prompt_diag = "root@(none):~#"
; ============================================================
; [1] Config
; ============================================================
SWB_UNIT0 = 1 ; 1 = this DUT has switch unit 0, wait for it ; 0 = skip
SWB_UNIT1 = 1 ; 1 = this DUT has switch unit 1, wait for it ; 0 = skip
bb_post_hotkey = 'Post Code>>:0226' ; 看到此 POST code 後開始送 ESC
bb_esc_ack = 'Esc is pressed' ; BIOS 收到 ESC 的回應訊息
bb_fp_continue = 'continue to booting' ; Front Page:Continue 反白時的說明欄(同一 row 內的字串)
bb_fp_bootmgr = 'you to the Boot Manager' ; Front Page:Boot Manager 反白時的說明欄
bb_bm_header = 'EFI Boot Devices' ; Boot Manager 清單標題
bb_bm_footer = 'ESC to exit' ; Boot Manager 頁面最後一段文字(畫完判定)
bb_key_esc = #27
bb_key_down = #27'[B'
bb_key_enter = #13
;diag_tok = 'KINGSHARKS' ; EFI USB Device (KINGSHARKS-ANTU04)
;sonic_tok = 'J983670007' ; EFI Hard Drive (J983670007-TS2TMTE712P-VS2)
diag_tok = 'USB Device' ; EFI USB Device (KINGSHARKS-ANTU04)
sonic_tok = 'Hard Drive' ; EFI Hard Drive (J983670007-TS2TMTE712P-VS2)
diag_sig = 'ast1813b_diag' ; EFI Shell 執行 startup.nsh 載入的 diag kernel
sonic_sig = 'SONiC-OS' ; SONiC GRUB entry 名稱(請依實際 GRUB 畫面確認)
gettime str_starttime "%Y%m%d-%H%M%S"
getdir mdir
sprintf2 filename '%s\Logs\%s_%s_%s.log' mdir "Blanton" "BER_Cycle" str_starttime
; logopen <file> <binary> <append> <PlainText> <timestamp>
; binary=0 text mode, so PlainText / timestamp are honoured
; append=1 keep earlier cycles, do not overwrite
; PlainText=1 strip the ANSI colour codes SONiC emits
logopen filename 0 1 1 1
test_cycle = 0
while 1
test_cycle = test_cycle + 1
flushrecv
logwrite ''#13#10
sprintf2 log_cycle_msg 'BER Diag/SONiC Cycle Test : %d'#13#10 test_cycle
logwrite '#####################################'#13#10
logwrite log_cycle_msg
logwrite '#####################################'#13#10
settitle log_cycle_msg
; ============================================================
; [2] Call : Script where switching is needed
; ============================================================
; ====== Diag Test ======
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30"'
wait prompt_diag
sendln "sleep 40"
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear"'
wait prompt_diag
sendln 'swutil 0:dsh -c "phydiag 256-259 dsc"'
wait prompt_diag
sendln 'swutil 0:show temp'
wait prompt_diag
sendln "swutil *:extphy core_diag all"
wait prompt_diag
; ---- Diag -> SONiC ----
sendln 'fpga_switch.sh cb 0 0x480 0xD0000'
bb_target_tok = sonic_tok
bb_sig_target = sonic_sig
bb_sig_other = diag_sig
call bb_boot_to
if bb_ok = 0 then
sprintf2 bb_msg 'Boot to SONiC failed: %s' bb_err
messagebox bb_msg 'bios_boot'
end
endif
; ========== SONiC Test ==========
wait prompt_login
sendln "admin"
wait "Password:"
sendln "YourPaSsWoRd"
wait prompt_sonic
sendln "sudo -i"
wait prompt_sonic_root
sendln "sleep 10"
; ========== FAN SPEED ==========
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 18-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/unbind"
wait prompt_sonic_root
sendln "sleep .5"
wait prompt_sonic_root
sendln "echo 25-0020 > /sys/bus/i2c/drivers/max31790/bind"
wait prompt_sonic_root
sprintf2 fan_ctrl_cmd 'fan-speed-control.sh %d' 30
sendln fan_ctrl_cmd
wait "Set all configured fan channels to"
sendln "y"
; ========== Wait DUT Init ==========
include "utils/wait_init.ttl"
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs set p=3' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs get' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STArt Interval=30' 39 ' "'
wait prompt_sonic_root
sendln "sleep 40"
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat Ber' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbsstat STOp' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c " dsh -c ' 39 'phydiag 1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565 prbs clear' 39 ' "'
wait prompt_sonic_root
sendln 'bcmcmd -n 0 -c "dsh -c ' 39 'phydiag 256-259 dsc' 39 '"'
wait prompt_sonic_root
sendln 'show plat temperature'
; ---- SONiC -> Diag ----
wait prompt_sonic_root
sendln 'pcimem /sys/bus/pci/devices/0000:05:00.0/resource0 0x480 w 0xD0000'
bb_target_tok = diag_tok
bb_sig_target = diag_sig
bb_sig_other = sonic_sig
call bb_boot_to
if bb_ok = 0 then
sprintf2 bb_msg 'Boot to Diag failed: %s' bb_err
messagebox bb_msg 'bios_boot'
end
endif
endwhile
logclose
end
; ============================================================
; [3] Subroutine
; ============================================================
:bb_boot_to
bb_saved_to = timeout
call bb_run
timeout = bb_saved_to
mtimeout = 0
return
:bb_run
bb_ok = 0
bb_err = ''
call bb_enter_bios
if bb_ok = 0 return
call bb_goto_bootmgr
if bb_ok = 0 return
call bb_find_idx
if bb_ok = 0 return
call bb_select
call bb_verify
return
; ------------------------------------------------------------
; 等 POST 0226,之後連送 ESC 直到 BIOS 回應 'Esc is pressed'
; ------------------------------------------------------------
:bb_enter_bios
bb_ok = 0
flushrecv ; 清掉 reboot 前的舊資料,避免誤比對
timeout = 300
mtimeout = 0
wait bb_post_hotkey
if result = 0 then
bb_err = 'timeout waiting POST code 0226'
return
endif
timeout = 0
mtimeout = 300
for bb_i 1 200 ; 300 ms x 200 = 最多約 60 秒
send bb_key_esc
wait bb_esc_ack
if result > 0 then
bb_ok = 1
break ; 收到 ack 立即停送,避免多餘 ESC 把 Front Page 退掉
endif
next
mtimeout = 0
if bb_ok = 0 bb_err = 'no ESC ack from BIOS'
return
; ------------------------------------------------------------
; Front Page:預設反白在 Continue,按一次 Down 到 Boot Manager
; 以右側說明欄文字確認反白位置,再按 Enter
; ------------------------------------------------------------
:bb_goto_bootmgr
bb_ok = 0
timeout = 30
wait bb_fp_continue
if result = 0 then
bb_err = 'Front Page not shown'
return
endif
mpause 500
send bb_key_down
timeout = 5
wait bb_fp_bootmgr
if result = 0 then
bb_err = 'cannot highlight Boot Manager'
return
endif
mpause 300
send bb_key_enter
timeout = 15
wait bb_bm_header
if result = 0 then
bb_err = 'Boot Manager page not shown'
return
endif
bb_ok = 1
return
; ------------------------------------------------------------
; 解析 Boot Manager 清單,計算目標 entry 的 index(0-based)
; 每個 entry 以 'EFI '(含 UEFI)或 'SVOS' 開頭計數,命中目標字串即停止
; ------------------------------------------------------------
:bb_find_idx
bb_ok = 0
bb_idx = -1
bb_cnt = 0
timeout = 0
mtimeout = 3000
for bb_i 1 20
wait 'EFI ' 'SVOS' bb_target_tok
if result = 0 break ; 清單畫完仍未命中
if result = 3 then
bb_idx = bb_cnt - 1 ; 目標字串前的 'EFI ' 屬於目標 entry 本身
break
endif
bb_cnt = bb_cnt + 1
next
mtimeout = 0
if bb_idx < 0 then
bb_err = 'target entry not found in Boot Manager'
return
endif
timeout = 5
wait bb_bm_footer ; 等整頁畫完才開始按鍵
bb_ok = 1
return
; ------------------------------------------------------------
; 預設反白在第一個 entry,往下移 bb_idx 格後按 Enter
; ------------------------------------------------------------
:bb_select
mpause 300
if bb_idx > 0 then ; TTL 的 for 1 0 會倒數執行,必須先擋掉
for bb_i 1 bb_idx
send bb_key_down
timeout = 3
wait bb_bm_footer ; BIOS 每按一次會整頁重畫,畫完再按下一次
mpause 200
next
endif
send bb_key_enter
; 之後不可再送任何按鍵:Diag 走 EFI Shell,
; 任何按鍵都會被當成「跳過 / 中斷 startup.nsh」
return
; ------------------------------------------------------------
; 同時等目標與另一個 image 的特徵字串
; ------------------------------------------------------------
:bb_verify
bb_ok = 0
timeout = 300
wait bb_sig_target bb_sig_other
if result = 1 then
bb_ok = 1
elseif result = 2 then
bb_err = 'booted into wrong image'
else
bb_err = 'timeout waiting boot signature'
endif
return