Annotation of qemu/target-cris/mmu.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  CRIS mmu emulation.
        !             3:  *
        !             4:  *  Copyright (c) 2007 AXIS Communications AB
        !             5:  *  Written by Edgar E. Iglesias.
        !             6:  *
        !             7:  * This library is free software; you can redistribute it and/or
        !             8:  * modify it under the terms of the GNU Lesser General Public
        !             9:  * License as published by the Free Software Foundation; either
        !            10:  * version 2 of the License, or (at your option) any later version.
        !            11:  *
        !            12:  * This library is distributed in the hope that it will be useful,
        !            13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            15:  * Lesser General Public License for more details.
        !            16:  *
        !            17:  * You should have received a copy of the GNU Lesser General Public
        !            18:  * License along with this library; if not, write to the Free Software
        !            19:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            20:  */
        !            21: 
        !            22: #ifndef CONFIG_USER_ONLY
        !            23: 
        !            24: #include <stdio.h>
        !            25: #include <string.h>
        !            26: #include <stdlib.h>
        !            27: 
        !            28: #include "config.h"
        !            29: #include "cpu.h"
        !            30: #include "mmu.h"
        !            31: #include "exec-all.h"
        !            32: 
        !            33: 
        !            34: static int cris_mmu_enabled(uint32_t rw_gc_cfg)
        !            35: {
        !            36:        return (rw_gc_cfg & 12) != 0;
        !            37: }
        !            38: 
        !            39: static int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg)
        !            40: {
        !            41:        return (1 << seg) & rw_mm_cfg;
        !            42: }
        !            43: 
        !            44: static uint32_t cris_mmu_translate_seg(CPUState *env, int seg)
        !            45: {
        !            46:        uint32_t base;
        !            47:        int i;
        !            48: 
        !            49:        if (seg < 8)
        !            50:                base = env->sregs[SFR_RW_MM_KBASE_LO];
        !            51:        else
        !            52:                base = env->sregs[SFR_RW_MM_KBASE_HI];
        !            53: 
        !            54:        i = seg & 7;
        !            55:        base >>= i * 4;
        !            56:        base &= 15;
        !            57: 
        !            58:        base <<= 28;
        !            59:        return base;
        !            60: }
        !            61: /* Used by the tlb decoder.  */
        !            62: #define EXTRACT_FIELD(src, start, end) \
        !            63:             (((src) >> start) & ((1 << (end - start + 1)) - 1))
        !            64: 
        !            65: static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
        !            66:                                   CPUState *env, uint32_t vaddr,
        !            67:                                   int rw, int usermode)
        !            68: {
        !            69:        unsigned int vpage;
        !            70:        unsigned int idx;
        !            71:        uint32_t lo, hi;
        !            72:        uint32_t vpn, pfn = 0, pid, fg, fv, fk, fw, fx;
        !            73:        int i, match = 0;
        !            74: 
        !            75:        vpage = vaddr >> 13;
        !            76:        idx = vpage & 31;
        !            77:        vpage >>= 4;
        !            78: 
        !            79:        /* We know the index which to check on each set.
        !            80:           Scan both I and D.  */
        !            81:        for (i = 0; i < 4; i++)
        !            82:        {
        !            83:                lo = env->tlbsets[0][i][idx].lo;
        !            84:                hi = env->tlbsets[0][i][idx].hi;
        !            85: 
        !            86:                vpn = EXTRACT_FIELD(hi, 13, 31);
        !            87:                pid = EXTRACT_FIELD(hi, 0, 7);
        !            88: 
        !            89:                if (vpn == vpage
        !            90:                    && pid == env->pregs[SR_PID]) {
        !            91:                        match = 1;
        !            92:                        break;
        !            93:                }
        !            94:        }
        !            95: 
        !            96:        if (match) {
        !            97:                pfn = EXTRACT_FIELD(lo, 13, 31);
        !            98:                fg = EXTRACT_FIELD(lo, 4, 4);
        !            99:                fv = EXTRACT_FIELD(lo, 3, 3);
        !           100:                fk = EXTRACT_FIELD(lo, 2, 2);
        !           101:                fw = EXTRACT_FIELD(lo, 1, 1);
        !           102:                fx = EXTRACT_FIELD(lo, 0, 0);
        !           103:        }
        !           104:        printf ("%s match=%d vaddr=%x vpage=%x vpn=%x pfn=%x pid=%x %x\n",
        !           105:                __func__, match,
        !           106:                vaddr, vpage,
        !           107:                vpn, pfn, pid, env->pregs[SR_PID]);
        !           108:        res->pfn = pfn;
        !           109:        return !match;
        !           110: }
        !           111: 
        !           112: int cris_mmu_translate(struct cris_mmu_result_t *res,
        !           113:                       CPUState *env, uint32_t vaddr,
        !           114:                       int rw, int mmu_idx)
        !           115: {
        !           116:        uint32_t phy = vaddr;
        !           117:        int seg;
        !           118:        int miss = 0;
        !           119:         int is_user = mmu_idx == MMU_USER_IDX;
        !           120: 
        !           121:        if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
        !           122:                res->phy = vaddr;
        !           123:                return 0;
        !           124:        }
        !           125: 
        !           126:        seg = vaddr >> 28;
        !           127:        if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
        !           128:        {
        !           129:                uint32_t base;
        !           130: 
        !           131:                miss = 0;
        !           132:                base = cris_mmu_translate_seg(env, seg);
        !           133:                phy = base | (0x0fffffff & vaddr);
        !           134:                res->phy = phy;
        !           135:        }
        !           136:        else
        !           137:        {
        !           138:                miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user);
        !           139:                if (!miss) {
        !           140:                        phy &= 8191;
        !           141:                        phy |= (res->pfn << 13);
        !           142:                        res->phy = phy;
        !           143:                }
        !           144:        }
        !           145: //     printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy);
        !           146:        return miss;
        !           147: }
        !           148: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.