bsp/qoriq: 64-bit MMU support

Update #3082.
This commit is contained in:
Sebastian Huber
2017-08-02 14:36:32 +02:00
parent 77c8101686
commit c8aeb76c44
4 changed files with 56 additions and 47 deletions

View File

@@ -47,8 +47,8 @@ extern "C" {
#define QORIQ_MMU_POWER_STEP 2 #define QORIQ_MMU_POWER_STEP 2
typedef struct { typedef struct {
uint32_t begin; uintptr_t begin;
uint32_t last; uintptr_t last;
uint32_t mas1; uint32_t mas1;
uint32_t mas2; uint32_t mas2;
uint32_t mas3; uint32_t mas3;
@@ -64,8 +64,8 @@ void qoriq_mmu_context_init(qoriq_mmu_context *self);
bool qoriq_mmu_add( bool qoriq_mmu_add(
qoriq_mmu_context *self, qoriq_mmu_context *self,
uint32_t begin, uintptr_t begin,
uint32_t last, uintptr_t last,
uint32_t mas1, uint32_t mas1,
uint32_t mas2, uint32_t mas2,
uint32_t mas3, uint32_t mas3,
@@ -86,8 +86,8 @@ void qoriq_tlb1_write(
uint32_t mas2, uint32_t mas2,
uint32_t mas3, uint32_t mas3,
uint32_t mas7, uint32_t mas7,
uint32_t ea, uintptr_t ea,
uint32_t tsize int tsize
); );
void qoriq_tlb1_invalidate(int esel); void qoriq_tlb1_invalidate(int esel);

View File

@@ -37,23 +37,23 @@
#define DATA __attribute__((section(".bsp_start_data"))) #define DATA __attribute__((section(".bsp_start_data")))
typedef struct { typedef struct {
uint32_t begin; uintptr_t begin;
uint32_t size; uintptr_t size;
uint32_t mas2; uint32_t mas2;
uint32_t mas3; uint32_t mas3;
uint32_t mas7; uint32_t mas7;
} entry; } entry;
#define ENTRY_X(b, s) { \ #define ENTRY_X(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = 0, \ .mas2 = 0, \
.mas3 = FSL_EIS_MAS3_SX \ .mas3 = FSL_EIS_MAS3_SX \
} }
#define ENTRY_R(b, s) { \ #define ENTRY_R(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = 0, \ .mas2 = 0, \
.mas3 = FSL_EIS_MAS3_SR \ .mas3 = FSL_EIS_MAS3_SR \
} }
@@ -65,22 +65,22 @@ typedef struct {
#endif #endif
#define ENTRY_RW(b, s) { \ #define ENTRY_RW(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = ENTRY_RW_MAS2, \ .mas2 = ENTRY_RW_MAS2, \
.mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
} }
#define ENTRY_IO(b, s) { \ #define ENTRY_IO(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \ .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
.mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW \
} }
#define ENTRY_DEV(b, s) { \ #define ENTRY_DEV(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \ .mas2 = FSL_EIS_MAS2_I | FSL_EIS_MAS2_G, \
.mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
.mas7 = QORIQ_MMU_DEVICE_MAS7 \ .mas7 = QORIQ_MMU_DEVICE_MAS7 \
@@ -96,8 +96,8 @@ typedef struct {
* will occur. No documentation reference for this is available. * will occur. No documentation reference for this is available.
*/ */
#define ENTRY_DEV_CACHED(b, s) { \ #define ENTRY_DEV_CACHED(b, s) { \
.begin = (uint32_t) b, \ .begin = (uintptr_t) b, \
.size = (uint32_t) s, \ .size = (uintptr_t) s, \
.mas2 = FSL_EIS_MAS2_M | FSL_EIS_MAS2_G, \ .mas2 = FSL_EIS_MAS2_M | FSL_EIS_MAS2_G, \
.mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \ .mas3 = FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW, \
.mas7 = QORIQ_MMU_DEVICE_MAS7 \ .mas7 = QORIQ_MMU_DEVICE_MAS7 \

View File

@@ -32,7 +32,11 @@
qoriq_tlb1_write: qoriq_tlb1_write:
rlwinm r3, r3, 16, 10, 15 rlwinm r3, r3, 16, 10, 15
#ifdef __powerpc64__
rldicr r8, r8, 0, 51
#else
rlwinm r8, r8, 0, 0, 19 rlwinm r8, r8, 0, 0, 19
#endif
oris r3, r3, 0x1000 oris r3, r3, 0x1000
mtspr FSL_EIS_MAS0, r3 mtspr FSL_EIS_MAS0, r3
oris r4, r4, 0xc000 oris r4, r4, 0xc000
@@ -43,6 +47,11 @@ qoriq_tlb1_write:
mtspr FSL_EIS_MAS2, r5 mtspr FSL_EIS_MAS2, r5
or r6, r8, r6 or r6, r8, r6
mtspr FSL_EIS_MAS3, r6 mtspr FSL_EIS_MAS3, r6
#ifdef __powerpc64__
srdi r8, r8, 32
or r7, r7, r8
mtspr FSL_EIS_MAS7, r7
#endif
mtspr FSL_EIS_MAS7, r7 mtspr FSL_EIS_MAS7, r7
#ifdef QORIQ_HAS_HYPERVISOR_MODE #ifdef QORIQ_HAS_HYPERVISOR_MODE
li r0, 0 li r0, 0

View File

@@ -25,11 +25,11 @@
#define TEXT __attribute__((section(".bsp_start_text"))) #define TEXT __attribute__((section(".bsp_start_text")))
static uint32_t TEXT power_of_two(uint32_t val) static uintptr_t TEXT power_of_two(uintptr_t val)
{ {
uint32_t test_power = QORIQ_MMU_MIN_POWER; uintptr_t test_power = QORIQ_MMU_MIN_POWER;
uint32_t power = test_power; uintptr_t power = test_power;
uint32_t alignment = 1U << test_power; uintptr_t alignment = 1U << test_power;
while (test_power <= QORIQ_MMU_MAX_POWER && (val & (alignment - 1)) == 0) { while (test_power <= QORIQ_MMU_MAX_POWER && (val & (alignment - 1)) == 0) {
power = test_power; power = test_power;
@@ -40,11 +40,11 @@ static uint32_t TEXT power_of_two(uint32_t val)
return power; return power;
} }
static uint32_t TEXT max_power_of_two(uint32_t val) static uintptr_t TEXT max_power_of_two(uintptr_t val)
{ {
uint32_t test_power = QORIQ_MMU_MIN_POWER; uintptr_t test_power = QORIQ_MMU_MIN_POWER;
uint32_t power = test_power; uintptr_t power = test_power;
uint32_t max = 1U << test_power; uintptr_t max = 1U << test_power;
do { do {
power = test_power; power = test_power;
@@ -150,7 +150,7 @@ static void TEXT compact(qoriq_mmu_context *self)
merge(self); merge(self);
} }
static void TEXT align(qoriq_mmu_context *self, uint32_t alignment) static void TEXT align(qoriq_mmu_context *self, uintptr_t alignment)
{ {
qoriq_mmu_entry *entries = self->entries; qoriq_mmu_entry *entries = self->entries;
int n = self->count; int n = self->count;
@@ -176,8 +176,8 @@ static void TEXT append(qoriq_mmu_context *self, const qoriq_mmu_entry *new_entr
bool TEXT qoriq_mmu_add( bool TEXT qoriq_mmu_add(
qoriq_mmu_context *self, qoriq_mmu_context *self,
uint32_t begin, uintptr_t begin,
uint32_t last, uintptr_t last,
uint32_t mas1, uint32_t mas1,
uint32_t mas2, uint32_t mas2,
uint32_t mas3, uint32_t mas3,
@@ -211,7 +211,7 @@ bool TEXT qoriq_mmu_add(
return ok; return ok;
} }
static uint32_t TEXT min(uint32_t a, uint32_t b) static uintptr_t TEXT min(uintptr_t a, uintptr_t b)
{ {
return a < b ? a : b; return a < b ? a : b;
} }
@@ -219,14 +219,14 @@ static uint32_t TEXT min(uint32_t a, uint32_t b)
static bool TEXT split(qoriq_mmu_context *self, qoriq_mmu_entry *cur) static bool TEXT split(qoriq_mmu_context *self, qoriq_mmu_entry *cur)
{ {
bool again = false; bool again = false;
uint32_t begin = cur->begin; uintptr_t begin = cur->begin;
uint32_t end = cur->last + 1; uintptr_t end = cur->last + 1;
uint32_t size = end - begin; uintptr_t size = end - begin;
uint32_t begin_power = power_of_two(begin); uintptr_t begin_power = power_of_two(begin);
uint32_t size_power = max_power_of_two(size); uintptr_t size_power = max_power_of_two(size);
uint32_t power = min(begin_power, size_power); uintptr_t power = min(begin_power, size_power);
uint32_t split_size = power < 32 ? (1U << power) : 0; uintptr_t split_size = power < 32 ? (1U << power) : 0;
uint32_t split_pos = begin + split_size; uintptr_t split_pos = begin + split_size;
if (split_pos != end && !is_full(self)) { if (split_pos != end && !is_full(self)) {
qoriq_mmu_entry new_entry = *cur; qoriq_mmu_entry new_entry = *cur;
@@ -263,7 +263,7 @@ static TEXT void partition(qoriq_mmu_context *self)
void TEXT qoriq_mmu_partition(qoriq_mmu_context *self, int max_count) void TEXT qoriq_mmu_partition(qoriq_mmu_context *self, int max_count)
{ {
uint32_t alignment = 4096; uintptr_t alignment = 4096;
do { do {
align(self, alignment); align(self, alignment);
@@ -280,9 +280,9 @@ void TEXT qoriq_mmu_write_to_tlb1(qoriq_mmu_context *self, int first_tlb)
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
qoriq_mmu_entry *cur = &entries [i]; qoriq_mmu_entry *cur = &entries [i];
uint32_t ea = cur->begin; uintptr_t ea = cur->begin;
uint32_t size = cur->last - ea + 1; uintptr_t size = cur->last - ea + 1;
uint32_t tsize = (power_of_two(size) - 10) / 2; uintptr_t tsize = (power_of_two(size) - 10) / 2;
int tlb = first_tlb + i; int tlb = first_tlb + i;
qoriq_tlb1_write( qoriq_tlb1_write(
@@ -292,7 +292,7 @@ void TEXT qoriq_mmu_write_to_tlb1(qoriq_mmu_context *self, int first_tlb)
cur->mas3, cur->mas3,
cur->mas7, cur->mas7,
ea, ea,
tsize (int) tsize
); );
} }
} }
@@ -302,8 +302,8 @@ void qoriq_mmu_change_perm(uint32_t test, uint32_t set, uint32_t clear)
int i = 0; int i = 0;
for (i = 0; i < 16; ++i) { for (i = 0; i < 16; ++i) {
int mas0 = FSL_EIS_MAS0_TLBSEL | FSL_EIS_MAS0_ESEL(i); uint32_t mas0 = FSL_EIS_MAS0_TLBSEL | FSL_EIS_MAS0_ESEL(i);
int mas1 = 0; uint32_t mas1 = 0;
PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0); PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0);
asm volatile ("tlbre"); asm volatile ("tlbre");