@@ -69,7 +69,15 @@ enum Trace {
6969 seq_state : Result < fmc_periph:: A0Sm , u8 > ,
7070 } ,
7171 PowerDownError ( drv_cpu_seq_api:: SeqError ) ,
72-
72+ Coretype {
73+ coretype0 : bool ,
74+ coretype1 : bool ,
75+ coretype2 : bool ,
76+ sp5r1 : bool ,
77+ sp5r2 : bool ,
78+ sp5r3 : bool ,
79+ sp5r4 : bool ,
80+ } ,
7381 #[ count( skip) ]
7482 None ,
7583}
@@ -101,6 +109,25 @@ const SP_TO_FPGA2_SYSTEM_RESET_L: sys_api::PinSet = sys_api::Port::A.pin(5);
101109// to use that pin for FMC).
102110const SP_TO_IGN_TRGT_FPGA_FAULT_L : Option < sys_api:: PinSet > = None ;
103111
112+ const SP5_TO_SP_PRESENT_L : sys_api:: PinSet = sys_api:: Port :: C . pin ( 13 ) ;
113+
114+ const SP5_TO_SP_SP5R1 : sys_api:: PinSet = sys_api:: Port :: I . pin ( 4 ) ;
115+ const SP5_TO_SP_SP5R2 : sys_api:: PinSet = sys_api:: Port :: H . pin ( 15 ) ;
116+ const SP5_TO_SP_SP5R3 : sys_api:: PinSet = sys_api:: Port :: F . pin ( 3 ) ;
117+ const SP5_TO_SP_SP5R4 : sys_api:: PinSet = sys_api:: Port :: F . pin ( 4 ) ;
118+
119+ const SP5_TO_SP_CORETYPE0 : sys_api:: PinSet = sys_api:: Port :: I . pin ( 5 ) ;
120+ const SP5_TO_SP_CORETYPE1 : sys_api:: PinSet = sys_api:: Port :: I . pin ( 10 ) ;
121+ const SP5_TO_SP_CORETYPE2 : sys_api:: PinSet = sys_api:: Port :: I . pin ( 11 ) ;
122+
123+ // All of these are externally pulled to V3P3_SP5_A1
124+ const CORETYPE_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
125+ const CPU_PRESENT_L_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
126+ const SP5R1_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
127+ const SP5R2_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
128+ const SP5R3_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
129+ const SP5R4_PULL : sys_api:: Pull = sys_api:: Pull :: None ;
130+
104131////////////////////////////////////////////////////////////////////////////////
105132
106133/// Helper type which includes both sequencer and NIC state machine states
@@ -181,6 +208,16 @@ fn init() -> Result<ServerImpl, SeqError> {
181208 ) ;
182209 sys. gpio_reset ( SP_CHASSIS_STATUS_LED ) ;
183210
211+ // Set all of the presence-related pins to be inputs
212+ sys. gpio_configure_input ( SP5_TO_SP_CORETYPE0 , CORETYPE_PULL ) ;
213+ sys. gpio_configure_input ( SP5_TO_SP_CORETYPE1 , CORETYPE_PULL ) ;
214+ sys. gpio_configure_input ( SP5_TO_SP_CORETYPE2 , CORETYPE_PULL ) ;
215+ sys. gpio_configure_input ( SP5_TO_SP_PRESENT_L , CPU_PRESENT_L_PULL ) ;
216+ sys. gpio_configure_input ( SP5_TO_SP_SP5R1 , SP5R1_PULL ) ;
217+ sys. gpio_configure_input ( SP5_TO_SP_SP5R2 , SP5R2_PULL ) ;
218+ sys. gpio_configure_input ( SP5_TO_SP_SP5R3 , SP5R3_PULL ) ;
219+ sys. gpio_configure_input ( SP5_TO_SP_SP5R4 , SP5R4_PULL ) ;
220+
184221 let spi_front = drv_spi_api:: Spi :: from ( SPI_FRONT . get_task_id ( ) ) ;
185222 let aux = drv_auxflash_api:: AuxFlash :: from ( AUXFLASH . get_task_id ( ) ) ;
186223
@@ -397,6 +434,11 @@ impl ServerImpl {
397434 Ok ( A0Sm :: Faulted ) | Err ( _) => {
398435 break ;
399436 }
437+ Ok ( A0Sm :: EnableGrpA ) => {
438+ // We have an outstanding issue on v1 hardware-cosmo#658
439+ // that prevents us from checking `CPU_PRESENT` at
440+ // `A0Sm::ENABLE_GRP_A` time
441+ }
400442 _ => ( ) ,
401443 }
402444 hl:: sleep_for ( 10 ) ;
@@ -414,6 +456,46 @@ impl ServerImpl {
414456 return Err ( CpuSeqError :: A0Timeout ) ;
415457 }
416458
459+ let coretype0 = self . sys . gpio_read ( SP5_TO_SP_CORETYPE0 ) != 0 ;
460+ let coretype1 = self . sys . gpio_read ( SP5_TO_SP_CORETYPE1 ) != 0 ;
461+ let coretype2 = self . sys . gpio_read ( SP5_TO_SP_CORETYPE2 ) != 0 ;
462+ let sp5r1 = self . sys . gpio_read ( SP5_TO_SP_SP5R1 ) != 0 ;
463+ let sp5r2 = self . sys . gpio_read ( SP5_TO_SP_SP5R2 ) != 0 ;
464+ let sp5r3 = self . sys . gpio_read ( SP5_TO_SP_SP5R3 ) != 0 ;
465+ let sp5r4 = self . sys . gpio_read ( SP5_TO_SP_SP5R4 ) != 0 ;
466+
467+ ringbuf_entry ! ( Trace :: Coretype {
468+ coretype0,
469+ coretype1,
470+ coretype2,
471+ sp5r1,
472+ sp5r2,
473+ sp5r3,
474+ sp5r4
475+ } ) ;
476+
477+ // From sp5-mobo-guide-56870_1.1.pdf table 72
478+ match ( coretype0, coretype1, coretype2) {
479+ // These correspond to Type-2 and Type-3
480+ ( true , false , true ) | ( true , false , false ) => ( ) ,
481+ // Reject all other combos and return to A0
482+ _ => {
483+ self . seq . power_ctrl . modify ( |m| m. set_a0_en ( false ) ) ;
484+ return Err ( CpuSeqError :: UnrecognizedCPU ) ;
485+ }
486+ } ;
487+
488+ // From sp5-mobo-guide-56870_1.1.pdf table 73
489+ match ( sp5r1, sp5r2, sp5r3, sp5r4) {
490+ // There is only combo we accept here
491+ ( true , false , false , false ) => ( ) ,
492+ // Reject all other combos and return to A0
493+ _ => {
494+ self . seq . power_ctrl . modify ( |m| m. set_a0_en ( false ) ) ;
495+ return Err ( CpuSeqError :: UnrecognizedCPU ) ;
496+ }
497+ } ;
498+
417499 // Flip the host flash mux so the CPU can read from it
418500 // (this is secretly infallible on Cosmo, so we can unwrap it)
419501 self . hf . set_mux ( drv_hf_api:: HfMuxState :: HostCPU ) . unwrap ( ) ;
0 commit comments