#ifndef _ARM_CP_H_ #define _ARM_CP_H_ class armcoprocessor { typedef std::map mrcmap_t; typedef uint32_t (*uint32fn)(uint32_t); mrcmap_t _mrccode; static int mapkey(int rd, int cp, int o1, int n, int m, int o2) { return (rd<<20)|(cp<<16)|(o1<<12)|(n<<8)|(m<<4)|(o2); } uint32fn findmrc(int rd, int cp, int o1, int n, int m, int o2) { std::pair j= _mrccode.insert(mrcmap_t::value_type(mapkey(rd,cp,o1,n,m,o2), DwordVector())); if (j.second) { genmrc((*j.first).second, rd,cp,o1,n,m,o2); //debug("%08lx: cp[%08lx]: %s\n", &((*j.first).second[0]), (*j.first).first, hexdump((BYTE*)(&((*j.first).second[0])), (*j.first).second.size(), 4).c_str()); } return reinterpret_cast(&((*j.first).second[0])); } static void genmrc(DwordVector& code, int rd, int cp, int o1, int n, int m, int o2) { // MCR {} , , , CRn and CRm {, } * [ write cp reg ] // cond 1110 opcode_1,0 CRn : Rd cp_num opcode_2,1 CRm // MRC {} , , , CRn and CRm {, } * [ read cp reg ] // cond 1110 opcode_1,1 CRn : Rd cp_num opcode_2,1 CRm code.push_back(0xee000010 +(o1<<21)+(rd<<20)+(n<<16)+(0<<12)+(cp<<8)+(o2<<5)+m); // MCR/MRC cp,o1,R0,CRn,CRm,o2 code.push_back(0xe12fff1e); // BX LR CacheRangeFlush(0, 0, CACHE_SYNC_ALL); } public: uint32_t read(int cp, int o1, int n, int m, int o2) { uint32fn mrcfn= findmrc(1,cp,o1,n,m,o2); __try { return mrcfn(0); } __except(1) { debug("ERROR calling(cp%d,%d,C%d,C%d,%d)\n", cp,o1,n,m,o2,mrcfn); return -1; } } void write(int cp, int o1, int n, int m, int o2, uint32_t reg) { uint32fn mrcfn= findmrc(0,cp,o1,n,m,o2); mrcfn(reg); } }; #endif