Some bits of Linux/MIPS host support, still segfaulty.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2771 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2007-05-05 19:23:11 +00:00
parent 26ea091859
commit c4b89d18ba
7 changed files with 172 additions and 4 deletions

View File

@ -181,6 +181,7 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
endif
ifeq ($(ARCH),mips)
OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch
ifeq ($(WORDS_BIGENDIAN),yes)
BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
else
@ -189,6 +190,7 @@ endif
endif
ifeq ($(ARCH),mips64)
OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch
ifeq ($(WORDS_BIGENDIAN),yes)
BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
else

View File

@ -20,7 +20,7 @@
#ifndef CPU_ALL_H
#define CPU_ALL_H
#if defined(__arm__) || defined(__sparc__)
#if defined(__arm__) || defined(__sparc__) || defined(__mips__)
#define WORDS_ALIGNED
#endif
@ -1022,6 +1022,27 @@ static inline int64_t cpu_get_real_ticks (void)
return rval.i64;
#endif
}
#elif defined(__mips__)
static inline int64_t cpu_get_real_ticks(void)
{
#if __mips_isa_rev >= 2
uint32_t count;
static uint32_t cyc_per_count = 0;
if (!cyc_per_count)
__asm__ __volatile__("rdhwr %0, $3" : "=r" (cyc_per_count));
__asm__ __volatile__("rdhwr %1, $2" : "=r" (count));
return (int64_t)(count * cyc_per_count);
#else
/* FIXME */
static int64_t ticks = 0;
return ticks++;
#endif
}
#else
/* The host CPU doesn't have an easily accessible cycle counter.
Just return a monotonically increasing vlue. This will be totally wrong,

View File

@ -1540,8 +1540,22 @@ int cpu_signal_handler(int host_signum, void *pinfo,
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write,
&uc->uc_sigmask, puc);
is_write, &uc->uc_sigmask, puc);
}
#elif defined(__mips__)
int cpu_signal_handler(int host_signum, struct siginfo *info,
void *puc)
{
struct ucontext *uc = puc;
greg_t pc = uc->uc_mcontext.pc;
int is_write;
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write, &uc->uc_sigmask, puc);
}
#else

View File

@ -129,10 +129,15 @@ extern int printf(const char *, ...);
#define AREG3 "r6"
#endif
#ifdef __mips__
#define AREG0 "s3"
#define AREG0 "fp"
#define AREG1 "s0"
#define AREG2 "s1"
#define AREG3 "s2"
#define AREG4 "s3"
#define AREG5 "s4"
#define AREG6 "s5"
#define AREG7 "s6"
#define AREG8 "s7"
#endif
#ifdef __sparc__
#ifdef HOST_SOLARIS
@ -280,5 +285,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
#ifdef __mc68000
#define EXIT_TB() asm volatile ("rts")
#endif
#ifdef __mips__
#define EXIT_TB() asm volatile ("jr $ra")
#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
#endif
#endif /* !defined(__DYNGEN_EXEC_H__) */

View File

@ -117,6 +117,13 @@
#define elf_check_arch(x) ((x) == EM_68K)
#define ELF_USES_RELOCA
#elif defined(HOST_MIPS)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_MIPS
#define elf_check_arch(x) ((x) == EM_MIPS)
#define ELF_USES_RELOC
#else
#error unsupported CPU - please update the code
#endif
@ -1641,6 +1648,26 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
error("rts expected at the end of %s", name);
copy_size = p - p_start;
}
#elif defined(HOST_MIPS)
{
#define INSN_RETURN 0x03e00008
#define INSN_NOP 0x00000000
uint8_t *p = p_end;
if (p < (p_start + 0x8)) {
error("empty code for %s", name);
} else {
uint32_t end_insn1, end_insn2;
p -= 0x8;
end_insn1 = get32((uint32_t *)(p + 0x0));
end_insn2 = get32((uint32_t *)(p + 0x4));
if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
error("jr ra not found at end of %s", name);
}
copy_size = p - p_start;
}
#else
#error unsupported CPU
#endif
@ -2483,6 +2510,71 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
}
}
}
#elif defined(HOST_MIPS)
{
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
char name[256];
int type;
int addend;
int reloc_offset;
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
/* the compiler leave some unnecessary references to the code */
if (sym_name[0] == '\0')
continue;
get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = get32((uint32_t *)(text + rel->r_offset));
reloc_offset = rel->r_offset - start_offset;
switch (type) {
case R_MIPS_HI16:
fprintf(outfile, " /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n",
rel->r_offset, sym_name);
fprintf(outfile,
" *(uint32_t *)(gen_code_ptr + 0x%x) = "
"((*(uint32_t *)(gen_code_ptr + 0x%x)) "
" & ~0xffff) "
" | (((%s - 0x8000) >> 16) & 0xffff);\n",
reloc_offset, reloc_offset, name);
break;
case R_MIPS_LO16:
fprintf(outfile, " /* R_MIPS_LO16 RELOC, offset 0x%x, name %s */\n",
rel->r_offset, sym_name);
fprintf(outfile,
" *(uint32_t *)(gen_code_ptr + 0x%x) = "
"((*(uint32_t *)(gen_code_ptr + 0x%x)) "
" & ~0xffff) "
" | (%s & 0xffff);\n",
reloc_offset, reloc_offset, name);
break;
case R_MIPS_PC16:
fprintf(outfile, " /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
rel->r_offset, sym_name);
fprintf(outfile,
" *(uint32_t *)(gen_code_ptr + 0x%x) = "
"(0x%x & ~0xffff) "
"| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
" & 0xffff);\n",
reloc_offset, addend, addend, name, reloc_offset);
break;
case R_MIPS_GOT16:
case R_MIPS_CALL16:
fprintf(outfile, " /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
rel->r_offset, sym_name);
fprintf(outfile,
" *(uint32_t *)(gen_code_ptr + 0x%x) = "
"((*(uint32_t *)(gen_code_ptr + 0x%x)) "
" & ~0xffff) "
" | (((%s - 0x8000) >> 16) & 0xffff);\n",
reloc_offset, reloc_offset, name);
break;
default:
error("unsupported MIPS relocation (%d)", type);
}
}
}
}
#else
#error unsupported CPU
#endif

View File

@ -463,3 +463,11 @@ static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
}
#endif
#ifdef __mips__
#include <sys/cachectl.h>
static inline void flush_icache_range(unsigned long start, unsigned long stop)
{
_flush_cache ((void *)start, stop - start, BCACHE);
}
#endif

View File

@ -481,6 +481,28 @@ static inline int testandset (int *p)
}
#endif
#ifdef __mips__
static inline int testandset (int *p)
{
int ret;
__asm__ __volatile__ (
" .set push \n"
" .set noat \n"
" .set mips2 \n"
"1: li $1, 1 \n"
" ll %0, %1 \n"
" sc $1, %1 \n"
" bnez $1, 1b \n"
" .set pop "
: "=r" (ret), "+R" (*p)
:
: "memory");
return ret;
}
#endif
typedef int spinlock_t;
#define SPIN_LOCK_UNLOCKED 0