WIP: further implement init process, add PCIE SPICO / SerDes init
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2021-01-03 09:19:51 +01:00
parent 6f91e3e7c4
commit ff27bfe764
10 changed files with 349 additions and 6 deletions

View file

@ -8,6 +8,7 @@ src/rrc-as: rrcc/CMakeLists.txt
firmware.bin: src/rrc-as src/entrypoint.asm
rrcc/rrc-as \
config.asm src/platform.asm \
blobs/master_spico_fw.asm blobs/serdes_spico_fw.asm \
src/entrypoint.asm \
src/clocking.asm \
src/pcie.asm \

View file

@ -12,3 +12,8 @@ WARNING: **This is a Work In Progress project**. Do not use on any cards you don
* `$ make`
* The firmware will be output to `firmware.bin`
* You might want to change settings on file `config.asm` to fit your needs.
## License
* BSD-3-Clause
* See [COPYING](COPYING) for the full license.
* Files under [blobs/](blobs/) are obtained from rrcBig's firmware and reference Intel IES BSD-3-Clause switch API

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
; File used to declare configuration to be placed on the firmware image
.constant firmware_versionNumber 0x0222 ; Define version reported back on register. 0x0222 = same as rrcBig_02.22
.constant platform_firmware_versionNumber 0x0222 ; Define version reported back on register. 0x0222 = same as rrcBig_02.22
; Picks between DEVICE_CFG.SystimeClockSource values. 0 = PCIE_REFCLK, 1 = IEEE1588_REFCLK
.constant bootCfg_systimeClockSource 0

2
rrcc

@ -1 +1 @@
Subproject commit 624fad13191c3077511d53cab59e19c9ed1aeecc
Subproject commit a51287bceeb4e08072b5b2e59ff8f053466e443d

View file

@ -57,6 +57,12 @@ init_startClocks:
WAIT 10
RET
init_PCIE_setClockDivTo50:
SET PLL_PCIE_CTRL, 0x280000, 0xfc0000 ; Set OutDiv = 50
SET PLL_PCIE_STAT, 0x40, 0x40 ; Value & Mask, set MiscCtrl, "Fast Calibration Mode" = 0, "Asynchronous load signal for PLL output divider." = 1
SET PLL_PCIE_STAT, 0x00, 0x40 ; Value & Mask, set MiscCtrl all 0 (?)
RET
; FASTCALL void(bool useSystimeClockSource)
init_setClockSource:
BEQ P0, 0, 0x1, @.return ; If clock source is defined as system = 0

View file

@ -38,6 +38,16 @@ entrypoint:
SET SOFT_RESET, 0, 0x6 ; Enable areas, EPLReset = 0, SwitchReset = 0
WAIT 10 ; Wait 100ns, minimum
FASTCALL @init_setPciePEPEnabled, bootCfg_pep0_enable, bootCfg_pep1_enable, bootCfg_pep2_enable, bootCfg_pep3_enable, bootCfg_pep4_enable, bootCfg_pep5_enable, bootCfg_pep6_enable, bootCfg_pep7_enable, bootCfg_pep8_enable
CALL @init_PCIE_setClockDivTo50
CALL @lock_PCIE_SBUS_take ; Try to take lock for ourselves
BNE RRET, 1, 0x1, @.skipPcieInit ; We failed to take the lock
CALL @init_PCIE_MASTER_SPICO
BNE RRET, 1, 0x1, @.skipPcieInit ; Failed to init properly
CALL @init_PCIE_SERDES_SPICO
BNE RRET, 1, 0x1, @.skipPcieInit ; Failed to init properly
; TODO complete this
@ -52,7 +62,7 @@ entrypoint:
CALL @lock_PCIE_SBUS_release
.noReleaseLock:
CALL @config_load_bootCfg_customMac
MOV api_EEPROM_IMAGE_VERSION, firmware_versionNumber ; Sets the version on memory where a switch manager can read it
MOV api_EEPROM_IMAGE_VERSION, platform_firmware_versionNumber ; Sets the version on memory where a switch manager can read it
RET
init_markSbusBooted:

View file

@ -84,8 +84,302 @@ init_setPciePEPEnabled:
RET
; CALL bool(), Return in RRET
; TODO: make this a proper loop with n retries
lock_PCIE_SBUS_take:
PNE api_PCIE_SBUS_LOCK_STATE, 0, 0x3, 20000, 50, @.failToTakeLock ; Check if something else is holding the lock, and wait until freed
SET api_PCIE_SBUS_LOCK_STATE, 1, 0x3 ; Take lock for ourselves
BNE api_PCIE_SBUS_LOCK_STATE, 1, 0x3, @.tryTakeLockAgain; Check if we actually took the lock or driver/switch manager did, or retry
MOV RRET, 1 ; Success
RET
.tryTakeLockAgain:
PNE api_PCIE_SBUS_LOCK_STATE, 0, 0x3, 20000, 50, @.failToTakeLock ; Check if something else is holding the lock, and wait until freed
SET api_PCIE_SBUS_LOCK_STATE, 1, 0x3 ; Take lock for ourselves
BNE api_PCIE_SBUS_LOCK_STATE, 1, 0x3, @.failToTakeLock; Check if we actually took the lock or driver/switch manager did
MOV RRET, 1 ; Success
RET
.failToTakeLock:
MOV RRET, 0 ; Failure
SET api_SW_LOCK_ERR_STATUS, 1, 0x1
BEQ api_SW_LOCK_ERR_STATUS, 0xfe, 0xfe, @.resetErrorStatus
ADD api_SW_LOCK_ERR_STATUS, api_SW_LOCK_ERR_STATUS, 2
RET
.resetErrorStatus:
SET api_SW_LOCK_ERR_STATUS, 0, 0xfe
ADD api_SW_LOCK_ERR_STATUS, api_SW_LOCK_ERR_STATUS, 2
RET
lock_PCIE_SBUS_release:
BNE api_PCIE_SBUS_LOCK_STATE, 1, 0x3, @.return ; If we hold the lock
SET api_PCIE_SBUS_LOCK_STATE, 0, 0x3 ; Release lock
BNE api_PCIE_SBUS_LOCK_STATE, platform_PCIE_SBUS_LOCK_NVM, 0x3, @.return ; If we hold the lock
SET api_PCIE_SBUS_LOCK_STATE, platform_PCIE_SBUS_LOCK_FREE, 0x3 ; Release lock
.return:
RET
RET
; FASTCALL bool, uint result(uint & 0xff Register, uint & 0xff DeviceAddress, bool doRead, uint commandData). bool is in RRET, result in RRET_X
execute_SBus_PCIE_Command:
MOV~03 SBUS_PCIE_REQUEST, P3 ; Set commandData into the request
SHL R0, P1, 8 ; P1 << 8
AND R0, R0, 0xff00
OR R0, R0, P0 ; Combine (DeviceAddress << 8) | Register
BEQ~3 P2, 1, 0x1, @.doRead ; Check if we are doing a write or read op
; Do write
SET R0, 0x210000, 0xff0000 ; Set WRITE Op 0x21
MOV R1, 0x04000000 ; Success value for write ResultCode
JUMP @.executeCommand
.doRead:
; Do read
SET R0, 0x220000, 0xff0000 ; Set READ Op 0x22
MOV R1, 0x10000000 ; Success value for read ResultCode
.executeCommand:
MOV SBUS_PCIE_COMMAND, R0 ; Write command and operators
SET SBUS_PCIE_COMMAND, 0x01000000, 0x01000000 ; Set Execute = 1 to start the command. Should automatically set Busy = 1 as well
PNE SBUS_PCIE_COMMAND, 0, 0x02000000, 65535, 1, @.failCommand ; Poll until Busy = 0
AND R0, SBUS_PCIE_COMMAND, 0x1c000000 ; Get ResultCode
SUB R0, R0, R1 ; Compare ResultCode to expected
BNE R0, 0, 0xffffffff, @.failCommand ; Fail if ResultCode != Expected Success ResultCode
.successCommand:
MOV RRET, 1 ; Success
MOV RRET_X, SBUS_PCIE_RESPONSE
MOV SBUS_PCIE_COMMAND, 0 ; Reset command
RET
.failCommand:
MOV RRET, 0 ; Fail
MOV RRET_X, SBUS_PCIE_RESPONSE
MOV SBUS_PCIE_COMMAND, 0 ; Reset command
RET
init_PCIE_MASTER_SPICO:
MOV api_PCIE_MASTER_STATUS, 0
MOV api_BSM_STATUS, 0x0101000e
FASTCALL @execute_SBus_PCIE_Command, 0x0a, 0xfe, 0, 0x01
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x01, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0xc0
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x01, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x0240
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x03, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x80000000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
MOV api_BSM_STATUS, 0x0102000e
CALL @download_master_spico_fw
MOV api_BSM_STATUS, 0x0103000e
FASTCALL @execute_SBus_PCIE_Command, 0x01, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x40
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x16, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x000c0000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x01, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x0140
BNE RRET, 1, 0x1, @.failCommand ; Command failed
MOV api_MASTER_FW_VERSION, plaftorm_MASTER_FW_VERSION
MOV RRET, 1 ; Success
MOV api_BSM_STATUS, 0x0108000e
MOV api_PCIE_MASTER_FW_DL_STATUS, api_BSM_STATUS
RET
.failCommand:
MOV RRET, 0 ; Failure
SET api_BSM_STATUS, 0x0000fff0, 0x0000fff0
MOV api_PCIE_MASTER_FW_DL_STATUS, api_BSM_STATUS
MOV api_PCIE_MASTER_STATUS, 1
RET
init_PCIE_SERDES_SPICO:
MOV api_PCIE_SERDES_STATUS, 0
MOV R0, 0 ; Why, this must be a constant!
BEQ R0, 1, 0x1, @.skipUnlock
MOV api_BSM_STATUS, 0x0001000e
FASTCALL @execute_SBus_PCIE_Command, 0x07, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x11
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x07, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x10
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x00, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x40000000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
.skipUnlock: ; (??)
MOV api_BSM_STATUS, 0x0002000e
CALL @download_serdes_spico_fw
MOV R1, 0 ; Why, this must be a constant!
BEQ R1, 1, 0x1, @.skipFullLock
MOV api_BSM_STATUS, 0x0003000e
MOV R2, 0 ; Why, this must be a constant!
BEQ R2, 0, 0x1, @.skipLock
FASTCALL @execute_SBus_PCIE_Command, 0x0a, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0xc000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x0a, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0xc000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x0a, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0xc000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
.skipLock: ; (??)
FASTCALL @execute_SBus_PCIE_Command, 0x00, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x00
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x0b, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x0c0000
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x07, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x02
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x08, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x00
BNE RRET, 1, 0x1, @.failCommand ; Command failed
.skipFullLock: ; (??)
MOV api_SERDES_FW_VERSION, plaftorm_SERDES_FW_VERSION
MOV R3, 1 ; Why, this must be a constant!. Also registered loc_089110_load_config_unknown_1 on original code
BEQ R3, 0, 0x1, @.successCommand ; Skip CRC and version checks
MOV api_BSM_STATUS, 0x0004000e
FASTCALL @execute_SBus_PCIE_Command, 0x02, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x02 ; Do MASTER FW CRC check
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x07, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x01 ; Do MASTER FW CRC check read result
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x03, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x3c0000 ; Do All SerDes FW CRC check
BNE RRET, 1, 0x1, @.failCommand ; Command failed
WAIT 1000
.doMasterCRCCheck:
FASTCALL @execute_SBus_PCIE_Command, 0x09, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 1, 0x00 ; Check MASTER FW CRC check
BNE RRET, 1, 0x1, @.failCommand ; Command failed
BEQ RRET_X, 0x00008000, 0x00008000, @.doMasterCRCCheck ; If not finish check yet?
BNE RRET_X, 0x00010000, 0xffff0000, @.doAllSerdesCRCCheck ; If check failed, skip setting the proper value
; Command Executed
SET api_BSM_STATUS, 0x00100000, 0x00100000 ; Set Master CRC = OK
MOV api_PCIE_FW_CHECK_STATUS, api_BSM_STATUS
WRITE api_SERDES_STATUS_1, 0x00000000, 0x00000000 ; 64-bit write
.doAllSerdesCRCCheck:
MOV BSM_COUNTER_1, platform_SERDES_SPICO_COUNT ; Number of SerDes SPICO
.loopAllSerdesCRCCheck:
BEQ BSM_COUNTER_1, 0, 0xffffffff, @.finishAllSerdesCRCCheck
BEQ BSM_COUNTER_1, 0, 0x00000001, @.doSingleSerdesCRCCheck
SUB BSM_COUNTER_1, BSM_COUNTER_1, 1
JUMP @.loopAllSerdesCRCCheck
.doSingleSerdesCRCCheck:
FASTCALL @execute_SBus_PCIE_Command, 0x04, BSM_COUNTER_1, 1, 0x00 ; Do SerDes SPICO read
BNE RRET, 1, 0x1, @.failCommand ; Command failed
BEQ RRET_X, 0x00010000, 0x00010000, @.doSingleSerdesCRCCheck ; If not finish check yet?
BNE RRET_X, 0x00000000, 0x0000ffff, @.finishAllSerdesCRCCheck ; If check failed, skip setting the proper value
; Prepare and set register for success
MOV R4, 0x00000001
BEQ BSM_COUNTER_1, platform_SERDES_SPICO_COUNT, 0xffffffff, @.setAllSerdesCRCCheckValue ; Number of SerDes SPICO
SHR R5, BSM_COUNTER_1, 1
SUB R5, R5, 1
SHL R4, R4, R5
; R4 = 1 << (R5 = (BSM_COUNTER[1] >> 1) - 1)
OR api_SERDES_STATUS_1, api_SERDES_STATUS_1, R4
JUMP @.finishAllSerdesCRCCheck
.setAllSerdesCRCCheckValue:
MOV api_SERDES_STATUS_2, R4
.finishAllSerdesCRCCheck:
LOOP~1, @.loopAllSerdesCRCCheck
BNE api_SERDES_STATUS_2, 0x01, 0xffffffff, @.doMasterVersionCheck; Checks failed
BNE api_SERDES_STATUS_1, 0xffffffff, 0xffffffff, @.doMasterVersionCheck; Checks failed
SET api_BSM_STATUS, 0x00200000, 0x00200000 ; Set All Serdes CRC = OK
MOV api_PCIE_FW_CHECK_STATUS, api_BSM_STATUS
.doMasterVersionCheck:
FASTCALL @execute_SBus_PCIE_Command, 0x02, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x00 ; Do MASTER FW Version check
BNE RRET, 1, 0x1, @.failCommand ; Command failed
FASTCALL @execute_SBus_PCIE_Command, 0x07, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 0, 0x01 ; Do MASTER FW Version check read result
BNE RRET, 1, 0x1, @.failCommand ; Command failed
.doMasterVersionCheckRead:
FASTCALL @execute_SBus_PCIE_Command, 0x08, platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS, 1, 0x00 ; Check MASTER FW Version
BNE RRET, 1, 0x1, @.failCommand ; Command failed
BEQ RRET_X, 0x00008000, 0x00008000, @.doMasterVersionCheckRead ; If not finish check yet?
; Compare api_MASTER_FW_VERSION and Returned version
AND R6, api_MASTER_FW_VERSION, 0xffff0000
AND R7, RRET_X, 0xffff0000
SUB R6, R6, R7
BNE R6, 0x00000000, 0xffffffff, @.doAllSerdesVersionCheck ; If check failed, skip setting the proper value
; Command Executed
SET api_BSM_STATUS, 0x01000000, 0x01000000 ; Set Master version = OK
MOV api_PCIE_FW_CHECK_STATUS, api_BSM_STATUS
.doAllSerdesVersionCheck:
FASTCALL @execute_SBus_PCIE_Command, 0x03, platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS, 0, 0x00 ; Do All SerDes FW Version check
BNE RRET, 1, 0x1, @.failCommand ; Command failed
WRITE api_SERDES_STATUS_3, 0x00000000, 0x00000000 ; 64-bit write
MOV BSM_COUNTER_1, platform_SERDES_SPICO_COUNT ; Number of SerDes SPICO
AND R6, api_SERDES_FW_VERSION, 0xffff0000
SHR R6, R6, 0x10 ; R6 >> 10
.loopAllSerdesVersionCheck:
BEQ BSM_COUNTER_1, 0, 0xffffffff, @.finishAllSerdesVersionCheck
BEQ BSM_COUNTER_1, 0, 0x00000001, @.doSingleSerdesVersionCheck
SUB BSM_COUNTER_1, BSM_COUNTER_1, 1
JUMP @.loopAllSerdesVersionCheck
.doSingleSerdesVersionCheck:
FASTCALL @execute_SBus_PCIE_Command, 0x04, BSM_COUNTER_1, 1, 0x00 ; Do SerDes SPICO read
BNE RRET, 1, 0x1, @.failCommand ; Command failed
BEQ RRET_X, 0x00010000, 0x00010000, @.doSingleSerdesVersionCheck ; If not finish check yet?
AND R7, RRET_X, 0x0000ffff
SUB R7, R6, R7 ; Compare against api_SERDES_FW_VERSION
BNE R7, 0x00000000, 0xffffffff, @.finishAllSerdesVersionCheck ; If check failed, skip setting the proper value
; Prepare and set register for success
MOV R4, 0x00000001
BEQ BSM_COUNTER_1, platform_SERDES_SPICO_COUNT, 0xffffffff, @.setAllSerdesVersionCheckValue ; Number of SerDes SPICO
SHR R5, BSM_COUNTER_1, 1
SUB R5, R5, 1
SHL R4, R4, R5
; R4 = 1 << (R5 = (BSM_COUNTER[1] >> 1) - 1)
OR api_SERDES_STATUS_3, api_SERDES_STATUS_3, R4
JUMP @.finishAllSerdesVersionCheck
.setAllSerdesVersionCheckValue:
MOV api_SERDES_STATUS_4, R4
.finishAllSerdesVersionCheck:
LOOP~1, @.loopAllSerdesVersionCheck
BNE api_SERDES_STATUS_4, 0x01, 0xffffffff, @.successCommand ; Checks failed
BNE api_SERDES_STATUS_3, 0xffffffff, 0xffffffff, @.successCommand ; Checks failed
SET api_BSM_STATUS, 0x00200000, 0x00200000 ; Set All Serdes version = OK
MOV api_PCIE_FW_CHECK_STATUS, api_BSM_STATUS
.successCommand:
MOV RRET, 1 ; Success
MOV api_BSM_STATUS, 0x0008000e
MOV api_PCIE_SERDES_FW_DL_STATUS, api_BSM_STATUS
RET
.failCommand:
MOV RRET, 0 ; Failure
SET api_BSM_STATUS, 0x0000fff0, 0x0000fff0
MOV api_PCIE_SERDES_FW_DL_STATUS, api_BSM_STATUS
MOV api_PCIE_SERDES_STATUS, 1
RET

View file

@ -26,6 +26,15 @@
.constant platform_STEPPING_A0 0 ; Old FM10K?. Unknown features
.constant platform_STEPPING_B0 1 ; Existing FM10K
.constant platform_PCIE_SBUS_LOCK_FREE 0
.constant platform_PCIE_SBUS_LOCK_NVM 1
.constant platform_PCIE_SBUS_LOCK_API 2
.constant platform_PCIE_MASTER_SPICO_DEVICE_ADDRESS 0xfd
.constant platform_PCIE_ALL_SERDES_SPICO_DEVICE_ADDRESS 0xff
.constant platform_SERDES_SPICO_COUNT 0x42
; Change this?
.constant platform_PCIE_SBUS_LOCK_HOLD BSM_SCRATCH_START +0x166