FreeCalypso > hg > fc-tourmaline
view src/cs/services/cst/cst_pei.c @ 223:740a8e8fc9d7
startup sync logic rework for the new PWON button boot scheme
Previously we added logic to the MMI task to hold off PEI init until
R2D is running, and then extended that condition to wait for FCHG
init too. However, the dependencies of MMI upon R2D and FCHG don't
start until mmiInit(), and that call is driven by Switch_ON() code,
hence the wait for R2D and FCHG init can be made in that code path
instead of the MMI task. Furthermore, with our new way of signaling
PWON button boot to MMI, we need a new wait to ensure that the MMI
task is up - previously this assurance was provided by the wait for
Kp pointers to be set.
Solution: revert our previous PEI init hold-off additions to MMI,
add a new flag indicating MMI task init done, and put the combined
wait for all needed conditions into our new PWON button boot code
in power.c.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 27 Apr 2021 06:24:52 +0000 |
parents | 4e78acac3d88 |
children |
line wrap: on
line source
/* +--------------------------------------------------------------------+ /* +-------------------------------------------------------------------+ | PROJECT: GSM-F&D (8411) $Workfile:: cst_pei.c $| | $Author:: Be $ CONDAT GmbH $Revision:: 14 $| | CREATED: 01.02.99 $Modtime:: 14.02.00 12:14 $| | STATE : code | +--------------------------------------------------------------------+ MODULE : CST_PEI PURPOSE : This Modul defines the process body interface for the component CST of the mobile station. EXPORT : pei_create - Create the Protocol Stack Entity pei_init - Initialize Protocol Stack Entity pei_primitive - Process Primitive pei_timeout - Process Timeout pei_exit - Close resources and terminate pei_run - Process Primitive pei_config - Dynamic Configuration pei_monitor - Monitoring of physical Parameters */ #ifndef CST_PEI_C #define CST_PEI_C #endif #include "config/swconfig.cfg" #include "config/chipset.cfg" #ifndef DISABLE_SLEEP #define DISABLE_SLEEP 0 #endif #define ENTITY_CST /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <ctype.h> #include "typedefs.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "prim.h" #include "cst/cnf_cst.h" #include "cst/cus_cst.h" #include "cst/mon_cst.h" #include "tok.h" #include "p_cst.h" #include "cst/cst.h" #include "rx.h" #include "audio.h" /*==== CONSTANTS ==================================================*/ // token processing #define ERROR -1 #define EOS 1 #define COMMA 2 #define EQUAL 3 #define IDENT 4 #define STRING 5 #define LBRACK 6 #define RBRACK 7 /*==== EXPORT =====================================================*/ extern void CST_stack_trace(void); int cst_gsm_parameters(TOK_DCB *dcb); extern void l1_cst_l1_parameters(char*); extern void csf_adc_start (UBYTE tx_flag, UBYTE traffic_period, UBYTE idle_period); extern void spi_adc_on (void); GLOBAL T_HANDLE t_adc_timer = VSI_ERROR; GLOBAL T_HANDLE hCommPL = VSI_ERROR; /* PL Communication */ GLOBAL T_HANDLE hCommL1 = VSI_ERROR; /* L1 Communication */ T_HANDLE cst_handle; GLOBAL UBYTE extDisplay = 0; EXTERN UBYTE audio_is_free; /*==== PRIVATE ====================================================*/ LOCAL const void pei_not_supported (void *data); #ifdef OPTION_RELATIVE LOCAL ULONG offset; #endif /*==== VARIABLES ==================================================*/ LOCAL USHORT t_flag = 0; LOCAL BOOL exit_flag = FALSE; LOCAL BOOL first_access = TRUE; LOCAL T_MONITOR cst_mon; /*==== FUNCTIONS ==================================================*/ LOCAL const T_FUNC cst_table[] = { MAK_FUNC_0 ( csf_adc_process , CST_ADC_IND ) }; /*==== PROTOTYPES==================================================*/ #if defined (_TMS470) static SHORT cst_tok_gettok (TOK_DCB *dcb, char ** token); static SHORT cst_tok_value (TOK_DCB *dcb, char * value []); static int cst_tokenizer_has_more_data(const TOK_DCB *dcb); static SHORT cst_tok_issep (char c); static void cst_tok_init (char * s, TOK_DCB *dcb, char *buf, int buf_len); static SHORT cst_get_values(TOK_DCB *dcb, char *value[]); static int cst_getbyte(TOK_DCB *dcb); #endif /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_primitive | +--------------------------------------------------------------------+ PURPOSE : This function processes protocol specific primitives. */ LOCAL SHORT pei_primitive (void * ptr) { T_PRIM *prim = ptr; if (prim NEQ NULL) { USHORT opc = prim->custom.opc; USHORT n; const T_FUNC *table; VSI_PPM_REC ((T_PRIM_HEADER*)prim, __FILE__, __LINE__); switch (opc & OPC_MASK) { case CST_DL: table = cst_table; n = TAB_SIZE (cst_table); break; default : table = NULL; n = 0; break; } if (table != NULL ) { if ((opc & PRM_MASK) < n) { table += opc & PRM_MASK; #ifdef PALLOC_TRANSITION P_SDU(prim) = table->soff ? (T_sdu*) (((char*)&prim->data) + table->soff) : 0; P_LEN(prim) = table->size + sizeof (T_PRIM_HEADER); #endif JUMP (table->func) (P2D(prim)); } else { pei_not_supported (P2D(prim)); } return PEI_OK; } #ifdef GSM_ONLY PFREE (P2D(prim)) return PEI_ERROR; #else if (opc & SYS_MASK) { vsi_c_primitive (VSI_CALLER prim); } else { PFREE (P2D(prim)) return PEI_ERROR; } #endif } return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_not_supported | +--------------------------------------------------------------------+ PURPOSE : This function handles an unsupported primitive. */ LOCAL const void pei_not_supported (void *data) { TRACE_FUNCTION ("pei_not_supported()"); PFREE (data); } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_init | +--------------------------------------------------------------------+ PURPOSE : This function initializes the protocol stack entity */ LOCAL SHORT pei_init (T_HANDLE handle) { cst_handle = handle; TRACE_FUNCTION ("pei_init()"); exit_flag = FALSE; if (hCommPL < VSI_OK) { if ((hCommPL = vsi_c_open (VSI_CALLER PL_NAME)) < VSI_OK) { return PEI_ERROR; } } if (hCommL1 < VSI_OK) { if ((hCommL1 = vsi_c_open (VSI_CALLER L1_NAME)) < VSI_OK) { return PEI_ERROR; } } vsi_t_start (VSI_CALLER CST_ADC_TIMER, 230); // equal to 50 TDMA frames #if defined (_TMS470) // Set the sleep mode authorized for the layer1 synchronous. // Possible modes are : // for CHIPSET = 0 : NO_SLEEP, SMALL_SLEEP, BIG_SLEEP. // It is necessary to indicate in the prototype of power_down_config() // function which clocks (amongst ARMIO_CLK, UWIRE_CLK, SIM_CLK and UART_CLK) // to be stopped in case of BIG_SLEEP mode. // With this default init, ARMIO_CLK, UWIRE_CLK, SIM_CLK and UART_CLK will be stopped // in case of BIG_SLEEP mode, but it can be changed here. // other CHIPSETs : NO_SLEEP, SMALL_SLEEP, BIG_SLEEP, DEEP_SLEEP, ALL_SLEEP. // It is necessary to indicate in the prototype of power_down_config() // function which clocks to be stopped in case of BIG_SLEEP mode, // amongst ARMIO and UWIRE clocks. // With this default init, UWIRE_CLK will always be stopped // in case of BIG_SLEEP mode, but it can be changed here. // The default configuration is ALL SLEEP. It can be changed in this init. // WARNING !! THE SLEEP MODE SHOULD NOT BE MODIFIED ONCE THE SYSTEM INIT IS FINISHED !! #if !defined (TI_VERSION) #if (CHIPSET == 0) power_down_config(NO_SLEEP, ARMIO_CLK | UWIRE_CLK | SIM_CLK | UART_CLK); #elif (DISABLE_SLEEP == 1) power_down_config(NO_SLEEP, UWIRE_CLK_CUT); #elif ((CHIPSET == 2) || (CHIPSET == 3) || \ (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11)) power_down_config(ALL_SLEEP, UWIRE_CLK_CUT); #elif ((CHIPSET == 4) || (CHIPSET == 9)) power_down_config(NO_SLEEP, UWIRE_CLK_CUT); #endif #endif #endif return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_timeout | +--------------------------------------------------------------------+ PURPOSE : This function processes timeouts. */ LOCAL SHORT pei_timeout (USHORT index) { rx_timeout (index); audio_timeout (index); if (index EQ CST_ADC_TIMER) { // start the AD conversions in layer1 synchronous // this function will send MMI_ADC_REQ primitive to L1A for test reason. // The user has to implement it by himself in the MMI. // The parameters are : tx_flag, traffic_period, idle_period. // Please refer to the ADC specification for details. // WCS Patch : Schedule ADC on RX and TX #if (OP_WCP == 1) csf_adc_start(1, 10, 1); #else csf_adc_start(0, 10, 1); #endif spi_adc_on(); } return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_exit | +--------------------------------------------------------------------+ PURPOSE : This function closes all resources and terminates. */ LOCAL SHORT pei_exit (void) { TRACE_FUNCTION ("pei_exit()"); /* * clean up communication */ vsi_c_close (VSI_CALLER hCommPL); hCommPL = VSI_ERROR; vsi_c_close (VSI_CALLER hCommL1); hCommL1 = VSI_ERROR; exit_flag = TRUE; return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_config | +--------------------------------------------------------------------+ PURPOSE : Dynamic Configuration */ #if !defined (NCONFIG) LOCAL KW_DATA kwtab[] = { CST_CONFIG, ID_CONFIG, CST_MUTE, ID_MUTE, CST_GSM_PARAMETERS, ID_GSM_PARAMETERS, CST_L1_PARAMETERS, ID_L1_PARAMETERS, "", 0 }; GLOBAL KW_DATA partab[] = { "", 0 }; #endif GLOBAL SHORT pei_config (T_PEI_CONFIG inString) { #if !defined (NCONFIG) char * s = inString; SHORT valno; USHORT keyno; char * keyw; char * val [10]; TOK_DCB tokenizer; char token_buf[80]; SHORT token_type; int error; /* terminate processing */ TRACE_FUNCTION ("pei_config()"); TRACE_FUNCTION (s); cst_tok_init(s, &tokenizer, &token_buf[0], sizeof(token_buf)); /* * Parse next keyword and number of variables */ error = 0; while (!error && cst_tokenizer_has_more_data(&tokenizer)) { token_type = cst_tok_gettok(&tokenizer, &keyw); if (token_type != IDENT) { error = 1; } else { switch ((keyno = tok_key((KW_DATA *)kwtab, keyw))) { case ID_CONFIG: valno = cst_get_values(&tokenizer, val); if (valno EQ 3) { extDisplay = 1; } break; case ID_MUTE: valno = cst_get_values(&tokenizer, val); /* eat up rest of line */ /* * FTA testcase 26.6.3.4 needs the the MS is in audio free * environment. This config disables opening of the audio * path. */ audio_is_free = FALSE; break; case ID_GSM_PARAMETERS: cst_gsm_parameters(&tokenizer); break; case ID_L1_PARAMETERS: /* pass parameters to L1 function for further process */ l1_cst_l1_parameters(s); valno = cst_get_values(&tokenizer, val); /* eat up rest of line */ break; default: TRACE_ERROR ("[PEI_CONFIG]: Illegal Keyword"); break; } } } #endif return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : CST_PEI | | STATE : code ROUTINE : cst_pei_config | +--------------------------------------------------------------------+ PURPOSE : Dynamic Configuration */ GLOBAL SHORT cst_pei_config ( char * inString, char * dummy ) { pei_config ( inString ); } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_monitor | +--------------------------------------------------------------------+ PURPOSE : This function monitors physical parameters. */ LOCAL SHORT pei_monitor (void ** monitor) { TRACE_FUNCTION ("pei_monitor()"); cst_mon.version = VERSION_CST; *monitor = &cst_mon; return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : pei_create | +--------------------------------------------------------------------+ PURPOSE : This function creates the protocol stack entity. */ GLOBAL SHORT cst_pei_create (T_PEI_INFO **info) { static const T_PEI_INFO pei_info = { "CST", { pei_init, pei_exit, pei_primitive, pei_timeout, NULL, /* no signal function */ NULL, /* no run function */ pei_config, pei_monitor, }, 1536, /* Stack Size */ 10, /* Queue Entries */ 55, /* Priority */ MAX_CST_TIMER, /* number of timer */ 0x03 /* flags */ }; TRACE_FUNCTION ("pei_create()"); /* * Close Resources if open */ if (first_access) first_access = FALSE; else pei_exit (); /* * Export startup configuration data */ *info = (T_PEI_INFO *)&pei_info; return PEI_OK; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_tok_init | +--------------------------------------------------------------------+ PURPOSE : Initialize token scanner. */ static void cst_tok_init (char * s, TOK_DCB *dcb, char *buf, int buf_len) { int i; dcb->nexttok = dcb->tokbuf = buf; // can't use strcpy since it stops at 0s for (i=0; i<buf_len-1; i++) { dcb->tokbuf[i] = s[i]; } dcb->tokbuf[buf_len-1] = '\0'; dcb->lastchar = 0; } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_get_values | +--------------------------------------------------------------------+ */ static SHORT cst_get_values(TOK_DCB *dcb, char *value[]) { char * val; /* not identifier, so thrown away */ /* * Check next token */ switch (cst_tok_gettok (dcb, &val)) { /* * No value present */ case COMMA: return (0); /* * Value(s) follows */ case EQUAL: return (cst_tok_value (dcb, value)); /* * No value present and EOS */ case EOS: dcb->nexttok = NULL; return (0); /* * Syntax error */ default: dcb->nexttok = NULL; return (TOK_EOCS); } } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_tok_value | +--------------------------------------------------------------------+ */ static SHORT cst_tok_value (TOK_DCB *dcb, char * value []) { SHORT count; SHORT tok; SHORT inbrack; char * val; char * val2; inbrack = 0; /* * Get next token */ tok = cst_tok_gettok (dcb, &val); switch (tok) { case LBRACK: inbrack++; break; case IDENT : case STRING : tok = cst_tok_gettok (dcb, &val2); /* val2 ignored since next tok */ if ((tok == COMMA) || (tok == EOS)) /* shouldn't be an IDENT */ { /* just single value, return */ value[0] = val; return (1); } else { /* error */ dcb->nexttok = NULL; return (0); } case EOS : default : dcb->nexttok = NULL; return (0); } /* * Get first token of list */ tok = cst_tok_gettok (dcb, &val); count = 0; while (1) { if ((tok == IDENT) || (tok == STRING)) { value[count++] = val; } else { dcb->nexttok = NULL; return (0); } tok = cst_tok_gettok (dcb, &val); switch (tok) { case COMMA: break; case RBRACK : if (inbrack) { if (((tok = cst_tok_gettok (dcb, &val)) == COMMA) || (tok == EOS)) { return (count); } } /* * Fall through */ default: dcb->nexttok = NULL; return (0); } tok = cst_tok_gettok (dcb, &val); } return (0); } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_tok_gettok | +--------------------------------------------------------------------+ PURPOSE : Get list of values for token. Return number of values found. Formats: Value (Value) (Value, Value,...) () */ static SHORT cst_tok_gettok (TOK_DCB *dcb, char ** token) { SHORT tok; /* if previous token was IDENT, a '\0' was placed afterwards * for string processing and the overwritten character was * placed in lastchar. We now replace this character. */ if (dcb->lastchar) { *(dcb->nexttok) = dcb->lastchar; dcb->lastchar = 0; } /* * Skip leading white space */ while (isspace (*(dcb->nexttok))) { dcb->nexttok++; } * token = dcb->nexttok++; switch (** token) { case '\0': /* End of string */ case '\n': tok = EOS; break; case ',': ** token = '\0'; tok = COMMA; break; case '=': ** token = '\0'; tok = EQUAL; break; case '(': case '<': case '[': ** token = '\0'; tok = LBRACK; break; case ')': case '>': case ']': ** token = '\0'; tok = RBRACK; break; case '"': /* * Get first char of string */ * token = dcb->nexttok; while ((*(dcb->nexttok) != '\0') && (*(dcb->nexttok) != '"')) { dcb->nexttok++; } if (*(dcb->nexttok) != '\0') { *(dcb->nexttok++) = '\0'; } tok = STRING; break; default: /* * Read an identifier */ while ( !cst_tok_issep (*(dcb->nexttok)) ) { dcb->nexttok++; } dcb->lastchar = *(dcb->nexttok); *(dcb->nexttok) = '\0'; if (*token == dcb->nexttok) { /* no characters in identifier. Error in code! */ tok = ERROR; } else { tok = IDENT; } break; } return (tok); } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_tok_issep | +--------------------------------------------------------------------+ PURPOSE : Return 1 if special character. */ static SHORT cst_tok_issep (char c) { switch (c) { case '\0' : case '\n' : case ',' : case '=' : case '(' : case '<' : case '[' : case ')' : case '>' : case ']' : case '"' : return (1); default : return (isspace (c)); } } /* if string in tokenizer state has unprocessed tokens return 1 */ /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_tokenizer_has_more_data | +--------------------------------------------------------------------+ PURPOSE : Return 1 if string in tokenizer state has unprocessed tokens. */ static int cst_tokenizer_has_more_data(const TOK_DCB *dcb) { return (dcb->nexttok != NULL); } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_getbyte | +--------------------------------------------------------------------+ */ static int cst_getbyte(TOK_DCB *dcb) { if (dcb->nexttok) { return *(dcb->nexttok++); } else { return -1; } } /* +--------------------------------------------------------------------+ | PROJECT : XXX MODULE : CST_PEI | | STATE : code ROUTINE : cst_gsm_parameters | +--------------------------------------------------------------------+ */ int cst_gsm_parameters(TOK_DCB *dcb) { unsigned char id; char str[80]; int i; // STRIP FIRST TWO DELIMITERS { char *tok_string; if (cst_tok_gettok(dcb, &tok_string) != EQUAL) { return (0); } if (cst_tok_gettok(dcb, &tok_string) != LBRACK) { return (0); } } // GET CONTROL ID if ((id = cst_getbyte(dcb)) == -1) { // vsi_o_trace("CST", 0x08, "gsm_parameters() parser error: out of bytes"); return (0); } // STACK TRACE else if (id == '1') { CST_stack_trace(); } //end else if (id == '1') // Crash Me else if (id == '2') { // No instruction before setting the reset vector void (*reset_vector)() = (void (*)()) 0x3000000; (*reset_vector)(); } //end else if (id == '2') #if defined (ALR) // Print Reg Copy else if (id == '3') { extern int xdump_buffer; int *xp = &xdump_buffer; int magic_word; // displays the 16 User mode 32bits registers saved on exception // vsi_o_trace("CST", 0x08, "User mode registers [r0-r15] = ..."); for (i=0; i<4; i++) { sprintf(str, "%08x %08x %08x %08x", *(xp++), *(xp++), *(xp++), *(xp++)); // vsi_o_trace("CST", 0x08, str); } // displays the User mode CPSR saved on exception sprintf(str, "User mode CPSR = %08x", *(xp++)); // vsi_o_trace("CST", 0x08, str); // displays the magic word and the index of vector taken magic_word = *(xp++); sprintf(str, "Magic Word + Index of Vector = %08x", magic_word); // vsi_o_trace("CST", 0x08, str); // displays the cause of the exception magic_word &= 0x000F; switch (magic_word) { case 1: // vsi_o_trace("CST", 0x08, "Exception: Undefined Instruction"); break; case 2: // vsi_o_trace("CST", 0x08, "Exception: Unexpected Software Interrupt"); break; case 3: // vsi_o_trace("CST", 0x08, "Exception: Abort Prefetch"); break; case 4: // vsi_o_trace("CST", 0x08, "Exception: Abort Data"); break; case 5: // vsi_o_trace("CST", 0x08, "Exception: Reserved"); break; default: break; } // displays the bottom 20 words of user mode stack saved on exception // vsi_o_trace("CST", 0x08, "Bottom 20 words of User mode stack = ..."); for (i=0; i<5; i++) { sprintf(str, "%08x %08x %08x %08x", *(xp++), *(xp++), *(xp++), *(xp++)); // vsi_o_trace("CST", 0x08, str); } } //end else if (id == '3') // Clear Reg Copy else if (id == '4') { extern int xdump_buffer; int *xp = &xdump_buffer; // Clears the 38 32bits registers saved on exception for (i=0; i<38; i++) { *(xp+i) = 0; } // vsi_o_trace("CST", 0x08, "Registers Copy cleared ..."); } //end else if (id == '4') #endif #if (OP_WCP == 1) #if (WCP_PROF == 1) // Enable/disable MC profiler else if (id == '5') { PR_EnableProfiler(0); } else if (id == '6') { PR_EnableProfiler(1); power_down_config(0, 0x5ff); // disable sleep, which interferes with profiler } // Enable/disable CPU Meter else if (id == '7') { PR_EnableCpuMeter(0); } else if (id == '8') { PR_EnableCpuMeter(1); power_down_config(0, 0x5ff); // disable sleep, which interferes with CPU meter } #endif #endif // STRIP LAST DELIMITER { char *tok_string; if (cst_tok_gettok(dcb, &tok_string) != RBRACK) { return (0); } } } // end cst_gsm_parameters /* * Reach here if unexpected event occurs (e.g. Undefined instruction, Abort, * out of memory); choose whether to restart or stay in datadump mode to find * out cause of problem */ void exception_handler(void) { void (*jump_address)() = (void (*)()) ((unsigned)0x0); (*jump_address)(); }