Revision 496272a7 target-ppc/mmu-hash32.c

b/target-ppc/mmu-hash32.c
37 37
#define PTE_PTEM_MASK 0x7FFFFFBF
38 38
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
39 39

  
40
static int ppc_hash32_pp_check(int key, int pp, int nx)
41
{
42
    int access;
43

  
44
    /* Compute access rights */
45
    access = 0;
46
    if (key == 0) {
47
        switch (pp) {
48
        case 0x0:
49
        case 0x1:
50
        case 0x2:
51
            access |= PAGE_WRITE;
52
            /* No break here */
53
        case 0x3:
54
            access |= PAGE_READ;
55
            break;
56
        }
57
    } else {
58
        switch (pp) {
59
        case 0x0:
60
            access = 0;
61
            break;
62
        case 0x1:
63
        case 0x3:
64
            access = PAGE_READ;
65
            break;
66
        case 0x2:
67
            access = PAGE_READ | PAGE_WRITE;
68
            break;
69
        }
70
    }
71
    if (nx == 0) {
72
        access |= PAGE_EXEC;
73
    }
74

  
75
    return access;
76
}
77

  
78
static int ppc_hash32_check_prot(int prot, int rw, int access_type)
79
{
80
    int ret;
81

  
82
    if (access_type == ACCESS_CODE) {
83
        if (prot & PAGE_EXEC) {
84
            ret = 0;
85
        } else {
86
            ret = -2;
87
        }
88
    } else if (rw) {
89
        if (prot & PAGE_WRITE) {
90
            ret = 0;
91
        } else {
92
            ret = -2;
93
        }
94
    } else {
95
        if (prot & PAGE_READ) {
96
            ret = 0;
97
        } else {
98
            ret = -2;
99
        }
100
    }
101

  
102
    return ret;
103
}
104

  
40 105
static inline int pte_is_valid_hash32(target_ulong pte0)
41 106
{
42 107
    return pte0 & 0x80000000 ? 1 : 0;
......
66 131
                }
67 132
            }
68 133
            /* Compute access rights */
69
            access = pp_check(ctx->key, pp, ctx->nx);
134
            access = ppc_hash32_pp_check(ctx->key, pp, ctx->nx);
70 135
            /* Keep the matching PTE informations */
71 136
            ctx->raddr = pte1;
72 137
            ctx->prot = access;
73
            ret = check_prot(ctx->prot, rw, type);
138
            ret = ppc_hash32_check_prot(ctx->prot, rw, type);
74 139
            if (ret == 0) {
75 140
                /* Access granted */
76 141
                LOG_MMU("PTE access granted !\n");
......
84 149
    return ret;
85 150
}
86 151

  
152
static int ppc_hash32_pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
153
                                       int ret, int rw)
154
{
155
    int store = 0;
156

  
157
    /* Update page flags */
158
    if (!(*pte1p & 0x00000100)) {
159
        /* Update accessed flag */
160
        *pte1p |= 0x00000100;
161
        store = 1;
162
    }
163
    if (!(*pte1p & 0x00000080)) {
164
        if (rw == 1 && ret == 0) {
165
            /* Update changed flag */
166
            *pte1p |= 0x00000080;
167
            store = 1;
168
        } else {
169
            /* Force page fault for first write access */
170
            ctx->prot &= ~PAGE_WRITE;
171
        }
172
    }
173

  
174
    return store;
175
}
176

  
87 177
/* PTE table lookup */
88 178
static int find_pte32(CPUPPCState *env, mmu_ctx_t *ctx, int h,
89 179
                      int rw, int type, int target_page_bits)
......
138 228
                ctx->raddr, ctx->prot, ret);
139 229
        /* Update page flags */
140 230
        pte1 = ctx->raddr;
141
        if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
231
        if (ppc_hash32_pte_update_flags(ctx, &pte1, ret, rw) == 1) {
142 232
            if (env->external_htab) {
143 233
                stl_p(env->external_htab + pteg_off + (good * 8) + 4,
144 234
                      pte1);

Also available in: Unified diff