summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/bltohbdatamgr.C65
-rw-r--r--src/kernel/kernel.C32
-rw-r--r--src/kernel/pagemgr.C76
-rw-r--r--src/kernel/vmmmgr.C25
4 files changed, 125 insertions, 73 deletions
diff --git a/src/kernel/bltohbdatamgr.C b/src/kernel/bltohbdatamgr.C
index 1fa211381..537958214 100644
--- a/src/kernel/bltohbdatamgr.C
+++ b/src/kernel/bltohbdatamgr.C
@@ -28,6 +28,7 @@
#include <assert.h>
#include <arch/memorymap.H>
#include <bootloader/bootloaderif.H>
+#include <kernel/vmmmgr.H>
// Global and only BlToHbDataManager instance
BlToHbDataManager g_BlToHbDataManager;
@@ -76,6 +77,10 @@ void BlToHbDataManager::print() const
printkd("-- HBB header Addr = 0x%lX Size = 0x%lX\n", getHbbHeaderAddr(),
iv_data.hbbHeaderSize);
printkd("-- Reserved Size = 0x%lX\n", iv_preservedSize);
+ if(iv_data.version >= Bootloader::BLTOHB_SIZE)
+ {
+ printkd("-- Size of structure = 0x%lX\n", iv_data.sizeOfStructure);
+ }
printkd("\n");
}
}
@@ -166,13 +171,28 @@ printk("lpc=%lX, xscom=%lX\n", i_data.lpcBAR, i_data.xscomBAR );
printk("lpc=%lX, xscom=%lX, iv_data=%p\n", iv_data.lpcBAR, iv_data.xscomBAR,
static_cast<void *>(&iv_data) );
+ // Check if bootloader advertised the size of the structure it saw;
+ // otherwise use the default padded size
+ if(iv_data.version >= Bootloader::BLTOHB_SIZE)
+ {
+ iv_data.sizeOfStructure = i_data.sizeOfStructure;
+ }
+ else
+ {
+ iv_data.sizeOfStructure = Bootloader::INITIAL_BLTOHB_PADDED_SIZE;
+ }
// Size of data that needs to be preserved and pinned.
iv_preservedSize = ALIGN_PAGE(iv_data.secureRomSize +
iv_data.hwKeysHashSize +
iv_data.hbbHeaderSize );
+
+ // Move preserved content to a location free from cache clearing
+ relocatePreservedArea();
+
iv_initialized = true;
iv_dataValid = true;
+
print();
}
@@ -195,6 +215,46 @@ void BlToHbDataManager::initInvalid ()
print();
}
+void BlToHbDataManager::relocatePreservedArea()
+{
+ // Allow call this within the initializer
+ if (iv_initialized)
+ {
+ printk("E> BlToHbDataManager relocatePreservedArea called outside initializer\n");
+ kassert(!iv_initialized);
+ }
+ // Ensure the pointers were initialized
+ kassert(iv_data.secureRom!=nullptr);
+ kassert(iv_data.hwKeysHash!=nullptr);
+ kassert(iv_data.hbbHeader!=nullptr);
+
+ // Get destination location that will be preserved by the pagemgr
+ auto l_pBltoHbDataStart = reinterpret_cast<uint8_t *>(
+ VmmManager::BlToHbPreserveDataOffset());
+ // Copy in SecureRom
+ memcpy(l_pBltoHbDataStart,
+ iv_data.secureRom,
+ iv_data.secureRomSize);
+ // Change pointer to new location and increment
+ iv_data.secureRom = l_pBltoHbDataStart;
+ l_pBltoHbDataStart += iv_data.secureRomSize;
+
+ // Copy in HW keys' Hash
+ memcpy(l_pBltoHbDataStart,
+ iv_data.hwKeysHash,
+ iv_data.hwKeysHashSize);
+ // Change pointer to new location and increment
+ iv_data.hwKeysHash = l_pBltoHbDataStart;
+ l_pBltoHbDataStart += iv_data.hwKeysHashSize;
+
+ // Copy in HBB header
+ memcpy(l_pBltoHbDataStart,
+ iv_data.hbbHeader,
+ iv_data.hbbHeaderSize);
+ // Change pointer to new location
+ iv_data.hbbHeader = l_pBltoHbDataStart;
+}
+
const uint64_t BlToHbDataManager::getBranchtableOffset() const
{
return iv_data.branchtableOffset;
@@ -286,3 +346,8 @@ const uint64_t BlToHbDataManager::getXscomBAR() const
return reinterpret_cast<uint64_t>(iv_data.xscomBAR);
}
+const size_t BlToHbDataManager::getBlToHbDataSize() const
+{
+ return iv_data.sizeOfStructure;
+}
+
diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C
index 5e97ebb4c..d5952374a 100644
--- a/src/kernel/kernel.C
+++ b/src/kernel/kernel.C
@@ -82,38 +82,8 @@ int main()
if ( Bootloader::BlToHbDataValid(l_pBltoHbData) )
{
printk("BL to HB comm valid\n");
-
- // Make copy of structure so to not modify original pointers
- auto l_blToHbDataCopy = *l_pBltoHbData;
-
- // Get destination location that will be preserved by the pagemgr
- auto l_pBltoHbDataStart = reinterpret_cast<uint8_t *>(
- VmmManager::BLTOHB_DATA_START);
- // Copy in SecureRom
- memcpy(l_pBltoHbDataStart,
- l_blToHbDataCopy.secureRom,
- l_blToHbDataCopy.secureRomSize);
- // Change pointer to new location and increment
- l_blToHbDataCopy.secureRom = l_pBltoHbDataStart;
- l_pBltoHbDataStart += l_blToHbDataCopy.secureRomSize;
-
- // Copy in HW keys' Hash
- memcpy(l_pBltoHbDataStart,
- l_blToHbDataCopy.hwKeysHash,
- l_blToHbDataCopy.hwKeysHashSize);
- // Change pointer to new location and increment
- l_blToHbDataCopy.hwKeysHash = l_pBltoHbDataStart;
- l_pBltoHbDataStart += l_blToHbDataCopy.hwKeysHashSize;
-
- // Copy in HBB header
- memcpy(l_pBltoHbDataStart,
- l_blToHbDataCopy.hbbHeader,
- l_blToHbDataCopy.hbbHeaderSize);
- // Change pointer to new location
- l_blToHbDataCopy.hbbHeader = l_pBltoHbDataStart;
-
// Initialize Secureboot Data class
- g_BlToHbDataManager.initValid(l_blToHbDataCopy);
+ g_BlToHbDataManager.initValid(*l_pBltoHbData);
}
else
{
diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C
index 02e8ce710..bdc8244f2 100644
--- a/src/kernel/pagemgr.C
+++ b/src/kernel/pagemgr.C
@@ -202,61 +202,55 @@ PageManager::PageManager()
void PageManager::_initialize()
{
- typedef PageManagerCore::page_t page_t;
- uint64_t totalPages = 0;
-
- page_t* startAddr = reinterpret_cast<page_t*>(firstPageAddr());
- printk("PageManager starts at %p\n", startAddr);
+ printk("Hostboot base image ends at 0x%lX...\n", firstPageAddr());
- // Populate cache lines from end of HBB to PT offset and add to heap
- uint64_t startBlock = reinterpret_cast<uint64_t>(startAddr);
- uint64_t endBlock = VmmManager::INITIAL_PT_OFFSET;
+ uint64_t totalPages = 0;
+ // Extend memory footprint to half the cache
+ // There is a preserved area after the base image and boot loader to HB
+ // communication area. The page table must be 256KB aligned, so it is
+ // likely to not be flush against the preserved area end.
+ // Example:
+ // [HBB max size][BlToHBData][8 byte aligned]
+ // [128 byte aligned Preserved-area][256K aligned Page Table]
+ uint64_t l_endPreservedArea = VmmManager::endPreservedOffset();
+ uint64_t l_endInitCache = VmmManager::INITIAL_MEM_SIZE;
+ uint64_t l_pageTableOffset = VmmManager::pageTableOffset();
+ uint64_t l_endPageTable = l_pageTableOffset + VmmManager::PTSIZE;
+
+ printk("PageManager end of preserved area at 0X%lX\n", l_endPreservedArea);
+ printk("PageManager page table offset at 0X%lX\n", l_pageTableOffset);
+
+ // Populate half the cache after the preserved area
KernelMisc::populate_cache_lines(
- reinterpret_cast<uint64_t*>(startBlock),
- reinterpret_cast<uint64_t*>(endBlock));
-
- uint64_t pages = (endBlock - startBlock) / PAGESIZE;
- iv_heap.addMemory(startBlock, pages);
- totalPages += pages;
+ reinterpret_cast<uint64_t*>(l_endPreservedArea),
+ reinterpret_cast<uint64_t*>(l_endInitCache));
- // Populate cache lines of PT
- startBlock = VmmManager::INITIAL_PT_OFFSET;
- endBlock = VmmManager::INITIAL_PT_OFFSET + VmmManager::PTSIZE;
- KernelMisc::populate_cache_lines(reinterpret_cast<uint64_t*>(startBlock),
- reinterpret_cast<uint64_t*>(endBlock));
-
- // Populate cachelines from end of Preserved read (PT + securebood data) to
- // 4MB and add to heap
- // Add on secureboot data size to end of reserved space
- size_t securebootDataSize = 0;
- if (g_BlToHbDataManager.isValid())
+ // Allocate heap memory between end of preserved area and start of page
+ // table, if necessary
+ uint64_t pages = 0;
+ if ( (l_pageTableOffset - l_endPreservedArea) > 0 )
{
- securebootDataSize = g_BlToHbDataManager.getPreservedSize();
+ pages = (l_pageTableOffset - l_endPreservedArea) / PAGESIZE;
+ iv_heap.addMemory(l_endPreservedArea, pages);
+ totalPages += pages;
}
- size_t l_endReservedPage = VmmManager::BLTOHB_DATA_START
- + securebootDataSize;
- startBlock = l_endReservedPage;
- endBlock = VmmManager::INITIAL_MEM_SIZE;
- KernelMisc::populate_cache_lines(
- reinterpret_cast<uint64_t*>(startBlock),
- reinterpret_cast<uint64_t*>(endBlock));
-
- pages = (endBlock - startBlock) / PAGESIZE;
- iv_heap.addMemory(startBlock, pages);
+ // After the Page table
+ pages = (l_endInitCache - l_endPageTable) / PAGESIZE;
+ iv_heap.addMemory(l_endPageTable, pages);
totalPages += pages;
printk("%ld pages.\n", totalPages);
- // Reserve pages for the kernel.
- iv_heapKernel.addMemory(reinterpret_cast<uint64_t>(
- iv_heap.allocatePage(KERNEL_HEAP_RESERVED_PAGES)),
- KERNEL_HEAP_RESERVED_PAGES);
-
// Statistics
iv_pagesTotal = totalPages;
iv_pagesAvail = totalPages;
cv_low_page_count = totalPages;
+ // Reserve pages for the kernel.
+ iv_heapKernel.addMemory(reinterpret_cast<uint64_t>(
+ iv_heap.allocatePage(KERNEL_HEAP_RESERVED_PAGES)),
+ KERNEL_HEAP_RESERVED_PAGES);
+
KernelMemState::setMemScratchReg(KernelMemState::MEM_CONTAINED_L3,
KernelMemState::HALF_CACHE);
}
diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C
index 9902a0527..553fa3d34 100644
--- a/src/kernel/vmmmgr.C
+++ b/src/kernel/vmmmgr.C
@@ -33,6 +33,8 @@
#include <kernel/stacksegment.H>
#include <kernel/devicesegment.H>
#include <config.h>
+#include <kernel/bltohbdatamgr.H>
+#include <util/align.H>
extern void* data_load_address;
@@ -312,5 +314,26 @@ uint64_t VmmManager::pageTableOffset()
uint64_t VmmManager::_pageTableOffset() const
{
- return INITIAL_PT_OFFSET;
+ return ALIGN_X(_endPreservedOffset(), PT_ALIGNMENT);
+}
+
+uint64_t VmmManager::BlToHbPreserveDataOffset()
+{
+ return Singleton<VmmManager>::instance()._BlToHbPreserveDataOffset();
+}
+
+uint64_t VmmManager::_BlToHbPreserveDataOffset() const
+{
+ return ALIGN_8(MAX_HBB_SIZE + g_BlToHbDataManager.getBlToHbDataSize());
+}
+
+uint64_t VmmManager::endPreservedOffset()
+{
+ return Singleton<VmmManager>::instance()._endPreservedOffset();
+}
+
+uint64_t VmmManager::_endPreservedOffset() const
+{
+ return ALIGN_PAGE(_BlToHbPreserveDataOffset() +
+ g_BlToHbDataManager.getPreservedSize());
}
OpenPOWER on IntegriCloud