comparison m68k_core_x86.c @ 990:33a46d35b913

Implement privelege violation exceptions
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Apr 2016 23:11:24 -0700
parents d70000fdff0b
children 784bc1e45e80
comparison
equal deleted inserted replaced
989:d70000fdff0b 990:33a46d35b913
1968 } 1968 }
1969 } 1969 }
1970 1970
1971 #define BIT_SUPERVISOR 5 1971 #define BIT_SUPERVISOR 5
1972 1972
1973 void m68k_trap_if_not_supervisor(m68k_options *opts, m68kinst *inst)
1974 {
1975 code_info *code = &opts->gen.code;
1976 //check supervisor bit in SR and trap if not in supervisor mode
1977 bt_irdisp(code, BIT_SUPERVISOR, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
1978 code_ptr in_sup_mode = code->cur + 1;
1979 jcc(code, CC_C, code->cur + 2);
1980
1981 ldi_native(opts, VECTOR_PRIV_VIOLATION, opts->gen.scratch2);
1982 ldi_native(opts, inst->address, opts->gen.scratch1);
1983 jmp(code, opts->trap);
1984
1985 *in_sup_mode = code->cur - (in_sup_mode + 1);
1986 }
1987
1973 void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) 1988 void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst)
1974 { 1989 {
1975 code_info *code = &opts->gen.code; 1990 code_info *code = &opts->gen.code;
1991 if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) {
1992 m68k_trap_if_not_supervisor(opts, inst);
1993 }
1976 cycles(&opts->gen, 20); 1994 cycles(&opts->gen, 20);
1977 //TODO: If ANDI to SR, trap if not in supervisor mode
1978 uint32_t flag_mask = 0; 1995 uint32_t flag_mask = 0;
1979 uint32_t base_flag = inst->op == M68K_ANDI_SR || inst->op == M68K_ANDI_CCR ? X0 : X1; 1996 uint32_t base_flag = inst->op == M68K_ANDI_SR || inst->op == M68K_ANDI_CCR ? X0 : X1;
1980 for (int i = 0; i < 5; i++) 1997 for (int i = 0; i < 5; i++)
1981 { 1998 {
1982 if ((base_flag == X0) ^ ((inst->src.params.immed & 1 << i) > 0)) 1999 if ((base_flag == X0) ^ ((inst->src.params.immed & 1 << i) > 0))
2007 } 2024 }
2008 2025
2009 void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst) 2026 void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst)
2010 { 2027 {
2011 code_info *code = &opts->gen.code; 2028 code_info *code = &opts->gen.code;
2029 if (inst->op == M68K_EORI_SR) {
2030 m68k_trap_if_not_supervisor(opts, inst);
2031 }
2012 cycles(&opts->gen, 20); 2032 cycles(&opts->gen, 20);
2013 //TODO: If ANDI to SR, trap if not in supervisor mode
2014 if (inst->src.params.immed & 0x1) { 2033 if (inst->src.params.immed & 0x1) {
2015 xor_flag(opts, 1, FLAG_C); 2034 xor_flag(opts, 1, FLAG_C);
2016 } 2035 }
2017 if (inst->src.params.immed & 0x2) { 2036 if (inst->src.params.immed & 0x2) {
2018 xor_flag(opts, 1, FLAG_V); 2037 xor_flag(opts, 1, FLAG_V);
2047 } 2066 }
2048 2067
2049 void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 2068 void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
2050 { 2069 {
2051 code_info *code = &opts->gen.code; 2070 code_info *code = &opts->gen.code;
2052 //TODO: Privilege check for MOVE to SR 2071 if (inst->op == M68K_MOVE_SR) {
2072 m68k_trap_if_not_supervisor(opts, inst);
2073 }
2053 if (src_op->mode == MODE_IMMED) { 2074 if (src_op->mode == MODE_IMMED) {
2054 set_all_flags(opts, src_op->disp); 2075 set_all_flags(opts, src_op->disp);
2055 if (inst->op == M68K_MOVE_SR) { 2076 if (inst->op == M68K_MOVE_SR) {
2056 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); 2077 mov_irdisp(code, (src_op->disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
2057 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2078 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
2083 } 2104 }
2084 } 2105 }
2085 2106
2086 void translate_m68k_stop(m68k_options *opts, m68kinst *inst) 2107 void translate_m68k_stop(m68k_options *opts, m68kinst *inst)
2087 { 2108 {
2088 //TODO: Trap if not in system mode 2109 m68k_trap_if_not_supervisor(opts, inst);
2089 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 2110 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
2090 //possibly even 12 since that's how long MOVE to SR takes 2111 //possibly even 12 since that's how long MOVE to SR takes
2091 //On further thought prefetch + the fact that this stops the CPU may make 2112 //On further thought prefetch + the fact that this stops the CPU may make
2092 //Motorola's accounting make sense here 2113 //Motorola's accounting make sense here
2093 code_info *code = &opts->gen.code; 2114 code_info *code = &opts->gen.code;
2187 } 2208 }
2188 2209
2189 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) 2210 void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
2190 { 2211 {
2191 code_info *code = &opts->gen.code; 2212 code_info *code = &opts->gen.code;
2192 //TODO: Trap if not in system mode
2193 call(code, opts->get_sr); 2213 call(code, opts->get_sr);
2194 if (dst_op->mode == MODE_REG_DIRECT) { 2214 if (dst_op->mode == MODE_REG_DIRECT) {
2195 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); 2215 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W);
2196 } else { 2216 } else {
2197 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W); 2217 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W);