Revision 0b5c1ce8 cpu-exec.c

b/cpu-exec.c
746 746
#if !defined(CONFIG_SOFTMMU)
747 747

  
748 748
#if defined(TARGET_I386)
749
#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
750
#else
751
#define EXCEPTION_ACTION cpu_loop_exit()
752
#endif
749 753

  
750 754
/* 'pc' is the host PC at which the exception was raised. 'address' is
751 755
   the effective address of the memory exception. 'is_write' is 1 if a
......
770 774
    }
771 775

  
772 776
    /* see if it is an MMU fault */
773
    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
774
    if (ret < 0)
775
        return 0; /* not an MMU fault */
776
    if (ret == 0)
777
        return 1; /* the MMU fault was handled without causing real CPU fault */
778
    /* now we have a real cpu fault */
779
    tb = tb_find_pc(pc);
780
    if (tb) {
781
        /* the PC is inside the translated code. It means that we have
782
           a virtual CPU fault */
783
        cpu_restore_state(tb, env, pc, puc);
784
    }
785
    if (ret == 1) {
786
#if 0
787
        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
788
               env->eip, env->cr[2], env->error_code);
789
#endif
790
        /* we restore the process signal mask as the sigreturn should
791
           do it (XXX: use sigsetjmp) */
792
        sigprocmask(SIG_SETMASK, old_set, NULL);
793
        raise_exception_err(env->exception_index, env->error_code);
794
    } else {
795
        /* activate soft MMU for this block */
796
        env->hflags |= HF_SOFTMMU_MASK;
797
        cpu_resume_from_signal(env, puc);
798
    }
799
    /* never comes here */
800
    return 1;
801
}
802

  
803
#elif defined(TARGET_ARM)
804
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
805
                                    int is_write, sigset_t *old_set,
806
                                    void *puc)
807
{
808
    TranslationBlock *tb;
809
    int ret;
810

  
811
    if (cpu_single_env)
812
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
813
#if defined(DEBUG_SIGNAL)
814
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
815
           pc, address, is_write, *(unsigned long *)old_set);
816
#endif
817
    /* XXX: locking issue */
818
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
819
        return 1;
820
    }
821
    /* see if it is an MMU fault */
822
    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
777
    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
823 778
    if (ret < 0)
824 779
        return 0; /* not an MMU fault */
825 780
    if (ret == 0)
......
831 786
           a virtual CPU fault */
832 787
        cpu_restore_state(tb, env, pc, puc);
833 788
    }
834
    /* we restore the process signal mask as the sigreturn should
835
       do it (XXX: use sigsetjmp) */
836
    sigprocmask(SIG_SETMASK, old_set, NULL);
837
    cpu_loop_exit();
838
    /* never comes here */
839
    return 1;
840
}
841
#elif defined(TARGET_SPARC)
842
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
843
                                    int is_write, sigset_t *old_set,
844
                                    void *puc)
845
{
846
    TranslationBlock *tb;
847
    int ret;
848 789

  
849
    if (cpu_single_env)
850
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
851
#if defined(DEBUG_SIGNAL)
852
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
853
           pc, address, is_write, *(unsigned long *)old_set);
854
#endif
855
    /* XXX: locking issue */
856
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
857
        return 1;
858
    }
859
    /* see if it is an MMU fault */
860
    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
861
    if (ret < 0)
862
        return 0; /* not an MMU fault */
863
    if (ret == 0)
864
        return 1; /* the MMU fault was handled without causing real CPU fault */
865
    /* now we have a real cpu fault */
866
    tb = tb_find_pc(pc);
867
    if (tb) {
868
        /* the PC is inside the translated code. It means that we have
869
           a virtual CPU fault */
870
        cpu_restore_state(tb, env, pc, puc);
871
    }
872 790
    /* we restore the process signal mask as the sigreturn should
873 791
       do it (XXX: use sigsetjmp) */
874 792
    sigprocmask(SIG_SETMASK, old_set, NULL);
875
    cpu_loop_exit();
876
    /* never comes here */
877
    return 1;
878
}
879
#elif defined (TARGET_PPC)
880
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
881
                                    int is_write, sigset_t *old_set,
882
                                    void *puc)
883
{
884
    TranslationBlock *tb;
885
    int ret;
886

  
887
    if (cpu_single_env)
888
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
889
#if defined(DEBUG_SIGNAL)
890
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
891
           pc, address, is_write, *(unsigned long *)old_set);
892
#endif
893
    /* XXX: locking issue */
894
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
895
        return 1;
896
    }
897

  
898
    /* see if it is an MMU fault */
899
    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
900
    if (ret < 0)
901
        return 0; /* not an MMU fault */
902
    if (ret == 0)
903
        return 1; /* the MMU fault was handled without causing real CPU fault */
904

  
905
    /* now we have a real cpu fault */
906
    tb = tb_find_pc(pc);
907
    if (tb) {
908
        /* the PC is inside the translated code. It means that we have
909
           a virtual CPU fault */
910
        cpu_restore_state(tb, env, pc, puc);
911
    }
912
    if (ret == 1) {
913
#if 0
914
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
915
               env->nip, env->error_code, tb);
916
#endif
917
    /* we restore the process signal mask as the sigreturn should
918
       do it (XXX: use sigsetjmp) */
919
        sigprocmask(SIG_SETMASK, old_set, NULL);
920
        cpu_loop_exit();
921
    } else {
922
        /* activate soft MMU for this block */
923
        cpu_resume_from_signal(env, puc);
924
    }
925
    /* never comes here */
926
    return 1;
927
}
793
    EXCEPTION_ACTION;
928 794

  
929
#elif defined(TARGET_M68K)
930
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
931
                                    int is_write, sigset_t *old_set,
932
                                    void *puc)
933
{
934
    TranslationBlock *tb;
935
    int ret;
936

  
937
    if (cpu_single_env)
938
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
939
#if defined(DEBUG_SIGNAL)
940
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
941
           pc, address, is_write, *(unsigned long *)old_set);
942
#endif
943
    /* XXX: locking issue */
944
    if (is_write && page_unprotect(address, pc, puc)) {
945
        return 1;
946
    }
947
    /* see if it is an MMU fault */
948
    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
949
    if (ret < 0)
950
        return 0; /* not an MMU fault */
951
    if (ret == 0)
952
        return 1; /* the MMU fault was handled without causing real CPU fault */
953
    /* now we have a real cpu fault */
954
    tb = tb_find_pc(pc);
955
    if (tb) {
956
        /* the PC is inside the translated code. It means that we have
957
           a virtual CPU fault */
958
        cpu_restore_state(tb, env, pc, puc);
959
    }
960
    /* we restore the process signal mask as the sigreturn should
961
       do it (XXX: use sigsetjmp) */
962
    sigprocmask(SIG_SETMASK, old_set, NULL);
963
    cpu_loop_exit();
964 795
    /* never comes here */
965 796
    return 1;
966 797
}
967 798

  
968
#elif defined (TARGET_MIPS)
969
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
970
                                    int is_write, sigset_t *old_set,
971
                                    void *puc)
972
{
973
    TranslationBlock *tb;
974
    int ret;
975

  
976
    if (cpu_single_env)
977
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
978
#if defined(DEBUG_SIGNAL)
979
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
980
           pc, address, is_write, *(unsigned long *)old_set);
981
#endif
982
    /* XXX: locking issue */
983
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
984
        return 1;
985
    }
986

  
987
    /* see if it is an MMU fault */
988
    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
989
    if (ret < 0)
990
        return 0; /* not an MMU fault */
991
    if (ret == 0)
992
        return 1; /* the MMU fault was handled without causing real CPU fault */
993

  
994
    /* now we have a real cpu fault */
995
    tb = tb_find_pc(pc);
996
    if (tb) {
997
        /* the PC is inside the translated code. It means that we have
998
           a virtual CPU fault */
999
        cpu_restore_state(tb, env, pc, puc);
1000
    }
1001
    if (ret == 1) {
1002
#if 0
1003
        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1004
               env->PC, env->error_code, tb);
1005
#endif
1006
    /* we restore the process signal mask as the sigreturn should
1007
       do it (XXX: use sigsetjmp) */
1008
        sigprocmask(SIG_SETMASK, old_set, NULL);
1009
        cpu_loop_exit();
1010
    } else {
1011
        /* activate soft MMU for this block */
1012
        cpu_resume_from_signal(env, puc);
1013
    }
1014
    /* never comes here */
1015
    return 1;
1016
}
1017

  
1018
#elif defined (TARGET_MICROBLAZE)
1019
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1020
                                    int is_write, sigset_t *old_set,
1021
                                    void *puc)
1022
{
1023
    TranslationBlock *tb;
1024
    int ret;
1025

  
1026
    if (cpu_single_env)
1027
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1028
#if defined(DEBUG_SIGNAL)
1029
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1030
           pc, address, is_write, *(unsigned long *)old_set);
1031
#endif
1032
    /* XXX: locking issue */
1033
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1034
        return 1;
1035
    }
1036

  
1037
    /* see if it is an MMU fault */
1038
    ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1039
    if (ret < 0)
1040
        return 0; /* not an MMU fault */
1041
    if (ret == 0)
1042
        return 1; /* the MMU fault was handled without causing real CPU fault */
1043

  
1044
    /* now we have a real cpu fault */
1045
    tb = tb_find_pc(pc);
1046
    if (tb) {
1047
        /* the PC is inside the translated code. It means that we have
1048
           a virtual CPU fault */
1049
        cpu_restore_state(tb, env, pc, puc);
1050
    }
1051
    if (ret == 1) {
1052
#if 0
1053
        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
1054
               env->PC, env->error_code, tb);
1055
#endif
1056
    /* we restore the process signal mask as the sigreturn should
1057
       do it (XXX: use sigsetjmp) */
1058
        sigprocmask(SIG_SETMASK, old_set, NULL);
1059
        cpu_loop_exit();
1060
    } else {
1061
        /* activate soft MMU for this block */
1062
        cpu_resume_from_signal(env, puc);
1063
    }
1064
    /* never comes here */
1065
    return 1;
1066
}
1067

  
1068
#elif defined (TARGET_SH4)
1069
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1070
                                    int is_write, sigset_t *old_set,
1071
                                    void *puc)
1072
{
1073
    TranslationBlock *tb;
1074
    int ret;
1075

  
1076
    if (cpu_single_env)
1077
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1078
#if defined(DEBUG_SIGNAL)
1079
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1080
           pc, address, is_write, *(unsigned long *)old_set);
1081
#endif
1082
    /* XXX: locking issue */
1083
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1084
        return 1;
1085
    }
1086

  
1087
    /* see if it is an MMU fault */
1088
    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1089
    if (ret < 0)
1090
        return 0; /* not an MMU fault */
1091
    if (ret == 0)
1092
        return 1; /* the MMU fault was handled without causing real CPU fault */
1093

  
1094
    /* now we have a real cpu fault */
1095
    tb = tb_find_pc(pc);
1096
    if (tb) {
1097
        /* the PC is inside the translated code. It means that we have
1098
           a virtual CPU fault */
1099
        cpu_restore_state(tb, env, pc, puc);
1100
    }
1101
#if 0
1102
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1103
               env->nip, env->error_code, tb);
1104
#endif
1105
    /* we restore the process signal mask as the sigreturn should
1106
       do it (XXX: use sigsetjmp) */
1107
    sigprocmask(SIG_SETMASK, old_set, NULL);
1108
    cpu_loop_exit();
1109
    /* never comes here */
1110
    return 1;
1111
}
1112

  
1113
#elif defined (TARGET_ALPHA)
1114
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1115
                                    int is_write, sigset_t *old_set,
1116
                                    void *puc)
1117
{
1118
    TranslationBlock *tb;
1119
    int ret;
1120

  
1121
    if (cpu_single_env)
1122
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1123
#if defined(DEBUG_SIGNAL)
1124
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1125
           pc, address, is_write, *(unsigned long *)old_set);
1126
#endif
1127
    /* XXX: locking issue */
1128
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1129
        return 1;
1130
    }
1131

  
1132
    /* see if it is an MMU fault */
1133
    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1134
    if (ret < 0)
1135
        return 0; /* not an MMU fault */
1136
    if (ret == 0)
1137
        return 1; /* the MMU fault was handled without causing real CPU fault */
1138

  
1139
    /* now we have a real cpu fault */
1140
    tb = tb_find_pc(pc);
1141
    if (tb) {
1142
        /* the PC is inside the translated code. It means that we have
1143
           a virtual CPU fault */
1144
        cpu_restore_state(tb, env, pc, puc);
1145
    }
1146
#if 0
1147
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1148
               env->nip, env->error_code, tb);
1149
#endif
1150
    /* we restore the process signal mask as the sigreturn should
1151
       do it (XXX: use sigsetjmp) */
1152
    sigprocmask(SIG_SETMASK, old_set, NULL);
1153
    cpu_loop_exit();
1154
    /* never comes here */
1155
    return 1;
1156
}
1157
#elif defined (TARGET_CRIS)
1158
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1159
                                    int is_write, sigset_t *old_set,
1160
                                    void *puc)
1161
{
1162
    TranslationBlock *tb;
1163
    int ret;
1164

  
1165
    if (cpu_single_env)
1166
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1167
#if defined(DEBUG_SIGNAL)
1168
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1169
           pc, address, is_write, *(unsigned long *)old_set);
1170
#endif
1171
    /* XXX: locking issue */
1172
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1173
        return 1;
1174
    }
1175

  
1176
    /* see if it is an MMU fault */
1177
    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1178
    if (ret < 0)
1179
        return 0; /* not an MMU fault */
1180
    if (ret == 0)
1181
        return 1; /* the MMU fault was handled without causing real CPU fault */
1182

  
1183
    /* now we have a real cpu fault */
1184
    tb = tb_find_pc(pc);
1185
    if (tb) {
1186
        /* the PC is inside the translated code. It means that we have
1187
           a virtual CPU fault */
1188
        cpu_restore_state(tb, env, pc, puc);
1189
    }
1190
    /* we restore the process signal mask as the sigreturn should
1191
       do it (XXX: use sigsetjmp) */
1192
    sigprocmask(SIG_SETMASK, old_set, NULL);
1193
    cpu_loop_exit();
1194
    /* never comes here */
1195
    return 1;
1196
}
1197

  
1198
#else
1199
#error unsupported target CPU
1200
#endif
1201

  
1202 799
#if defined(__i386__)
1203 800

  
1204 801
#if defined(__APPLE__)

Also available in: Unified diff