// // processor_state.c - processor state management routines // // Copyright (c) 2005-2010 Tensilica Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include //---------------------------------------------------------------------- #if defined(__SPLIT__extra_size) // space for "extra" (user special registers and non-coprocessor TIE) state: const unsigned int Xthal_extra_size = XCHAL_NCP_SA_SIZE; #elif defined(__SPLIT__extra_align) const unsigned int Xthal_extra_align = XCHAL_NCP_SA_ALIGN; #elif defined(__SPLIT__cpregs_size) // space for state of TIE coprocessors: const unsigned int Xthal_cpregs_size[8] = { XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_SIZE }; #elif defined(__SPLIT__cpregs_align) const unsigned int Xthal_cpregs_align[8] = { XCHAL_CP0_SA_ALIGN, XCHAL_CP1_SA_ALIGN, XCHAL_CP2_SA_ALIGN, XCHAL_CP3_SA_ALIGN, XCHAL_CP4_SA_ALIGN, XCHAL_CP5_SA_ALIGN, XCHAL_CP6_SA_ALIGN, XCHAL_CP7_SA_ALIGN }; #elif defined(__SPLIT__cp_names) const char * const Xthal_cp_names[8] = { XCHAL_CP0_NAME, XCHAL_CP1_NAME, XCHAL_CP2_NAME, XCHAL_CP3_NAME, XCHAL_CP4_NAME, XCHAL_CP5_NAME, XCHAL_CP6_NAME, XCHAL_CP7_NAME }; #elif defined(__SPLIT__all_extra_size) // total save area size (extra + all coprocessors + min 16-byte alignment everywhere) const unsigned int Xthal_all_extra_size = XCHAL_TOTAL_SA_SIZE; #elif defined(__SPLIT__all_extra_align) // maximum required alignment for the total save area (this might be useful): const unsigned int Xthal_all_extra_align = XCHAL_TOTAL_SA_ALIGN; #elif defined(__SPLIT__num_coprocessors) // number of coprocessors starting contiguously from zero // (same as Xthal_cp_max, but included for Tornado2): const unsigned int Xthal_num_coprocessors = XCHAL_CP_MAX; #elif defined(__SPLIT__cp_num) // actual number of coprocessors: const unsigned char Xthal_cp_num = XCHAL_CP_NUM; #elif defined(__SPLIT__cp_max) // index of highest numbered coprocessor, plus one: const unsigned char Xthal_cp_max = XCHAL_CP_MAX; // index of highest allowed coprocessor number, per cfg, plus one: //const unsigned char Xthal_cp_maxcfg = XCHAL_CP_MAXCFG; #elif defined(__SPLIT__cp_mask) // bitmask of which coprocessors are present: const unsigned int Xthal_cp_mask = XCHAL_CP_MASK; #elif defined(__SPLIT__cp_id_mappings) // Coprocessor ID from its name # ifdef XCHAL_CP0_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP0_IDENT) = 0; # endif # ifdef XCHAL_CP1_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP1_IDENT) = 1; # endif # ifdef XCHAL_CP2_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP2_IDENT) = 2; # endif # ifdef XCHAL_CP3_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP3_IDENT) = 3; # endif # ifdef XCHAL_CP4_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP4_IDENT) = 4; # endif # ifdef XCHAL_CP5_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP5_IDENT) = 5; # endif # ifdef XCHAL_CP6_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP6_IDENT) = 6; # endif # ifdef XCHAL_CP7_IDENT const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP7_IDENT) = 7; # endif #elif defined(__SPLIT__cp_mask_mappings) // Coprocessor "mask" (1 << ID) from its name # ifdef XCHAL_CP0_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP0_IDENT) = (1 << 0); # endif # ifdef XCHAL_CP1_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP1_IDENT) = (1 << 1); # endif # ifdef XCHAL_CP2_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP2_IDENT) = (1 << 2); # endif # ifdef XCHAL_CP3_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP3_IDENT) = (1 << 3); # endif # ifdef XCHAL_CP4_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP4_IDENT) = (1 << 4); # endif # ifdef XCHAL_CP5_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP5_IDENT) = (1 << 5); # endif # ifdef XCHAL_CP6_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP6_IDENT) = (1 << 6); # endif # ifdef XCHAL_CP7_IDENT const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT) = (1 << 7); # endif //---------------------------------------------------------------------- #elif defined(__SPLIT__init_mem_extra) // CMS: I have made the assumptions that 0's are safe initial // values. That may be wrong at some point. // // initialize the extra processor void xthal_init_mem_extra(void *address) /* not clear that it is safe to call memcpy and also not clear that performance is important. */ { unsigned int *ptr; unsigned int *end; ptr = (unsigned int *)address; end = (unsigned int *)((int)address + XCHAL_NCP_SA_SIZE); while( ptr < end ) { *ptr++ = 0; } } #elif defined(__SPLIT__init_mem_cp) // initialize the TIE coprocessor void xthal_init_mem_cp(void *address, int cp) { unsigned int *ptr; unsigned int *end; if( cp <= 7 ) { end = (unsigned int *)((int)address + Xthal_cpregs_size[cp]); ptr = (unsigned int *)address; while( ptr < end ) { *ptr++ = 0; } } } #endif /*splitting*/ /* Nothing implemented below this point. */ /************************************************************************/ // save all extra+cp processor state (NOT IMPLEMENTED) /*void xthal_save_all_extra(void *base) { xthal_save_extra(base); ... here we need to iterate over configured coprocessor register files ... // xthal_save_cpregs(base+XCHAL_NCP_SA_SIZE, 0); }*/ // restore all extra+cp processor state (NOT IMPLEMENTED) /*void xthal_restore_all_extra(void *base) { xthal_restore_extra(base); ... here we need to iterate over configured coprocessor register files ... // xthal_restore_cpregs(base+XCHAL_NCP_SA_SIZE, 0); }*/ // initialize the extra processor (NOT IMPLEMENTED) /*void xthal_init_extra() { }*/ // initialize the TIE coprocessor (NOT IMPLEMENTED) /*void xthal_init_cp(int cp) { }*/ #if 0 /* read extra state register (NOT IMPLEMENTED) */ int xthal_read_extra(void *base, unsigned reg, unsigned *value) { if (reg&0x1000) { switch(reg) { #if XCHAL_HAVE_MAC16 case 16: *value = ((unsigned *)base)[0]; return reg; case 17: *value = ((unsigned *)base)[1]; return reg; case 32: *value = ((unsigned *)base)[2]; return reg; case 33: *value = ((unsigned *)base)[3]; return reg; case 34: *value = ((unsigned *)base)[4]; return reg; case 35: *value = ((unsigned *)base)[5]; return reg; #endif /* XCHAL_HAVE_MAC16 */ } } return -1; } /* write extra state register (NOT IMPLEMENTED) */ int xthal_write_extra(void *base, unsigned reg, unsigned value) { if (reg&0x1000) { switch(reg) { #if XCHAL_HAVE_MAC16 case 16: ((unsigned *)base)[0] = value; return reg; case 17: ((unsigned *)base)[1] = value; return reg; case 32: ((unsigned *)base)[2] = value; return reg; case 33: ((unsigned *)base)[3] = value; return reg; case 34: ((unsigned *)base)[4] = value; return reg; case 35: ((unsigned *)base)[5] = value; return reg; #endif /* XCHAL_HAVE_MAC16 */ } } return -1; } #endif /*0*/ /* read TIE coprocessor register (NOT IMPLEMENTED) */ /*int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value) { return -1; }*/ /* write TIE coproessor register (NOT IMPLEMENTED) */ /*int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value) { return -1; }*/ /* return coprocessor number based on register (NOT IMPLEMENTED) */ /*int xthal_which_cp(unsigned reg) { return -1; }*/