-
Notifications
You must be signed in to change notification settings - Fork 793
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented CTN SRAM driver that mimics Flash functionality for bootstrap. Signed-off-by: Daniel Beitel <[email protected]>
- Loading branch information
1 parent
a5f5b09
commit 96f91ea
Showing
8 changed files
with
554 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "sw/device/silicon_creator/lib/drivers/ctn_sram.h" | ||
|
||
#include <assert.h> | ||
|
||
#include "sw/lib/sw/device/base/abs_mmio.h" | ||
#include "sw/lib/sw/device/base/hardened.h" | ||
#include "sw/lib/sw/device/base/memory.h" | ||
#include "sw/lib/sw/device/base/multibits.h" | ||
|
||
#include "flash_ctrl_regs.h" // Generated. | ||
#include "hw/top_darjeeling/sw/autogen/top_darjeeling.h" | ||
#include "sram_ctrl_regs.h" // Generated. | ||
|
||
enum { | ||
/* | ||
* Base ctn sram address, exclusive. | ||
*/ | ||
kBaseAddress = TOP_DARJEELING_RAM_CTN_BASE_ADDR, | ||
/* | ||
* Maximum ctn sram size to be used as flash, exclusive. | ||
*/ | ||
kMaxSize = FLASH_CTRL_PARAM_BYTES_PER_BANK * FLASH_CTRL_PARAM_REG_NUM_BANKS, | ||
/** | ||
* Value of a word in sram after erase. | ||
*/ | ||
kErasedWord = UINT32_MAX, | ||
}; | ||
|
||
static_assert(kMaxSize <= TOP_DARJEELING_RAM_CTN_SIZE_BYTES, | ||
"CTN SRAM area for image bootstap must be smaller than total."); | ||
|
||
rom_error_t ctn_sram_data_write(uint32_t addr, uint32_t len, const void *data) { | ||
if (addr + len * sizeof(uint32_t) >= kMaxSize) { | ||
return kErrorFlashCtrlDataWrite; | ||
} | ||
memcpy((void *)(kBaseAddress + addr), data, len * sizeof(uint32_t)); | ||
return kErrorOk; | ||
} | ||
|
||
rom_error_t ctn_sram_data_erase(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type) { | ||
static_assert(__builtin_popcount(FLASH_CTRL_PARAM_BYTES_PER_BANK) == 1, | ||
"Bytes per bank must be a power of two."); | ||
|
||
if (addr >= kMaxSize) { | ||
return kErrorFlashCtrlDataErase; | ||
} | ||
size_t byte_count = 0; | ||
switch (erase_type) { | ||
case kCtnSramEraseTypeBank: | ||
HARDENED_CHECK_EQ(erase_type, kCtnSramEraseTypeBank); | ||
byte_count = FLASH_CTRL_PARAM_BYTES_PER_BANK; | ||
break; | ||
case kCtnSramEraseTypePage: | ||
HARDENED_CHECK_EQ(erase_type, kCtnSramEraseTypePage); | ||
byte_count = FLASH_CTRL_PARAM_BYTES_PER_PAGE; | ||
break; | ||
default: | ||
HARDENED_TRAP(); | ||
byte_count = 0U; | ||
break; | ||
} | ||
// Truncate to the closest lower bank/page aligned address. | ||
addr &= ~byte_count + 1; | ||
memset((void *)(kBaseAddress + addr), 0xff, byte_count); | ||
return kErrorOk; | ||
} | ||
|
||
rom_error_t ctn_sram_data_erase_verify(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type) { | ||
static_assert(__builtin_popcount(FLASH_CTRL_PARAM_BYTES_PER_BANK) == 1, | ||
"Bytes per bank must be a power of two."); | ||
|
||
if (addr >= kMaxSize) { | ||
return kErrorFlashCtrlDataErase; | ||
} | ||
size_t byte_count = 0; | ||
rom_error_t error = kErrorFlashCtrlDataEraseVerify; | ||
switch (launder32(erase_type)) { | ||
case kCtnSramEraseTypeBank: | ||
HARDENED_CHECK_EQ(erase_type, kCtnSramEraseTypeBank); | ||
byte_count = FLASH_CTRL_PARAM_BYTES_PER_BANK; | ||
error = kErrorOk ^ (byte_count - 1); | ||
break; | ||
case kCtnSramEraseTypePage: | ||
HARDENED_CHECK_EQ(erase_type, kCtnSramEraseTypePage); | ||
byte_count = FLASH_CTRL_PARAM_BYTES_PER_PAGE; | ||
error = kErrorOk ^ (byte_count - 1); | ||
break; | ||
default: | ||
HARDENED_TRAP(); | ||
byte_count = 0U; | ||
break; | ||
} | ||
|
||
// Truncate to the closest lower bank/page aligned address. | ||
addr &= ~byte_count + 1; | ||
uint32_t mask = kErasedWord; | ||
size_t i = 0, r = byte_count - 1; | ||
for (; launder32(i) < byte_count && launder32(r) < byte_count; | ||
i += sizeof(uint32_t), r -= sizeof(uint32_t)) { | ||
uint32_t word = abs_mmio_read32(kBaseAddress + addr + i); | ||
mask &= word; | ||
error &= word; | ||
} | ||
HARDENED_CHECK_EQ(i, byte_count); | ||
HARDENED_CHECK_EQ((uint32_t)r, UINT32_MAX); | ||
|
||
if (launder32(mask) == kErasedWord) { | ||
HARDENED_CHECK_EQ(mask, kErasedWord); | ||
return error ^ (byte_count - 1); | ||
} | ||
|
||
return kErrorFlashCtrlDataEraseVerify; | ||
} | ||
|
||
void ctn_sram_data_default_perms_set(ctn_sram_perms_t perms) { | ||
// Note: provided to maintain compatibility with flash controller | ||
} | ||
|
||
void ctn_sram_bank_erase_perms_set(hardened_bool_t enable) { | ||
// Note: provided to maintain compatibility with flash controller | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_CTN_SRAM_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_CTN_SRAM_H_ | ||
|
||
#include "sw/lib/sw/device/base/hardened.h" | ||
#include "sw/lib/sw/device/base/multibits.h" | ||
#include "sw/lib/sw/device/silicon_creator/error.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* Write data into CTN SRAM at a specific address. | ||
* | ||
* @param addr starting address to write data into sram. | ||
* @param len number of words of data to write into sram. | ||
* @param data data to write into sram. | ||
* @return Result of the operation. | ||
*/ | ||
rom_error_t ctn_sram_data_write(uint32_t addr, uint32_t len, const void *data); | ||
|
||
/* | ||
* Encoding generated with | ||
* $ ./util/design/sparse-fsm-encode.py -d 5 -m 2 -n 32 \ | ||
* -s 2181785819 --language=c | ||
* | ||
* Minimum Hamming distance: 14 | ||
* Maximum Hamming distance: 14 | ||
* Minimum Hamming weight: 14 | ||
* Maximum Hamming weight: 18 | ||
*/ | ||
|
||
typedef enum ctn_sram_erase_type { | ||
/** | ||
* Erase a page. | ||
*/ | ||
kCtnSramEraseTypePage = 0xaf0eab8b, | ||
/** | ||
* Erase a bank. | ||
*/ | ||
kCtnSramEraseTypeBank = 0x80329be9, | ||
} ctn_sram_erase_type_t; | ||
|
||
/** | ||
* Erases a data partition page or bank. | ||
* | ||
* The flash controller will truncate to the closest page boundary for page | ||
* erase operations, and to the nearest bank aligned boundary for bank erase | ||
* operations. | ||
* | ||
* @param addr Address that falls within the bank or page being deleted. | ||
* @param erase_type Whether to erase a page or a bank. | ||
* @return Result of the operation. | ||
*/ | ||
OT_WARN_UNUSED_RESULT | ||
rom_error_t ctn_sram_data_erase(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type); | ||
|
||
/** | ||
* Verifies that a data partition page or bank was erased. | ||
* | ||
* @param addr Address that falls within the bank or page erased. | ||
* @param erase_type Whether to verify a page or a bank. | ||
* @return Result of the operation. | ||
*/ | ||
OT_WARN_UNUSED_RESULT | ||
rom_error_t ctn_sram_data_erase_verify(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type); | ||
|
||
/** | ||
* A struct for specifying access permissions. | ||
* | ||
* ctn_sram config registers use 4-bits for boolean values. Use | ||
* `kMultiBitBool4True` to enable and `kMultiBitBool4False` to disable | ||
* permissions. | ||
* | ||
* Note: provided to maintain compatibility with flash controller | ||
*/ | ||
typedef struct ctn_sram_perms { | ||
/** | ||
* Read. | ||
*/ | ||
multi_bit_bool_t read; | ||
/** | ||
* Write. | ||
*/ | ||
multi_bit_bool_t write; | ||
/** | ||
* Erase. | ||
*/ | ||
multi_bit_bool_t erase; | ||
} ctn_sram_perms_t; | ||
|
||
/** | ||
* Sets default access permissions for the data partition. | ||
* | ||
* A permission is enabled only if the corresponding field in `perms` is | ||
* `kMultiBitBool4True`. | ||
* | ||
* Note: provided to maintain compatibility with flash controller | ||
* | ||
* @param perms New permissions. | ||
*/ | ||
void ctn_sram_data_default_perms_set(ctn_sram_perms_t perms); | ||
|
||
/** | ||
* Set bank erase permissions for both flash banks. | ||
* | ||
* Note: provided to maintain compatibility with flash controller | ||
* | ||
* @param enable Whether to enable bank erase. | ||
*/ | ||
void ctn_sram_bank_erase_perms_set(hardened_bool_t enable); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_CTN_SRAM_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "sw/device/silicon_creator/lib/drivers/mock_ctn_sram.h" | ||
|
||
namespace rom_test { | ||
extern "C" { | ||
|
||
rom_error_t ctn_sram_data_write(uint32_t addr, uint32_t len, const void *data) { | ||
return MockCtnSram::Instance().DataWrite(addr, len, data); | ||
} | ||
|
||
rom_error_t ctn_sram_data_erase(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type) { | ||
return MockCtnSram::Instance().DataErase(addr, erase_type); | ||
} | ||
|
||
rom_error_t ctn_sram_data_erase_verify(uint32_t addr, | ||
ctn_sram_erase_type_t erase_type) { | ||
return MockCtnSram::Instance().DataEraseVerify(addr, erase_type); | ||
} | ||
|
||
void ctn_sram_data_default_perms_set(ctn_sram_perms_t perms) { | ||
MockCtnSram::Instance().DataDefaultPermsSet(perms); | ||
} | ||
|
||
void ctn_sram_bank_erase_perms_set(hardened_bool_t enable) { | ||
MockCtnSram::Instance().BankErasePermsSet(enable); | ||
} | ||
|
||
} // extern "C" | ||
} // namespace rom_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_MOCK_CTN_SRAM_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_MOCK_CTN_SRAM_H_ | ||
|
||
#include "sw/device/silicon_creator/lib/drivers/ctn_sram.h" | ||
#include "sw/lib/sw/device/base/global_mock.h" | ||
|
||
namespace rom_test { | ||
namespace internal { | ||
|
||
/** | ||
* Mock class for ctn_sram.c. | ||
*/ | ||
class MockCtnSram : public global_mock::GlobalMock<MockCtnSram> { | ||
public: | ||
MOCK_METHOD(rom_error_t, DataWrite, (uint32_t, uint32_t, const void *)); | ||
MOCK_METHOD(rom_error_t, DataErase, (uint32_t, ctn_sram_erase_type_t)); | ||
MOCK_METHOD(rom_error_t, DataEraseVerify, (uint32_t, ctn_sram_erase_type_t)); | ||
MOCK_METHOD(void, DataDefaultPermsSet, (ctn_sram_perms_t)); | ||
MOCK_METHOD(void, BankErasePermsSet, (hardened_bool_t)); | ||
}; | ||
|
||
} // namespace internal | ||
|
||
using MockCtnSram = testing::StrictMock<internal::MockCtnSram>; | ||
|
||
} // namespace rom_test | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_MOCK_CTN_SRAM_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.