Changeset 9ec5ff4e in rtems


Ignore:
Timestamp:
Jan 9, 2018, 9:09:57 AM (19 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
81eced53
Parents:
5ce2dfa
git-author:
Sebastian Huber <sebastian.huber@…> (01/09/18 09:09:57)
git-committer:
Sebastian Huber <sebastian.huber@…> (01/22/18 06:21:19)
Message:

bsp/qoriq: Fix hypervisor guest MMU config

Account for DPAA resources defined in the device tree.

Prevent merging of areas with incompatible MAS2.

Update #3085.

Location:
c/src/lib/libbsp/powerpc/qoriq/startup
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/qoriq/startup/mmu-config.c

    r5ce2dfa r9ec5ff4e  
    88
    99/*
    10  * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2011, 2018 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    151151static DATA char memory_path[] = "/memory";
    152152
    153 static void TEXT config_fdt_adjust(void)
    154 {
    155         const void *fdt = bsp_fdt_get();
     153#ifdef QORIQ_IS_HYPERVISOR_GUEST
     154static void TEXT add_dpaa_bqman_portals(
     155        qoriq_mmu_context *context,
     156        const void *fdt,
     157        const char *compatible
     158)
     159{
     160        int node;
     161
     162        node = -1;
     163
     164        while (true) {
     165                const void *val;
     166                int len;
     167                uintptr_t paddr;
     168                uintptr_t size;
     169
     170                node = fdt_node_offset_by_compatible(fdt, node, compatible);
     171                if (node < 0) {
     172                        break;
     173                }
     174
     175                val = fdt_getprop(fdt, node, "reg", &len);
     176                if (len != 32) {
     177                        continue;
     178                }
     179
     180                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
     181                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
     182
     183                qoriq_mmu_add(
     184                        context,
     185                        paddr,
     186                        paddr + size - 1,
     187                        0,
     188                        FSL_EIS_MAS2_M | FSL_EIS_MAS2_G,
     189                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
     190                        QORIQ_MMU_DEVICE_MAS7
     191                );
     192
     193                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
     194                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[3]);
     195
     196                qoriq_mmu_add(
     197                        context,
     198                        paddr,
     199                        paddr + size - 1,
     200                        0,
     201                        FSL_EIS_MAS2_I | FSL_EIS_MAS2_G,
     202                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
     203                        QORIQ_MMU_DEVICE_MAS7
     204                );
     205        }
     206}
     207
     208static void TEXT add_dpaa_bpool(qoriq_mmu_context *context, const void *fdt)
     209{
     210        int node;
     211
     212        node = -1;
     213
     214        while (true) {
     215                const void *val;
     216                int len;
     217                uintptr_t config_count;
     218                uintptr_t size;
     219                uintptr_t paddr;
     220
     221                node = fdt_node_offset_by_compatible(fdt, node, "fsl,bpool");
     222                if (node < 0) {
     223                        break;
     224                }
     225
     226                val = fdt_getprop(fdt, node, "fsl,bpool-ethernet-cfg", &len);
     227                if (len != 24) {
     228                        continue;
     229                }
     230
     231                config_count = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[0]);
     232                size = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[1]);
     233                paddr = (uintptr_t) fdt64_to_cpu(((fdt64_t *) val)[2]);
     234
     235                qoriq_mmu_add(
     236                        context,
     237                        paddr,
     238                        paddr + config_count * size - 1,
     239                        0,
     240                        FSL_EIS_MAS2_M,
     241                        FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW,
     242                        0
     243                );
     244        }
     245}
     246#endif
     247
     248static void TEXT config_fdt_adjust(const void *fdt)
     249{
    156250        int node;
    157251
     
    199293{
    200294        qoriq_mmu_context context;
    201         int i = 0;
    202 
    203         if (boot_processor) {
    204                 config_fdt_adjust();
    205         }
    206 
    207         qoriq_mmu_context_init(&context);
     295        const void *fdt;
     296        int max_count;
     297        int i;
    208298
    209299        for (i = 0; i < QORIQ_TLB1_ENTRY_COUNT; ++i) {
     
    211301                        qoriq_tlb1_invalidate(i);
    212302                }
     303        }
     304
     305        fdt = bsp_fdt_get();
     306        qoriq_mmu_context_init(&context);
     307
     308#ifdef QORIQ_IS_HYPERVISOR_GUEST
     309        add_dpaa_bqman_portals(&context, fdt, "fsl,bman-portal");
     310        add_dpaa_bqman_portals(&context, fdt, "fsl,qman-portal");
     311        add_dpaa_bpool(&context, fdt);
     312        max_count = QORIQ_TLB1_ENTRY_COUNT - 1;
     313#else
     314        max_count = (3 * QORIQ_TLB1_ENTRY_COUNT) / 4;
     315#endif
     316
     317        if (boot_processor) {
     318                config_fdt_adjust(fdt);
    213319        }
    214320
     
    228334        }
    229335
    230         qoriq_mmu_partition(&context, (3 * QORIQ_TLB1_ENTRY_COUNT) / 4);
     336        qoriq_mmu_partition(&context, max_count);
    231337        qoriq_mmu_write_to_tlb1(&context, first_tlb);
    232338}
  • c/src/lib/libbsp/powerpc/qoriq/startup/mmu.c

    r5ce2dfa r9ec5ff4e  
    88
    99/*
    10  * Copyright (c) 2011-2015 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2011, 2018 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    8585}
    8686
    87 static bool TEXT mas_equal(const qoriq_mmu_entry *a, const qoriq_mmu_entry *b)
    88 {
    89         return a->mas1 == b->mas1 && a->mas2 == b->mas2 && a->mas3 == b->mas3;
     87static bool TEXT mas_compatible(const qoriq_mmu_entry *a, const qoriq_mmu_entry *b)
     88{
     89        uint32_t m = FSL_EIS_MAS2_M;
     90
     91        return (a->mas2 & ~m) == (b->mas2 & ~m);
    9092}
    9193
    9294static bool TEXT can_merge(const qoriq_mmu_entry *prev, const qoriq_mmu_entry *cur)
    9395{
    94         bool can = false;
    95 
    96         if (prev->begin == cur->begin || prev->last >= cur->begin - 1) {
    97                 /*
    98                  * Here we can technically merge.  We need a heuristic to
    99                  * prevent merges in case the MAS values differ and the boarder
    100                  * is reasonably well aligned.
    101                  */
    102                 if (
    103                         mas_equal(prev, cur)
    104                                 || prev->last != cur->begin - 1
    105                                 || power_of_two(cur->begin) < 24
    106                 ) {
    107                         can = true;
    108                 }
    109         }
    110 
    111         return can;
     96        return mas_compatible(prev, cur)
     97                && (prev->begin == cur->begin || prev->last >= cur->begin - 1);
    11298}
    11399
     
    131117                        if (cur->last > prev->last) {
    132118                                prev->last = cur->last;
    133                         }       
     119                        }
    134120
    135121                        for (j = i + 1; j < n; ++j) {
     
    151137}
    152138
     139static bool TEXT can_expand_down(
     140        const qoriq_mmu_context *self,
     141        const qoriq_mmu_entry *cur,
     142        int i,
     143        uintptr_t new_begin
     144)
     145{
     146        int j;
     147
     148        for (j = 0; j < i; ++j) {
     149                const qoriq_mmu_entry *before = &self->entries[j];
     150
     151                if (
     152                        before->begin <= new_begin
     153                                && new_begin <= before->last
     154                                && !mas_compatible(before, cur)
     155                ) {
     156                        return false;
     157                }
     158        }
     159
     160        return true;
     161}
     162
     163static bool TEXT can_expand_up(
     164        const qoriq_mmu_context *self,
     165        const qoriq_mmu_entry *cur,
     166        int i,
     167        int n,
     168        uintptr_t new_last
     169)
     170{
     171        int j;
     172
     173        for (j = i + 1; j < n; ++j) {
     174                const qoriq_mmu_entry *after = &self->entries[j];
     175
     176                if (
     177                        after->begin <= new_last
     178                                && new_last <= after->last
     179                                && !mas_compatible(after, cur)
     180                ) {
     181                        return false;
     182                }
     183        }
     184
     185        return true;
     186}
     187
    153188static void TEXT align(qoriq_mmu_context *self, uintptr_t alignment)
    154189{
    155         qoriq_mmu_entry *entries = self->entries;
    156         int n = self->count;
    157         int i = 0;
     190        int n = self->count;
     191        int i;
    158192
    159193        for (i = 0; i < n; ++i) {
    160                 qoriq_mmu_entry *cur = &entries [i];
    161                 cur->begin &= ~(alignment - 1);
    162                 cur->last = alignment + (cur->last & ~(alignment - 1)) - 1;
     194                qoriq_mmu_entry *cur = &self->entries[i];
     195                uintptr_t new_begin = cur->begin & ~(alignment - 1);
     196                uintptr_t new_last = alignment + (cur->last & ~(alignment - 1)) - 1;
     197
     198                if (
     199                        can_expand_down(self, cur, i, new_begin)
     200                                && can_expand_up(self, cur, i, n, new_last)
     201                ) {
     202                        cur->begin = new_begin;
     203                        cur->last = new_last;
     204                }
    163205        }
    164206}
     
    266308        uintptr_t alignment = 4096;
    267309
     310        sort(self);
     311
    268312        do {
    269313                align(self, alignment);
Note: See TracChangeset for help on using the changeset viewer.