diff options
| author | Stephen Cprek <smcprek@us.ibm.com> | 2016-12-05 16:29:06 -0600 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-01-30 11:15:34 -0500 |
| commit | aff3f67b49b87d5e2755b364ecb512641bbb4540 (patch) | |
| tree | e87cd2eb0afe2d3721ae2bfb7928c6a6b134e590 /src/include/securerom/hw_utils.H | |
| parent | 5784da25300866c71551f1f0411d469eb3a3c922 (diff) | |
| download | blackbird-hostboot-aff3f67b49b87d5e2755b364ecb512641bbb4540.tar.gz blackbird-hostboot-aff3f67b49b87d5e2755b364ecb512641bbb4540.zip | |
Add ROM code files in Hostboot
RTC: 143902
Change-Id: Iff00250b1dd36c301c311147a1540a5f3c33f19b
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33607
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/include/securerom/hw_utils.H')
| -rw-r--r-- | src/include/securerom/hw_utils.H | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/src/include/securerom/hw_utils.H b/src/include/securerom/hw_utils.H new file mode 100644 index 000000000..324cdfc25 --- /dev/null +++ b/src/include/securerom/hw_utils.H @@ -0,0 +1,430 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/securerom/hw_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* 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" + +#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 ENTRY_MASK 0x7ffffffffffffffCull // 4Byte page aligned + +#define HRMOR_IGNORE 0x8000000000000000ull +#define HRMOR_RELATIVE(_a) ((_a)&~HRMOR_IGNORE) +#define ABSOLUTE_ADDR(_a) ((_a)|HRMOR_IGNORE) + + +#define CONTEXT 0 + +#ifdef EMULATE_HW + +extern int FAIL; +extern int GOOD; + +#define HOST_RESET_VECTOR 0x100 + +#define TEST_SYSTEM_MEMORY (64*1024*1024) +#define TRUSTED_MEMORY_BASE (8*1024*1024) // should be 256MB +#define TOTAL_TEST_MEMORY (TEST_SYSTEM_MEMORY+4*1024) +#define MEMORY_MASK 0x7fffffffffffffffull +#define CACHE_MASK 0x7fffffffffffff80ull // 128B cache line aligned + +#define PHYSICAL(_a) ((_a)&MEMORY_MASK) + +#define LOG(_c) Log(CONTEXT|(_c)) +#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; +} hw_settings; + +extern hw_settings HW; + +#define r1 HW.GPR[1] +#define r2 HW.GPR[2] + +extern void HW_Init (void); +extern void HW_Free (void); + +extern void Log (uint64_t code); +extern void Error (uint64_t code); +extern void Check_Stop (char* msg); +extern void Error_Stop (uint64_t code, char* msg); + +extern void assem_DCBI (uint64_t addr); +extern void assem_DCBZ (uint64_t addr); +extern void assem_DCBST (uint8_t* addr); +extern void assem_ICBI (uint64_t* addr); +extern void assem_SYNC (void); +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 void mtspr_SCRATCH0(uint64_t val) { + HW.SCRATCH0 = val; +} + +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_SCRATCH2(uint64_t val) { + HW.SCRATCH2 = val; +} + +static inline uint64_t mfspr_SCRATCH2(void) { + return HW.SCRATCH2; +} + +static inline void mtspr_SCRATCH3(uint64_t val) { + HW.SCRATCH3 = val; +} + +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 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); + +#else //emulate_hw + +/* SPRs numbers -- the wrong ones: */ +//#define SPRG0 272 /* Software Special Purpose Register 0 */ +//#define SPRG1 273 /* Software Special Purpose Register 1 */ +//#define SPRG2 274 /* Software Special Purpose Register 2 */ +//#define SPRG3 275 /* Software Special Purpose Register 3 */ + +#define SPRC 276 +#define SPRC_SCRATCH0 0x0000000000000040 +#define SPRC_SCRATCH1 0x0000000000000048 +#define SPRC_SCRATCH2 0x0000000000000050 +#define SPRC_SCRATCH3 0x0000000000000058 +#define SPRC_AVP_out 0x00000000000001C8 +#define SPRD 277 + +#define HRMOR 313 + +#define HMER 336 +#define HMER_XSCOM_FAIL 0x0080000000000000 //Bit 8 +#define HMER_XSCOM_DONE 0x0040000000000000 //Bit 9 +#define HMER_XSCOM_RSLT 0x0000070000000000 //Bit 21-23 +#define HMER_XSCOM_RTRY 0x0000010000000000 //RSLT = 001 = retry + +/* SCOM Register addresses */ +#define OTP 0x00018000 +#define OTP_ECID OTP +0x0000 +#define PIBMEM 0x00080000 +#define PIBMEM_HW_KEY_HASH PIBMEM +0x0008 + +#define ALTD_UNTRUSTED_BAR_ADDR_REG 0x02020015 +#define ALTD_UNTRUSTED_BAR_MASK_ADDR_REG 0x02020016 +#define PSIHB_NOTRUST_BAR0 0x02013f40 +#define PSIHB_NOTRUST_BAR0MASK 0x02013f42 +#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_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_SYNC(void) { + asm volatile("sync 0":::"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 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)); +} + +/****************************************************************************/ +#if !(CONFIG_MAMBO && CONFIG_MAMBO_WITHOUT_SCRATCH) + +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 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_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); +} + +#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 +/****************************************************************************/ + +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"); } + + +/****************************************************************************/ +/* 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 + // 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"); +} + +#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); + 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; +} + +/****************************************************************************/ +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"); +// } +} + +/****************************************************************************/ +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"); + //} +} + +/****************************************************************************/ + +#define Convert_Mem_Addr(_addr) ((uint8_t*) (_addr)) +#define Convert_Mem_Offset(_addr) ((uint64_t) (_addr)) + +#define physical_addr(_addr) _addr + +#define GET16(_data) _data +#define GET32(_data) _data +#define GET64(_data) _data + +#endif //emulate_hw - else case + +#endif |

