From a4ad138162e1c2b0e7ae008d38d91a0094393bd7 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Mon, 25 Jul 2011 16:41:57 -0500 Subject: Reduce memory footprint to 3MB. Change-Id: I309bc63bdb27baa21f65de05e12324b9c4ce3407 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/212 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/include/kernel/cpuid.H | 93 +++++++++++++++----------------------------- src/include/kernel/taskmgr.H | 6 +-- src/include/kernel/vmmmgr.H | 13 ++----- src/kernel/basesegment.C | 19 ++++++++- src/kernel/cpuid.C | 44 +++++++++++++++++++++ src/kernel/cpumgr.C | 22 +++++------ src/kernel/makefile | 2 +- src/kernel/pagemgr.C | 15 ++++--- src/makefile | 2 +- 9 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 src/kernel/cpuid.C (limited to 'src') diff --git a/src/include/kernel/cpuid.H b/src/include/kernel/cpuid.H index fa9b0649b..75287a66e 100644 --- a/src/include/kernel/cpuid.H +++ b/src/include/kernel/cpuid.H @@ -1,74 +1,45 @@ #ifndef __KERNEL_CPUID_H #define __KERNEL_CPUID_H +#include #include -/** @enum ProcessorCoreType - * @brief Enumeration of the different supported processor cores. - */ -enum ProcessorCoreType +namespace CpuID { + /** @enum ProcessorCoreType + * @brief Enumeration of the different supported processor cores. + */ + enum ProcessorCoreType + { /** Base Power7 */ - POWER7, + POWER7, /** Power7+ */ - POWER7_PLUS, + POWER7_PLUS, /** Power8 "Salerno" (low-end) core */ - POWER8_SALERNO, + POWER8_SALERNO, /** Power8 "Venice" (high-end) core */ - POWER8_VENICE, - - UNKNOWN, + POWER8_VENICE, + + UNKNOWN, + }; + + /** @fn getCpuType() + * @brief Decode the processor type from the PVR register. + * + * These values come from the pervasive spec for each processor. + * + * @return ProcessorCoreType - Value from enumeration for this core. + */ + ProcessorCoreType getCpuType(); + + /** @fn getCpuDD + * @brief Decode the processor DD level from the PVR register. + * + * These offsets come from the pervasive spec for each processor. + * + * @return 1 byte DD level as . + */ + uint8_t getCpuDD(); }; - -/** @fn getCpuType() - * @brief Decode the processor type from the PVR register. - * - * These values come from the pervasive spec for each processor. - * - * @return ProcessorCoreType - Value from enumeration for this core. - */ -ALWAYS_INLINE -ProcessorCoreType getCpuType() -{ - uint64_t l_pvr = getPVR(); - - // Layout of the PVR is (32-bit): - // 2 nibbles reserved. - // 2 nibbles chip type. - // 1 nibble technology. - // 1 nibble major DD. - // 1 nibble reserved. - // 1 nibble minor DD. - - switch(l_pvr & 0xFFFF0000) - { - case 0x003F0000: - return POWER7; - - case 0x004A0000: - return POWER7_PLUS; - - case 0x004B0000: - return POWER8_VENICE; - - default: - return UNKNOWN; - } -} - -/** @fn getCpuDD - * @brief Decode the processor DD level from the PVR register. - * - * These offsets come from the pervasive spec for each processor. - * - * @return 1 byte DD level as . - */ -ALWAYS_INLINE -uint8_t getCpuDD() -{ - uint64_t l_pvr = getPVR(); - return ((l_pvr & 0x0F00) >> 4) | (l_pvr & 0x000F); -} - #endif diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H index b34a1d3b1..82aab7da1 100644 --- a/src/include/kernel/taskmgr.H +++ b/src/include/kernel/taskmgr.H @@ -10,7 +10,7 @@ class TaskManager public: static task_t* getCurrentTask(); static void setCurrentTask(task_t* t); - + typedef void(*task_fn_t)(void*); static task_t* createTask(task_fn_t, void*); @@ -22,8 +22,8 @@ class TaskManager static task_t* createIdleTask(); private: - tid_t getNextTid() - { return iv_nextTid.next() + VmmManager::FirstPid; }; + tid_t getNextTid() + { return iv_nextTid.next(); }; Util::Lockfree::Counter iv_nextTid; static void idleTaskLoop(void*); diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H index 49101feed..f57f01677 100644 --- a/src/include/kernel/vmmmgr.H +++ b/src/include/kernel/vmmmgr.H @@ -10,9 +10,11 @@ class VmmManager public: enum VMM_CONSTS { - EIGHT_MEG = 8 * 1024 * 1024, + ONE_MEG = 1 * 1024 * 1024, + THREE_MEG = 3 * ONE_MEG, + EIGHT_MEG = 8 * ONE_MEG, - FULL_MEM_SIZE = 1 * EIGHT_MEG, + FULL_MEM_SIZE = THREE_MEG, // put the Page Table at the end of our memory space PTSIZE = (1 << 18), @@ -28,13 +30,6 @@ class VmmManager RO_EXE_ACCESS, }; - enum PID_ALLOCATIONS - { - LinearSpace = (FULL_MEM_SIZE / EIGHT_MEG) - 1, - MMIOSpace = LinearSpace + 1, - FirstPid, - }; - static void init(); static void init_slb(); diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C index 70d91ac72..467f8209c 100644 --- a/src/kernel/basesegment.C +++ b/src/kernel/basesegment.C @@ -5,6 +5,7 @@ #include #include #include +#include BaseSegment::~BaseSegment() { @@ -21,8 +22,22 @@ void BaseSegment::_init() // Assign segment to segment manager. SegmentManager::addSegment(this, SegmentManager::BASE_SEGMENT_ID); - // Create initial static 8MB block. - iv_block = new Block(0x0, 0x800000); + // Create initial static 3 or 8MB block. + uint64_t iv_baseBlockSize = 0; + switch (CpuID::getCpuType()) + { + case CpuID::POWER7: + case CpuID::POWER7_PLUS: + case CpuID::POWER8_VENICE: + iv_baseBlockSize = VmmManager::EIGHT_MEG; + break; + + case CpuID::POWER8_SALERNO: + default: + iv_baseBlockSize = VmmManager::THREE_MEG; + break; + } + iv_block = new Block(0x0, iv_baseBlockSize); iv_block->setParent(this); // Set default page permissions on block. diff --git a/src/kernel/cpuid.C b/src/kernel/cpuid.C new file mode 100644 index 000000000..a8d884bf2 --- /dev/null +++ b/src/kernel/cpuid.C @@ -0,0 +1,44 @@ +/** @file cpuid.C + * Implementation of the cpuid functions. + */ + +#include + +namespace CpuID +{ + ProcessorCoreType getCpuType() + { + uint64_t l_pvr = getPVR(); + + // Layout of the PVR is (32-bit): + // 2 nibbles reserved. + // 2 nibbles chip type. + // 1 nibble technology. + // 1 nibble major DD. + // 1 nibble reserved. + // 1 nibble minor DD. + + switch(l_pvr & 0xFFFF0000) + { + case 0x003F0000: + return POWER7; + + case 0x004A0000: + return POWER7_PLUS; + + case 0x004B0000: + return POWER8_VENICE; + + default: + return UNKNOWN; + } + } + + uint8_t getCpuDD() + { + uint64_t l_pvr = getPVR(); + return ((l_pvr & 0x0F00) >> 4) | (l_pvr & 0x000F); + } +}; + + diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index fc421431e..49dfb0919 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -37,19 +37,19 @@ void CpuManager::init() // Determine number of threads on this core. size_t threads = -1; - switch (getCpuType()) + switch (CpuID::getCpuType()) { - case POWER7: - case POWER7_PLUS: + case CpuID::POWER7: + case CpuID::POWER7_PLUS: threads = 4; break; - case POWER8_VENICE: - case POWER8_SALERNO: + case CpuID::POWER8_VENICE: + case CpuID::POWER8_SALERNO: threads = 8; break; - case UNKNOWN: + case CpuID::UNKNOWN: default: kassert(false); break; @@ -88,9 +88,9 @@ void CpuManager::startCPU(ssize_t i) // Initialize CPU structure. if (NULL == cv_cpus[i]) { - printk("Starting CPU %ld...", i); + printk("Starting CPU %ld...", i); cpu_t* cpu = cv_cpus[i] = new cpu_t; - + // Initialize CPU. cpu->cpu = i; if (currentCPU) @@ -103,14 +103,14 @@ void CpuManager::startCPU(ssize_t i) } cpu->scheduler = &Singleton::instance(); cpu->scheduler_extra = NULL; - cpu->kernel_stack = + cpu->kernel_stack = (void*) (((uint64_t)PageManager::allocatePage(4)) + 16320); cpu->xscom_mutex = (mutex_t)MUTEX_INITIALIZER; - + // Create idle task. cpu->idle_task = TaskManager::createIdleTask(); cpu->idle_task->cpu = cpu; - + printk("done\n"); } diff --git a/src/kernel/makefile b/src/kernel/makefile index f3d58dee0..d02141bb6 100644 --- a/src/kernel/makefile +++ b/src/kernel/makefile @@ -3,7 +3,7 @@ ROOTPATH = ../.. OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o timemgr.o OBJS += futexmgr.o ptmgr.o segmentmgr.o devicesegment.o basesegment.o -OBJS += block.o +OBJS += block.o cpuid.o include ${ROOTPATH}/config.mk diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C index 9ca2821d6..95719b241 100644 --- a/src/kernel/pagemgr.C +++ b/src/kernel/pagemgr.C @@ -28,19 +28,19 @@ PageManager::PageManager() : iv_pagesAvail(0) uint64_t addr = (uint64_t) VFS_LAST_ADDRESS; if (0 != (addr % PAGESIZE)) addr = (addr - (addr % PAGESIZE)) + PAGESIZE; - + // Determine number of pages available. page_t* page = (page_t*)((void*) addr); size_t length = (MEMLEN - addr) / PAGESIZE; // Update statistics. __sync_add_and_fetch(&iv_pagesAvail, length); - + // Display. printk("Initializing PageManager with %zd pages starting at %lx...", length, (uint64_t)page); - + // Populate L3 cache lines. uint64_t* cache_line = (uint64_t*) addr; uint64_t* end_cache_line = (uint64_t*) VmmManager::FULL_MEM_SIZE; @@ -62,6 +62,9 @@ PageManager::PageManager() : iv_pagesAvail(0) length -= (1 << page_length); } + // @TODO: Venice: Clear 3-8MB region and add to free memory pool. + // Can't do this now due to fake-PNOR driver. + printk("done\n"); } @@ -69,7 +72,7 @@ void* PageManager::_allocatePage(size_t n) { size_t which_bucket = 0; while (n > (size_t)(1 << which_bucket)) which_bucket++; - + int retries = 0; page_t* page = (page_t*)NULL; while ((page == NULL) && (retries < 3)) @@ -109,11 +112,11 @@ void PageManager::_freePage(void* p, size_t n) PageManager::page_t* PageManager::pop_bucket(size_t n) { if (n >= BUCKETS) return NULL; - + page_t* p = first_page[n].pop(); if (NULL == p) - { + { // Couldn't allocate from the correct size bucket, so split up an // item from the next sized bucket. p = pop_bucket(n+1); diff --git a/src/makefile b/src/makefile index 3c1a75a15..c002d5bf6 100644 --- a/src/makefile +++ b/src/makefile @@ -30,7 +30,7 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \ syscall_msg.o syscall_mmio.o syscall_time.o \ init_main.o vfs_main.o sync.o futexmgr.o \ ptmgr.o segmentmgr.o basesegment.o devicesegment.o \ - block.o cxxtest_data.o + block.o cxxtest_data.o cpuid.o ## STUB_TESTCASE_OBJECT = cxxtest_stub.o -- cgit v1.2.1