summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c')
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c368
1 files changed, 0 insertions, 368 deletions
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c b/c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c
deleted file mode 100644
index 2629c9f999..0000000000
--- a/c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/**
- * @file
- *
- * @ingroup QorIQMMU
- *
- * @brief MMU implementation.
- */
-
-/*
- * Copyright (c) 2011, 2018 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp/mmu.h>
-#include <libcpu/powerpc-utility.h>
-
-#define TEXT __attribute__((section(".bsp_start_text")))
-
-static uintptr_t TEXT power_of_two(uintptr_t val)
-{
- uintptr_t test_power = QORIQ_MMU_MIN_POWER;
- uintptr_t power = test_power;
- uintptr_t alignment = 1U << test_power;
-
- while (test_power <= QORIQ_MMU_MAX_POWER && (val & (alignment - 1)) == 0) {
- power = test_power;
- alignment <<= QORIQ_MMU_POWER_STEP;
- test_power += QORIQ_MMU_POWER_STEP;
- }
-
- return power;
-}
-
-static uintptr_t TEXT max_power_of_two(uintptr_t val)
-{
- uintptr_t test_power = QORIQ_MMU_MIN_POWER;
- uintptr_t power = test_power;
- uintptr_t max = 1U << test_power;
-
- do {
- power = test_power;
- max <<= QORIQ_MMU_POWER_STEP;
- test_power += QORIQ_MMU_POWER_STEP;
- } while (test_power <= QORIQ_MMU_MAX_POWER && max <= val);
-
- return power;
-}
-
-void TEXT qoriq_mmu_context_init(qoriq_mmu_context *self)
-{
- int *cur = (int *) self;
- const int *end = cur + sizeof(*self) / sizeof(*cur);
-
- while (cur != end) {
- *cur = 0;
- ++cur;
- }
-}
-
-static void TEXT sort(qoriq_mmu_context *self)
-{
- qoriq_mmu_entry *entries = self->entries;
- int n = self->count;
- int i = 0;
-
- for (i = 1; i < n; ++i) {
- qoriq_mmu_entry key = entries [i];
- int j = 0;
-
- for (j = i - 1; j >= 0 && entries [j].begin > key.begin; --j) {
- entries [j + 1] = entries [j];
- }
-
- entries [j + 1] = key;
- }
-}
-
-static bool TEXT mas_compatible(const qoriq_mmu_entry *a, const qoriq_mmu_entry *b)
-{
- uint32_t m = FSL_EIS_MAS2_M;
-
- return (a->mas2 & ~m) == (b->mas2 & ~m);
-}
-
-static bool TEXT can_merge(const qoriq_mmu_entry *prev, const qoriq_mmu_entry *cur)
-{
- return mas_compatible(prev, cur)
- && (prev->begin == cur->begin || prev->last >= cur->begin - 1);
-}
-
-static void TEXT merge(qoriq_mmu_context *self)
-{
- qoriq_mmu_entry *entries = self->entries;
- int n = self->count;
- int i = 0;
-
- for (i = 1; i < n; ++i) {
- qoriq_mmu_entry *prev = &entries [i - 1];
- qoriq_mmu_entry *cur = &entries [i];
-
- if (can_merge(prev, cur)) {
- int j = 0;
-
- prev->mas1 |= cur->mas1;
- prev->mas2 |= cur->mas2;
- prev->mas3 |= cur->mas3;
-
- if (cur->last > prev->last) {
- prev->last = cur->last;
- }
-
- for (j = i + 1; j < n; ++j) {
- entries [j - 1] = entries [j];
- }
-
- --i;
- --n;
- }
- }
-
- self->count = n;
-}
-
-static void TEXT compact(qoriq_mmu_context *self)
-{
- sort(self);
- merge(self);
-}
-
-static bool TEXT can_expand_down(
- const qoriq_mmu_context *self,
- const qoriq_mmu_entry *cur,
- int i,
- uintptr_t new_begin
-)
-{
- int j;
-
- for (j = 0; j < i; ++j) {
- const qoriq_mmu_entry *before = &self->entries[j];
-
- if (
- before->begin <= new_begin
- && new_begin <= before->last
- && !mas_compatible(before, cur)
- ) {
- return false;
- }
- }
-
- return true;
-}
-
-static bool TEXT can_expand_up(
- const qoriq_mmu_context *self,
- const qoriq_mmu_entry *cur,
- int i,
- int n,
- uintptr_t new_last
-)
-{
- int j;
-
- for (j = i + 1; j < n; ++j) {
- const qoriq_mmu_entry *after = &self->entries[j];
-
- if (
- after->begin <= new_last
- && new_last <= after->last
- && !mas_compatible(after, cur)
- ) {
- return false;
- }
- }
-
- return true;
-}
-
-static void TEXT align(qoriq_mmu_context *self, uintptr_t alignment)
-{
- int n = self->count;
- int i;
-
- for (i = 0; i < n; ++i) {
- qoriq_mmu_entry *cur = &self->entries[i];
- uintptr_t new_begin = cur->begin & ~(alignment - 1);
- uintptr_t new_last = alignment + (cur->last & ~(alignment - 1)) - 1;
-
- if (
- can_expand_down(self, cur, i, new_begin)
- && can_expand_up(self, cur, i, n, new_last)
- ) {
- cur->begin = new_begin;
- cur->last = new_last;
- }
- }
-}
-
-static bool TEXT is_full(qoriq_mmu_context *self)
-{
- return self->count >= QORIQ_TLB1_ENTRY_COUNT;
-}
-
-static void TEXT append(qoriq_mmu_context *self, const qoriq_mmu_entry *new_entry)
-{
- self->entries [self->count] = *new_entry;
- ++self->count;
-}
-
-bool TEXT qoriq_mmu_add(
- qoriq_mmu_context *self,
- uintptr_t begin,
- uintptr_t last,
- uint32_t mas1,
- uint32_t mas2,
- uint32_t mas3,
- uint32_t mas7
-)
-{
- bool ok = true;
-
- if (is_full(self)) {
- compact(self);
- }
-
- if (!is_full(self)) {
- if (begin < last) {
- qoriq_mmu_entry new_entry = {
- .begin = begin,
- .last = last,
- .mas1 = mas1,
- .mas2 = mas2,
- .mas3 = mas3,
- .mas7 = mas7
- };
- append(self, &new_entry);
- } else {
- ok = false;
- }
- } else {
- ok = false;
- }
-
- return ok;
-}
-
-static uintptr_t TEXT min(uintptr_t a, uintptr_t b)
-{
- return a < b ? a : b;
-}
-
-static bool TEXT split(qoriq_mmu_context *self, qoriq_mmu_entry *cur)
-{
- bool again = false;
- uintptr_t begin = cur->begin;
- uintptr_t end = cur->last + 1;
- uintptr_t size = end - begin;
- uintptr_t begin_power = power_of_two(begin);
- uintptr_t size_power = max_power_of_two(size);
- uintptr_t power = min(begin_power, size_power);
- uintptr_t split_size = power < 32 ? (1U << power) : 0;
- uintptr_t split_pos = begin + split_size;
-
- if (split_pos != end && !is_full(self)) {
- qoriq_mmu_entry new_entry = *cur;
- cur->begin = split_pos;
- new_entry.last = split_pos - 1;
- append(self, &new_entry);
- again = true;
- }
-
- return again;
-}
-
-static void TEXT split_all(qoriq_mmu_context *self)
-{
- qoriq_mmu_entry *entries = self->entries;
- int n = self->count;
- int i = 0;
-
- for (i = 0; i < n; ++i) {
- qoriq_mmu_entry *cur = &entries [i];
-
- while (split(self, cur)) {
- /* Repeat */
- }
- }
-}
-
-static TEXT void partition(qoriq_mmu_context *self)
-{
- compact(self);
- split_all(self);
- sort(self);
-}
-
-void TEXT qoriq_mmu_partition(qoriq_mmu_context *self, int max_count)
-{
- uintptr_t alignment = 4096;
-
- sort(self);
-
- do {
- align(self, alignment);
- partition(self);
- alignment *= 4;
- } while (self->count > max_count);
-}
-
-void TEXT qoriq_mmu_write_to_tlb1(qoriq_mmu_context *self, int first_tlb)
-{
- qoriq_mmu_entry *entries = self->entries;
- int n = self->count;
- int i = 0;
-
- for (i = 0; i < n; ++i) {
- qoriq_mmu_entry *cur = &entries [i];
- uintptr_t ea = cur->begin;
- uintptr_t size = cur->last - ea + 1;
- uintptr_t tsize = (power_of_two(size) - 10) / 2;
- int tlb = first_tlb + i;
-
- qoriq_tlb1_write(
- tlb,
- cur->mas1,
- cur->mas2,
- cur->mas3,
- cur->mas7,
- ea,
- (int) tsize
- );
- }
-}
-
-void qoriq_mmu_change_perm(uint32_t test, uint32_t set, uint32_t clear)
-{
- int i = 0;
-
- for (i = 0; i < 16; ++i) {
- uint32_t mas0 = FSL_EIS_MAS0_TLBSEL | FSL_EIS_MAS0_ESEL(i);
- uint32_t mas1 = 0;
-
- PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0);
- asm volatile ("tlbre");
-
- mas1 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1);
- if ((mas1 & FSL_EIS_MAS1_V) != 0) {
- uint32_t mask = 0x3ff;
- uint32_t mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3);
-
- if ((mas3 & mask) == test) {
- mas3 &= ~(clear & mask);
- mas3 |= set & mask;
- PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3, mas3);
- asm volatile ("isync; msync; tlbwe; isync" : : : "memory");
- }
- }
- }
-}