diff options
Diffstat (limited to 'src/include/securerom/hw_utils.H')
-rw-r--r-- | src/include/securerom/hw_utils.H | 387 |
1 files changed, 165 insertions, 222 deletions
diff --git a/src/include/securerom/hw_utils.H b/src/include/securerom/hw_utils.H index 324cdfc25..014d82d20 100644 --- a/src/include/securerom/hw_utils.H +++ b/src/include/securerom/hw_utils.H @@ -22,22 +22,20 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -/**************************************************************************** - * - ****************************************************************************/ + #ifndef HW_UTILS_H #define HW_UTILS_H #include <stdint.h> -#include "sha512.h" -#include "status_codes.h" +#include <securerom/sha512.H> +#include <securerom/status_codes.H> #define ECID_SIZE 16 #define CACHE_LINE 128 #define XSCOM_MASK 0x0003fe0000000000ull // bit 14:22 implemented #define HRMOR_MASK 0x0003fffffe000000ull // 32MB aligned -#define STACK_MASK 0x0003fffffffff000ull // 4KB page aligned //WEH bug fix +#define STACK_MASK 0x0003fffffffff000ull // 4KB page aligned #define ENTRY_MASK 0x7ffffffffffffffCull // 4Byte page aligned #define HRMOR_IGNORE 0x8000000000000000ull @@ -66,22 +64,24 @@ extern int GOOD; #define CHECK_STOP(_m) Check_Stop(_m) #define ERROR_STOP(_c,_m) Error_Stop(CONTEXT|(_c), _m) -typedef struct { - uint64_t GPR[32]; - uint64_t SCRATCH0; - uint64_t SCRATCH1; - uint64_t SCRATCH2; - uint64_t SCRATCH3; - uint64_t HRMOR; - struct { - uint64_t value; - uint64_t mask; - } FSP_BAR; - uint8_t ECID[ECID_SIZE]; - sha2_hash_t PIBMEM_HW_KEY_HASH; - uint8_t* data; // 64M+4K malloc/mmap - uint8_t* memory; // 64M (4K aligned) - int mfd; +typedef struct +{ + uint64_t GPR[32]; + uint64_t SCRATCH0; + uint64_t SCRATCH1; + uint64_t SCRATCH2; + uint64_t SCRATCH3; + uint64_t HRMOR; + struct + { + uint64_t value; + uint64_t mask; + } FSP_BAR; + uint8_t ECID[ECID_SIZE]; + sha2_hash_t PIBMEM_HW_KEY_HASH; + uint8_t* data; // 64M+4K malloc/mmap + uint8_t* memory; // 64M (4K aligned) + int mfd; } hw_settings; extern hw_settings HW; @@ -107,49 +107,55 @@ extern void assem_ISYNC (void); extern void mtspr_HRMOR (uint64_t addr); //extern uint64_t mfspr_HRMOR (void); -static inline uint64_t mfspr_SCRATCH0(void) { - return HW.SCRATCH0; +static inline uint64_t mfspr_SCRATCH0(void) +{ + return HW.SCRATCH0; } -static inline void mtspr_SCRATCH0(uint64_t val) { - HW.SCRATCH0 = val; +static inline void mtspr_SCRATCH0(uint64_t val) +{ + HW.SCRATCH0 = val; } -static inline uint64_t mfspr_SCRATCH1(void) { - return HW.SCRATCH1; +static inline uint64_t mfspr_SCRATCH1(void) +{ + return HW.SCRATCH1; } -static inline void mtspr_SCRATCH1(uint64_t val) { - HW.SCRATCH1 = val; +static inline void mtspr_SCRATCH1(uint64_t val) +{ + HW.SCRATCH1 = val; } -static inline void mtspr_SCRATCH2(uint64_t val) { - HW.SCRATCH2 = val; +static inline void mtspr_SCRATCH2(uint64_t val) +{ + HW.SCRATCH2 = val; } -static inline uint64_t mfspr_SCRATCH2(void) { - return HW.SCRATCH2; +static inline uint64_t mfspr_SCRATCH2(void) +{ + return HW.SCRATCH2; } -static inline void mtspr_SCRATCH3(uint64_t val) { - HW.SCRATCH3 = val; +static inline void mtspr_SCRATCH3(uint64_t val) +{ + HW.SCRATCH3 = val; } -static inline uint64_t mfspr_SCRATCH3(void) { - return HW.SCRATCH3; +static inline uint64_t mfspr_SCRATCH3(void) +{ + return HW.SCRATCH3; } extern uint64_t getscom_FSP_BAR_value (uint64_t base); extern uint64_t getscom_FSP_BAR_mask (uint64_t base); -extern void getscom_HW_ECID (uint64_t base, uint8_t* buf); -extern void getscom_PIBMEM_HW_Key_Hash (uint64_t base, uint8_t* buf); +extern void getscom_HW_ECID (uint64_t base, uint8_t* buf); extern uint64_t physical_addr (uint64_t addr); extern uint8_t* Convert_Mem_Addr (uint64_t); extern uint64_t Convert_Mem_Offset (uint8_t*); -/****************************************************************************/ extern uint16_t GET16 (uint16_t data); extern uint32_t GET32 (uint32_t data); extern uint64_t GET64 (uint64_t data); @@ -191,230 +197,167 @@ extern uint64_t GET64 (uint64_t data); #define PSIHB_NOTRUST_BAR1 0x02013f41 #define PSIHB_NOTRUST_BAR1MASK 0x02013f43 -/****************************************************************************/ -static inline void assem_DCBI(uint64_t addr) { - asm volatile(" dcbi 0,%0 " : : "r" (addr) : "memory"); +static inline void assem_DCBI(uint64_t addr) +{ + asm volatile(" dcbi 0,%0 " : : "r" (addr) : "memory"); } -/****************************************************************************/ -static inline void assem_DCBZ(uint64_t addr) { - asm volatile(" dcbz 0,%0 " : : "r" (addr) : "memory"); +static inline void assem_DCBZ(uint64_t addr) +{ + asm volatile(" dcbz 0,%0 " : : "r" (addr) : "memory"); } -/****************************************************************************/ -static inline void assem_ICBI(uint64_t* addr) { - asm volatile(" icbi 0,%0 " : : "r" (addr) : "memory"); +static inline void assem_ICBI(uint64_t* addr) +{ + asm volatile(" icbi 0,%0 " : : "r" (addr) : "memory"); } -/****************************************************************************/ -static inline void assem_SYNC(void) { - asm volatile("sync 0":::"memory"); +static inline void assem_SYNC(void) +{ + asm volatile("sync 0":::"memory"); } -/****************************************************************************/ -static inline void assem_ISYNC(void) { - asm volatile("isync":::"memory"); +static inline void assem_ISYNC(void) +{ + asm volatile("isync":::"memory"); } -/****************************************************************************/ -static inline uint64_t mfspr(int reg) { - unsigned long val; - asm volatile("mfspr %0, %1" : "=r" (val) : "i" (reg)); - return val; +static inline uint64_t mfspr(int reg) +{ + unsigned long val; + asm volatile("mfspr %0, %1" : "=r" (val) : "i" (reg)); + return val; } -static inline void mtspr(int reg, uint64_t val) { - asm volatile("mtspr %0, %1" : : "i" (reg), "r" (val)); +static inline void mtspr(int reg, uint64_t val) +{ + asm volatile("mtspr %0, %1" : : "i" (reg), "r" (val)); } -/****************************************************************************/ -// -//static inline uint64_t mfspr_HRMOR(void) { -// unsigned long val; -// asm volatile("mfspr %0, %1" : "=r" (val) : "i" (HRMOR)); -// return val; -//} - -static inline void mtspr_HRMOR(uint64_t addr) { - asm volatile("mtspr %0, %1" : : "i" (HRMOR), "r" (addr & HRMOR_MASK)); +static inline void mtspr_HRMOR(uint64_t addr) +{ + asm volatile("mtspr %0, %1" : : "i" (HRMOR), "r" (addr & HRMOR_MASK)); } -/****************************************************************************/ -#if !(CONFIG_MAMBO && CONFIG_MAMBO_WITHOUT_SCRATCH) - -static inline uint64_t mfspr_SCRATCH0(void) { - mtspr(SPRC,SPRC_SCRATCH0); - return mfspr(SPRD); +static inline uint64_t mfspr_SCRATCH0(void) +{ + mtspr(SPRC,SPRC_SCRATCH0); + return mfspr(SPRD); } -static inline void mtspr_SCRATCH0(uint64_t val) { - mtspr(SPRC,SPRC_SCRATCH0); - mtspr(SPRD,val); +static inline void mtspr_SCRATCH0(uint64_t val) +{ + mtspr(SPRC,SPRC_SCRATCH0); + mtspr(SPRD,val); } -static inline uint64_t mfspr_SCRATCH1(void) { - mtspr(SPRC,SPRC_SCRATCH1); - return mfspr(SPRD); +static inline uint64_t mfspr_SCRATCH1(void) +{ + mtspr(SPRC,SPRC_SCRATCH1); + return mfspr(SPRD); } -static inline void mtspr_SCRATCH1(uint64_t val) { - mtspr(SPRC,SPRC_SCRATCH1); - mtspr(SPRD,val); +static inline void mtspr_SCRATCH1(uint64_t val) +{ + mtspr(SPRC,SPRC_SCRATCH1); + mtspr(SPRD,val); } -static inline void mtspr_SCRATCH2(uint64_t val) { - mtspr(SPRC,SPRC_SCRATCH2); - mtspr(SPRD,val); +static inline void mtspr_SCRATCH2(uint64_t val) +{ + mtspr(SPRC,SPRC_SCRATCH2); + mtspr(SPRD,val); } -static inline void mtspr_SCRATCH3(uint64_t val) { - mtspr(SPRC,SPRC_SCRATCH3); - mtspr(SPRD,val); +static inline void mtspr_SCRATCH3(uint64_t val) +{ + mtspr(SPRC,SPRC_SCRATCH3); + mtspr(SPRD,val); } -#else - - #define mfspr_SCRATCH0() ci_read( 0x80C0FFEE00000000ull) - #define mtspr_SCRATCH0(value) ci_write(0x80C0FFEE00000000ull,(value)) - #define mfspr_SCRATCH1() ci_read( 0x80C0FFEE00000008ull) - #define mtspr_SCRATCH1(value) ci_write(0x80C0FFEE00000008ull,(value)) - #define mfspr_SCRATCH2() ci_read( 0x80C0FFEE00000010ull) - #define mtspr_SCRATCH2(value) ci_write(0x80C0FFEE00000010ull,(value)) - #define mfspr_SCRATCH3() ci_read( 0x80C0FFEE00000018ull) - #define mtspr_SCRATCH3(value) ci_write(0x80C0FFEE00000018ull,(value)) - -#endif -/****************************************************************************/ - +extern "C" void __attribute__((noreturn)) Check_Stop(void); -/****************************************************************************/ - #define LOG(_c) mtspr_SCRATCH2(CONTEXT|(_c)) -#define ERROR_STOP(_c,_m) { mtspr_SCRATCH3(ERROR_EVENT|CONTEXT|(_c)); asm volatile("b .Check_Stop"); } - +#define ERROR_STOP(_c,_m) { mtspr_SCRATCH3(ERROR_EVENT|CONTEXT|(_c)); \ + asm volatile("b .Check_Stop"); } -/****************************************************************************/ -/* Bit 56, 61, 62, 63 is not used in XSCOM addresss and must be 0 - */ -#define PCB2PBUS(scom_addr) \ - ((((scom_addr) & 0x7FFFFFF0) << 4) | \ - (((scom_addr) & 0x0000000F) << 3)) +/* Bit 56, 61, 62, 63 is not used in XSCOM addresss and must be 0 */ +#define PCB2PBUS(scom_addr) \ + ((((scom_addr) & 0x7FFFFFF0) << 4) | \ + (((scom_addr) & 0x0000000F) << 3)) -static inline uint64_t ci_read(const uint64_t reg) { - unsigned long val; - asm volatile( "ldcix %0, 0, %1" - : "=r" (val) // output, %0 - : "r" (reg) // input, %1 +static inline uint64_t ci_read(const uint64_t reg) +{ + unsigned long val; + asm volatile( "ldcix %0, 0, %1" + : "=r" (val) // output, %0 + : "r" (reg) // input, %1 // no impacts - ); - //old prism code: - //asm volatile( "ld %0, 0(%1)\n" - // "eieio" - // : "=r" (val) /* output */ - // : "r" (reg) /* input */ - // ); + ); return val; } - -static inline void ci_write(const uint64_t reg, uint64_t val) { - asm volatile("stdcix %0, 0, %1" - : // no outputs - : "r" (val), "r" (reg) // inputs, %0, %1 - : "memory" // affects memory - ); - //old prism code: - //asm volatile("st %0, 0(%1)\n" - // "eieio" - // : /* output */ - // : "r" (val) , "r" (reg) /* input */ - // : "memory"); +static inline void ci_write(const uint64_t reg, uint64_t val) +{ + asm volatile("stdcix %0, 0, %1" + : // no outputs + : "r" (val), "r" (reg) // inputs, %0, %1 + : "memory" // affects memory + ); } -#ifndef CONFIG_MAMBO - - #define getscom(a, b) _getscom((a)+PCB2PBUS(b)) - static inline uint64_t _getscom(uint64_t addr) { - mtspr(HMER,0); - uint64_t value; - uint64_t rslt; - do { - value = ci_read(addr); +#define getscom(a, b) _getscom((a)+PCB2PBUS(b)) +static inline uint64_t _getscom(uint64_t addr) +{ + mtspr(HMER,0); + uint64_t value; + uint64_t rslt; do { - rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL); - } while( (rslt & HMER_XSCOM_DONE)==0 ); - } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry - if(rslt != HMER_XSCOM_DONE){ - ERROR_STOP(XSCOM_ERROR,"XScom read returned unexpected result code"); - } - return value; - } - - #define putscom(xscom_base, scom_addr, value) _putscom(xscom_base + PCB2PBUS(scom_addr),value) - static inline void _putscom(uint64_t addr, uint64_t value) { - mtspr(HMER,0); - uint64_t rslt = -1; - do { - ci_write(addr,value); - do { - rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL); - } while( (rslt & HMER_XSCOM_DONE)==0 ); - } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry - if(rslt != HMER_XSCOM_DONE){ - ERROR_STOP(XSCOM_ERROR,"XScom write returned unexpected result code"); - } - } - -#else - - #define getscom(xscom_base, scom_addr) ci_read(xscom_base+scom_addr*8) - #define putscom(xscom_base, scom_addr, value) ci_write(xscom_base+scom_addr*8,value) - -#endif - - - -static inline uint64_t popcountll(uint64_t input) { - unsigned long result; - asm volatile("popcntd %0, %1" : "=r" (result) : "r" (input)); - return result; + value = ci_read(addr); + do { + rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL); + } while( (rslt & HMER_XSCOM_DONE)==0 ); + } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry + if(rslt != HMER_XSCOM_DONE) + { + ERROR_STOP(XSCOM_ERROR,"XScom read returned unexpected result code"); + } + return value; } -/****************************************************************************/ -static inline void getscom_HW_ECID(uint64_t base, uint8_t* buf) { - uint64_t* buf64 = (uint64_t *) buf; - unsigned int i; -// uint64_t sum=0; // detect any change after fuse programming - for(i=0; i<ECID_SIZE/sizeof(uint64_t);i++) { - uint64_t val=getscom(base,OTP_ECID+i); -// sum += popcountll(val); - buf64[i] = val; - } -// const unsigned int count = sizeof(sha2_hash_t)/sizeof(uint64_t); -// uint64_t lastval=getscom(base,OTP_HW_KEY_HASH+count); -// if(((lastval & 0x00000000FFFF0000UL)>>16) != (~sum)) { -// ERROR_STOP(OTP_ECID_INVPOPSUM_CHECK,"Inverted Populationcount of ECID does not match"); -// } +#define putscom(xscom_base, scom_addr, value) _putscom(xscom_base \ + + PCB2PBUS(scom_addr),value) +static inline void _putscom(uint64_t addr, uint64_t value) +{ + mtspr(HMER,0); + uint64_t rslt = -1; + do { + ci_write(addr,value); + do { + rslt = mfspr(HMER)&(HMER_XSCOM_RSLT|HMER_XSCOM_DONE|HMER_XSCOM_FAIL); + } while( (rslt & HMER_XSCOM_DONE)==0 ); + } while(rslt == (HMER_XSCOM_RTRY|HMER_XSCOM_DONE|HMER_XSCOM_FAIL) ); // 001 retry + if(rslt != HMER_XSCOM_DONE) + { + ERROR_STOP(XSCOM_ERROR,"XScom write returned unexpected result code"); + } } -/****************************************************************************/ -static inline void getscom_PIBMEM_HW_Key_Hash(uint64_t base, uint8_t* buf) { - - uint64_t* buf64 = (uint64_t *) buf; - unsigned int i; - const unsigned int count = sizeof(sha2_hash_t)/sizeof(uint64_t); - uint64_t sum=0; // detect any change after fuse programming - for(i=0; i<count;i++) { - uint64_t val=getscom(base,PIBMEM_HW_KEY_HASH+i); - sum += popcountll(val); - buf64[i] = val; - } - //uint64_t lastval=getscom(base,OTP_HW_KEY_HASH+count); - //sum += popcountll(lastval & 0xFFFFFFFFFFFF0000UL); - //if((lastval & 0x000000000000FFFFUL) != (~sum)) { - // ERROR_STOP(OTP_KEY_INVPOPSUM_CHECK,"Inverted Populationcount of ECID does not match"); - //} +static inline uint64_t popcountll(uint64_t input) +{ + unsigned long result; + asm volatile("popcntd %0, %1" : "=r" (result) : "r" (input)); + return result; } -/****************************************************************************/ +static inline void getscom_HW_ECID(uint64_t base, uint8_t* buf) +{ + uint64_t* buf64 = (uint64_t *) buf; + unsigned int i; + for(i=0; i<ECID_SIZE/sizeof(uint64_t);i++) + { + uint64_t val=getscom(base,OTP_ECID+i); + buf64[i] = val; + } +} #define Convert_Mem_Addr(_addr) ((uint8_t*) (_addr)) #define Convert_Mem_Offset(_addr) ((uint64_t) (_addr)) |