Revision b769d8fe

b/exec-all.h
592 592
#endif
593 593
    if (__builtin_expect(env->tlb_read[is_user][index].address != 
594 594
                         (addr & TARGET_PAGE_MASK), 0)) {
595
#if defined (TARGET_PPC)
596
	env->access_type = ACCESS_CODE;
597
	ldub_code((void *)addr);
598
	env->access_type = ACCESS_INT;
599
#else
600 595
        ldub_code((void *)addr);
601
#endif
602 596
    }
603 597
    return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
604 598
}
b/exec.c
2115 2115
#define MMUSUFFIX _cmmu
2116 2116
#define GETPC() NULL
2117 2117
#define env cpu_single_env
2118
#define SOFTMMU_CODE_ACCESS
2118 2119

  
2119 2120
#define SHIFT 0
2120 2121
#include "softmmu_template.h"
b/softmmu_template.h
39 39
#error unsupported data size
40 40
#endif
41 41

  
42
#ifdef SOFTMMU_CODE_ACCESS
43
#define READ_ACCESS_TYPE 2
44
#else
45
#define READ_ACCESS_TYPE 0
46
#endif
47

  
42 48
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, 
43 49
                                                        int is_user,
44 50
                                                        void *retaddr);
45
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, 
46
                                                   DATA_TYPE val, 
47
                                                   int is_user,
48
                                                   void *retaddr);
49

  
50 51
static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, 
51 52
                                              unsigned long tlb_addr)
52 53
{
......
68 69
    return res;
69 70
}
70 71

  
71
static inline void glue(io_write, SUFFIX)(unsigned long physaddr, 
72
                                          DATA_TYPE val,
73
                                          unsigned long tlb_addr,
74
                                          void *retaddr)
75
{
76
    int index;
77

  
78
    index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
79
    env->mem_write_vaddr = tlb_addr;
80
    env->mem_write_pc = (unsigned long)retaddr;
81
#if SHIFT <= 2
82
    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
83
#else
84
#ifdef TARGET_WORDS_BIGENDIAN
85
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
86
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
87
#else
88
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
89
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
90
#endif
91
#endif /* SHIFT > 2 */
92
}
93

  
94 72
/* handle all cases except unaligned access which span two pages */
95 73
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
96 74
                                                         int is_user)
......
125 103
    } else {
126 104
        /* the page is not in the TLB : fill it */
127 105
        retaddr = GETPC();
128
        tlb_fill(addr, 0, is_user, retaddr);
106
        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
129 107
        goto redo;
130 108
    }
131 109
    return res;
......
172 150
        }
173 151
    } else {
174 152
        /* the page is not in the TLB : fill it */
175
        tlb_fill(addr, 0, is_user, retaddr);
153
        tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
176 154
        goto redo;
177 155
    }
178 156
    return res;
179 157
}
180 158

  
159
#ifndef SOFTMMU_CODE_ACCESS
160

  
161
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, 
162
                                                   DATA_TYPE val, 
163
                                                   int is_user,
164
                                                   void *retaddr);
165

  
166
static inline void glue(io_write, SUFFIX)(unsigned long physaddr, 
167
                                          DATA_TYPE val,
168
                                          unsigned long tlb_addr,
169
                                          void *retaddr)
170
{
171
    int index;
172

  
173
    index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
174
    env->mem_write_vaddr = tlb_addr;
175
    env->mem_write_pc = (unsigned long)retaddr;
176
#if SHIFT <= 2
177
    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
178
#else
179
#ifdef TARGET_WORDS_BIGENDIAN
180
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
181
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
182
#else
183
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
184
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
185
#endif
186
#endif /* SHIFT > 2 */
187
}
181 188

  
182 189
void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, 
183 190
                                                    DATA_TYPE val,
......
257 264
    }
258 265
}
259 266

  
267
#endif /* !defined(SOFTMMU_CODE_ACCESS) */
268

  
269
#undef READ_ACCESS_TYPE
260 270
#undef SHIFT
261 271
#undef DATA_TYPE
262 272
#undef SUFFIX
b/target-i386/helper2.c
331 331
    printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", 
332 332
           addr, is_write, is_user, env->eip);
333 333
#endif
334

  
334
    is_write &= 1;
335
    
335 336
    if (env->user_mode_only) {
336 337
        /* user mode only emulation */
337 338
        error_code = 0;
b/target-ppc/helper.c
432 432
       generated code */
433 433
    saved_env = env;
434 434
    env = cpu_single_env;
435
#if 0
435 436
    {
436 437
        unsigned long tlb_addrr, tlb_addrw;
437 438
        int index;
438 439
        index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
439 440
        tlb_addrr = env->tlb_read[is_user][index].address;
440 441
        tlb_addrw = env->tlb_write[is_user][index].address;
441
#if 0
442 442
        if (loglevel) {
443 443
            fprintf(logfile,
444 444
                    "%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx "
......
447 447
               tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK,
448 448
               tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
449 449
        }
450
#endif
451 450
    }
451
#endif
452 452
    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
453 453
    if (ret) {
454 454
        if (retaddr) {
......
463 463
        }
464 464
        do_raise_exception_err(env->exception_index, env->error_code);
465 465
    }
466
#if 0
466 467
    {
467 468
        unsigned long tlb_addrr, tlb_addrw;
468 469
        int index;
469 470
        index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
470 471
        tlb_addrr = env->tlb_read[is_user][index].address;
471 472
        tlb_addrw = env->tlb_write[is_user][index].address;
472
#if 0
473 473
        printf("%s 2 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx "
474 474
               "(0x%08lx 0x%08lx)\n", __func__, env,
475 475
               &env->tlb_read[is_user][index], index, addr,
476 476
               tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK,
477 477
               tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
478
#endif
479 478
    }
479
#endif
480 480
    env = saved_env;
481 481
}
482 482

  
......
496 496
    int access_type;
497 497
    int ret = 0;
498 498

  
499
//    printf("%s 0\n", __func__);
500
    access_type = env->access_type;
499
    if (rw == 2) {
500
        /* code access */
501
        rw = 0;
502
        access_type = ACCESS_CODE;
503
    } else {
504
        /* data access */
505
        /* XXX: put correct access by using cpu_restore_state()
506
           correctly */
507
        access_type = ACCESS_INT;
508
        //        access_type = env->access_type;
509
    }
501 510
    if (env->user_mode_only) {
502 511
        /* user mode only emulation */
503 512
        ret = -2;
504 513
        goto do_fault;
505 514
    }
506
    /* NASTY BUG workaround */
507
    if (access_type == ACCESS_CODE && rw) {
508
	printf("%s: ERROR WRITE CODE ACCESS\n", __func__);
509
	access_type = ACCESS_INT;
510
    }
511 515
    ret = get_physical_address(env, &physical, &prot,
512 516
                               address, rw, access_type);
513 517
    if (ret == 0) {
......
590 594
        env->error_code = error_code;
591 595
        ret = 1;
592 596
    }
593

  
594 597
    return ret;
595 598
}
596 599

  
......
671 674
        if (loglevel > 0) {
672 675
            fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",
673 676
                    env->nip, excp << 8, env->error_code);
674
    }
677
        }
675 678
	if (loglevel > 0)
676 679
	    cpu_ppc_dump_state(env, logfile, 0);
677 680
    }
678 681
#endif
682
    if (loglevel & CPU_LOG_INT) {
683
        fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",
684
                env->nip, excp << 8, env->error_code);
685
    }
679 686
    /* Generate informations in save/restore registers */
680 687
    switch (excp) {
681 688
    case EXCP_OFCALL:
......
824 831
        }
825 832
        goto store_next;
826 833
    case EXCP_SYSCALL:
827
#if defined (DEBUG_EXCEPTIONS)
828
	if (msr_pr) {
829
	    if (loglevel) {
830
		fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
831
			env->gpr[0], env->gpr[3], env->gpr[4],
832
			env->gpr[5], env->gpr[6]);
833
	    } else {
834
		printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
835
		       env->gpr[0], env->nip, env->gpr[3], env->gpr[4],
836
		       env->gpr[5], env->gpr[6]);
837
	    }
838
	}
839
#endif
834
        if (loglevel & CPU_LOG_INT) {
835
            fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
836
                    env->gpr[0], env->gpr[3], env->gpr[4],
837
                    env->gpr[5], env->gpr[6]);
838
            if (env->gpr[0] == 4 && env->gpr[3] == 1) {
839
                int len, addr, i;
840
                uint8_t c;
841

  
842
                fprintf(logfile, "write: ");
843
                addr = env->gpr[4];
844
                len = env->gpr[5];
845
                if (len > 64)
846
                    len = 64;
847
                for(i = 0; i < len; i++) {
848
                    c = 0;
849
                    cpu_memory_rw_debug(env, addr + i, &c, 1, 0);
850
                    if (c < 32 || c > 126)
851
                        c = '.';
852
                    fprintf(logfile, "%c", c);
853
                }
854
                fprintf(logfile, "\n");
855
            }
856
        }
840 857
        goto store_next;
841 858
    case EXCP_TRACE:
842 859
        goto store_next;
b/target-ppc/translate.c
3002 3002
#else
3003 3003
    env->nip = 0xFFFFFFFC;
3004 3004
#endif
3005
    env->access_type = ACCESS_INT;
3006 3005
    cpu_single_env = env;
3007 3006
    return env;
3008 3007
}
......
3050 3049
    /* Single step trace mode */
3051 3050
    msr_se = 1;
3052 3051
#endif
3053
    env->access_type = ACCESS_CODE;
3054 3052
    /* Set env in case of segfault during code fetch */
3055 3053
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
3056 3054
        if (search_pc) {
3057
            if (loglevel > 0)
3058
                fprintf(logfile, "Search PC...\n");
3059 3055
            j = gen_opc_ptr - gen_opc_buf;
3060 3056
            if (lj < j) {
3061 3057
                lj++;
......
3187 3183
        fprintf(logfile, "\n");
3188 3184
    }
3189 3185
#endif
3190
    env->access_type = ACCESS_INT;
3191

  
3192 3186
    return 0;
3193 3187
}
3194 3188

  
b/target-sparc/cpu.h
86 86
#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT)
87 87
#define PG_CACHE_MASK    (1 << PG_CACHE_BIT)
88 88

  
89
#define ACCESS_DATA	0
90
#define ACCESS_CODE	1
91
#define ACCESS_MMU	2
92

  
93 89
#define NWINDOWS  32
94 90

  
95 91
typedef struct CPUSPARCState {
......
131 127
    CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
132 128
    CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
133 129
    int error_code;
134
    int access_type;
135 130
    /* MMU regs */
136 131
    uint32_t mmuregs[16];
137 132
    /* temporary float registers */
b/target-sparc/helper.c
132 132
                              int is_user, int is_softmmu)
133 133
{
134 134
    int exception = 0;
135
    int access_type, access_perms = 0, access_index = 0;
135
    int access_perms = 0, access_index = 0;
136 136
    uint8_t *pde_ptr;
137 137
    uint32_t pde, virt_addr;
138 138
    int error_code = 0, is_dirty, prot, ret = 0;
139 139
    unsigned long paddr, vaddr, page_offset;
140 140

  
141
    access_type = env->access_type;
142 141
    if (env->user_mode_only) {
143 142
        /* user mode only emulation */
144 143
        ret = -2;
......
156 155
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
157 156
    /* Context base + context number */
158 157
    pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
159
    env->access_type = ACCESS_MMU;
160 158
    pde = ldl_raw(pde_ptr);
161 159

  
162 160
    /* Ctx pde */
......
219 217
    }
220 218

  
221 219
    /* update page modified and dirty bits */
222
    is_dirty = rw && !(pde & PG_MODIFIED_MASK);
220
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
223 221
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
224 222
	pde |= PG_ACCESSED_MASK;
225 223
	if (is_dirty)
......
228 226
    }
229 227

  
230 228
    /* check access */
231
    access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1);
229
    access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
232 230
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
233 231
    error_code = access_table[access_index][access_perms];
234 232
    if (error_code)
......
249 247
    paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
250 248

  
251 249
 do_mapping:
252
    env->access_type = access_type;
253 250
    vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
254 251

  
255 252
    ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
256 253
    return ret;
257 254

  
258 255
 do_fault:
259
    env->access_type = access_type;
260 256
    if (env->mmuregs[3]) /* Fault status register */
261 257
	env->mmuregs[3] = 1; /* overflow (not read before another fault) */
262 258
    env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
b/target-sparc/translate.c
1278 1278
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1279 1279
    gen_opparam_ptr = gen_opparam_buf;
1280 1280

  
1281
    env->access_type = ACCESS_CODE;
1282

  
1283 1281
    do {
1284 1282
        if (env->nb_breakpoints > 0) {
1285 1283
            for(j = 0; j < env->nb_breakpoints; j++) {
......
1352 1350
        }
1353 1351
    }
1354 1352
#endif
1355

  
1356
    env->access_type = ACCESS_DATA;
1357 1353
    return 0;
1358 1354
}
1359 1355

  
......
1379 1375
    env->cwp = 0;
1380 1376
    env->wim = 1;
1381 1377
    env->regwptr = env->regbase + (env->cwp * 16);
1382
    env->access_type = ACCESS_DATA;
1383 1378
#if defined(CONFIG_USER_ONLY)
1384 1379
    env->user_mode_only = 1;
1385 1380
#else

Also available in: Unified diff