diff options
-rw-r--r-- | src/build/debug/Hostboot/VirtToPhys.pm | 28 | ||||
-rwxr-xr-x | src/build/debug/Hostboot/_DebugFrameworkVMM.pm | 46 | ||||
-rwxr-xr-x | src/build/debug/simics-debug-framework.pl | 58 | ||||
-rwxr-xr-x | src/build/debug/simics-debug-framework.py | 24 | ||||
-rw-r--r-- | src/include/kernel/devicesegment.H | 53 | ||||
-rw-r--r-- | src/include/kernel/ptmgr.H | 52 | ||||
-rw-r--r-- | src/include/kernel/syscalls.H | 48 | ||||
-rw-r--r-- | src/include/kernel/vmmmgr.H | 69 | ||||
-rw-r--r-- | src/include/sys/mm.h | 56 | ||||
-rw-r--r-- | src/kernel/basesegment.C | 2 | ||||
-rw-r--r-- | src/kernel/block.C | 47 | ||||
-rw-r--r-- | src/kernel/devicesegment.C | 74 | ||||
-rw-r--r-- | src/kernel/exception.C | 2 | ||||
-rw-r--r-- | src/kernel/ptmgr.C | 68 | ||||
-rw-r--r-- | src/kernel/syscall.C | 66 | ||||
-rw-r--r-- | src/kernel/vmmmgr.C | 64 | ||||
-rw-r--r-- | src/lib/syscall_mm.C | 53 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/thread_activate/thread_activate.C | 3 | ||||
-rw-r--r-- | src/usr/testcore/kernel/misctest.H | 54 | ||||
-rw-r--r-- | src/usr/testcore/kernel/ptmgrtest.H | 51 |
20 files changed, 572 insertions, 346 deletions
diff --git a/src/build/debug/Hostboot/VirtToPhys.pm b/src/build/debug/Hostboot/VirtToPhys.pm index 8a55c53d5..9a0dbdb39 100644 --- a/src/build/debug/Hostboot/VirtToPhys.pm +++ b/src/build/debug/Hostboot/VirtToPhys.pm @@ -47,7 +47,7 @@ sub main } - if (defined $args->{"showSPTE"}) + if( (defined $args->{"SPTE"}) || (defined $args->{"spte"}) ) { $displaySPTE = 1; } @@ -55,20 +55,30 @@ sub main # Parse 'vaddr' argument. if (not defined $args->{"vaddr"}) { - ::userDisplay "ERROR.. Did not pass in Virtual Address.\n"; - die; + ::userDisplay "ERROR.. Did not pass in Virtual Address.\n"; + die; } my $vaddr = hex($args->{"vaddr"}); if ($debug) { - ::userDisplay (sprintf "\n Virtual Address = %X\n" , $vaddr); + ::userDisplay (sprintf "\n Virtual Address = %X\n" , $vaddr); } - - $phyAddr = Hostboot::_DebugFrameworkVMM::getPhysicalAddr($vaddr, $debug, $displaySPTE); - - return $phyAddr; + + $phyAddr = Hostboot::_DebugFrameworkVMM::getPhysicalAddr($vaddr, $debug, $displaySPTE); + + if (($phyAddr eq Hostboot::_DebugFrameworkVMM::NotFound) || + ($phyAddr eq Hostboot::_DebugFrameworkVMM::NotPresent)) + { + ::userDisplay ("The Physical Address = $phyAddr\n"); + } + else + { + ::userDisplay (sprintf "The Physical Address = 0x%X\n" , $phyAddr); + } + + return $phyAddr; } @@ -80,7 +90,7 @@ sub helpInfo options => { "vaddr=<number>" => ["Virtual Address "], "debug" => ["More debug output."], - "displaySPTE" => ["Display the SPTE for the VA passed in"], + "SPTE" => ["Display the SPTE for the VA passed in"], }, ); diff --git a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm index a4e5bef03..dc5cbfa59 100755 --- a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm +++ b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm @@ -1,26 +1,26 @@ #!/usr/bin/perl -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/build/debug/Hostboot/_DebugFrameworkVMM.pm $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011-2012 -# -# p1 -# -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code -# -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. -# -# Origin: 30 -# -# IBM_PROLOG_END_TAG +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/debug/Hostboot/_DebugFrameworkVMM.pm $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011,2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG # _DebugFrameworkVMM.pm # # This module is a set of utility functions for the debug framework, which @@ -336,6 +336,8 @@ sub getPhyAddrfromSPTE $paddr = $SPTEaddr + $addrOffset; + # add the HRMOR value to get the actual physical address + $paddr += ::getHRMOR(); } else { diff --git a/src/build/debug/simics-debug-framework.pl b/src/build/debug/simics-debug-framework.pl index f78f34284..c83ed905f 100755 --- a/src/build/debug/simics-debug-framework.pl +++ b/src/build/debug/simics-debug-framework.pl @@ -1,26 +1,26 @@ #!/usr/bin/perl -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/build/debug/simics-debug-framework.pl $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011-2012 -# -# p1 -# -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code -# -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. -# -# Origin: 30 -# -# IBM_PROLOG_END_TAG +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/debug/simics-debug-framework.pl $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011,2012 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG # @file simics-debug-framework.pl # @brief Implementation of the common debug framework for running in simics. # @@ -94,6 +94,8 @@ sub readData my $addr = shift; my $size = shift; + $addr += getHRMOR(); + sendIPCMsg("read-data", "$addr,$size"); my ($type, $data) = recvIPCMsg(); @@ -114,6 +116,8 @@ sub writeData my $size = shift; my $value = shift; + $addr += getHRMOR(); + my $value = unpack("H*", $value); sendIPCMsg("write-data", "$addr,$size,$value"); @@ -288,6 +292,16 @@ sub checkContTrace() } +## +## Retrieve the HRMOR value +## +sub getHRMOR() +{ + sendIPCMsg("get-hrmor",""); + my ($unused, $hrmor) = recvIPCMsg(); + return $hrmor; +} + # Get tool name. sendIPCMsg("get-tool",""); my ($unused, $tool) = recvIPCMsg(); diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py index 3f54263a6..0824839e0 100755 --- a/src/build/debug/simics-debug-framework.py +++ b/src/build/debug/simics-debug-framework.py @@ -233,6 +233,13 @@ class DebugFrameworkProcess: if ( result ): print "simics ERROR running %s: %d "%( syscmd, result ) + # Read HRMOR from processors. + # This message has no input data + def get_hrmor(self,data): + hrmor = getHRMOR() + self.sendMsg("data-response", "%d"%(hrmor) ) + + # @fn run_hb_debug_framework # @brief Wrapper function to execute a tool module. # @@ -260,6 +267,7 @@ def run_hb_debug_framework(tool = "Printk", toolOpts = "", "get-img-path" : DebugFrameworkProcess.get_img_path, "write-scom" : DebugFrameworkProcess.write_xscom, "read-scom" : DebugFrameworkProcess.read_xscom, + "get-hrmor" : DebugFrameworkProcess.get_hrmor, "exit" : DebugFrameworkProcess.endProcess, } operations[msg[0]](fp,msg[1]) @@ -329,10 +337,18 @@ def hexDumpToNumber(hexlist): return int(strNumber,16) +# Fetch the current HRMOR value. +def getHRMOR(): + runStr = "(system_cmp0.cpu0_0_05_0).read-reg HRMOR" + ( result, out ) = quiet_run_command( runStr, output_modes.regular ) + return result + + # Read simics memory and return a list of strings such as ['0x0','0x2b','0x8'] # representing the data read from simics. The list returned may be handed # to hexDumpToNumber() to turn the list into a number. def dumpSimicsMemory(address,bytecount): + address = address + getHRMOR() hexlist = map(hex, conf.system_cmp0.phys_mem.memory[[address,address+bytecount-1]]) return hexlist @@ -348,6 +364,7 @@ def readLong(address): return hexDumpToNumber(hexlist) def writeLong(address,datvalue): + address = address + getHRMOR() conf.system_cmp0.phys_mem.memory[[address,address+3]] = [0,0,0,datvalue] return @@ -356,6 +373,7 @@ def writeLong(address,datvalue): # Write simics memory. address is an integer. # data is a list of byte-sized integers. def writeSimicsMemory(address,data): + address = address + getHRMOR() size = len(data) conf.system_cmp0.phys_mem.memory[[address, address+size-1]] = data; @@ -489,6 +507,12 @@ def magic_instruction_callback(user_arg, cpu, arg): # the byte at offset 0 of the buffer which contains a 0x02 in # fsp-trace style. writeLongLong(tracBinaryInfoAddr+8,1) + # Figure out if we are running out of the cache or mainstore + runStr = "(system_cmp0.phys_mem)->map[0][1]" + ( result, out ) = quiet_run_command( runStr, output_modes.regular ) + # Add the HRMOR if we're running from memory + if 'cache' not in result: + pTracBinaryBuffer = pTracBinaryBuffer + getHRMOR() # Save the tracBinary buffer to a file named tracBINARY in current dir saveCommand = "(system_cmp0.phys_mem)->map[0][1]->image.save tracBINARY 0x%x %d"%(pTracBinaryBuffer,cbUsed) SIM_run_alone(run_command, saveCommand ) diff --git a/src/include/kernel/devicesegment.H b/src/include/kernel/devicesegment.H index 2b87c9161..c010ffba8 100644 --- a/src/include/kernel/devicesegment.H +++ b/src/include/kernel/devicesegment.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/kernel/devicesegment.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/devicesegment.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __KERNEL_DEVICESEGMENT_H #define __KERNEL_DEVICESEGMENT_H @@ -81,6 +80,14 @@ class DeviceSegment : public Segment */ int devUnmap(void* ea); + /** + * @brief Locate the physical address of the given virtual address + * @param[in] i_vaddr virtual address + * @return the physical address bound to the virtual address, or + * -EFAULT if i_vaddr not found. @see errno.h + */ + uint64_t findPhysicalAddress(uint64_t i_vaddr) const; + private: /** * Attributes to represent a mapped device within a segment block diff --git a/src/include/kernel/ptmgr.H b/src/include/kernel/ptmgr.H index b570e0d14..ba86bf965 100644 --- a/src/include/kernel/ptmgr.H +++ b/src/include/kernel/ptmgr.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/ptmgr.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/ptmgr.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __KERNEL_PTMGR_H #define __KERNEL_PTMGR_H @@ -121,15 +121,19 @@ class PageTableManager * * @param[in] i_pnStart First Physical Page to remove (page number) * @param[in] i_pnFinish Last Physical Page to remove (page number) + * @param[in] i_applyHRMOR If true then the HRMOR is applied to the + * page numbers, MMIOs should set to false */ static void delRangePN( uint64_t i_pnStart, - uint64_t i_pnFinish ); + uint64_t i_pnFinish, + bool i_applyHRMOR = true ); /** * @brief Return status information about an entry in the hardware page table * * @param[in] i_vAddr Virtual Address within the page to be queried (full address) - * @param[out] o_pn Real physical page number to map to, INVALID_PN if PTE is invalid + * @param[out] o_pn Real physical page number va is mapped to, + * INVALID_PN if PTE is invalid * * @return uint64_t ORed combination of status flags */ diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H index b02fd2216..f31526868 100644 --- a/src/include/kernel/syscalls.H +++ b/src/include/kernel/syscalls.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/kernel/syscalls.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2010-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/syscalls.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** @file syscalls.H * @brief Defines all the system call IDs to be shared between the kernel and * the system libc. @@ -108,6 +107,9 @@ namespace Systemcalls /** mm_alloc_pages() */ MM_ALLOC_PAGES, + /** mm_virt_to_phys() */ + MM_VIRT_TO_PHYS, + SYSCALL_MAX }; diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H index 8a8fb6103..0c11ffeb8 100644 --- a/src/include/kernel/vmmmgr.H +++ b/src/include/kernel/vmmmgr.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/vmmmgr.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2010 - 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/vmmmgr.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __KERNEL_VMMMGR_H #define __KERNEL_VMMMGR_H @@ -29,6 +29,7 @@ #include <kernel/types.h> #include <kernel/spinlock.H> + class MessageQueue; class VmmManager @@ -43,12 +44,16 @@ class VmmManager // put the Page Table at the end of our memory space PTSIZE = (1 << 18), - HTABORG = (FULL_MEM_SIZE - PTSIZE), + HTABORG_OFFSET = (FULL_MEM_SIZE - PTSIZE), // Put the DMA Pages just under the Page Table MBOX_DMA_PAGES = 64, // must be <= 64 MBOX_DMA_PAGESIZE = (1 * KILOBYTE), - MBOX_DMA_ADDR = (HTABORG - (MBOX_DMA_PAGES * MBOX_DMA_PAGESIZE)) + MBOX_DMA_ADDR = (HTABORG_OFFSET + - (MBOX_DMA_PAGES * MBOX_DMA_PAGESIZE)), + + // Tells processor to ignore HRMOR + FORCE_PHYS_ADDR = 0x8000000000000000, }; enum castout_t @@ -117,7 +122,7 @@ class VmmManager static int mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size); /** - * @brief Find the phyiscal address bound to the given address + * @brief Find the physical address bound to the given address * @param[in] i_vaddr The address * @return the physical address or -EFAULT @see errno.h */ @@ -166,6 +171,20 @@ class VmmManager */ static int mmSetPermission(void* i_va,uint64_t i_size, uint64_t i_access_type); + /** + * @brief Retrieve the current HTABORG value + * @return uint64_t - value of HTABORG + */ + static uint64_t HTABORG(); + + /** + * @brief Find the kernel addressable address bound to the + * given virtual address + * @param[in] i_vaddr The address + * @return the kernel address or -EFAULT @see errno.h + */ + static uint64_t findKernelAddress(uint64_t i_vaddr); + protected: VmmManager(); ~VmmManager() {}; diff --git a/src/include/sys/mm.h b/src/include/sys/mm.h index d9b5536a1..82e32bf46 100644 --- a/src/include/sys/mm.h +++ b/src/include/sys/mm.h @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/sys/mm.h $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/sys/mm.h $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __SYS_MM_H #define __SYS_MM_H @@ -109,5 +108,16 @@ int mm_set_permission(void* va, uint64_t size, uint64_t access_type); */ void mm_icache_invalidate(void * i_addr, size_t i_cpu_word_count); +/** @fn mm_virt_to_phys() + * @brief System call to return the physical address backing a + * virtual address + * + * @param[in] i_vaddr - Virtual address to translate + * + * @return uint64_t - 0 if there is no associated address, + * physical address otherwise + */ +uint64_t mm_virt_to_phys( void* i_vaddr ); + #endif diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C index 56f7b6229..c9a826f8e 100644 --- a/src/kernel/basesegment.C +++ b/src/kernel/basesegment.C @@ -131,7 +131,7 @@ uint64_t BaseSegment::findPhysicalAddress(uint64_t i_vaddr) const // Anything in the physical address size is valid (and linear mapped) // except NULL. if (i_vaddr >= PAGE_SIZE) - return i_vaddr; + return (i_vaddr | getHRMOR()); else return -EFAULT; } return (iv_block ? iv_block->findPhysicalAddress(i_vaddr) : -EFAULT); diff --git a/src/kernel/block.C b/src/kernel/block.C index 8afc39ae7..1ea12d2c0 100644 --- a/src/kernel/block.C +++ b/src/kernel/block.C @@ -1,26 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/kernel/block.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END - +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/block.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <limits.h> #include <assert.h> #include <string.h> @@ -38,6 +37,7 @@ #include <kernel/console.H> #include <util/align.H> #include <kernel/basesegment.H> +#include <arch/ppc.H> // Track eviction requests due to aging pages uint32_t Block::cv_ro_evict_req = 0; @@ -265,6 +265,7 @@ uint64_t Block::findPhysicalAddress(uint64_t i_vaddr) const { paddr = pte->getPageAddr(); paddr += i_vaddr % PAGESIZE; + paddr |= getHRMOR(); } return paddr; diff --git a/src/kernel/devicesegment.C b/src/kernel/devicesegment.C index 04e41b7be..4236417e8 100644 --- a/src/kernel/devicesegment.C +++ b/src/kernel/devicesegment.C @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/kernel/devicesegment.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/devicesegment.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <util/singleton.H> #include <limits.h> #include <assert.h> @@ -130,10 +130,38 @@ int DeviceSegment::devUnmap(void *ea) { //Remove all of the defined block's size (<= 32GB) PageTableManager::delRangePN(iv_mmioMap[idx].addr / PAGESIZE, - (iv_mmioMap[idx].addr + iv_mmioMap[idx].size) / PAGESIZE); + (iv_mmioMap[idx].addr + iv_mmioMap[idx].size) / PAGESIZE, + false); iv_mmioMap[idx].addr = 0; rc = 0; } return rc; } + +/** + * Locate the physical address of the given virtual address + */ +uint64_t DeviceSegment::findPhysicalAddress(uint64_t i_vaddr) const +{ + uint64_t rc = -EFAULT; + uint64_t segment_ea = i_vaddr; + //Verify input address falls within this segment's address range + if (segment_ea < this->getBaseAddress() || + segment_ea >= (this->getBaseAddress() + (1ull << SLBE_s))) + { + return rc; + } + segment_ea = segment_ea - this->getBaseAddress(); + //TODO - Calculate idx by segment block size if/when new device size needed + size_t idx = segment_ea / ((1ull << SLBE_s) / MMIO_MAP_DEVICES); + if (0 != iv_mmioMap[idx].addr) + { + //memory offset within this device's window + uint64_t offset = segment_ea - idx*((1ull << SLBE_s) / MMIO_MAP_DEVICES); + return (iv_mmioMap[idx].addr + offset); + } + + return rc; +} + diff --git a/src/kernel/exception.C b/src/kernel/exception.C index 836a57a57..d1b365535 100644 --- a/src/kernel/exception.C +++ b/src/kernel/exception.C @@ -161,7 +161,7 @@ namespace ExceptionHandles { bool PrivInstr(task_t* t) { - uint64_t phys_addr = VmmManager::findPhysicalAddress( + uint64_t phys_addr = VmmManager::findKernelAddress( reinterpret_cast<uint64_t>(t->context.nip)); if (-EFAULT != static_cast<int64_t>(phys_addr)) diff --git a/src/kernel/ptmgr.C b/src/kernel/ptmgr.C index bf8937b78..573712994 100644 --- a/src/kernel/ptmgr.C +++ b/src/kernel/ptmgr.C @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/kernel/ptmgr.C $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/ptmgr.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <kernel/ptmgr.H> #include <kernel/vmmmgr.H> #include <util/singleton.H> @@ -35,6 +34,7 @@ #define Tprintk(args...) #define Eprintk(args...) printk(args) + // Utilities to do some bit manipulation /** @@ -208,7 +208,15 @@ void PageTableManager::addEntry( uint64_t i_vAddr, uint64_t i_page, uint64_t i_accessType ) { - return Singleton<PageTableManager>::instance()._addEntry( i_vAddr, i_page, i_accessType ); + // adjust physical address for the HRMOR unless this is a mmio + if( SegmentManager::CI_ACCESS != i_accessType ) + { + i_page |= (getHRMOR() / PAGESIZE); + } + + return Singleton<PageTableManager>::instance()._addEntry( i_vAddr, + i_page, + i_accessType ); } /** @@ -235,8 +243,16 @@ void PageTableManager::delRangeVA( uint64_t i_vAddrStart, * @brief Remove a range of entries from the hardware page table */ void PageTableManager::delRangePN( uint64_t i_pnStart, - uint64_t i_pnFinish ) + uint64_t i_pnFinish, + bool i_applyHRMOR ) { + // adjust physical address for the HRMOR unless this is a mmio + if( i_applyHRMOR ) + { + i_pnStart |= (getHRMOR() / PAGESIZE); + i_pnFinish |= (getHRMOR() / PAGESIZE); + } + return Singleton<PageTableManager>::instance()._delRangePN(i_pnStart,i_pnFinish); } @@ -857,7 +873,7 @@ uint64_t PageTableManager::getAddress( void ) if(unlikely(ivTABLE != NULL)) { return (uint64_t)ivTABLE; } else { - return VmmManager::HTABORG; + return VmmManager::HTABORG(); } } diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 94c6a5860..a38f08b78 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/kernel/syscall.C $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2010-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/syscall.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <assert.h> #include <errno.h> #include <kernel/cpu.H> @@ -92,6 +91,7 @@ namespace Systemcalls void MmRemovePages(task_t *t); void MmSetPermission(task_t *t); void MmAllocPages(task_t *t); + void MmVirtToPhys(task_t *t); syscall syscalls[] = @@ -130,6 +130,7 @@ namespace Systemcalls &MmRemovePages, // MM_REMOVE_PAGES &MmSetPermission, // MM_SET_PERMISSION &MmAllocPages, // MM_ALLOC_PAGES + &MmVirtToPhys, // MM_VIRT_TO_PHYS }; }; @@ -207,7 +208,7 @@ namespace Systemcalls if (status != NULL) { uint64_t addr = - VmmManager::findPhysicalAddress( + VmmManager::findKernelAddress( reinterpret_cast<uint64_t>(status)); if (addr == (static_cast<uint64_t>(-EFAULT))) @@ -222,7 +223,7 @@ namespace Systemcalls if (retval != NULL) { uint64_t addr = - VmmManager::findPhysicalAddress( + VmmManager::findKernelAddress( reinterpret_cast<uint64_t>(retval)); if (addr == (static_cast<uint64_t>(-EFAULT))) @@ -543,7 +544,7 @@ namespace Systemcalls // Set RC to success initially. TASK_SETRTN(t,0); - futex = VmmManager::findPhysicalAddress(futex); + futex = VmmManager::findKernelAddress(futex); if(futex == (static_cast<uint64_t>(-EFAULT))) { printk("Task %d terminated. No physical address found for address 0x%p", @@ -579,7 +580,7 @@ namespace Systemcalls case FUTEX_REQUEUE: // Wake (val) task(s) on futex && requeue remaining tasks on futex2 - futex2 = VmmManager::findPhysicalAddress(futex2); + futex2 = VmmManager::findKernelAddress(futex2); if(futex2 == (static_cast<uint64_t>(-EFAULT))) { printk("Task %d terminated. No physical address found for address 0x%p", @@ -779,5 +780,16 @@ namespace Systemcalls } } + + /** + * Return the physical address backing a virtual address + * @param[in] t: The task used + */ + void MmVirtToPhys(task_t* t) + { + uint64_t i_vaddr = (uint64_t)TASK_GETARG0(t); + uint64_t phys = VmmManager::findPhysicalAddress(i_vaddr); + TASK_SETRTN(t, phys); + } }; diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C index ed88a4879..b7c98a0c5 100644 --- a/src/kernel/vmmmgr.C +++ b/src/kernel/vmmmgr.C @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/kernel/vmmmgr.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2010 - 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/vmmmgr.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <limits.h> #include <util/singleton.H> #include <kernel/vmmmgr.H> @@ -31,10 +31,12 @@ #include <kernel/stacksegment.H> #include <kernel/devicesegment.H> + extern void* data_load_address; VmmManager::VmmManager() : lock() { + printk("HRMOR = %lX\n", getHRMOR()); } void VmmManager::init() @@ -108,7 +110,7 @@ void VmmManager::initPTEs() void VmmManager::initSDR1() { // HTABORG, HTABSIZE = 0 (11 bits, 256k table) - register uint64_t sdr1 = (uint64_t)HTABORG; + register uint64_t sdr1 = HTABORG(); asm volatile("mtsdr1 %0" :: "r"(sdr1) : "memory"); } @@ -229,3 +231,19 @@ int VmmManager::_devUnmap(void* ea) return rc; } +uint64_t VmmManager::HTABORG() +{ + return ((uint32_t)HTABORG_OFFSET + getHRMOR()); +} + +uint64_t VmmManager::findKernelAddress(uint64_t i_vaddr) +{ + //in hypervisor mode the HRMOR is automatically ORed onto + // the address so we need to tell the hardware to ignore it + uint64_t phys = VmmManager::findPhysicalAddress(i_vaddr); + if( static_cast<uint64_t>(-EFAULT) != phys ) + { + phys |= FORCE_PHYS_ADDR; + } + return phys; +} diff --git a/src/lib/syscall_mm.C b/src/lib/syscall_mm.C index b539cf05a..72c520db6 100644 --- a/src/lib/syscall_mm.C +++ b/src/lib/syscall_mm.C @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/lib/syscall_mm.C $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/lib/syscall_mm.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <sys/syscall.h> #include <sys/mm.h> #include <arch/ppc.H> @@ -81,3 +80,11 @@ int mm_set_permission(void* va, uint64_t size, uint64_t access_type) { return (int64_t)_syscall3(MM_SET_PERMISSION, va, (void*)size, (void*)access_type); } + +/** + * System call to return the physical address backing a virtual address + */ +uint64_t mm_virt_to_phys( void* i_vaddr ) +{ + return (uint64_t) _syscall1(MM_VIRT_TO_PHYS,i_vaddr); +} diff --git a/src/usr/hwpf/hwp/thread_activate/thread_activate.C b/src/usr/hwpf/hwp/thread_activate/thread_activate.C index c8f418f35..bbefc6112 100644 --- a/src/usr/hwpf/hwp/thread_activate/thread_activate.C +++ b/src/usr/hwpf/hwp/thread_activate/thread_activate.C @@ -50,9 +50,6 @@ #include <hwpf/plat/fapiPlatTrace.H> -//@fixme - Patrick is adding this constant under 37009 -#define MAGIC_SIMICS_CORESTATESAVE 10 - namespace THREAD_ACTIVATE { diff --git a/src/usr/testcore/kernel/misctest.H b/src/usr/testcore/kernel/misctest.H index 9a7cbb2ba..e31b3cc9c 100644 --- a/src/usr/testcore/kernel/misctest.H +++ b/src/usr/testcore/kernel/misctest.H @@ -26,6 +26,7 @@ #include <sys/misc.h> #include <kernel/cpumgr.H> +#include <targeting/common/targetservice.H> /** @file misctest.H * @@ -49,6 +50,59 @@ class MiscTest : public CxxTest::TestSuite TS_FAIL("LPCR value is not as expected."); } } + + /** Tests for mm_virt_to_phys() */ + void testVirtToPhys() + { + uint64_t phys = 0; + uint64_t hrmor = cpu_spr_value(CPU_SPR_HRMOR); + + // Verify a regular heap address + uint8_t* heap = (uint8_t*)malloc(1); + *heap = 0xAB; //to make sure it gets paged in + phys = mm_virt_to_phys( heap ); + if( phys != (reinterpret_cast<uint64_t>(heap)|hrmor) ) + { + TS_FAIL("Unexpected Physical Address for Heap."); + TS_TRACE( "heap> virt=%p, phys=%lX", (void*)heap, phys ); + } + free(heap); + + // Verify a regular stack address + phys = mm_virt_to_phys( (void*)&phys ); + if( phys < hrmor ) + { + TS_FAIL("Unexpected Physical Address for Stack."); + TS_TRACE( "stack> virt=%p, phys=%lX", &phys, phys ); + } + + // Verify a MMIO (XSCOM) + TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL); + epath.addLast(TARGETING::TYPE_SYS,0); + epath.addLast(TARGETING::TYPE_NODE,0); + epath.addLast(TARGETING::TYPE_PROC,1); + TARGETING::Target* l_targ = + TARGETING::targetService().toTarget(epath); + if(l_targ != NULL) + { + uint64_t xscom = + l_targ->getAttr<TARGETING::ATTR_XSCOM_VIRTUAL_ADDR>(); + phys = mm_virt_to_phys( (void*)xscom ); + if( (phys != (1020*TERABYTE+32*GIGABYTE)) + && (xscom != 0) ) //never got set + { + TS_FAIL("Unexpected Physical Address for MMIO."); + TS_TRACE( "mmio1> virt=%lX, phys=%lX\n", xscom, phys ); + } + } + + + /* Hardcoded interrupt presenter address for testing on 1-proc model + uint64_t intr = 0x20800000000; + phys = mm_virt_to_phys( (void*)intr ); + TS_TRACE( "mmio2> virt=%lX, phys=%lX\n", intr, phys ); + */ + } }; #endif diff --git a/src/usr/testcore/kernel/ptmgrtest.H b/src/usr/testcore/kernel/ptmgrtest.H index e97457513..635901318 100644 --- a/src/usr/testcore/kernel/ptmgrtest.H +++ b/src/usr/testcore/kernel/ptmgrtest.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/testcore/kernel/ptmgrtest.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/kernel/ptmgrtest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __PTMGRTEST_H #define __PTMGRTEST_H /** @@ -154,7 +154,8 @@ class ptmgrtest : public CxxTest::TestSuite TS_TRACE( "Addr=%.16lX, Status=%.16lX", TEST_DATA[x].va, status ); fails++; } - else if( (status & PageTableManager::PTE_VALID) && (pn == TEST_DATA[x].page) ) + else if( (status & PageTableManager::PTE_VALID) + && (pn == TEST_DATA[x].page) ) { PASS_TRACE( "ptmgrtest::test_addEntry> PASS1 : 0x%.16lX", TEST_DATA[x].va ); @@ -162,8 +163,8 @@ class ptmgrtest : public CxxTest::TestSuite uint64_t va = ptmgr->getVirtAddrFromPTE(pte); if( va != (TEST_DATA[x].va - TEST_DATA[x].va%4096) ) { - printk( "ptmgrtest::test_addEntry> ERROR6 : VA doesn't match expected" ); - printk( "Exp=%.16lX, Act=%.16lX", TEST_DATA[x].va, va ); + TS_FAIL( "ptmgrtest::test_addEntry> ERROR6 : VA doesn't match expected" ); + TS_TRACE( "Exp=%.16lX, Act=%.16lX", TEST_DATA[x].va, va ); fails++; } total++; |