[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