semihosting: create SemihostingConfig structure and semihost.h
Remove semihosting_enabled and semihosting_target and replace them with SemihostingConfig structure containing equivalent fields. The structure is defined in vl.c where it is actually set. Also introduce separate header file include/exec/semihost.h allowing to access semihosting config related stuff from target specific semihosting code. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1434643256-16858-2-git-send-email-leon.alrae@imgtec.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									b58850e79d
								
							
						
					
					
						commit
						cfe67cef48
					
				| @ -40,6 +40,7 @@ | ||||
| #include "cpu.h" | ||||
| #include "qemu/sockets.h" | ||||
| #include "sysemu/kvm.h" | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| #ifdef CONFIG_USER_ONLY | ||||
| #define GDB_ATTACHED "0" | ||||
| @ -323,8 +324,6 @@ static GDBState *gdbserver_state; | ||||
| 
 | ||||
| bool gdb_has_xml; | ||||
| 
 | ||||
| int semihosting_target = SEMIHOSTING_TARGET_AUTO; | ||||
| 
 | ||||
| #ifdef CONFIG_USER_ONLY | ||||
| /* XXX: This is not thread safe.  Do we care?  */ | ||||
| static int gdbserver_fd = -1; | ||||
| @ -362,10 +361,11 @@ static enum { | ||||
| /* Decide if either remote gdb syscalls or native file IO should be used. */ | ||||
| int use_gdb_syscalls(void) | ||||
| { | ||||
|     if (semihosting_target == SEMIHOSTING_TARGET_NATIVE) { | ||||
|     SemihostingTarget target = semihosting_get_target(); | ||||
|     if (target == SEMIHOSTING_TARGET_NATIVE) { | ||||
|         /* -semihosting-config target=native */ | ||||
|         return false; | ||||
|     } else if (semihosting_target == SEMIHOSTING_TARGET_GDB) { | ||||
|     } else if (target == SEMIHOSTING_TARGET_GDB) { | ||||
|         /* -semihosting-config target=gdb */ | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -95,10 +95,4 @@ extern bool gdb_has_xml; | ||||
| /* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */ | ||||
| extern const char *const xml_builtin[][2]; | ||||
| 
 | ||||
| /* Command line option defining whether semihosting should go via gdb or not */ | ||||
| extern int semihosting_target; | ||||
| #define SEMIHOSTING_TARGET_AUTO     0 | ||||
| #define SEMIHOSTING_TARGET_NATIVE   1 | ||||
| #define SEMIHOSTING_TARGET_GDB      2 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										44
									
								
								include/exec/semihost.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								include/exec/semihost.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /*
 | ||||
|  * Semihosting support | ||||
|  * | ||||
|  * Copyright (c) 2015 Imagination Technologies | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #ifndef SEMIHOST_H | ||||
| #define SEMIHOST_H | ||||
| 
 | ||||
| typedef enum SemihostingTarget { | ||||
|     SEMIHOSTING_TARGET_AUTO = 0, | ||||
|     SEMIHOSTING_TARGET_NATIVE, | ||||
|     SEMIHOSTING_TARGET_GDB | ||||
| } SemihostingTarget; | ||||
| 
 | ||||
| #ifdef CONFIG_USER_ONLY | ||||
| static inline bool semihosting_enabled(void) | ||||
| { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static inline SemihostingTarget semihosting_get_target(void) | ||||
| { | ||||
|     return SEMIHOSTING_TARGET_AUTO; | ||||
| } | ||||
| #else | ||||
| bool semihosting_enabled(void); | ||||
| SemihostingTarget semihosting_get_target(void); | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| @ -126,7 +126,6 @@ extern int cursor_hide; | ||||
| extern int graphic_rotate; | ||||
| extern int no_quit; | ||||
| extern int no_shutdown; | ||||
| extern int semihosting_enabled; | ||||
| extern int old_param; | ||||
| extern int boot_menu; | ||||
| extern bool boot_strict; | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
| #include "exec/cpu_ldst.h" | ||||
| #include "arm_ldst.h" | ||||
| #include <zlib.h> /* For crc32 */ | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| #ifndef CONFIG_USER_ONLY | ||||
| static inline bool get_phys_addr(CPUARMState *env, target_ulong address, | ||||
| @ -4554,7 +4555,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) | ||||
|         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); | ||||
|         return; | ||||
|     case EXCP_BKPT: | ||||
|         if (semihosting_enabled) { | ||||
|         if (semihosting_enabled()) { | ||||
|             int nr; | ||||
|             nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; | ||||
|             if (nr == 0xab) { | ||||
| @ -4866,7 +4867,7 @@ void arm_cpu_do_interrupt(CPUState *cs) | ||||
|             offset = 4; | ||||
|         break; | ||||
|     case EXCP_SWI: | ||||
|         if (semihosting_enabled) { | ||||
|         if (semihosting_enabled()) { | ||||
|             /* Check for semihosting interrupt.  */ | ||||
|             if (env->thumb) { | ||||
|                 mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code) | ||||
| @ -4893,7 +4894,7 @@ void arm_cpu_do_interrupt(CPUState *cs) | ||||
|         break; | ||||
|     case EXCP_BKPT: | ||||
|         /* See if this is a semihosting syscall.  */ | ||||
|         if (env->thumb && semihosting_enabled) { | ||||
|         if (env->thumb && semihosting_enabled()) { | ||||
|             mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff; | ||||
|             if (mask == 0xab | ||||
|                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { | ||||
|  | ||||
| @ -20,6 +20,7 @@ | ||||
| #include "cpu.h" | ||||
| #include "qemu/host-utils.h" | ||||
| #include "sysemu/sysemu.h" | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, | ||||
|                               int mmu_idx) | ||||
| @ -162,7 +163,7 @@ void lm32_cpu_do_interrupt(CPUState *cs) | ||||
| 
 | ||||
|     switch (cs->exception_index) { | ||||
|     case EXCP_SYSTEMCALL: | ||||
|         if (unlikely(semihosting_enabled)) { | ||||
|         if (unlikely(semihosting_enabled())) { | ||||
|             /* do_semicall() returns true if call was handled. Otherwise
 | ||||
|              * do the normal exception handling. */ | ||||
|             if (lm32_cpu_do_semihosting(cs)) { | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| #include "cpu.h" | ||||
| #include "exec/helper-proto.h" | ||||
| #include "exec/cpu_ldst.h" | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
| 
 | ||||
| @ -33,8 +34,6 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| extern int semihosting_enabled; | ||||
| 
 | ||||
| /* Try to fill the TLB and return an exception if error. If retaddr is
 | ||||
|    NULL, it means that the function was called in C code (i.e. not | ||||
|    from generated code or from helper.c) */ | ||||
| @ -85,7 +84,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw) | ||||
|             do_rte(env); | ||||
|             return; | ||||
|         case EXCP_HALT_INSN: | ||||
|             if (semihosting_enabled | ||||
|             if (semihosting_enabled() | ||||
|                     && (env->sr & SR_S) != 0 | ||||
|                     && (env->pc & 3) == 0 | ||||
|                     && cpu_lduw_code(env, env->pc - 4) == 0x4e71 | ||||
|  | ||||
| @ -37,6 +37,7 @@ | ||||
| #include "qemu/log.h" | ||||
| #include "sysemu/sysemu.h" | ||||
| #include "exec/cpu_ldst.h" | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| #include "exec/helper-proto.h" | ||||
| #include "exec/helper-gen.h" | ||||
| @ -1216,7 +1217,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) | ||||
|                         break; | ||||
| 
 | ||||
|                     case 1: /*SIMCALL*/ | ||||
|                         if (semihosting_enabled) { | ||||
|                         if (semihosting_enabled()) { | ||||
|                             if (gen_check_privilege(dc)) { | ||||
|                                 gen_helper_simcall(cpu_env); | ||||
|                             } | ||||
|  | ||||
							
								
								
									
										38
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								vl.c
									
									
									
									
									
								
							| @ -119,6 +119,7 @@ int main(int argc, char **argv) | ||||
| #include "qapi/opts-visitor.h" | ||||
| #include "qom/object_interfaces.h" | ||||
| #include "qapi-event.h" | ||||
| #include "exec/semihost.h" | ||||
| 
 | ||||
| #define MAX_VIRTIO_CONSOLES 1 | ||||
| #define MAX_SCLP_CONSOLES 1 | ||||
| @ -169,7 +170,6 @@ int graphic_rotate = 0; | ||||
| const char *watchdog; | ||||
| QEMUOptionRom option_rom[MAX_OPTION_ROMS]; | ||||
| int nb_option_roms; | ||||
| int semihosting_enabled = 0; | ||||
| int old_param = 0; | ||||
| const char *qemu_name; | ||||
| int alt_grab = 0; | ||||
| @ -1245,6 +1245,26 @@ static void configure_msg(QemuOpts *opts) | ||||
|     enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); | ||||
| } | ||||
| 
 | ||||
| /***********************************************************/ | ||||
| /* Semihosting */ | ||||
| 
 | ||||
| typedef struct SemihostingConfig { | ||||
|     bool enabled; | ||||
|     SemihostingTarget target; | ||||
| } SemihostingConfig; | ||||
| 
 | ||||
| static SemihostingConfig semihosting; | ||||
| 
 | ||||
| bool semihosting_enabled(void) | ||||
| { | ||||
|     return semihosting.enabled; | ||||
| } | ||||
| 
 | ||||
| SemihostingTarget semihosting_get_target(void) | ||||
| { | ||||
|     return semihosting.target; | ||||
| } | ||||
| 
 | ||||
| /***********************************************************/ | ||||
| /* USB devices */ | ||||
| 
 | ||||
| @ -3622,24 +3642,24 @@ int main(int argc, char **argv, char **envp) | ||||
|                 nb_option_roms++; | ||||
|                 break; | ||||
|             case QEMU_OPTION_semihosting: | ||||
|                 semihosting_enabled = 1; | ||||
|                 semihosting_target = SEMIHOSTING_TARGET_AUTO; | ||||
|                 semihosting.enabled = true; | ||||
|                 semihosting.target = SEMIHOSTING_TARGET_AUTO; | ||||
|                 break; | ||||
|             case QEMU_OPTION_semihosting_config: | ||||
|                 semihosting_enabled = 1; | ||||
|                 semihosting.enabled = true; | ||||
|                 opts = qemu_opts_parse(qemu_find_opts("semihosting-config"), | ||||
|                                            optarg, 0); | ||||
|                 if (opts != NULL) { | ||||
|                     semihosting_enabled = qemu_opt_get_bool(opts, "enable", | ||||
|                     semihosting.enabled = qemu_opt_get_bool(opts, "enable", | ||||
|                                                             true); | ||||
|                     const char *target = qemu_opt_get(opts, "target"); | ||||
|                     if (target != NULL) { | ||||
|                         if (strcmp("native", target) == 0) { | ||||
|                             semihosting_target = SEMIHOSTING_TARGET_NATIVE; | ||||
|                             semihosting.target = SEMIHOSTING_TARGET_NATIVE; | ||||
|                         } else if (strcmp("gdb", target) == 0) { | ||||
|                             semihosting_target = SEMIHOSTING_TARGET_GDB; | ||||
|                             semihosting.target = SEMIHOSTING_TARGET_GDB; | ||||
|                         } else  if (strcmp("auto", target) == 0) { | ||||
|                             semihosting_target = SEMIHOSTING_TARGET_AUTO; | ||||
|                             semihosting.target = SEMIHOSTING_TARGET_AUTO; | ||||
|                         } else { | ||||
|                             fprintf(stderr, "Unsupported semihosting-config" | ||||
|                                     " %s\n", | ||||
| @ -3647,7 +3667,7 @@ int main(int argc, char **argv, char **envp) | ||||
|                             exit(1); | ||||
|                         } | ||||
|                     } else { | ||||
|                         semihosting_target = SEMIHOSTING_TARGET_AUTO; | ||||
|                         semihosting.target = SEMIHOSTING_TARGET_AUTO; | ||||
|                     } | ||||
|                 } else { | ||||
|                     fprintf(stderr, "Unsupported semihosting-config %s\n", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Leon Alrae
						Leon Alrae