import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_thread_db.c
//
//Doorbell3 interrupt handler
//
//Note: This enabled on both QuadManagerCME and SiblingCME
Doorbell3 interrupt handler
Note: This enabled on both QuadManagerCME and SiblingCME
Doorbell3 interrupt handler Note : This enabled on both QuadManagerCME and SiblingCME
void p9_cme_pstate_db3_handler(void)
{
    cppm_cmedb3_t    db3;
    ppm_sshsrc_t sshsrc;
    uint32_t cm;
    out32(G_CME_LCL_EISR_CLR, BITS32(10, 2));
    CME_GETSCOM(CPPM_CMEDB3, G_cme_pstate_record.firstGoodCoreMask, db3.value);
    PK_TRACE_INF("DB3 Handler DB3=0x%08x%08x", db3.value >> 32, db3.value);
    if((db3.fields.cme_message_numbern == MSGID_DB3_HIGH_PRIORITY_PSTATE) ||
       (db3.fields.cme_message_numbern == MSGID_DB3_REPLAY_DB0) ||
       (db3.fields.cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE))
    {
        G_cme_pstate_record.updateAnalogError = 0;
        G_cme_pstate_record.skipSiblingLock = 1;
        if(G_cme_pstate_record.qmFlag)
        {
            p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2);
            p9_cme_pstate_process_db0();
        }
        else
        {
            while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39)));
            intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0);
            p9_cme_pstate_sibling_lock_and_intercme_protocol(INTERCME_MSG_LOCK_SKIP);
        }
        if (db3.fields.cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE)
        {
            out32(G_CME_LCL_FLAGS_OR, BIT32(CME_FLAGS_SAFE_MODE));
        }
        G_cme_pstate_record.skipSiblingLock = 0;
    }
    else if (db3.fields.cme_message_numbern == MSGID_DB3_DISABLE_SGPE_HANDOFF)
    {
        G_cme_record.disableSGPEHandoff = 1;
        for(cm = 2; cm > 0; cm--)
        {
            if (in32(G_CME_LCL_FLAGS) & cm)
            {
                CME_GETSCOM(PPM_SSHSRC, cm, sshsrc);
                if ((sshsrc.fields.stop_gated == 1) && (
                        (sshsrc.fields.act_stop_level < 5) ||
                        (sshsrc.fields.act_stop_level == 5 && sshsrc.fields.stop_transition != 0x2)))
                {
                    CME_PUTSCOM(CPPM_CPMMR_CLR, cm, BIT64(13));
                    out32(G_CME_LCL_EIMR_CLR, cm << SHIFT32(13));
                }
            }
        }
        if (G_cme_pstate_record.qmFlag)
        {
            p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2);
            send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK);
        }
        else
        {
            while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39)));
            intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0);
        }
    }
    else if (db3.fields.cme_message_numbern == MSGID_DB3_SUSPEND_STOP_ENTRY)
    {
        G_cme_stop_record.core_vdm_droop = CME_MASK_BC;
        if (!(G_cme_stop_record.entry_ongoing ||
              G_cme_stop_record.exit_ongoing))
        {
            p9_cme_stop_eval_eimr_override();
        }
    }
    else if (db3.fields.cme_message_numbern == MSGID_DB3_UNSUSPEND_STOP_ENTRY)
    {
        G_cme_stop_record.core_vdm_droop = 0;
        if (!(G_cme_stop_record.entry_ongoing ||
              G_cme_stop_record.exit_ongoing))
        {
            p9_cme_stop_eval_eimr_override();
        }
        if (G_cme_pstate_record.qmFlag)
        {
            p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2);
            send_ack_to_pgpe(MSGID_PCB_TYPE4_UNSUSPEND_ENTRY_ACK);
        }
        else
        {
            while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39)));
            intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0);
        }
    }
    else if (db3.fields.cme_message_numbern == MSGID_DB3_CLIP_BROADCAST)
    {
        PK_TRACE_INF("PSTATE: DB3 Clip Enter");
        uint32_t dbQuadInfo, dbBit8_15;
        cppm_cmedb0_t dbData;
        CME_GETSCOM(CPPM_CMEDB0, G_cme_pstate_record.firstGoodCoreMask, dbData.value);
        dbBit8_15 = (dbData.value & BITS64(8, 8)) >> SHIFT64(15);
        dbQuadInfo = (dbData.value >> (in32(G_CME_LCL_SRTCH0) &
                                       (BITS32(CME_SCRATCH_LOCAL_PSTATE_IDX_START, CME_SCRATCH_LOCAL_PSTATE_IDX_LENGTH)
                                       ))) & 0xFF;
        if(G_cme_pstate_record.qmFlag)
        {
            p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2);
            if (dbBit8_15 == DB0_CLIP_BCAST_TYPE_PMIN)
            {
                G_cme_pstate_record.pmin = dbQuadInfo;
            }
            else
            {
                G_cme_pstate_record.pmax = dbQuadInfo;
            }
            PK_TRACE_INF("PSTATE: Pmin=0x%x,Pmax=0x%x", G_cme_pstate_record.pmin, G_cme_pstate_record.pmax);
            p9_cme_pstate_pmsr_updt();
            p9_cme_pstate_notify_sib(INTERCME_DIRECT_IN2); 
            send_ack_to_pgpe(MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK);
        }
        else
        {
            while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39)));
            intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0);
            if (dbBit8_15 == DB0_CLIP_BCAST_TYPE_PMIN)
            {
                G_cme_pstate_record.pmin = dbQuadInfo;
            }
            else
            {
                G_cme_pstate_record.pmax = dbQuadInfo;
            }
            p9_cme_pstate_pmsr_updt();
            while(!(in32_sh(CME_LCL_EISR) & BIT64SH(39)));
            intercme_direct(INTERCME_DIRECT_IN2, INTERCME_DIRECT_ACK, 0);
        }
        PK_TRACE_INF("PSTATE: DB3 Clip Exit");
    }
    else
    {
    }
    PK_TRACE_INF("DB3 Handler Done ");
}
void p9_cme_pstate_db3_handler ( void ) { cppm_cmedb3_t db3 ; ppm_sshsrc_t sshsrc ; uint32_t cm ; out32 ( G_CME_LCL_EISR_CLR , BITS32 ( 10 , 2 ) ) ; CME_GETSCOM ( CPPM_CMEDB3 , G_cme_pstate_record . firstGoodCoreMask , db3 . value ) ; PK_TRACE_INF ( " " , db3 . value >> 32 , db3 . value ) ; if ( ( db3 . fields . cme_message_numbern == MSGID_DB3_HIGH_PRIORITY_PSTATE ) || ( db3 . fields . cme_message_numbern == MSGID_DB3_REPLAY_DB0 ) || ( db3 . fields . cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE ) ) { G_cme_pstate_record . updateAnalogError = 0 ; G_cme_pstate_record . skipSiblingLock = 1 ; if ( G_cme_pstate_record . qmFlag ) { p9_cme_pstate_notify_sib ( INTERCME_DIRECT_IN2 ) ; p9_cme_pstate_process_db0 ( ) ; } else { while ( ! ( in32_sh ( CME_LCL_EISR ) & BIT64SH ( 39 ) ) ) ; intercme_direct ( INTERCME_DIRECT_IN2 , INTERCME_DIRECT_ACK , 0 ) ; p9_cme_pstate_sibling_lock_and_intercme_protocol ( INTERCME_MSG_LOCK_SKIP ) ; } if ( db3 . fields . cme_message_numbern == MSGID_DB3_ENTER_SAFE_MODE ) { out32 ( G_CME_LCL_FLAGS_OR , BIT32 ( CME_FLAGS_SAFE_MODE ) ) ; } G_cme_pstate_record . skipSiblingLock = 0 ; } else if ( db3 . fields . cme_message_numbern == MSGID_DB3_DISABLE_SGPE_HANDOFF ) { G_cme_record . disableSGPEHandoff = 1 ; for ( cm = 2 ; cm > 0 ; cm -- ) { if ( in32 ( G_CME_LCL_FLAGS ) & cm ) { CME_GETSCOM ( PPM_SSHSRC , cm , sshsrc ) ; if ( ( sshsrc . fields . stop_gated == 1 ) && ( ( sshsrc . fields . act_stop_level < 5 ) || ( sshsrc . fields . act_stop_level == 5 && sshsrc . fields . stop_transition != 0x2 ) ) ) { CME_PUTSCOM ( CPPM_CPMMR_CLR , cm , BIT64 ( 13 ) ) ; out32 ( G_CME_LCL_EIMR_CLR , cm << SHIFT32 ( 13 ) ) ; } } } if ( G_cme_pstate_record . qmFlag ) { p9_cme_pstate_notify_sib ( INTERCME_DIRECT_IN2 ) ; send_ack_to_pgpe ( MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK ) ; } else { while ( ! ( in32_sh ( CME_LCL_EISR ) & BIT64SH ( 39 ) ) ) ; intercme_direct ( INTERCME_DIRECT_IN2 , INTERCME_DIRECT_ACK , 0 ) ; } } else if ( db3 . fields . cme_message_numbern == MSGID_DB3_SUSPEND_STOP_ENTRY ) { G_cme_stop_record . core_vdm_droop = CME_MASK_BC ; if ( ! ( G_cme_stop_record . entry_ongoing || G_cme_stop_record . exit_ongoing ) ) { p9_cme_stop_eval_eimr_override ( ) ; } } else if ( db3 . fields . cme_message_numbern == MSGID_DB3_UNSUSPEND_STOP_ENTRY ) { G_cme_stop_record . core_vdm_droop = 0 ; if ( ! ( G_cme_stop_record . entry_ongoing || G_cme_stop_record . exit_ongoing ) ) { p9_cme_stop_eval_eimr_override ( ) ; } if ( G_cme_pstate_record . qmFlag ) { p9_cme_pstate_notify_sib ( INTERCME_DIRECT_IN2 ) ; send_ack_to_pgpe ( MSGID_PCB_TYPE4_UNSUSPEND_ENTRY_ACK ) ; } else { while ( ! ( in32_sh ( CME_LCL_EISR ) & BIT64SH ( 39 ) ) ) ; intercme_direct ( INTERCME_DIRECT_IN2 , INTERCME_DIRECT_ACK , 0 ) ; } } else if ( db3 . fields . cme_message_numbern == MSGID_DB3_CLIP_BROADCAST ) { PK_TRACE_INF ( " " ) ; uint32_t dbQuadInfo , dbBit8_15 ; cppm_cmedb0_t dbData ; CME_GETSCOM ( CPPM_CMEDB0 , G_cme_pstate_record . firstGoodCoreMask , dbData . value ) ; dbBit8_15 = ( dbData . value & BITS64 ( 8 , 8 ) ) >> SHIFT64 ( 15 ) ; dbQuadInfo = ( dbData . value >> ( in32 ( G_CME_LCL_SRTCH0 ) & ( BITS32 ( CME_SCRATCH_LOCAL_PSTATE_IDX_START , CME_SCRATCH_LOCAL_PSTATE_IDX_LENGTH ) ) ) ) & 0xFF ; if ( G_cme_pstate_record . qmFlag ) { p9_cme_pstate_notify_sib ( INTERCME_DIRECT_IN2 ) ; if ( dbBit8_15 == DB0_CLIP_BCAST_TYPE_PMIN ) { G_cme_pstate_record . pmin = dbQuadInfo ; } else { G_cme_pstate_record . pmax = dbQuadInfo ; } PK_TRACE_INF ( " " , G_cme_pstate_record . pmin , G_cme_pstate_record . pmax ) ; p9_cme_pstate_pmsr_updt ( ) ; p9_cme_pstate_notify_sib ( INTERCME_DIRECT_IN2 ) ; send_ack_to_pgpe ( MSGID_PCB_TYPE4_ACK_PSTATE_PROTO_ACK ) ; } else { while ( ! ( in32_sh ( CME_LCL_EISR ) & BIT64SH ( 39 ) ) ) ; intercme_direct ( INTERCME_DIRECT_IN2 , INTERCME_DIRECT_ACK , 0 ) ; if ( dbBit8_15 == DB0_CLIP_BCAST_TYPE_PMIN ) { G_cme_pstate_record . pmin = dbQuadInfo ; } else { G_cme_pstate_record . pmax = dbQuadInfo ; } p9_cme_pstate_pmsr_updt ( ) ; while ( ! ( in32_sh ( CME_LCL_EISR ) & BIT64SH ( 39 ) ) ) ; intercme_direct ( INTERCME_DIRECT_IN2 , INTERCME_DIRECT_ACK , 0 ) ; } PK_TRACE_INF ( " " ) ; } else { } PK_TRACE_INF ( " " ) ; }
Doorbell3 interrupt handler
Note: This enabled on both QuadManagerCME and SiblingCME
Doorbell3 interrupt handler Note : This enabled on both QuadManagerCME and SiblingCME
//Clear EISR and read DB3 register //On quadManage, we process the data in DB0. The data is written //by PGPE before writing the DB3 register //On Sibling, poll on intercme_msg "LOCK_SIBLING", then //poll on intercme_in0/1 direct msg. //Wait to receive a notify from Quad Manager //and then ACK back to quad manager //then clear the EIMR[PC_INTERRUPT_PENDING_C1)] //Notify and Receive ack from sibling CME. This syncs up //Quad Manager and Sibling before Quad Manager acks back to //PGPE //Wait to receive a notify from Quad Manager //and then ACK back to quad manager //Note: we don't ack back to PGPE. Instead, the STOP code will set the //CME_FLAGS[SUSPEND_ENTRY] whenever it finishes any currently ongoing entry //Notify and Receive ack from sibling CME. This syncs up //Quad Manager and Sibling before Quad Manager acks back to //PGPE //Wait to receive a notify from Quad Manager //and then ACK back to quad manager //Quad Manager //Sync up with sibling CME //Sync up with the sibling CME before ACKing back to PGPE //Notify sibling //Send type4(ack doorbell) //On Sibling, poll on intercme_in2 direct msg. //Wait to receive a notify from Quad Manager //and then ACK back to quad manager //Wait to receive a notify from Quad Manager //and then ACK back to quad manager //\todo  Will be done as part of 41947 //41947