[PATCH 3/4] powerpc: add support for libmm for powerpc with psim bsp

Gedare Bloom gedare at rtems.org
Thu Oct 11 19:10:22 UTC 2012


From: Hesham AL-Matary <heshamelmatary at gmail.com>

---
 c/src/lib/libbsp/powerpc/psim/startup/bspstart.c  |    8 +-
 c/src/lib/libbsp/powerpc/psim/startup/device-tree |    2 +-
 c/src/lib/libcpu/powerpc/Makefile.am              |    9 +-
 c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.c |  287 +++++++++++++++++++++
 c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.h |   98 +++++++
 c/src/lib/libcpu/powerpc/mpc6xx/mmu/pagetable_.c  |  189 ++++++++++++++
 c/src/lib/libcpu/powerpc/preinstall.am            |    8 +
 7 files changed, 595 insertions(+), 6 deletions(-)
 create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.c
 create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.h
 create mode 100644 c/src/lib/libcpu/powerpc/mpc6xx/mmu/pagetable_.c

diff --git a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
index 29cbb76..1a8b0db 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/psim/startup/bspstart.c
@@ -24,7 +24,7 @@
 #include <libcpu/cpuIdent.h>
 #include <libcpu/bat.h>
 #include <libcpu/spr.h>
-
+#include <libcpu/mmu_support.h>
 SPR_RW(SPRG1)
 
 /*  On psim, each click of the decrementer register corresponds
@@ -123,7 +123,7 @@ void bsp_start( void )
    * Initalize RTEMS IRQ system
    */
   BSP_rtems_irq_mng_init(0);
-
+  mmu_irq_init();
   /*
    * Setup BATs and enable MMU
    */
@@ -134,7 +134,9 @@ void bsp_start( void )
   setdbat(1, 0x8<<24, 0x8<<24, 1<<24,  IO_PAGE);
   setdbat(2, 0xc<<24, 0xc<<24, 1<<24,  IO_PAGE);
 
+  /* Invalidate all TLB Entries */
+  asm volatile("sync; isync; tlbia; sync; isync");
   _write_MSR(_read_MSR() | MSR_DR | MSR_IR);
-  __asm__ volatile("sync; isync");
 
+  __asm__ volatile("sync; isync");
 }
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/device-tree b/c/src/lib/libbsp/powerpc/psim/startup/device-tree
index bd2a2a5..f4af7be 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/device-tree
+++ b/c/src/lib/libbsp/powerpc/psim/startup/device-tree
@@ -1,4 +1,4 @@
 #/openprom/init/register/pc 0
 #/openprom/options/smp 2
 #/openprom/options/oea-memory-size 4194304
-/openprom/options/oea-memory-size 8388608
+/openprom/options/oea-memory-size 8388608 
diff --git a/c/src/lib/libcpu/powerpc/Makefile.am b/c/src/lib/libcpu/powerpc/Makefile.am
index 462beec..66a2523 100644
--- a/c/src/lib/libcpu/powerpc/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/Makefile.am
@@ -217,12 +217,17 @@ endif
 if mpc6xx
 
 # mpc6xx/mmu
-include_libcpu_HEADERS += mpc6xx/mmu/bat.h mpc6xx/mmu/pte121.h
+include_libcpu_HEADERS += mpc6xx/mmu/bat.h mpc6xx/mmu/pte121.h \
+		 mpc6xx/mmu/mmu_support.h \
+    ../shared/include/memorymanagement.h
 
 noinst_PROGRAMS += mpc6xx/mmu.rel
 mpc6xx_mmu_rel_SOURCES = mpc6xx/mmu/bat.c mpc6xx/mmu/bat.h \
     mpc6xx/mmu/pte121.c mpc6xx/mmu/pte121.h \
-    mpc6xx/mmu/mmuAsm.S
+    mpc6xx/mmu/mmuAsm.S \
+		mpc6xx/mmu/mmu_support.h mpc6xx/mmu/mmu_support.c mpc6xx/mmu/pagetable_.c \
+    ../shared/include/memorymanagement.h \
+		../shared/src/memorymanagement_manager.c
 mpc6xx_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
 mpc6xx_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
 
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.c
new file mode 100644
index 0000000..7f5ec0d
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.c
@@ -0,0 +1,287 @@
+/*
+*  COPYRIGHT (c) 1989-2012.
+*  On-Line Applications Research Corporation (OAR).
+*
+*  The license and distribution terms for this file may be
+*  found in the file LICENSE in this distribution or at
+*  http://www.rtems.com/license/LICENSE.
+*/
+
+#include <rtems.h>
+#include <libcpu/bat.h>
+#include <libcpu/spr.h>
+#include <bsp/irq_supp.h>
+#include <rtems/powerpc/powerpc.h>
+#include <rtems/irq.h>
+#include <stdio.h>
+#include <rtems/asm.h>
+#include <rtems/rtems/status.h>
+#include <libcpu/memorymanagement.h>
+#include "mmu_support.h"
+
+SPR_RO(PPC_DAR);
+SPR_RW(SDR1);
+SPR_RO(DSISR);
+
+//uint32_t BSP_MAX_ARENA = 64;
+
+static int pte_counter = 5;
+
+static int search_empty_pte_slot(ppc_bsp_mm_mpe *pteg)
+{
+  int i;
+  for(i = 0; i < 8; i++) {
+    if((pteg[i].ptew0 & PTEW0_VALID) != 0x80000000) {
+      /* Found empty pte slot */
+      return i;
+    }
+  }
+  /* No PTE  free entry found, so rotate count and select a PTE */
+  return -1;
+}
+
+static int search_valid_pte(
+    ppc_bsp_mm_mpe *pteg,
+    uint32_t vsid,
+    uint32_t api
+) {
+  register int i;
+  register uint32_t temp_vsid;
+  register uint32_t temp_api;
+
+  for(i = 0; i < 8; i++) {
+    if((pteg[i].ptew0 & PTEW0_VALID) == 0x80000000) {
+
+      temp_api  = pteg[i].ptew0 & PTEW0_API;
+      temp_vsid = (pteg[i].ptew0 & PTEW0_VSID) >> 7;
+
+      if(temp_api == api && temp_vsid == vsid) { /* hit */
+  	    return i;
+      }
+    }
+  }
+  return -1;  /* Failed search */
+}
+
+ppc_bsp_mm_mpe* BSP_ppc_add_pte(
+  ppc_bsp_mm_mpe *ppteg,
+  ppc_bsp_mm_mpe *spteg,
+  uint32_t vsid,
+  uint32_t pi,
+  uint32_t wimg,
+  uint32_t protp
+) {
+  int index;
+  uint32_t hash, rpn, api;
+  ppc_bsp_mm_mpe* pteg;
+
+  /* Search empty PTE slot in PPTEG */
+  index = search_empty_pte_slot(ppteg);
+  if (index != -1){
+    pteg = ppteg;
+    hash = 0;
+  } else {
+    /* Search Empty slot in  SPTEG */
+    index = search_empty_pte_slot(spteg);
+    if (index == -1) {
+      /* Replace random pte entry depending on a counter */
+      index = pte_counter;
+      if (pte_counter == 7){
+  	    pte_counter = 0;
+      }
+      pte_counter++;
+      pteg = ppteg;
+      hash = 0;
+    }else {
+      pteg = spteg;
+      hash = 1;
+    }
+  }
+
+  api = pi >> 10;
+  rpn = pi;
+
+  /* Clear the pte first . Invalidate */
+  pteg[index].ptew0 = 0x00000000;
+  pteg[index].ptew1 = 0x00000000;
+
+  /* Update the PTE with new entry */
+  pteg[index].ptew0 |= (vsid << 7) & PTEW0_VSID;
+  pteg[index].ptew0 |= (hash << 6) & PTEW0_HASHF;
+  pteg[index].ptew0 |= (api & PTEW0_API);
+  pteg[index].ptew1 |= (rpn << 12);
+  pteg[index].ptew1 |= (wimg << 3) & (PTEW1_WIMG);
+  pteg[index].ptew1 |= (protp & PTEW1_PROTP);
+  pteg[index].ptew0 |= PTEW0_VALID;
+  return &pteg[index];
+}
+
+void get_pteg_addr(
+  ppc_bsp_mm_mpe** pteg,
+  uint32_t hash
+) {
+  uint32_t masked_hash = 0x0;
+  uint32_t htaborg, htabmask;
+  htabmask = _read_SDR1() & 0x000001ff;
+  htaborg = _read_SDR1() & 0xffff0000;
+  masked_hash = ((htaborg >> 16) & 0x000001ff) | ((hash >> 10) & htabmask);
+  *pteg = (ppc_bsp_mm_mpe *)
+            (htaborg | (masked_hash << 16) | (hash & 0x000003ff) << 6);
+}
+
+/* This function shall be called upon exception on the DSISR
+   register. depending on the type of exception appropriate action
+   will be taken in this function. Most likely parameters for this
+   function are
+   - Exception Type (depending on DSISR[0..n]
+   - address for which the transaltion failed
+   - Anything else? */
+static int mmu_handle_dsi_exception(
+    BSP_Exception_frame *f,
+    unsigned vector
+) {
+  volatile uint32_t ea, sr_data, vsid, pi, hash1, hash2;
+  volatile uint32_t key, api, alut_access_attrb;
+  volatile int ppteg_search_status, spteg_search_status;
+  int status, pp, wimg;
+  ppc_bsp_mm_mpe* ppteg;
+  ppc_bsp_mm_mpe* spteg;
+  volatile unsigned long cause, msr;
+  rtems_memory_management_entry* alut_entry;
+
+  /* Switch MMU and other Interrupts off */
+  msr = _read_MSR();
+  _write_MSR(msr & ~ (MSR_EE | MSR_DR | MSR_IR));
+
+  #ifdef MMUS_DEBUG
+  printk("~~~<debug information: get into the DSI exception handler!>~~~\n");
+  #endif
+
+  /* get effective address from DAR */
+  ea = _read_PPC_DAR();
+  cause = _read_DSISR();
+
+  /* Read corresponding SR Data */
+  sr_data = _read_SR((void *) ea);
+
+  /* Extract VSID */
+  vsid = sr_data & SR_VSID;
+
+  /* get page index (PI) from EA */
+  pi = (ea >> 12) & 0x0000ffff;
+  api = pi >> 10;
+
+  if(ea > (int)RamSize)
+  {
+    printk("Unexpected address 0x%x, RamSize = 0x%x\n",
+        (unsigned int)ea,(unsigned int)RamSize);
+    rtems_task_delete(RTEMS_SELF);
+  }
+
+  /* Compute HASH 1 */
+  hash1 = PTE_HASH_FUNC1(vsid, pi);
+
+  /* Compute PTEG Address from the hash 1 value */
+  get_pteg_addr(&ppteg, hash1);
+
+  /* Search for PTE in group */
+  ppteg_search_status = search_valid_pte(ppteg, vsid, api);
+
+  if (ppteg_search_status == -1) {
+    /* PTE Not found . Search in SPTEG */
+    hash2 = PTE_HASH_FUNC2(hash1);
+    get_pteg_addr(&spteg, hash2);
+    spteg_search_status = search_valid_pte(spteg, vsid, api);
+    if (spteg_search_status == -1){
+      /* PTE not found in second PTEG also */
+      printk("No CPU MPE found for this address");
+    } else {
+      /* PTE found in second group */
+      /* Code for determining access attribute goes here */
+      key = ((sr_data & SR_KP) && MSR_PR) || ((sr_data & SR_KS) && ~(MSR_PR));
+      pp = spteg[spteg_search_status].ptew1 & PTEW1_PROTP;
+      if (((key && (pp == 1 || pp == 0 || pp == 3)) ||
+        (~(key) && (pp == 3)) ) &&(cause & 0x02000000)){
+        /* Write access denied */
+        printk("Error:Write access denied. Please check the access\
+        	attribute of address 0x%x! RTEMS delete self\n", ea);
+        rtems_task_delete(RTEMS_SELF);
+      } else if ((key && (pp == 0)) && (~cause & 0x02000000)) {
+        /* Read access denied */
+        printk("Error:Read access denied. Please check the access\
+                attribute of address 0x%x! RTEMS delete self\n", ea);
+        rtems_task_delete(RTEMS_SELF);
+      } else {
+        /* Access permitted */
+      }
+    }
+  } else {
+    /* PTE found in primary group itself */
+    /* Code for determining attribute goes here */
+    key = ((sr_data & SR_KP) && MSR_PR) || ((sr_data & SR_KS) && ~(MSR_PR));
+    pp = ppteg[ppteg_search_status].ptew1 & PTEW1_PROTP;
+    if (((key && (pp == 1 || pp == 0 || pp == 3)) ||
+      (~(key) && (pp == 3))) &&(cause & 0x02000000)){
+        /* Write access denied */
+         printk("Error:Write access denied. Please check the access\
+	            	 attribute of address 0x%x! RTEMS delete self\n", ea);
+        rtems_task_delete(RTEMS_SELF);
+    } else if ((key && (pp == 0)) && (~cause & 0x02000000)) {
+      /* Read access denied */
+      printk("Error:Read access denied. Please check the access\
+	            attribute of address 0x%x! RTEMS delete self\n", ea);
+      rtems_task_delete(RTEMS_SELF);
+    } else {
+      /* Access permitted */
+    }
+  }
+
+  /* Before returning turn on MMU */
+  _write_MSR( msr );
+  return 0;
+}
+
+static int mmu_handle_tlb_dlmiss_exception(
+    BSP_Exception_frame *f,
+    unsigned vector
+) {
+  printk("DL TLB MISS Exception \n");
+  return 0;
+}
+
+static int mmu_handle_tlb_dsmiss_exception(
+    BSP_Exception_frame *f,
+    unsigned vector
+) {
+  printk("DS TLB MISS Exception \n");
+  return 0;
+}
+
+void mmu_irq_init(void)
+{
+  uint32_t i;
+  ppc_exc_set_handler(ASM_PROT_VECTOR, mmu_handle_dsi_exception);
+  ppc_exc_set_handler(ASM_60X_DLMISS_VECTOR, mmu_handle_tlb_dlmiss_exception);
+  ppc_exc_set_handler(ASM_60X_DSMISS_VECTOR, mmu_handle_tlb_dsmiss_exception);
+
+  /* Initialise segment registers */
+  for (i=0; i<16; i++)
+    _write_SR(i|0x60000000 , (void *)(i<<28 ));
+
+  /* Set up SDR1 register for page table address */
+  _write_SDR1((unsigned long) 0x00FF0000);
+
+  _CPU_Memory_management_Initialize();
+}
+
+/* Make a BAT entry (either IBAT or DBAT entry) Parameters to pass
+   would be EA, PA, Block Length, Access Bits */
+void mmu_make_bat_entry(void)
+{
+}
+
+/* Same thing as above but for Instruction access */
+void
+mmu_handle_isi_exception(void)
+{
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.h b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.h
new file mode 100644
index 0000000..b885b4e
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmu_support.h
@@ -0,0 +1,98 @@
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _LIBCPU_MMU_SUPPORT_H
+#define _LIBCPU_MMU_SUPPORT_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Access definition macros below */
+#define _PPC_MMU_ACCESS_SUPERVISOR_ONLY     	  0
+#define _PPC_MMU_ACCESS_SUPERVISOR_WRITE_ONLY   1
+#define _PPC_MMU_ACCESS_NO_PROT        		      2
+#define _PPC_MMU_ACCESS_READ_ONLY      		      3
+
+#define _PPC_CACHE_WRITETHROUGH                 0x8
+#define _PPC_CACHE_WRITEBACK                    0x0
+#define _PPC_CACHE_ALLOW                        0x0
+#define _PPC_CACHE_DISABLE                      0x4
+#define _PPC_CACHE_MEM_COHERENCY                0x2
+#define _PPC_CACHE_MEM_NONCOHERENCY             0x0
+#define _PPC_CACHE_GUARDED                      0x1
+#define _PPC_CACHE_UNGUARDED                    0x0
+
+/* Defining masks for the various bits of the PTE
+ *    Referenced from OEA PowerPC Manual
+ */
+
+#define PTEW0_VALID            0x80000000
+#define PTEW0_VSID             0x7fffff80
+#define PTEW0_HASHF            0x00000040
+#define PTEW0_API              0x0000003f
+#define PTEW1_RPN              0xfffff000
+#define PTEW1_REF              0x00000100
+#define PTEW1_CHG              0x00000080
+#define PTEW1_WIMG             0x00000078
+#define PTEW1_PROTP            0x00000003
+
+#define SR_VSID                0x00ffffff
+#define SR_KS                  0x40000000
+#define SR_KP                  0x20000000
+
+#define RTEMS_MPE_PAGE_SIZE    0x1000
+
+/* Splitting the 64 bit PTE into two 32 bit words. As shown in the OEA
+ *    Manual of PowerPC */
+#define KEY_SUP      		        (1<<30) /* supervisor mode key */
+#define KEY_USR      		        (1<<29) /* user mode key */
+#define LD_PG_SIZE              12 /* In logarithm base */
+#define LD_PI_SIZE              16
+#define LD_VSID_SIZE            24
+#define LD_HASH_SIZE            19
+#define MMUS_DEBUG
+/* Primary and secondary PTE hash functions */
+
+/* Compute the primary hash from a VSID and a PI */
+#define PTE_HASH_FUNC1(vsid, pi) (((vsid)^(pi))&(0x0007FFFF))
+
+/* Compute the secondary hash from a primary hash */
+#define PTE_HASH_FUNC2(hash1) ((~(hash1))&(0x0007FFFF))
+
+typedef struct
+{
+  uint32_t ptew0; /* Word 0 */
+  uint32_t ptew1; /* Word 1 */
+} ppc_bsp_mm_mpe;
+
+extern char RamBase[];
+extern char RamSize[];
+
+/*
+ * @brief Function prototypes that can be shared with high
+ * level modules go in here
+ * */
+void mmu_irq_init(void);
+
+extern ppc_bsp_mm_mpe* BSP_ppc_add_pte(
+    ppc_bsp_mm_mpe *ppteg,
+    ppc_bsp_mm_mpe *spteg,
+    uint32_t vsid,
+    uint32_t pi,
+    uint32_t wimg,
+    uint32_t protp
+);
+
+void get_pteg_addr(ppc_bsp_mm_mpe** pteg, uint32_t hash);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pagetable_.c b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pagetable_.c
new file mode 100644
index 0000000..7df8f11
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/mmu/pagetable_.c
@@ -0,0 +1,189 @@
+/* COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <libcpu/spr.h>
+#include <rtems/rtems/status.h>
+#include <libcpu/mmu_support.h>
+#include <libcpu/memorymanagement.h>
+
+SPR_RW(SDR1);
+
+rtems_status_code _CPU_Memory_management_Initialize(void)
+{
+  uint32_t pt_base,pt_end,cache_line_size;
+  ppc_bsp_mm_mpe* pte;
+  unsigned long msr;
+  void *ea;
+
+  pt_base = _read_SDR1() & 0xffff0000;
+  pt_end = pt_base + (( ( _read_SDR1() & 0x000001ff)+1 )<<16);
+
+  /* Switch MMU and other Interrupts off */
+  msr = _read_MSR();
+  _write_MSR(msr & ~ (MSR_EE | MSR_DR | MSR_IR));
+
+  asm volatile ("sync":::"memory");
+   /*rtems_cache_flush_entire_data for mpc6XX is not actually implemented*/
+  /*rtems_cache_flush_entire_data();*/
+
+  /*I am not quite sure is it proper to flush each line of entire address*
+   * space for flushing cache.*/
+  rtems_cache_flush_multiple_data_lines((void*)RamBase, (size_t)RamSize);
+
+  for(pte = (ppc_bsp_mm_mpe*)pt_base; pte < (ppc_bsp_mm_mpe*)pt_end; pte+=1){
+    pte->ptew0 &= ~0x80000000;
+  }
+
+  asm volatile(  \
+    " sync ;  isync; \n"  \
+    " tlbia ;  eieio;  \n"  \
+    " tlbsync ;        \n"  \
+    " sync ; isync;  \n"  \
+    : : :"0");
+
+  /* restore, i.e., switch MMU and IRQs back on */
+  _write_MSR( msr );
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_status_code ppc_pte_change_attributes(
+  rtems_memory_management_entry *mpe,
+  uint32_t wimg,
+  uint32_t pp
+) {
+  ppc_bsp_mm_mpe* pt_entry;
+  uintptr_t ea, block_end;
+  unsigned long msr;
+
+  if(mpe->cpu_mpe == NULL) {
+    printf("PTE not installed !");
+    return RTEMS_UNSATISFIED;
+  }
+
+  if (wimg < 0 && pp < 0)
+    return RTEMS_UNSATISFIED;
+
+  ea = (uintptr_t) mpe->region.base;
+  block_end = (uintptr_t)(mpe->region.base + mpe->region.size);
+  rtems_cache_flush_multiple_data_lines(mpe->region.base, mpe->region.size);
+  pt_entry = (ppc_bsp_mm_mpe *) mpe->cpu_mpe;
+
+  /* Switch MMU and other Interrupts off */
+  msr = _read_MSR();
+  _write_MSR(msr & ~ (MSR_EE | MSR_DR | MSR_IR));
+
+  for( ; ea < block_end; ea += RTEMS_MPE_PAGE_SIZE ) {
+     pt_entry->ptew0 &= ~PTEW0_VALID;
+
+     asm volatile ("sync":::"memory");
+
+     pt_entry->ptew1 |= PTEW1_WIMG & wimg;
+
+     pt_entry->ptew1 &= ~PTEW1_PROTP;
+     pt_entry->ptew1 |= PTEW1_PROTP & pp;
+
+     asm volatile ("sync; tlbie %0; eieio"::"r" (ea):"memory");
+     pt_entry->ptew0 &= ~PTEW0_VALID;
+     asm volatile ("tlbsync; sync":::"memory");
+     pt_entry--;
+  }
+  /* restore, i.e., switch MMU and IRQs back on */
+  _write_MSR( msr );
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code _CPU_Memory_management_Install_MPE(
+    rtems_memory_management_entry *mpe
+) {
+  ppc_bsp_mm_mpe* pt_entry, * ppteg,*spteg;
+  int status;
+  unsigned long msr;
+  volatile uint32_t   sr_data, vsid, pi, hash1, hash2, api;
+  volatile int ppteg_search_status, spteg_search_status;
+  volatile int alut_access_attrb;
+  uintptr_t ea, block_end;
+  int wimg, pp;
+
+  rtems_status_code retval = RTEMS_SUCCESSFUL;
+
+  ea = (uintptr_t) mpe->region.base;
+  block_end = (uintptr_t)(mpe->region.base + mpe->region.size);
+  rtems_cache_flush_multiple_data_lines(mpe->region.base, mpe->region.size);
+
+  for( ; ea < block_end; ea += RTEMS_MPE_PAGE_SIZE ) {
+
+    /* Read corresponding SR Data */
+    sr_data = _read_SR((void *) ea);
+
+    /* Extract VSID */
+    vsid = sr_data & SR_VSID;
+
+    /* get page index (PI) from EA */
+    pi = (ea >> 12) & 0x0000ffff;
+    api = pi >> 10;
+
+    /* Compute HASH 1 */
+    hash1 = PTE_HASH_FUNC1(vsid, pi);
+
+    /* Compute PTEG Address from the hash 1 value */
+    get_pteg_addr(&ppteg, hash1);
+
+    /* setting default permissions to no protection*/
+    pp = _PPC_MMU_ACCESS_NO_PROT;
+    mpe->cpu_mpe = BSP_ppc_add_pte(ppteg, spteg, vsid, pi, wimg, pp);
+
+    if ( mpe->cpu_mpe == NULL ){
+      retval = RTEMS_UNSATISFIED;
+      break;
+    }
+  }
+  return retval;
+}
+
+rtems_status_code _CPU_Memory_management_Verify_size(
+    size_t size
+) {
+   /* Check for invalid block size */
+  if(((size % RTEMS_MPE_PAGE_SIZE) != 0) ||  (size == 0))
+    return RTEMS_INVALID_SIZE;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code _CPU_Memory_management_Set_read_only(
+   rtems_memory_management_entry  *mpe
+){
+  uint32_t pp;
+  rtems_status_code status;
+
+  pp = _PPC_MMU_ACCESS_READ_ONLY;
+
+  status = ppc_pte_change_attributes(mpe,0x0,pp);
+  if(status != RTEMS_SUCCESSFUL)
+    return RTEMS_UNSATISFIED;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code _CPU_Memory_management_Set_write(
+   rtems_memory_management_entry  *mpe
+){
+  uint32_t pp;
+  rtems_status_code status;
+
+  pp = _PPC_MMU_ACCESS_NO_PROT;
+
+  status = ppc_pte_change_attributes(mpe,0x0,pp);
+  if(status != RTEMS_SUCCESSFUL)
+    return RTEMS_UNSATISFIED;
+
+  return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libcpu/powerpc/preinstall.am b/c/src/lib/libcpu/powerpc/preinstall.am
index 79b7d88..2394554 100644
--- a/c/src/lib/libcpu/powerpc/preinstall.am
+++ b/c/src/lib/libcpu/powerpc/preinstall.am
@@ -157,6 +157,14 @@ $(PROJECT_INCLUDE)/libcpu/pte121.h: mpc6xx/mmu/pte121.h $(PROJECT_INCLUDE)/libcp
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/pte121.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/pte121.h
 
+$(PROJECT_INCLUDE)/libcpu/mmu_support.h: mpc6xx/mmu/mmu_support.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu_support.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu_support.h
+
+$(PROJECT_INCLUDE)/libcpu/memorymanagement.h: ../shared/include/memorymanagement.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/memorymanagement.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/memorymanagement.h
+
 $(PROJECT_INCLUDE)/libcpu/c_clock.h: mpc6xx/clock/c_clock.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/c_clock.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/c_clock.h
-- 
1.7.1




More information about the devel mailing list