Commit 3475187dd814be9b27c4632b59c1e3c76d966d63

Authored by bellard
1 parent 8979b227

sparc64 marge (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1462 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 23 of 26 files are displayed.

Changelog
@@ -4,6 +4,7 @@ version 0.7.1: @@ -4,6 +4,7 @@ version 0.7.1:
4 - Windows 2000 install disk full hack (original idea from Vladimir 4 - Windows 2000 install disk full hack (original idea from Vladimir
5 N. Oleynik) 5 N. Oleynik)
6 - VMDK disk image creation (Filip Navara) 6 - VMDK disk image creation (Filip Navara)
  7 + - SPARC64 progress (Blue Swirl)
7 8
8 version 0.7.0: 9 version 0.7.0:
9 10
Makefile.target
@@ -349,7 +349,11 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o @@ -349,7 +349,11 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
349 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o 349 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
350 endif 350 endif
351 ifeq ($(TARGET_BASE_ARCH), sparc) 351 ifeq ($(TARGET_BASE_ARCH), sparc)
352 -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o fdc.o esp.o 352 +ifeq ($(TARGET_ARCH), sparc64)
  353 +VL_OBJS+= sun4u.o m48t08.o magic-load.o slavio_serial.o
  354 +else
  355 +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o
  356 +endif
353 endif 357 endif
354 ifdef CONFIG_GDBSTUB 358 ifdef CONFIG_GDBSTUB
355 VL_OBJS+=gdbstub.o 359 VL_OBJS+=gdbstub.o
@@ -442,7 +446,8 @@ op.o: op.c op_template.h @@ -442,7 +446,8 @@ op.o: op.c op_template.h
442 endif 446 endif
443 447
444 ifeq ($(TARGET_BASE_ARCH), sparc) 448 ifeq ($(TARGET_BASE_ARCH), sparc)
445 -op.o: op.c op_template.h op_mem.h 449 +op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h
  450 +magic_load.o: elf_op.h
446 endif 451 endif
447 452
448 ifeq ($(TARGET_ARCH), ppc) 453 ifeq ($(TARGET_ARCH), ppc)
cpu-exec.c
@@ -47,6 +47,9 @@ void cpu_loop_exit(void) @@ -47,6 +47,9 @@ void cpu_loop_exit(void)
47 longjmp(env->jmp_env, 1); 47 longjmp(env->jmp_env, 1);
48 } 48 }
49 #endif 49 #endif
  50 +#ifndef TARGET_SPARC
  51 +#define reg_T2
  52 +#endif
50 53
51 /* exit the current TB from a signal handler. The host registers are 54 /* exit the current TB from a signal handler. The host registers are
52 restored in a state compatible with the CPU emulator 55 restored in a state compatible with the CPU emulator
@@ -74,8 +77,12 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) @@ -74,8 +77,12 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
74 77
75 int cpu_exec(CPUState *env1) 78 int cpu_exec(CPUState *env1)
76 { 79 {
77 - int saved_T0, saved_T1, saved_T2; 80 + int saved_T0, saved_T1;
  81 +#if defined(reg_T2)
  82 + int saved_T2;
  83 +#endif
78 CPUState *saved_env; 84 CPUState *saved_env;
  85 +#if defined(TARGET_I386)
79 #ifdef reg_EAX 86 #ifdef reg_EAX
80 int saved_EAX; 87 int saved_EAX;
81 #endif 88 #endif
@@ -100,6 +107,11 @@ int cpu_exec(CPUState *env1) @@ -100,6 +107,11 @@ int cpu_exec(CPUState *env1)
100 #ifdef reg_EDI 107 #ifdef reg_EDI
101 int saved_EDI; 108 int saved_EDI;
102 #endif 109 #endif
  110 +#elif defined(TARGET_SPARC)
  111 +#if defined(reg_REGWPTR)
  112 + uint32_t *saved_regwptr;
  113 +#endif
  114 +#endif
103 #ifdef __sparc__ 115 #ifdef __sparc__
104 int saved_i7, tmp_T0; 116 int saved_i7, tmp_T0;
105 #endif 117 #endif
@@ -115,7 +127,9 @@ int cpu_exec(CPUState *env1) @@ -115,7 +127,9 @@ int cpu_exec(CPUState *env1)
115 env = env1; 127 env = env1;
116 saved_T0 = T0; 128 saved_T0 = T0;
117 saved_T1 = T1; 129 saved_T1 = T1;
  130 +#if defined(reg_T2)
118 saved_T2 = T2; 131 saved_T2 = T2;
  132 +#endif
119 #ifdef __sparc__ 133 #ifdef __sparc__
120 /* we also save i7 because longjmp may not restore it */ 134 /* we also save i7 because longjmp may not restore it */
121 asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); 135 asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
@@ -164,6 +178,9 @@ int cpu_exec(CPUState *env1) @@ -164,6 +178,9 @@ int cpu_exec(CPUState *env1)
164 env->cpsr = psr & ~CACHED_CPSR_BITS; 178 env->cpsr = psr & ~CACHED_CPSR_BITS;
165 } 179 }
166 #elif defined(TARGET_SPARC) 180 #elif defined(TARGET_SPARC)
  181 +#if defined(reg_REGWPTR)
  182 + saved_regwptr = REGWPTR;
  183 +#endif
167 #elif defined(TARGET_PPC) 184 #elif defined(TARGET_PPC)
168 #else 185 #else
169 #error unsupported target CPU 186 #error unsupported target CPU
@@ -354,7 +371,9 @@ int cpu_exec(CPUState *env1) @@ -354,7 +371,9 @@ int cpu_exec(CPUState *env1)
354 cpu_dump_state(env, logfile, fprintf, 0); 371 cpu_dump_state(env, logfile, fprintf, 0);
355 env->cpsr &= ~CACHED_CPSR_BITS; 372 env->cpsr &= ~CACHED_CPSR_BITS;
356 #elif defined(TARGET_SPARC) 373 #elif defined(TARGET_SPARC)
357 - cpu_dump_state (env, logfile, fprintf, 0); 374 + REGWPTR = env->regbase + (env->cwp * 16);
  375 + env->regwptr = REGWPTR;
  376 + cpu_dump_state(env, logfile, fprintf, 0);
358 #elif defined(TARGET_PPC) 377 #elif defined(TARGET_PPC)
359 cpu_dump_state(env, logfile, fprintf, 0); 378 cpu_dump_state(env, logfile, fprintf, 0);
360 #else 379 #else
@@ -376,7 +395,11 @@ int cpu_exec(CPUState *env1) @@ -376,7 +395,11 @@ int cpu_exec(CPUState *env1)
376 cs_base = 0; 395 cs_base = 0;
377 pc = env->regs[15]; 396 pc = env->regs[15];
378 #elif defined(TARGET_SPARC) 397 #elif defined(TARGET_SPARC)
379 - flags = 0; 398 +#ifdef TARGET_SPARC64
  399 + flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
  400 +#else
  401 + flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);
  402 +#endif
380 cs_base = env->npc; 403 cs_base = env->npc;
381 pc = env->pc; 404 pc = env->pc;
382 #elif defined(TARGET_PPC) 405 #elif defined(TARGET_PPC)
@@ -657,6 +680,9 @@ int cpu_exec(CPUState *env1) @@ -657,6 +680,9 @@ int cpu_exec(CPUState *env1)
657 env->cpsr = compute_cpsr(); 680 env->cpsr = compute_cpsr();
658 /* XXX: Save/restore host fpu exception state?. */ 681 /* XXX: Save/restore host fpu exception state?. */
659 #elif defined(TARGET_SPARC) 682 #elif defined(TARGET_SPARC)
  683 +#if defined(reg_REGWPTR)
  684 + REGWPTR = saved_regwptr;
  685 +#endif
660 #elif defined(TARGET_PPC) 686 #elif defined(TARGET_PPC)
661 #else 687 #else
662 #error unsupported target CPU 688 #error unsupported target CPU
@@ -666,7 +692,9 @@ int cpu_exec(CPUState *env1) @@ -666,7 +692,9 @@ int cpu_exec(CPUState *env1)
666 #endif 692 #endif
667 T0 = saved_T0; 693 T0 = saved_T0;
668 T1 = saved_T1; 694 T1 = saved_T1;
  695 +#if defined(reg_T2)
669 T2 = saved_T2; 696 T2 = saved_T2;
  697 +#endif
670 env = saved_env; 698 env = saved_env;
671 return ret; 699 return ret;
672 } 700 }
@@ -155,6 +155,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) @@ -155,6 +155,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
155 print_insn = print_insn_arm; 155 print_insn = print_insn_arm;
156 #elif defined(TARGET_SPARC) 156 #elif defined(TARGET_SPARC)
157 print_insn = print_insn_sparc; 157 print_insn = print_insn_sparc;
  158 +#ifdef TARGET_SPARC64
  159 + disasm_info.mach = bfd_mach_sparc_v9b;
  160 +#endif
158 #elif defined(TARGET_PPC) 161 #elif defined(TARGET_PPC)
159 if (cpu_single_env->msr[MSR_LE]) 162 if (cpu_single_env->msr[MSR_LE])
160 disasm_info.endian = BFD_ENDIAN_LITTLE; 163 disasm_info.endian = BFD_ENDIAN_LITTLE;
gdbstub.c
1 /* 1 /*
2 * gdb server stub 2 * gdb server stub
3 * 3 *
4 - * Copyright (c) 2003 Fabrice Bellard 4 + * Copyright (c) 2003-2005 Fabrice Bellard
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -293,7 +293,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -293,7 +293,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
293 #elif defined (TARGET_SPARC) 293 #elif defined (TARGET_SPARC)
294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
295 { 295 {
296 - uint32_t *registers = (uint32_t *)mem_buf, tmp; 296 + target_ulong *registers = (target_ulong *)mem_buf;
297 int i; 297 int i;
298 298
299 /* fill in g0..g7 */ 299 /* fill in g0..g7 */
@@ -308,10 +308,15 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -308,10 +308,15 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
308 for (i = 0; i < 32; i++) { 308 for (i = 0; i < 32; i++) {
309 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i])); 309 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
310 } 310 }
  311 +#ifndef TARGET_SPARC64
311 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 312 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
312 registers[64] = tswapl(env->y); 313 registers[64] = tswapl(env->y);
313 - tmp = GET_PSR(env);  
314 - registers[65] = tswapl(tmp); 314 + {
  315 + target_ulong tmp;
  316 +
  317 + tmp = GET_PSR(env);
  318 + registers[65] = tswapl(tmp);
  319 + }
315 registers[66] = tswapl(env->wim); 320 registers[66] = tswapl(env->wim);
316 registers[67] = tswapl(env->tbr); 321 registers[67] = tswapl(env->tbr);
317 registers[68] = tswapl(env->pc); 322 registers[68] = tswapl(env->pc);
@@ -319,13 +324,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -319,13 +324,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
319 registers[70] = tswapl(env->fsr); 324 registers[70] = tswapl(env->fsr);
320 registers[71] = 0; /* csr */ 325 registers[71] = 0; /* csr */
321 registers[72] = 0; 326 registers[72] = 0;
322 -  
323 - return 73 * 4; 327 + return 73 * sizeof(target_ulong);
  328 +#else
  329 + for (i = 0; i < 32; i += 2) {
  330 + registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));
  331 + }
  332 + registers[81] = tswapl(env->pc);
  333 + registers[82] = tswapl(env->npc);
  334 + registers[83] = tswapl(env->tstate[env->tl]);
  335 + registers[84] = tswapl(env->fsr);
  336 + registers[85] = tswapl(env->fprs);
  337 + registers[86] = tswapl(env->y);
  338 + return 87 * sizeof(target_ulong);
  339 +#endif
324 } 340 }
325 341
326 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) 342 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
327 { 343 {
328 - uint32_t *registers = (uint32_t *)mem_buf; 344 + target_ulong *registers = (target_ulong *)mem_buf;
329 int i; 345 int i;
330 346
331 /* fill in g0..g7 */ 347 /* fill in g0..g7 */
@@ -334,12 +350,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -334,12 +350,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
334 } 350 }
335 /* fill in register window */ 351 /* fill in register window */
336 for(i = 0; i < 24; i++) { 352 for(i = 0; i < 24; i++) {
337 - env->regwptr[i] = tswapl(registers[i]); 353 + env->regwptr[i] = tswapl(registers[i + 8]);
338 } 354 }
339 /* fill in fprs */ 355 /* fill in fprs */
340 for (i = 0; i < 32; i++) { 356 for (i = 0; i < 32; i++) {
341 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]); 357 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
342 } 358 }
  359 +#ifndef TARGET_SPARC64
343 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 360 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
344 env->y = tswapl(registers[64]); 361 env->y = tswapl(registers[64]);
345 PUT_PSR(env, tswapl(registers[65])); 362 PUT_PSR(env, tswapl(registers[65]));
@@ -348,6 +365,20 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -348,6 +365,20 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
348 env->pc = tswapl(registers[68]); 365 env->pc = tswapl(registers[68]);
349 env->npc = tswapl(registers[69]); 366 env->npc = tswapl(registers[69]);
350 env->fsr = tswapl(registers[70]); 367 env->fsr = tswapl(registers[70]);
  368 +#else
  369 + for (i = 0; i < 32; i += 2) {
  370 + uint64_t tmp;
  371 + tmp = tswapl(registers[i/2 + 64]) << 32;
  372 + tmp |= tswapl(registers[i/2 + 64 + 1]);
  373 + *((uint64_t *)&env->fpr[i]) = tmp;
  374 + }
  375 + env->pc = tswapl(registers[81]);
  376 + env->npc = tswapl(registers[82]);
  377 + env->tstate[env->tl] = tswapl(registers[83]);
  378 + env->fsr = tswapl(registers[84]);
  379 + env->fprs = tswapl(registers[85]);
  380 + env->y = tswapl(registers[86]);
  381 +#endif
351 } 382 }
352 #elif defined (TARGET_ARM) 383 #elif defined (TARGET_ARM)
353 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 384 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
hw/elf_ops.h 0 โ†’ 100644
  1 +#ifdef BSWAP_NEEDED
  2 +static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
  3 +{
  4 + bswap16s(&ehdr->e_type); /* Object file type */
  5 + bswap16s(&ehdr->e_machine); /* Architecture */
  6 + bswap32s(&ehdr->e_version); /* Object file version */
  7 + bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
  8 + bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
  9 + bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
  10 + bswap32s(&ehdr->e_flags); /* Processor-specific flags */
  11 + bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
  12 + bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
  13 + bswap16s(&ehdr->e_phnum); /* Program header table entry count */
  14 + bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
  15 + bswap16s(&ehdr->e_shnum); /* Section header table entry count */
  16 + bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
  17 +}
  18 +
  19 +static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
  20 +{
  21 + bswap32s(&phdr->p_type); /* Segment type */
  22 + bswapSZs(&phdr->p_offset); /* Segment file offset */
  23 + bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
  24 + bswapSZs(&phdr->p_paddr); /* Segment physical address */
  25 + bswapSZs(&phdr->p_filesz); /* Segment size in file */
  26 + bswapSZs(&phdr->p_memsz); /* Segment size in memory */
  27 + bswap32s(&phdr->p_flags); /* Segment flags */
  28 + bswapSZs(&phdr->p_align); /* Segment alignment */
  29 +}
  30 +
  31 +static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
  32 +{
  33 + bswap32s(&shdr->sh_name);
  34 + bswap32s(&shdr->sh_type);
  35 + bswapSZs(&shdr->sh_flags);
  36 + bswapSZs(&shdr->sh_addr);
  37 + bswapSZs(&shdr->sh_offset);
  38 + bswapSZs(&shdr->sh_size);
  39 + bswap32s(&shdr->sh_link);
  40 + bswap32s(&shdr->sh_info);
  41 + bswapSZs(&shdr->sh_addralign);
  42 + bswapSZs(&shdr->sh_entsize);
  43 +}
  44 +
  45 +static void glue(bswap_sym, SZ)(struct elf_sym *sym)
  46 +{
  47 + bswap32s(&sym->st_name);
  48 + bswapSZs(&sym->st_value);
  49 + bswapSZs(&sym->st_size);
  50 + bswap16s(&sym->st_shndx);
  51 +}
  52 +#endif
  53 +
  54 +static int glue(find_phdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, elf_word type)
  55 +{
  56 + int i, retval;
  57 +
  58 + retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
  59 + if (retval < 0)
  60 + return -1;
  61 +
  62 + for (i = 0; i < ehdr->e_phnum; i++) {
  63 + retval = read(fd, phdr, sizeof(*phdr));
  64 + if (retval < 0)
  65 + return -1;
  66 + glue(bswap_phdr, SZ)(phdr);
  67 + if (phdr->p_type == type)
  68 + return 0;
  69 + }
  70 + return -1;
  71 +}
  72 +
  73 +static void * glue(find_shdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
  74 +{
  75 + int i, retval;
  76 +
  77 + retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
  78 + if (retval < 0)
  79 + return NULL;
  80 +
  81 + for (i = 0; i < ehdr->e_shnum; i++) {
  82 + retval = read(fd, shdr, sizeof(*shdr));
  83 + if (retval < 0)
  84 + return NULL;
  85 + glue(bswap_shdr, SZ)(shdr);
  86 + if (shdr->sh_type == type)
  87 + return qemu_malloc(shdr->sh_size);
  88 + }
  89 + return NULL;
  90 +}
  91 +
  92 +static void * glue(find_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
  93 +{
  94 + int retval;
  95 +
  96 + retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
  97 + if (retval < 0)
  98 + return NULL;
  99 +
  100 + retval = read(fd, shdr, sizeof(*shdr));
  101 + if (retval < 0)
  102 + return NULL;
  103 + glue(bswap_shdr, SZ)(shdr);
  104 + if (shdr->sh_type == SHT_STRTAB)
  105 + return qemu_malloc(shdr->sh_size);;
  106 + return NULL;
  107 +}
  108 +
  109 +static int glue(read_program, SZ)(int fd, struct elf_phdr *phdr, void *dst, elf_word entry)
  110 +{
  111 + int retval;
  112 + retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);
  113 + if (retval < 0)
  114 + return -1;
  115 + return read(fd, dst, phdr->p_filesz);
  116 +}
  117 +
  118 +static int glue(read_section, SZ)(int fd, struct elf_shdr *s, void *dst)
  119 +{
  120 + int retval;
  121 +
  122 + retval = lseek(fd, s->sh_offset, SEEK_SET);
  123 + if (retval < 0)
  124 + return -1;
  125 + retval = read(fd, dst, s->sh_size);
  126 + if (retval < 0)
  127 + return -1;
  128 + return 0;
  129 +}
  130 +
  131 +static void * glue(process_section, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
  132 +{
  133 + void *dst;
  134 +
  135 + dst = glue(find_shdr, SZ)(ehdr, fd, shdr, type);
  136 + if (!dst)
  137 + goto error;
  138 +
  139 + if (glue(read_section, SZ)(fd, shdr, dst))
  140 + goto error;
  141 + return dst;
  142 + error:
  143 + qemu_free(dst);
  144 + return NULL;
  145 +}
  146 +
  147 +static void * glue(process_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
  148 +{
  149 + void *dst;
  150 +
  151 + dst = glue(find_strtab, SZ)(ehdr, fd, shdr, symtab);
  152 + if (!dst)
  153 + goto error;
  154 +
  155 + if (glue(read_section, SZ)(fd, shdr, dst))
  156 + goto error;
  157 + return dst;
  158 + error:
  159 + qemu_free(dst);
  160 + return NULL;
  161 +}
  162 +
  163 +static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd)
  164 +{
  165 + struct elf_shdr symtab, strtab;
  166 + struct elf_sym *syms;
  167 +#if (SZ == 64)
  168 + struct elf32_sym *syms32;
  169 +#endif
  170 + struct syminfo *s;
  171 + int nsyms, i;
  172 + char *str;
  173 +
  174 + /* Symbol table */
  175 + syms = glue(process_section, SZ)(ehdr, fd, &symtab, SHT_SYMTAB);
  176 + if (!syms)
  177 + return;
  178 +
  179 + nsyms = symtab.sh_size / sizeof(struct elf_sym);
  180 +#if (SZ == 64)
  181 + syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
  182 +#endif
  183 + for (i = 0; i < nsyms; i++) {
  184 + glue(bswap_sym, SZ)(&syms[i]);
  185 +#if (SZ == 64)
  186 + syms32[i].st_name = syms[i].st_name;
  187 + syms32[i].st_info = syms[i].st_info;
  188 + syms32[i].st_other = syms[i].st_other;
  189 + syms32[i].st_shndx = syms[i].st_shndx;
  190 + syms32[i].st_value = syms[i].st_value & 0xffffffff;
  191 + syms32[i].st_size = syms[i].st_size & 0xffffffff;
  192 +#endif
  193 + }
  194 + /* String table */
  195 + str = glue(process_strtab, SZ)(ehdr, fd, &strtab, &symtab);
  196 + if (!str)
  197 + goto error_freesyms;
  198 +
  199 + /* Commit */
  200 + s = qemu_mallocz(sizeof(*s));
  201 +#if (SZ == 64)
  202 + s->disas_symtab = syms32;
  203 + qemu_free(syms);
  204 +#else
  205 + s->disas_symtab = syms;
  206 +#endif
  207 + s->disas_num_syms = nsyms;
  208 + s->disas_strtab = str;
  209 + s->next = syminfos;
  210 + syminfos = s;
  211 + return;
  212 + error_freesyms:
  213 +#if (SZ == 64)
  214 + qemu_free(syms32);
  215 +#endif
  216 + qemu_free(syms);
  217 + return;
  218 +}
hw/magic-load.c
@@ -56,213 +56,49 @@ static void bswap_ahdr(struct exec *e) @@ -56,213 +56,49 @@ static void bswap_ahdr(struct exec *e)
56 56
57 #include "elf.h" 57 #include "elf.h"
58 58
59 -#ifdef BSWAP_NEEDED  
60 -static void bswap_ehdr(Elf32_Ehdr *ehdr)  
61 -{  
62 - bswap16s(&ehdr->e_type); /* Object file type */  
63 - bswap16s(&ehdr->e_machine); /* Architecture */  
64 - bswap32s(&ehdr->e_version); /* Object file version */  
65 - bswap32s(&ehdr->e_entry); /* Entry point virtual address */  
66 - bswap32s(&ehdr->e_phoff); /* Program header table file offset */  
67 - bswap32s(&ehdr->e_shoff); /* Section header table file offset */  
68 - bswap32s(&ehdr->e_flags); /* Processor-specific flags */  
69 - bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */  
70 - bswap16s(&ehdr->e_phentsize); /* Program header table entry size */  
71 - bswap16s(&ehdr->e_phnum); /* Program header table entry count */  
72 - bswap16s(&ehdr->e_shentsize); /* Section header table entry size */  
73 - bswap16s(&ehdr->e_shnum); /* Section header table entry count */  
74 - bswap16s(&ehdr->e_shstrndx); /* Section header string table index */  
75 -}  
76 -  
77 -static void bswap_phdr(Elf32_Phdr *phdr)  
78 -{  
79 - bswap32s(&phdr->p_type); /* Segment type */  
80 - bswap32s(&phdr->p_offset); /* Segment file offset */  
81 - bswap32s(&phdr->p_vaddr); /* Segment virtual address */  
82 - bswap32s(&phdr->p_paddr); /* Segment physical address */  
83 - bswap32s(&phdr->p_filesz); /* Segment size in file */  
84 - bswap32s(&phdr->p_memsz); /* Segment size in memory */  
85 - bswap32s(&phdr->p_flags); /* Segment flags */  
86 - bswap32s(&phdr->p_align); /* Segment alignment */  
87 -}  
88 -  
89 -static void bswap_shdr(Elf32_Shdr *shdr)  
90 -{  
91 - bswap32s(&shdr->sh_name);  
92 - bswap32s(&shdr->sh_type);  
93 - bswap32s(&shdr->sh_flags);  
94 - bswap32s(&shdr->sh_addr);  
95 - bswap32s(&shdr->sh_offset);  
96 - bswap32s(&shdr->sh_size);  
97 - bswap32s(&shdr->sh_link);  
98 - bswap32s(&shdr->sh_info);  
99 - bswap32s(&shdr->sh_addralign);  
100 - bswap32s(&shdr->sh_entsize);  
101 -}  
102 -  
103 -static void bswap_sym(Elf32_Sym *sym)  
104 -{  
105 - bswap32s(&sym->st_name);  
106 - bswap32s(&sym->st_value);  
107 - bswap32s(&sym->st_size);  
108 - bswap16s(&sym->st_shndx);  
109 -}  
110 -#else  
111 -#define bswap_ehdr(e) do { } while (0)  
112 -#define bswap_phdr(e) do { } while (0)  
113 -#define bswap_shdr(e) do { } while (0)  
114 -#define bswap_sym(e) do { } while (0) 59 +#ifndef BSWAP_NEEDED
  60 +#define bswap_ehdr32(e) do { } while (0)
  61 +#define bswap_phdr32(e) do { } while (0)
  62 +#define bswap_shdr32(e) do { } while (0)
  63 +#define bswap_sym32(e) do { } while (0)
  64 +#ifdef TARGET_SPARC64
  65 +#define bswap_ehdr64(e) do { } while (0)
  66 +#define bswap_phdr64(e) do { } while (0)
  67 +#define bswap_shdr64(e) do { } while (0)
  68 +#define bswap_sym64(e) do { } while (0)
  69 +#endif
115 #endif 70 #endif
116 71
117 -static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type)  
118 -{  
119 - int i, retval;  
120 -  
121 - retval = lseek(fd, ehdr->e_phoff, SEEK_SET);  
122 - if (retval < 0)  
123 - return -1;  
124 -  
125 - for (i = 0; i < ehdr->e_phnum; i++) {  
126 - retval = read(fd, phdr, sizeof(*phdr));  
127 - if (retval < 0)  
128 - return -1;  
129 - bswap_phdr(phdr);  
130 - if (phdr->p_type == type)  
131 - return 0;  
132 - }  
133 - return -1;  
134 -}  
135 -  
136 -static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  
137 -{  
138 - int i, retval;  
139 -  
140 - retval = lseek(fd, ehdr->e_shoff, SEEK_SET);  
141 - if (retval < 0)  
142 - return NULL;  
143 -  
144 - for (i = 0; i < ehdr->e_shnum; i++) {  
145 - retval = read(fd, shdr, sizeof(*shdr));  
146 - if (retval < 0)  
147 - return NULL;  
148 - bswap_shdr(shdr);  
149 - if (shdr->sh_type == type)  
150 - return qemu_malloc(shdr->sh_size);  
151 - }  
152 - return NULL;  
153 -}  
154 -  
155 -static void *find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
156 -{  
157 - int retval;  
158 -  
159 - retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);  
160 - if (retval < 0)  
161 - return NULL;  
162 -  
163 - retval = read(fd, shdr, sizeof(*shdr));  
164 - if (retval < 0)  
165 - return NULL;  
166 - bswap_shdr(shdr);  
167 - if (shdr->sh_type == SHT_STRTAB)  
168 - return qemu_malloc(shdr->sh_size);;  
169 - return NULL;  
170 -}  
171 -  
172 -static int read_program(int fd, struct elf_phdr *phdr, void *dst, uint32_t entry)  
173 -{  
174 - int retval;  
175 - retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);  
176 - if (retval < 0)  
177 - return -1;  
178 - return read(fd, dst, phdr->p_filesz);  
179 -}  
180 -  
181 -static int read_section(int fd, struct elf_shdr *s, void *dst)  
182 -{  
183 - int retval;  
184 -  
185 - retval = lseek(fd, s->sh_offset, SEEK_SET);  
186 - if (retval < 0)  
187 - return -1;  
188 - retval = read(fd, dst, s->sh_size);  
189 - if (retval < 0)  
190 - return -1;  
191 - return 0;  
192 -}  
193 -  
194 -static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  
195 -{  
196 - void *dst;  
197 -  
198 - dst = find_shdr(ehdr, fd, shdr, type);  
199 - if (!dst)  
200 - goto error;  
201 -  
202 - if (read_section(fd, shdr, dst))  
203 - goto error;  
204 - return dst;  
205 - error:  
206 - qemu_free(dst);  
207 - return NULL;  
208 -}  
209 -  
210 -static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
211 -{  
212 - void *dst;  
213 -  
214 - dst = find_strtab(ehdr, fd, shdr, symtab);  
215 - if (!dst)  
216 - goto error;  
217 -  
218 - if (read_section(fd, shdr, dst))  
219 - goto error;  
220 - return dst;  
221 - error:  
222 - qemu_free(dst);  
223 - return NULL;  
224 -}  
225 -  
226 -static void load_symbols(struct elfhdr *ehdr, int fd)  
227 -{  
228 - struct elf_shdr symtab, strtab;  
229 - struct elf_sym *syms;  
230 - struct syminfo *s;  
231 - int nsyms, i;  
232 - char *str;  
233 -  
234 - /* Symbol table */  
235 - syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB);  
236 - if (!syms)  
237 - return;  
238 -  
239 - nsyms = symtab.sh_size / sizeof(struct elf_sym);  
240 - for (i = 0; i < nsyms; i++)  
241 - bswap_sym(&syms[i]);  
242 -  
243 - /* String table */  
244 - str = process_strtab(ehdr, fd, &strtab, &symtab);  
245 - if (!str)  
246 - goto error_freesyms;  
247 -  
248 - /* Commit */  
249 - s = qemu_mallocz(sizeof(*s));  
250 - s->disas_symtab = syms;  
251 - s->disas_num_syms = nsyms;  
252 - s->disas_strtab = str;  
253 - s->next = syminfos;  
254 - syminfos = s;  
255 - return;  
256 - error_freesyms:  
257 - qemu_free(syms);  
258 - return;  
259 -} 72 +#define SZ 32
  73 +#define elf_word uint32_t
  74 +#define bswapSZs bswap32s
  75 +#include "elf_ops.h"
  76 +
  77 +#ifdef TARGET_SPARC64
  78 +#undef elfhdr
  79 +#undef elf_phdr
  80 +#undef elf_shdr
  81 +#undef elf_sym
  82 +#undef elf_note
  83 +#undef elf_word
  84 +#undef bswapSZs
  85 +#undef SZ
  86 +#define elfhdr elf64_hdr
  87 +#define elf_phdr elf64_phdr
  88 +#define elf_note elf64_note
  89 +#define elf_shdr elf64_shdr
  90 +#define elf_sym elf64_sym
  91 +#define elf_word uint64_t
  92 +#define bswapSZs bswap64s
  93 +#define SZ 64
  94 +#include "elf_ops.h"
  95 +#endif
260 96
261 int load_elf(const char *filename, uint8_t *addr) 97 int load_elf(const char *filename, uint8_t *addr)
262 { 98 {
263 - struct elfhdr ehdr;  
264 - struct elf_phdr phdr; 99 + struct elf32_hdr ehdr;
265 int retval, fd; 100 int retval, fd;
  101 + Elf32_Half machine;
266 102
267 fd = open(filename, O_RDONLY | O_BINARY); 103 fd = open(filename, O_RDONLY | O_BINARY);
268 if (fd < 0) 104 if (fd < 0)
@@ -272,21 +108,43 @@ int load_elf(const char *filename, uint8_t *addr) @@ -272,21 +108,43 @@ int load_elf(const char *filename, uint8_t *addr)
272 if (retval < 0) 108 if (retval < 0)
273 goto error; 109 goto error;
274 110
275 - bswap_ehdr(&ehdr);  
276 -  
277 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' 111 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
278 - || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'  
279 - || (ehdr.e_machine != EM_SPARC  
280 - && ehdr.e_machine != EM_SPARC32PLUS)) 112 + || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
281 goto error; 113 goto error;
  114 + machine = tswap16(ehdr.e_machine);
  115 + if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
  116 + struct elf32_phdr phdr;
282 117
283 - if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))  
284 - goto error;  
285 - retval = read_program(fd, &phdr, addr, ehdr.e_entry);  
286 - if (retval < 0)  
287 - goto error; 118 + bswap_ehdr32(&ehdr);
288 119
289 - load_symbols(&ehdr, fd); 120 + if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
  121 + goto error;
  122 + retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
  123 + if (retval < 0)
  124 + goto error;
  125 + load_symbols32(&ehdr, fd);
  126 + }
  127 +#ifdef TARGET_SPARC64
  128 + else if (machine == EM_SPARCV9) {
  129 + struct elf64_hdr ehdr64;
  130 + struct elf64_phdr phdr;
  131 +
  132 + lseek(fd, 0, SEEK_SET);
  133 +
  134 + retval = read(fd, &ehdr64, sizeof(ehdr64));
  135 + if (retval < 0)
  136 + goto error;
  137 +
  138 + bswap_ehdr64(&ehdr64);
  139 +
  140 + if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
  141 + goto error;
  142 + retval = read_program64(fd, &phdr, addr, ehdr64.e_entry);
  143 + if (retval < 0)
  144 + goto error;
  145 + load_symbols64(&ehdr64, fd);
  146 + }
  147 +#endif
290 148
291 close(fd); 149 close(fd);
292 return retval; 150 return retval;
hw/slavio_intctl.c
@@ -144,14 +144,14 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uin @@ -144,14 +144,14 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uin
144 switch (saddr) { 144 switch (saddr) {
145 case 2: // clear (enable) 145 case 2: // clear (enable)
146 // Force clear unused bits 146 // Force clear unused bits
147 - val &= ~0x7fb2007f; 147 + val &= ~0x4fb2007f;
148 s->intregm_disabled &= ~val; 148 s->intregm_disabled &= ~val;
149 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 149 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
150 slavio_check_interrupts(s); 150 slavio_check_interrupts(s);
151 break; 151 break;
152 case 3: // set (disable, clear pending) 152 case 3: // set (disable, clear pending)
153 // Force clear unused bits 153 // Force clear unused bits
154 - val &= ~0x7fb2007f; 154 + val &= ~0x4fb2007f;
155 s->intregm_disabled |= val; 155 s->intregm_disabled |= val;
156 s->intregm_pending &= ~val; 156 s->intregm_pending &= ~val;
157 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 157 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
@@ -208,7 +208,7 @@ void slavio_irq_info(void *opaque) @@ -208,7 +208,7 @@ void slavio_irq_info(void *opaque)
208 208
209 static const uint32_t intbit_to_level[32] = { 209 static const uint32_t intbit_to_level[32] = {
210 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, 210 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
211 - 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0, 211 + 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
212 }; 212 };
213 213
214 static void slavio_check_interrupts(void *opaque) 214 static void slavio_check_interrupts(void *opaque)
hw/slavio_misc.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sparc SLAVIO aux io port emulation
  3 + *
  4 + * Copyright (c) 2005 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +/* debug misc */
  26 +//#define DEBUG_MISC
  27 +
  28 +/*
  29 + * This is the auxio port, chip control and system control part of
  30 + * chip STP2001 (Slave I/O), also produced as NCR89C105. See
  31 + * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  32 + *
  33 + * This also includes the PMC CPU idle controller.
  34 + */
  35 +
  36 +#ifdef DEBUG_MISC
  37 +#define MISC_DPRINTF(fmt, args...) \
  38 +do { printf("MISC: " fmt , ##args); } while (0)
  39 +#else
  40 +#define MISC_DPRINTF(fmt, args...)
  41 +#endif
  42 +
  43 +typedef struct MiscState {
  44 + int irq;
  45 + uint8_t config;
  46 + uint8_t aux1, aux2;
  47 + uint8_t diag, mctrl;
  48 +} MiscState;
  49 +
  50 +#define MISC_MAXADDR 1
  51 +
  52 +static void slavio_misc_update_irq(void *opaque)
  53 +{
  54 + MiscState *s = opaque;
  55 +
  56 + if ((s->aux2 & 0x4) && (s->config & 0x8)) {
  57 + pic_set_irq(s->irq, 1);
  58 + } else {
  59 + pic_set_irq(s->irq, 0);
  60 + }
  61 +}
  62 +
  63 +static void slavio_misc_reset(void *opaque)
  64 +{
  65 + MiscState *s = opaque;
  66 +
  67 + // Diagnostic register not cleared in reset
  68 + s->config = s->aux1 = s->aux2 = s->mctrl = 0;
  69 +}
  70 +
  71 +void slavio_set_power_fail(void *opaque, int power_failing)
  72 +{
  73 + MiscState *s = opaque;
  74 +
  75 + MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
  76 + if (power_failing && (s->config & 0x8)) {
  77 + s->aux2 |= 0x4;
  78 + } else {
  79 + s->aux2 &= ~0x4;
  80 + }
  81 + slavio_misc_update_irq(s);
  82 +}
  83 +
  84 +static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  85 +{
  86 + MiscState *s = opaque;
  87 +
  88 + switch (addr & 0xfff0000) {
  89 + case 0x1800000:
  90 + MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
  91 + s->config = val & 0xff;
  92 + slavio_misc_update_irq(s);
  93 + break;
  94 + case 0x1900000:
  95 + MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
  96 + s->aux1 = val & 0xff;
  97 + break;
  98 + case 0x1910000:
  99 + val &= 0x3;
  100 + MISC_DPRINTF("Write aux2 %2.2x\n", val);
  101 + val |= s->aux2 & 0x4;
  102 + if (val & 0x2) // Clear Power Fail int
  103 + val &= 0x1;
  104 + s->aux2 = val;
  105 + if (val & 1)
  106 + qemu_system_shutdown_request();
  107 + slavio_misc_update_irq(s);
  108 + break;
  109 + case 0x1a00000:
  110 + MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
  111 + s->diag = val & 0xff;
  112 + break;
  113 + case 0x1b00000:
  114 + MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
  115 + s->mctrl = val & 0xff;
  116 + break;
  117 + case 0x1f00000:
  118 + MISC_DPRINTF("Write system control %2.2x\n", val & 0xff);
  119 + if (val & 1)
  120 + qemu_system_reset_request();
  121 + break;
  122 + case 0xa000000:
  123 + MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
  124 +#if 0
  125 + // XXX: halting CPU does not work
  126 + raise_exception(EXCP_HLT);
  127 + cpu_loop_exit();
  128 +#endif
  129 + break;
  130 + }
  131 +}
  132 +
  133 +static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
  134 +{
  135 + MiscState *s = opaque;
  136 + uint32_t ret = 0;
  137 +
  138 + switch (addr & 0xfff0000) {
  139 + case 0x1800000:
  140 + ret = s->config;
  141 + MISC_DPRINTF("Read config %2.2x\n", ret);
  142 + break;
  143 + case 0x1900000:
  144 + ret = s->aux1;
  145 + MISC_DPRINTF("Read aux1 %2.2x\n", ret);
  146 + break;
  147 + case 0x1910000:
  148 + ret = s->aux2;
  149 + MISC_DPRINTF("Read aux2 %2.2x\n", ret);
  150 + break;
  151 + case 0x1a00000:
  152 + ret = s->diag;
  153 + MISC_DPRINTF("Read diag %2.2x\n", ret);
  154 + break;
  155 + case 0x1b00000:
  156 + ret = s->mctrl;
  157 + MISC_DPRINTF("Read modem control %2.2x\n", ret);
  158 + break;
  159 + case 0x1f00000:
  160 + MISC_DPRINTF("Read system control %2.2x\n", ret);
  161 + break;
  162 + case 0xa000000:
  163 + MISC_DPRINTF("Read power management %2.2x\n", ret);
  164 + break;
  165 + }
  166 + return ret;
  167 +}
  168 +
  169 +static CPUReadMemoryFunc *slavio_misc_mem_read[3] = {
  170 + slavio_misc_mem_readb,
  171 + slavio_misc_mem_readb,
  172 + slavio_misc_mem_readb,
  173 +};
  174 +
  175 +static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
  176 + slavio_misc_mem_writeb,
  177 + slavio_misc_mem_writeb,
  178 + slavio_misc_mem_writeb,
  179 +};
  180 +
  181 +static void slavio_misc_save(QEMUFile *f, void *opaque)
  182 +{
  183 + MiscState *s = opaque;
  184 +
  185 + qemu_put_be32s(f, &s->irq);
  186 + qemu_put_8s(f, &s->config);
  187 + qemu_put_8s(f, &s->aux1);
  188 + qemu_put_8s(f, &s->aux2);
  189 + qemu_put_8s(f, &s->diag);
  190 + qemu_put_8s(f, &s->mctrl);
  191 +}
  192 +
  193 +static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
  194 +{
  195 + MiscState *s = opaque;
  196 +
  197 + if (version_id != 1)
  198 + return -EINVAL;
  199 +
  200 + qemu_get_be32s(f, &s->irq);
  201 + qemu_get_8s(f, &s->config);
  202 + qemu_get_8s(f, &s->aux1);
  203 + qemu_get_8s(f, &s->aux2);
  204 + qemu_get_8s(f, &s->diag);
  205 + qemu_get_8s(f, &s->mctrl);
  206 + return 0;
  207 +}
  208 +
  209 +void *slavio_misc_init(uint32_t base, int irq)
  210 +{
  211 + int slavio_misc_io_memory;
  212 + MiscState *s;
  213 +
  214 + s = qemu_mallocz(sizeof(MiscState));
  215 + if (!s)
  216 + return NULL;
  217 +
  218 + slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
  219 + // Slavio control
  220 + cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory);
  221 + // AUX 1
  222 + cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory);
  223 + // AUX 2
  224 + cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory);
  225 + // Diagnostics
  226 + cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory);
  227 + // Modem control
  228 + cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory);
  229 + // System control
  230 + cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory);
  231 + // Power management
  232 + cpu_register_physical_memory(base + 0xa000000, MISC_MAXADDR, slavio_misc_io_memory);
  233 +
  234 + s->irq = irq;
  235 +
  236 + register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
  237 + qemu_register_reset(slavio_misc_reset, s);
  238 + slavio_misc_reset(s);
  239 + return s;
  240 +}
hw/sun4m.c
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 // bits 37 // bits
38 #define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */ 38 #define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */
39 #define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */ 39 #define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */
  40 +#define PHYS_JJ_SLAVIO 0x70000000 /* Slavio base */
40 #define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */ 41 #define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */
41 #define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */ 42 #define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */
42 #define PHYS_JJ_ESP_IRQ 18 43 #define PHYS_JJ_ESP_IRQ 18
@@ -55,6 +56,7 @@ @@ -55,6 +56,7 @@
55 #define PHYS_JJ_SER_IRQ 15 56 #define PHYS_JJ_SER_IRQ 15
56 #define PHYS_JJ_FDC 0x71400000 /* Floppy */ 57 #define PHYS_JJ_FDC 0x71400000 /* Floppy */
57 #define PHYS_JJ_FLOPPY_IRQ 22 58 #define PHYS_JJ_FLOPPY_IRQ 22
  59 +#define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */
58 60
59 /* TSC handling */ 61 /* TSC handling */
60 62
@@ -202,6 +204,13 @@ uint32_t iommu_translate(uint32_t addr) @@ -202,6 +204,13 @@ uint32_t iommu_translate(uint32_t addr)
202 return iommu_translate_local(iommu, addr); 204 return iommu_translate_local(iommu, addr);
203 } 205 }
204 206
  207 +static void *slavio_misc;
  208 +
  209 +void qemu_system_powerdown(void)
  210 +{
  211 + slavio_set_power_fail(slavio_misc, 1);
  212 +}
  213 +
205 /* Sun4m hardware initialisation */ 214 /* Sun4m hardware initialisation */
206 static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, 215 static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
207 DisplayState *ds, const char **fd_filename, int snapshot, 216 DisplayState *ds, const char **fd_filename, int snapshot,
@@ -230,6 +239,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, @@ -230,6 +239,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
230 slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]); 239 slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
231 fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table); 240 fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table);
232 esp_init(bs_table, PHYS_JJ_ESP_IRQ, PHYS_JJ_ESP, PHYS_JJ_ESPDMA); 241 esp_init(bs_table, PHYS_JJ_ESP_IRQ, PHYS_JJ_ESP, PHYS_JJ_ESPDMA);
  242 + slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ);
233 243
234 prom_offset = ram_size + vram_size; 244 prom_offset = ram_size + vram_size;
235 245
hw/sun4u.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sun4u System Emulator
  3 + *
  4 + * Copyright (c) 2005 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +#include "m48t08.h"
  26 +
  27 +#define KERNEL_LOAD_ADDR 0x00004000
  28 +#define CMDLINE_ADDR 0x007ff000
  29 +#define INITRD_LOAD_ADDR 0x00800000
  30 +#define PROM_ADDR 0xffd00000
  31 +#define PROM_FILENAMEB "proll-sparc64.bin"
  32 +#define PROM_FILENAMEE "proll-sparc64.elf"
  33 +#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */
  34 +#define PHYS_JJ_IDPROM_OFF 0x1FD8
  35 +#define PHYS_JJ_EEPROM_SIZE 0x2000
  36 +// IRQs are not PIL ones, but master interrupt controller register
  37 +// bits
  38 +#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */
  39 +#define PHYS_JJ_MS_KBD_IRQ 14
  40 +#define PHYS_JJ_SER 0x71100000 /* Serial */
  41 +#define PHYS_JJ_SER_IRQ 15
  42 +
  43 +/* TSC handling */
  44 +
  45 +uint64_t cpu_get_tsc()
  46 +{
  47 + return qemu_get_clock(vm_clock);
  48 +}
  49 +
  50 +int DMA_get_channel_mode (int nchan)
  51 +{
  52 + return 0;
  53 +}
  54 +int DMA_read_memory (int nchan, void *buf, int pos, int size)
  55 +{
  56 + return 0;
  57 +}
  58 +int DMA_write_memory (int nchan, void *buf, int pos, int size)
  59 +{
  60 + return 0;
  61 +}
  62 +void DMA_hold_DREQ (int nchan) {}
  63 +void DMA_release_DREQ (int nchan) {}
  64 +void DMA_schedule(int nchan) {}
  65 +void DMA_run (void) {}
  66 +void DMA_init (int high_page_enable) {}
  67 +void DMA_register_channel (int nchan,
  68 + DMA_transfer_handler transfer_handler,
  69 + void *opaque)
  70 +{
  71 +}
  72 +
  73 +static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)
  74 +{
  75 + m48t08_write(nvram, addr++, (value >> 8) & 0xff);
  76 + m48t08_write(nvram, addr++, value & 0xff);
  77 +}
  78 +
  79 +static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)
  80 +{
  81 + m48t08_write(nvram, addr++, value >> 24);
  82 + m48t08_write(nvram, addr++, (value >> 16) & 0xff);
  83 + m48t08_write(nvram, addr++, (value >> 8) & 0xff);
  84 + m48t08_write(nvram, addr++, value & 0xff);
  85 +}
  86 +
  87 +static void nvram_set_string (m48t08_t *nvram, uint32_t addr,
  88 + const unsigned char *str, uint32_t max)
  89 +{
  90 + unsigned int i;
  91 +
  92 + for (i = 0; i < max && str[i] != '\0'; i++) {
  93 + m48t08_write(nvram, addr + i, str[i]);
  94 + }
  95 + m48t08_write(nvram, addr + max - 1, '\0');
  96 +}
  97 +
  98 +static m48t08_t *nvram;
  99 +
  100 +extern int nographic;
  101 +
  102 +static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,
  103 + int boot_device, uint32_t RAM_size,
  104 + uint32_t kernel_size,
  105 + int width, int height, int depth)
  106 +{
  107 + unsigned char tmp = 0;
  108 + int i, j;
  109 +
  110 + // Try to match PPC NVRAM
  111 + nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
  112 + nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */
  113 + // NVRAM_size, arch not applicable
  114 + m48t08_write(nvram, 0x2F, nographic & 0xff);
  115 + nvram_set_lword(nvram, 0x30, RAM_size);
  116 + m48t08_write(nvram, 0x34, boot_device & 0xff);
  117 + nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR);
  118 + nvram_set_lword(nvram, 0x3C, kernel_size);
  119 + if (cmdline) {
  120 + strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
  121 + nvram_set_lword(nvram, 0x40, CMDLINE_ADDR);
  122 + nvram_set_lword(nvram, 0x44, strlen(cmdline));
  123 + }
  124 + // initrd_image, initrd_size passed differently
  125 + nvram_set_word(nvram, 0x54, width);
  126 + nvram_set_word(nvram, 0x56, height);
  127 + nvram_set_word(nvram, 0x58, depth);
  128 +
  129 + // Sun4m specific use
  130 + i = 0x1fd8;
  131 + m48t08_write(nvram, i++, 0x01);
  132 + m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
  133 + j = 0;
  134 + m48t08_write(nvram, i++, macaddr[j++]);
  135 + m48t08_write(nvram, i++, macaddr[j++]);
  136 + m48t08_write(nvram, i++, macaddr[j++]);
  137 + m48t08_write(nvram, i++, macaddr[j++]);
  138 + m48t08_write(nvram, i++, macaddr[j++]);
  139 + m48t08_write(nvram, i, macaddr[j]);
  140 +
  141 + /* Calculate checksum */
  142 + for (i = 0x1fd8; i < 0x1fe7; i++) {
  143 + tmp ^= m48t08_read(nvram, i);
  144 + }
  145 + m48t08_write(nvram, 0x1fe7, tmp);
  146 +}
  147 +
  148 +void pic_info()
  149 +{
  150 +}
  151 +
  152 +void irq_info()
  153 +{
  154 +}
  155 +
  156 +void pic_set_irq(int irq, int level)
  157 +{
  158 +}
  159 +
  160 +void vga_update_display()
  161 +{
  162 +}
  163 +
  164 +void vga_invalidate_display()
  165 +{
  166 +}
  167 +
  168 +void vga_screen_dump(const char *filename)
  169 +{
  170 +}
  171 +
  172 +void qemu_system_powerdown(void)
  173 +{
  174 +}
  175 +
  176 +/* Sun4u hardware initialisation */
  177 +static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
  178 + DisplayState *ds, const char **fd_filename, int snapshot,
  179 + const char *kernel_filename, const char *kernel_cmdline,
  180 + const char *initrd_filename)
  181 +{
  182 + char buf[1024];
  183 + int ret, linux_boot;
  184 + unsigned int i;
  185 + long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
  186 +
  187 + linux_boot = (kernel_filename != NULL);
  188 +
  189 + /* allocate RAM */
  190 + cpu_register_physical_memory(0, ram_size, 0);
  191 +
  192 + nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
  193 + // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
  194 + // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
  195 + slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
  196 +
  197 + prom_offset = ram_size + vram_size;
  198 +
  199 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
  200 + ret = load_elf(buf, phys_ram_base + prom_offset);
  201 + if (ret < 0) {
  202 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
  203 + ret = load_image(buf, phys_ram_base + prom_offset);
  204 + }
  205 + if (ret < 0) {
  206 + fprintf(stderr, "qemu: could not load prom '%s'\n",
  207 + buf);
  208 + exit(1);
  209 + }
  210 + cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
  211 + prom_offset | IO_MEM_ROM);
  212 +
  213 + kernel_size = 0;
  214 + if (linux_boot) {
  215 + kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  216 + if (kernel_size < 0)
  217 + kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  218 + if (kernel_size < 0)
  219 + kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  220 + if (kernel_size < 0) {
  221 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  222 + kernel_filename);
  223 + exit(1);
  224 + }
  225 +
  226 + /* load initrd */
  227 + initrd_size = 0;
  228 + if (initrd_filename) {
  229 + initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
  230 + if (initrd_size < 0) {
  231 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
  232 + initrd_filename);
  233 + exit(1);
  234 + }
  235 + }
  236 + if (initrd_size > 0) {
  237 + for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
  238 + if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
  239 + == 0x48647253) { // HdrS
  240 + stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
  241 + stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
  242 + break;
  243 + }
  244 + }
  245 + }
  246 + }
  247 + nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
  248 +}
  249 +
  250 +QEMUMachine sun4u_machine = {
  251 + "sun4u",
  252 + "Sun4u platform",
  253 + sun4u_init,
  254 +};
linux-user/main.c
@@ -552,6 +552,7 @@ void cpu_loop (CPUSPARCState *env) @@ -552,6 +552,7 @@ void cpu_loop (CPUSPARCState *env)
552 env->pc = env->npc; 552 env->pc = env->npc;
553 env->npc = env->npc + 4; 553 env->npc = env->npc + 4;
554 break; 554 break;
  555 +#ifndef TARGET_SPARC64
555 case TT_WIN_OVF: /* window overflow */ 556 case TT_WIN_OVF: /* window overflow */
556 save_window(env); 557 save_window(env);
557 break; 558 break;
@@ -569,6 +570,9 @@ void cpu_loop (CPUSPARCState *env) @@ -569,6 +570,9 @@ void cpu_loop (CPUSPARCState *env)
569 queue_signal(info.si_signo, &info); 570 queue_signal(info.si_signo, &info);
570 } 571 }
571 break; 572 break;
  573 +#else
  574 + // XXX
  575 +#endif
572 case 0x100: // XXX, why do we get these? 576 case 0x100: // XXX, why do we get these?
573 break; 577 break;
574 case EXCP_DEBUG: 578 case EXCP_DEBUG:
monitor.c
@@ -767,6 +767,11 @@ static void do_system_reset(void) @@ -767,6 +767,11 @@ static void do_system_reset(void)
767 qemu_system_reset_request(); 767 qemu_system_reset_request();
768 } 768 }
769 769
  770 +static void do_system_powerdown(void)
  771 +{
  772 + qemu_system_powerdown_request();
  773 +}
  774 +
770 #if defined(TARGET_I386) 775 #if defined(TARGET_I386)
771 static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask) 776 static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
772 { 777 {
@@ -922,6 +927,8 @@ static term_cmd_t term_cmds[] = { @@ -922,6 +927,8 @@ static term_cmd_t term_cmds[] = {
922 "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, 927 "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
923 { "system_reset", "", do_system_reset, 928 { "system_reset", "", do_system_reset,
924 "", "reset the system" }, 929 "", "reset the system" },
  930 + { "system_powerdown", "", do_system_powerdown,
  931 + "", "send system power down event" },
925 { "sum", "ii", do_sum, 932 { "sum", "ii", do_sum,
926 "addr size", "compute the checksum of a memory region" }, 933 "addr size", "compute the checksum of a memory region" },
927 { NULL, NULL, }, 934 { NULL, NULL, },
qemu-doc.texi
@@ -42,10 +42,11 @@ For system emulation, the following hardware targets are supported: @@ -42,10 +42,11 @@ For system emulation, the following hardware targets are supported:
42 @item PC (x86 processor) 42 @item PC (x86 processor)
43 @item PREP (PowerPC processor) 43 @item PREP (PowerPC processor)
44 @item PowerMac (PowerPC processor, in progress) 44 @item PowerMac (PowerPC processor, in progress)
45 -@item Sun4m (Sparc processor, in progress) 45 +@item Sun4m (32-bit Sparc processor)
  46 +@item Sun4u (64-bit Sparc processor, in progress)
46 @end itemize 47 @end itemize
47 48
48 -For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported. 49 +For user emulation, x86, PowerPC, ARM, and Sparc32/64 CPUs are supported.
49 50
50 @chapter Installation 51 @chapter Installation
51 52
@@ -999,15 +1000,15 @@ Set the initial VGA graphic mode. The default is 800x600x15. @@ -999,15 +1000,15 @@ Set the initial VGA graphic mode. The default is 800x600x15.
999 More information is available at 1000 More information is available at
1000 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}. 1001 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}.
1001 1002
1002 -@chapter Sparc System emulator invocation 1003 +@chapter Sparc32 System emulator invocation
1003 1004
1004 Use the executable @file{qemu-system-sparc} to simulate a JavaStation 1005 Use the executable @file{qemu-system-sparc} to simulate a JavaStation
1005 -(sun4m architecture). The emulation is far from complete. 1006 +(sun4m architecture). The emulation is somewhat complete.
1006 1007
1007 QEMU emulates the following sun4m peripherals: 1008 QEMU emulates the following sun4m peripherals:
1008 1009
1009 @itemize @minus 1010 @itemize @minus
1010 -@item 1011 +@item
1011 IOMMU 1012 IOMMU
1012 @item 1013 @item
1013 TCX Frame buffer 1014 TCX Frame buffer
@@ -1016,14 +1017,42 @@ Lance (Am7990) Ethernet @@ -1016,14 +1017,42 @@ Lance (Am7990) Ethernet
1016 @item 1017 @item
1017 Non Volatile RAM M48T08 1018 Non Volatile RAM M48T08
1018 @item 1019 @item
1019 -Slave I/O: timers, interrupt controllers, Zilog serial ports 1020 +Slave I/O: timers, interrupt controllers, Zilog serial ports, keyboard
  1021 +and power/reset logic
  1022 +@item
  1023 +ESP SCSI controller with hard disk and CD-ROM support
  1024 +@item
  1025 +Floppy drive
1020 @end itemize 1026 @end itemize
1021 1027
  1028 +The number of peripherals is fixed in the architecture.
  1029 +
1022 QEMU uses the Proll, a PROM replacement available at 1030 QEMU uses the Proll, a PROM replacement available at
1023 -@url{http://people.redhat.com/zaitcev/linux/}. 1031 +@url{http://people.redhat.com/zaitcev/linux/}. The required
  1032 +QEMU-specific patches are included with the sources.
  1033 +
  1034 +A sample Linux 2.6 series kernel and ram disk image are available on
  1035 +the QEMU web site. Please note that currently neither Linux 2.4
  1036 +series, NetBSD, nor OpenBSD kernels work.
  1037 +
  1038 +@c man begin OPTIONS
  1039 +
  1040 +The following options are specific to the Sparc emulation:
  1041 +
  1042 +@table @option
  1043 +
  1044 +@item -g WxH
  1045 +
  1046 +Set the initial TCX graphic mode. The default is 1024x768.
  1047 +
  1048 +@end table
  1049 +
  1050 +@c man end
  1051 +
  1052 +@chapter Sparc64 System emulator invocation
1024 1053
1025 -A sample Linux kernel and ram disk image are available on the QEMU web  
1026 -site. 1054 +Use the executable @file{qemu-system-sparc64} to simulate a Sun4u machine.
  1055 +The emulator is not usable for anything yet.
1027 1056
1028 @chapter QEMU User space emulator invocation 1057 @chapter QEMU User space emulator invocation
1029 1058
qemu-tech.texi
@@ -138,9 +138,32 @@ FPU and MMU. @@ -138,9 +138,32 @@ FPU and MMU.
138 @itemize 138 @itemize
139 139
140 @item Somewhat complete SPARC V8 emulation, including privileged 140 @item Somewhat complete SPARC V8 emulation, including privileged
141 -instructions, FPU and MMU. 141 +instructions, FPU and MMU. SPARC V9 emulation includes most privileged
  142 +instructions, FPU and I/D MMU, but misses VIS instructions.
142 143
143 -@item Can run some SPARC Linux binaries. 144 +@item Can run some 32-bit SPARC Linux binaries.
  145 +
  146 +@end itemize
  147 +
  148 +Current QEMU limitations:
  149 +
  150 +@itemize
  151 +
  152 +@item Tagged add/subtract instructions are not supported, but they are
  153 +probably not used.
  154 +
  155 +@item IPC syscalls are missing.
  156 +
  157 +@item 128-bit floating point operations are not supported, though none of the
  158 +real CPUs implement them either. FCMPE[SD] are not correctly
  159 +implemented. Floating point exception support is untested.
  160 +
  161 +@item Alignment is not enforced at all.
  162 +
  163 +@item Atomic instructions are not correctly implemented.
  164 +
  165 +@item Sparc64 emulators are not usable for anything yet.
  166 +Address space is limited to first 4 gigabytes.
144 167
145 @end itemize 168 @end itemize
146 169
target-sparc/cpu.h
@@ -6,12 +6,11 @@ @@ -6,12 +6,11 @@
6 #if !defined(TARGET_SPARC64) 6 #if !defined(TARGET_SPARC64)
7 #define TARGET_LONG_BITS 32 7 #define TARGET_LONG_BITS 32
8 #define TARGET_FPREGS 32 8 #define TARGET_FPREGS 32
9 -#define TARGET_FPREG_T float  
10 #else 9 #else
11 #define TARGET_LONG_BITS 64 10 #define TARGET_LONG_BITS 64
12 #define TARGET_FPREGS 64 11 #define TARGET_FPREGS 64
13 -#define TARGET_FPREG_T double  
14 #endif 12 #endif
  13 +#define TARGET_FPREG_T float
15 14
16 #include "cpu-defs.h" 15 #include "cpu-defs.h"
17 16
@@ -22,6 +21,7 @@ @@ -22,6 +21,7 @@
22 /*#define EXCP_INTERRUPT 0x100*/ 21 /*#define EXCP_INTERRUPT 0x100*/
23 22
24 /* trap definitions */ 23 /* trap definitions */
  24 +#ifndef TARGET_SPARC64
25 #define TT_TFAULT 0x01 25 #define TT_TFAULT 0x01
26 #define TT_ILL_INSN 0x02 26 #define TT_ILL_INSN 0x02
27 #define TT_PRIV_INSN 0x03 27 #define TT_PRIV_INSN 0x03
@@ -33,6 +33,21 @@ @@ -33,6 +33,21 @@
33 #define TT_EXTINT 0x10 33 #define TT_EXTINT 0x10
34 #define TT_DIV_ZERO 0x2a 34 #define TT_DIV_ZERO 0x2a
35 #define TT_TRAP 0x80 35 #define TT_TRAP 0x80
  36 +#else
  37 +#define TT_TFAULT 0x08
  38 +#define TT_ILL_INSN 0x10
  39 +#define TT_PRIV_INSN 0x11
  40 +#define TT_NFPU_INSN 0x20
  41 +#define TT_FP_EXCP 0x21
  42 +#define TT_CLRWIN 0x24
  43 +#define TT_DIV_ZERO 0x28
  44 +#define TT_DFAULT 0x30
  45 +#define TT_EXTINT 0x40
  46 +#define TT_SPILL 0x80
  47 +#define TT_FILL 0xc0
  48 +#define TT_WOTHER 0x10
  49 +#define TT_TRAP 0x100
  50 +#endif
36 51
37 #define PSR_NEG (1<<23) 52 #define PSR_NEG (1<<23)
38 #define PSR_ZERO (1<<22) 53 #define PSR_ZERO (1<<22)
@@ -49,6 +64,13 @@ @@ -49,6 +64,13 @@
49 /* Trap base register */ 64 /* Trap base register */
50 #define TBR_BASE_MASK 0xfffff000 65 #define TBR_BASE_MASK 0xfffff000
51 66
  67 +#if defined(TARGET_SPARC64)
  68 +#define PS_PEF (1<<4)
  69 +#define PS_AM (1<<3)
  70 +#define PS_PRIV (1<<2)
  71 +#define PS_IE (1<<1)
  72 +#endif
  73 +
52 /* Fcc */ 74 /* Fcc */
53 #define FSR_RD1 (1<<31) 75 #define FSR_RD1 (1<<31)
54 #define FSR_RD0 (1<<30) 76 #define FSR_RD0 (1<<30)
@@ -119,15 +141,15 @@ typedef struct CPUSPARCState { @@ -119,15 +141,15 @@ typedef struct CPUSPARCState {
119 target_ulong npc; /* next program counter */ 141 target_ulong npc; /* next program counter */
120 target_ulong y; /* multiply/divide register */ 142 target_ulong y; /* multiply/divide register */
121 uint32_t psr; /* processor state register */ 143 uint32_t psr; /* processor state register */
122 - uint32_t fsr; /* FPU state register */ 144 + target_ulong fsr; /* FPU state register */
123 uint32_t cwp; /* index of current register window (extracted 145 uint32_t cwp; /* index of current register window (extracted
124 from PSR) */ 146 from PSR) */
125 uint32_t wim; /* window invalid mask */ 147 uint32_t wim; /* window invalid mask */
126 - uint32_t tbr; /* trap base register */ 148 + target_ulong tbr; /* trap base register */
127 int psrs; /* supervisor mode (extracted from PSR) */ 149 int psrs; /* supervisor mode (extracted from PSR) */
128 int psrps; /* previous supervisor mode */ 150 int psrps; /* previous supervisor mode */
129 int psret; /* enable traps */ 151 int psret; /* enable traps */
130 - int psrpil; /* interrupt level */ 152 + uint32_t psrpil; /* interrupt level */
131 int psref; /* enable fpu */ 153 int psref; /* enable fpu */
132 jmp_buf jmp_env; 154 jmp_buf jmp_env;
133 int user_mode_only; 155 int user_mode_only;
@@ -150,13 +172,43 @@ typedef struct CPUSPARCState { @@ -150,13 +172,43 @@ typedef struct CPUSPARCState {
150 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; 172 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
151 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; 173 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
152 /* MMU regs */ 174 /* MMU regs */
  175 +#if defined(TARGET_SPARC64)
  176 + uint64_t lsu;
  177 +#define DMMU_E 0x8
  178 +#define IMMU_E 0x4
  179 + uint64_t immuregs[16];
  180 + uint64_t dmmuregs[16];
  181 + uint64_t itlb_tag[64];
  182 + uint64_t itlb_tte[64];
  183 + uint64_t dtlb_tag[64];
  184 + uint64_t dtlb_tte[64];
  185 +#else
153 uint32_t mmuregs[16]; 186 uint32_t mmuregs[16];
  187 +#endif
154 /* temporary float registers */ 188 /* temporary float registers */
155 - float ft0, ft1, ft2;  
156 - double dt0, dt1, dt2; 189 + float ft0, ft1;
  190 + double dt0, dt1;
157 float_status fp_status; 191 float_status fp_status;
158 #if defined(TARGET_SPARC64) 192 #if defined(TARGET_SPARC64)
159 - target_ulong t0, t1, t2; 193 +#define MAXTL 4
  194 + uint64_t t0, t1, t2;
  195 + uint64_t tpc[MAXTL];
  196 + uint64_t tnpc[MAXTL];
  197 + uint64_t tstate[MAXTL];
  198 + uint32_t tt[MAXTL];
  199 + uint32_t xcc; /* Extended integer condition codes */
  200 + uint32_t asi;
  201 + uint32_t pstate;
  202 + uint32_t tl;
  203 + uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
  204 + target_ulong agregs[8]; /* alternate general registers */
  205 + target_ulong igregs[8]; /* interrupt general registers */
  206 + target_ulong mgregs[8]; /* mmu general registers */
  207 + uint64_t version;
  208 + uint64_t fprs;
  209 +#endif
  210 +#if !defined(TARGET_SPARC64) && !defined(reg_T2)
  211 + target_ulong t2;
160 #endif 212 #endif
161 213
162 /* ice debug support */ 214 /* ice debug support */
@@ -165,6 +217,24 @@ typedef struct CPUSPARCState { @@ -165,6 +217,24 @@ typedef struct CPUSPARCState {
165 int singlestep_enabled; /* XXX: should use CPU single step mode instead */ 217 int singlestep_enabled; /* XXX: should use CPU single step mode instead */
166 218
167 } CPUSPARCState; 219 } CPUSPARCState;
  220 +#if defined(TARGET_SPARC64)
  221 +#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
  222 +#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
  223 + env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
  224 + } while (0)
  225 +#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
  226 +#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
  227 + env->fsr = _tmp & 0x3fcfc1c3ffULL; \
  228 + } while (0)
  229 +// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II)
  230 +#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) | \
  231 + (0 << 24) | (MAXTL << 8) | (NWINDOWS - 1))
  232 +#else
  233 +#define GET_FSR32(env) (env->fsr)
  234 +#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
  235 + env->fsr = _tmp & 0xcfc1ffff; \
  236 + } while (0)
  237 +#endif
168 238
169 CPUSPARCState *cpu_sparc_init(void); 239 CPUSPARCState *cpu_sparc_init(void);
170 int cpu_sparc_exec(CPUSPARCState *s); 240 int cpu_sparc_exec(CPUSPARCState *s);
@@ -194,6 +264,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); @@ -194,6 +264,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
194 cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \ 264 cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \
195 } while (0) 265 } while (0)
196 266
  267 +#ifdef TARGET_SPARC64
  268 +#define GET_CCR(env) ((env->xcc << 4) | (env->psr & PSR_ICC))
  269 +#define PUT_CCR(env, val) do { int _tmp = val; \
  270 + env->xcc = _tmp >> 4; \
  271 + env->psr = (_tmp & 0xf) << 20; \
  272 + } while (0)
  273 +#endif
  274 +
197 struct siginfo; 275 struct siginfo;
198 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc); 276 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
199 277
target-sparc/exec.h
1 #ifndef EXEC_SPARC_H 1 #ifndef EXEC_SPARC_H
2 #define EXEC_SPARC_H 1 2 #define EXEC_SPARC_H 1
3 #include "dyngen-exec.h" 3 #include "dyngen-exec.h"
  4 +#include "config.h"
4 5
5 register struct CPUSPARCState *env asm(AREG0); 6 register struct CPUSPARCState *env asm(AREG0);
6 #ifdef TARGET_SPARC64 7 #ifdef TARGET_SPARC64
7 #define T0 (env->t0) 8 #define T0 (env->t0)
8 #define T1 (env->t1) 9 #define T1 (env->t1)
9 #define T2 (env->t2) 10 #define T2 (env->t2)
  11 +#define REGWPTR env->regwptr
10 #else 12 #else
11 register uint32_t T0 asm(AREG1); 13 register uint32_t T0 asm(AREG1);
12 register uint32_t T1 asm(AREG2); 14 register uint32_t T1 asm(AREG2);
  15 +
  16 +#undef REG_REGWPTR // Broken
  17 +#ifdef REG_REGWPTR
  18 +register uint32_t *REGWPTR asm(AREG3);
  19 +#define reg_REGWPTR
  20 +
  21 +#ifdef AREG4
  22 +register uint32_t T2 asm(AREG4);
  23 +#define reg_T2
  24 +#else
  25 +#define T2 (env->t2)
  26 +#endif
  27 +
  28 +#else
  29 +#define REGWPTR env->regwptr
13 register uint32_t T2 asm(AREG3); 30 register uint32_t T2 asm(AREG3);
  31 +#define reg_T2
  32 +#endif
14 #endif 33 #endif
  34 +
15 #define FT0 (env->ft0) 35 #define FT0 (env->ft0)
16 #define FT1 (env->ft1) 36 #define FT1 (env->ft1)
17 -#define FT2 (env->ft2)  
18 #define DT0 (env->dt0) 37 #define DT0 (env->dt0)
19 #define DT1 (env->dt1) 38 #define DT1 (env->dt1)
20 -#define DT2 (env->dt2)  
21 39
22 #include "cpu.h" 40 #include "cpu.h"
23 #include "exec-all.h" 41 #include "exec-all.h"
@@ -38,6 +56,16 @@ void do_fsqrts(void); @@ -38,6 +56,16 @@ void do_fsqrts(void);
38 void do_fsqrtd(void); 56 void do_fsqrtd(void);
39 void do_fcmps(void); 57 void do_fcmps(void);
40 void do_fcmpd(void); 58 void do_fcmpd(void);
  59 +#ifdef TARGET_SPARC64
  60 +void do_fabsd(void);
  61 +void do_fcmps_fcc1(void);
  62 +void do_fcmpd_fcc1(void);
  63 +void do_fcmps_fcc2(void);
  64 +void do_fcmpd_fcc2(void);
  65 +void do_fcmps_fcc3(void);
  66 +void do_fcmpd_fcc3(void);
  67 +void do_popc();
  68 +#endif
41 void do_ldd_kernel(target_ulong addr); 69 void do_ldd_kernel(target_ulong addr);
42 void do_ldd_user(target_ulong addr); 70 void do_ldd_user(target_ulong addr);
43 void do_ldd_raw(target_ulong addr); 71 void do_ldd_raw(target_ulong addr);
target-sparc/fbranch_template.h 0 โ†’ 100644
  1 +/* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */
  2 +
  3 +void OPPROTO glue(op_eval_fbne, FCC)(void)
  4 +{
  5 +// !0
  6 + T2 = FFLAG_SET(FSR_FCC0) | FFLAG_SET(FSR_FCC1); /* L or G or U */
  7 +}
  8 +
  9 +void OPPROTO glue(op_eval_fblg, FCC)(void)
  10 +{
  11 +// 1 or 2
  12 + T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1);
  13 +}
  14 +
  15 +void OPPROTO glue(op_eval_fbul, FCC)(void)
  16 +{
  17 +// 1 or 3
  18 + T2 = FFLAG_SET(FSR_FCC0);
  19 +}
  20 +
  21 +void OPPROTO glue(op_eval_fbl, FCC)(void)
  22 +{
  23 +// 1
  24 + T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1);
  25 +}
  26 +
  27 +void OPPROTO glue(op_eval_fbug, FCC)(void)
  28 +{
  29 +// 2 or 3
  30 + T2 = FFLAG_SET(FSR_FCC1);
  31 +}
  32 +
  33 +void OPPROTO glue(op_eval_fbg, FCC)(void)
  34 +{
  35 +// 2
  36 + T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1);
  37 +}
  38 +
  39 +void OPPROTO glue(op_eval_fbu, FCC)(void)
  40 +{
  41 +// 3
  42 + T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1);
  43 +}
  44 +
  45 +void OPPROTO glue(op_eval_fbe, FCC)(void)
  46 +{
  47 +// 0
  48 + T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1);
  49 +}
  50 +
  51 +void OPPROTO glue(op_eval_fbue, FCC)(void)
  52 +{
  53 +// 0 or 3
  54 + T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0));
  55 + FORCE_RET();
  56 +}
  57 +
  58 +void OPPROTO glue(op_eval_fbge, FCC)(void)
  59 +{
  60 +// 0 or 2
  61 + T2 = !FFLAG_SET(FSR_FCC0);
  62 +}
  63 +
  64 +void OPPROTO glue(op_eval_fbuge, FCC)(void)
  65 +{
  66 +// !1
  67 + T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1));
  68 +}
  69 +
  70 +void OPPROTO glue(op_eval_fble, FCC)(void)
  71 +{
  72 +// 0 or 1
  73 + T2 = !FFLAG_SET(FSR_FCC1);
  74 +}
  75 +
  76 +void OPPROTO glue(op_eval_fbule, FCC)(void)
  77 +{
  78 +// !2
  79 + T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1));
  80 +}
  81 +
  82 +void OPPROTO glue(op_eval_fbo, FCC)(void)
  83 +{
  84 +// !3
  85 + T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1));
  86 +}
  87 +
  88 +#undef FCC
  89 +#undef FFLAG_SET
target-sparc/fop_template.h
@@ -40,16 +40,6 @@ void OPPROTO glue(op_store_FT1_fpr_fpr, REGNAME)(void) @@ -40,16 +40,6 @@ void OPPROTO glue(op_store_FT1_fpr_fpr, REGNAME)(void)
40 REG = FT1; 40 REG = FT1;
41 } 41 }
42 42
43 -void OPPROTO glue(op_load_fpr_FT2_fpr, REGNAME)(void)  
44 -{  
45 - FT2 = REG;  
46 -}  
47 -  
48 -void OPPROTO glue(op_store_FT2_fpr_fpr, REGNAME)(void)  
49 -{  
50 - REG = FT2;  
51 -}  
52 -  
53 /* double floating point registers moves */ 43 /* double floating point registers moves */
54 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void) 44 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void)
55 { 45 {
@@ -87,23 +77,5 @@ void OPPROTO glue(op_store_DT1_fpr_fpr, REGNAME)(void) @@ -87,23 +77,5 @@ void OPPROTO glue(op_store_DT1_fpr_fpr, REGNAME)(void)
87 *p = u.l.upper; 77 *p = u.l.upper;
88 } 78 }
89 79
90 -void OPPROTO glue(op_load_fpr_DT2_fpr, REGNAME)(void)  
91 -{  
92 - CPU_DoubleU u;  
93 - uint32_t *p = (uint32_t *)&REG;  
94 - u.l.lower = *(p +1);  
95 - u.l.upper = *p;  
96 - DT2 = u.d;  
97 -}  
98 -  
99 -void OPPROTO glue(op_store_DT2_fpr_fpr, REGNAME)(void)  
100 -{  
101 - CPU_DoubleU u;  
102 - uint32_t *p = (uint32_t *)&REG;  
103 - u.d = DT2;  
104 - *(p +1) = u.l.lower;  
105 - *p = u.l.upper;  
106 -}  
107 -  
108 #undef REG 80 #undef REG
109 #undef REGNAME 81 #undef REGNAME
target-sparc/helper.c
@@ -43,7 +43,6 @@ void cpu_unlock(void) @@ -43,7 +43,6 @@ void cpu_unlock(void)
43 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, 43 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44 int is_user, int is_softmmu) 44 int is_user, int is_softmmu)
45 { 45 {
46 - env->mmuregs[4] = address;  
47 if (rw & 2) 46 if (rw & 2)
48 env->exception_index = TT_TFAULT; 47 env->exception_index = TT_TFAULT;
49 else 48 else
@@ -102,6 +101,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -102,6 +101,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
102 env = saved_env; 101 env = saved_env;
103 } 102 }
104 103
  104 +#ifndef TARGET_SPARC64
105 static const int access_table[8][8] = { 105 static const int access_table[8][8] = {
106 { 0, 0, 0, 0, 2, 0, 3, 3 }, 106 { 0, 0, 0, 0, 2, 0, 3, 3 },
107 { 0, 0, 0, 0, 2, 0, 0, 0 }, 107 { 0, 0, 0, 0, 2, 0, 0, 0 },
@@ -268,6 +268,136 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -268,6 +268,136 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
268 return 1; 268 return 1;
269 } 269 }
270 } 270 }
  271 +#else
  272 +static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
  273 + int *access_index, target_ulong address, int rw,
  274 + int is_user)
  275 +{
  276 + target_ulong mask;
  277 + unsigned int i;
  278 +
  279 + if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
  280 + *physical = address & 0xffffffff;
  281 + *prot = PAGE_READ | PAGE_WRITE;
  282 + return 0;
  283 + }
  284 +
  285 + for (i = 0; i < 64; i++) {
  286 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
  287 + switch (env->dtlb_tte[i] >> 60) {
  288 + default:
  289 + case 0x4: // 8k
  290 + mask = 0xffffffffffffe000ULL;
  291 + break;
  292 + case 0x5: // 64k
  293 + mask = 0xffffffffffff0000ULL;
  294 + break;
  295 + case 0x6: // 512k
  296 + mask = 0xfffffffffff80000ULL;
  297 + break;
  298 + case 0x7: // 4M
  299 + mask = 0xffffffffffc00000ULL;
  300 + break;
  301 + }
  302 + // ctx match, vaddr match?
  303 + if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
  304 + (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
  305 + // access ok?
  306 + if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||
  307 + (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
  308 + env->exception_index = TT_DFAULT;
  309 + return 1;
  310 + }
  311 + *physical = env->dtlb_tte[i] & 0xffffe000;
  312 + *prot = PAGE_READ;
  313 + if (env->dtlb_tte[i] & 0x2)
  314 + *prot |= PAGE_WRITE;
  315 + return 0;
  316 + }
  317 + }
  318 + }
  319 + env->exception_index = TT_DFAULT;
  320 + return 1;
  321 +}
  322 +
  323 +static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
  324 + int *access_index, target_ulong address, int rw,
  325 + int is_user)
  326 +{
  327 + target_ulong mask;
  328 + unsigned int i;
  329 +
  330 + if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
  331 + *physical = address & 0xffffffff;
  332 + *prot = PAGE_READ;
  333 + return 0;
  334 + }
  335 + for (i = 0; i < 64; i++) {
  336 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
  337 + switch (env->itlb_tte[i] >> 60) {
  338 + default:
  339 + case 0x4: // 8k
  340 + mask = 0xffffffffffffe000ULL;
  341 + break;
  342 + case 0x5: // 64k
  343 + mask = 0xffffffffffff0000ULL;
  344 + break;
  345 + case 0x6: // 512k
  346 + mask = 0xfffffffffff80000ULL;
  347 + break;
  348 + case 0x7: // 4M
  349 + mask = 0xffffffffffc00000ULL;
  350 + break;
  351 + }
  352 + // ctx match, vaddr match?
  353 + if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
  354 + (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
  355 + // access ok?
  356 + if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {
  357 + env->exception_index = TT_TFAULT;
  358 + return 1;
  359 + }
  360 + *physical = env->itlb_tte[i] & 0xffffe000;
  361 + *prot = PAGE_READ;
  362 + return 0;
  363 + }
  364 + }
  365 + }
  366 + env->exception_index = TT_TFAULT;
  367 + return 1;
  368 +}
  369 +
  370 +int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
  371 + int *access_index, target_ulong address, int rw,
  372 + int is_user)
  373 +{
  374 + if (rw == 2)
  375 + return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
  376 + else
  377 + return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
  378 +}
  379 +
  380 +/* Perform address translation */
  381 +int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  382 + int is_user, int is_softmmu)
  383 +{
  384 + target_ulong virt_addr;
  385 + target_phys_addr_t paddr;
  386 + unsigned long vaddr;
  387 + int error_code = 0, prot, ret = 0, access_index;
  388 +
  389 + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
  390 + if (error_code == 0) {
  391 + virt_addr = address & TARGET_PAGE_MASK;
  392 + vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
  393 + ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
  394 + return ret;
  395 + }
  396 + // XXX
  397 + return 1;
  398 +}
  399 +
  400 +#endif
271 #endif 401 #endif
272 402
273 void memcpy32(target_ulong *dst, const target_ulong *src) 403 void memcpy32(target_ulong *dst, const target_ulong *src)
@@ -292,17 +422,73 @@ void set_cwp(int new_cwp) @@ -292,17 +422,73 @@ void set_cwp(int new_cwp)
292 if (new_cwp == (NWINDOWS - 1)) 422 if (new_cwp == (NWINDOWS - 1))
293 memcpy32(env->regbase + NWINDOWS * 16, env->regbase); 423 memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
294 env->regwptr = env->regbase + (new_cwp * 16); 424 env->regwptr = env->regbase + (new_cwp * 16);
  425 + REGWPTR = env->regwptr;
295 } 426 }
296 427
297 void cpu_set_cwp(CPUState *env1, int new_cwp) 428 void cpu_set_cwp(CPUState *env1, int new_cwp)
298 { 429 {
299 CPUState *saved_env; 430 CPUState *saved_env;
  431 +#ifdef reg_REGWPTR
  432 + target_ulong *saved_regwptr;
  433 +#endif
  434 +
300 saved_env = env; 435 saved_env = env;
  436 +#ifdef reg_REGWPTR
  437 + saved_regwptr = REGWPTR;
  438 +#endif
301 env = env1; 439 env = env1;
302 set_cwp(new_cwp); 440 set_cwp(new_cwp);
303 env = saved_env; 441 env = saved_env;
  442 +#ifdef reg_REGWPTR
  443 + REGWPTR = saved_regwptr;
  444 +#endif
304 } 445 }
305 446
  447 +#ifdef TARGET_SPARC64
  448 +void do_interrupt(int intno)
  449 +{
  450 +#ifdef DEBUG_PCALL
  451 + if (loglevel & CPU_LOG_INT) {
  452 + static int count;
  453 + fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
  454 + count, intno,
  455 + env->pc,
  456 + env->npc, env->regwptr[6]);
  457 + cpu_dump_state(env, logfile, fprintf, 0);
  458 +#if 0
  459 + {
  460 + int i;
  461 + uint8_t *ptr;
  462 +
  463 + fprintf(logfile, " code=");
  464 + ptr = (uint8_t *)env->pc;
  465 + for(i = 0; i < 16; i++) {
  466 + fprintf(logfile, " %02x", ldub(ptr + i));
  467 + }
  468 + fprintf(logfile, "\n");
  469 + }
  470 +#endif
  471 + count++;
  472 + }
  473 +#endif
  474 +#if !defined(CONFIG_USER_ONLY)
  475 + if (env->pstate & PS_IE) {
  476 + cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
  477 + return;
  478 + }
  479 +#endif
  480 + env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
  481 + ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
  482 + env->tpc[env->tl] = env->pc;
  483 + env->tnpc[env->tl] = env->npc;
  484 + env->tt[env->tl] = intno;
  485 + env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
  486 + env->tl++;
  487 + env->pc = env->tbr;
  488 + env->npc = env->pc + 4;
  489 + env->exception_index = 0;
  490 +}
  491 +#else
306 void do_interrupt(int intno) 492 void do_interrupt(int intno)
307 { 493 {
308 int cwp; 494 int cwp;
@@ -448,3 +634,4 @@ void dump_mmu(void) @@ -448,3 +634,4 @@ void dump_mmu(void)
448 printf("MMU dump ends\n"); 634 printf("MMU dump ends\n");
449 } 635 }
450 #endif 636 #endif
  637 +#endif
target-sparc/op.c
@@ -46,76 +46,76 @@ @@ -46,76 +46,76 @@
46 #define REG (env->gregs[7]) 46 #define REG (env->gregs[7])
47 #include "op_template.h" 47 #include "op_template.h"
48 #define REGNAME i0 48 #define REGNAME i0
49 -#define REG (env->regwptr[16]) 49 +#define REG (REGWPTR[16])
50 #include "op_template.h" 50 #include "op_template.h"
51 #define REGNAME i1 51 #define REGNAME i1
52 -#define REG (env->regwptr[17]) 52 +#define REG (REGWPTR[17])
53 #include "op_template.h" 53 #include "op_template.h"
54 #define REGNAME i2 54 #define REGNAME i2
55 -#define REG (env->regwptr[18]) 55 +#define REG (REGWPTR[18])
56 #include "op_template.h" 56 #include "op_template.h"
57 #define REGNAME i3 57 #define REGNAME i3
58 -#define REG (env->regwptr[19]) 58 +#define REG (REGWPTR[19])
59 #include "op_template.h" 59 #include "op_template.h"
60 #define REGNAME i4 60 #define REGNAME i4
61 -#define REG (env->regwptr[20]) 61 +#define REG (REGWPTR[20])
62 #include "op_template.h" 62 #include "op_template.h"
63 #define REGNAME i5 63 #define REGNAME i5
64 -#define REG (env->regwptr[21]) 64 +#define REG (REGWPTR[21])
65 #include "op_template.h" 65 #include "op_template.h"
66 #define REGNAME i6 66 #define REGNAME i6
67 -#define REG (env->regwptr[22]) 67 +#define REG (REGWPTR[22])
68 #include "op_template.h" 68 #include "op_template.h"
69 #define REGNAME i7 69 #define REGNAME i7
70 -#define REG (env->regwptr[23]) 70 +#define REG (REGWPTR[23])
71 #include "op_template.h" 71 #include "op_template.h"
72 #define REGNAME l0 72 #define REGNAME l0
73 -#define REG (env->regwptr[8]) 73 +#define REG (REGWPTR[8])
74 #include "op_template.h" 74 #include "op_template.h"
75 #define REGNAME l1 75 #define REGNAME l1
76 -#define REG (env->regwptr[9]) 76 +#define REG (REGWPTR[9])
77 #include "op_template.h" 77 #include "op_template.h"
78 #define REGNAME l2 78 #define REGNAME l2
79 -#define REG (env->regwptr[10]) 79 +#define REG (REGWPTR[10])
80 #include "op_template.h" 80 #include "op_template.h"
81 #define REGNAME l3 81 #define REGNAME l3
82 -#define REG (env->regwptr[11]) 82 +#define REG (REGWPTR[11])
83 #include "op_template.h" 83 #include "op_template.h"
84 #define REGNAME l4 84 #define REGNAME l4
85 -#define REG (env->regwptr[12]) 85 +#define REG (REGWPTR[12])
86 #include "op_template.h" 86 #include "op_template.h"
87 #define REGNAME l5 87 #define REGNAME l5
88 -#define REG (env->regwptr[13]) 88 +#define REG (REGWPTR[13])
89 #include "op_template.h" 89 #include "op_template.h"
90 #define REGNAME l6 90 #define REGNAME l6
91 -#define REG (env->regwptr[14]) 91 +#define REG (REGWPTR[14])
92 #include "op_template.h" 92 #include "op_template.h"
93 #define REGNAME l7 93 #define REGNAME l7
94 -#define REG (env->regwptr[15]) 94 +#define REG (REGWPTR[15])
95 #include "op_template.h" 95 #include "op_template.h"
96 #define REGNAME o0 96 #define REGNAME o0
97 -#define REG (env->regwptr[0]) 97 +#define REG (REGWPTR[0])
98 #include "op_template.h" 98 #include "op_template.h"
99 #define REGNAME o1 99 #define REGNAME o1
100 -#define REG (env->regwptr[1]) 100 +#define REG (REGWPTR[1])
101 #include "op_template.h" 101 #include "op_template.h"
102 #define REGNAME o2 102 #define REGNAME o2
103 -#define REG (env->regwptr[2]) 103 +#define REG (REGWPTR[2])
104 #include "op_template.h" 104 #include "op_template.h"
105 #define REGNAME o3 105 #define REGNAME o3
106 -#define REG (env->regwptr[3]) 106 +#define REG (REGWPTR[3])
107 #include "op_template.h" 107 #include "op_template.h"
108 #define REGNAME o4 108 #define REGNAME o4
109 -#define REG (env->regwptr[4]) 109 +#define REG (REGWPTR[4])
110 #include "op_template.h" 110 #include "op_template.h"
111 #define REGNAME o5 111 #define REGNAME o5
112 -#define REG (env->regwptr[5]) 112 +#define REG (REGWPTR[5])
113 #include "op_template.h" 113 #include "op_template.h"
114 #define REGNAME o6 114 #define REGNAME o6
115 -#define REG (env->regwptr[6]) 115 +#define REG (REGWPTR[6])
116 #include "op_template.h" 116 #include "op_template.h"
117 #define REGNAME o7 117 #define REGNAME o7
118 -#define REG (env->regwptr[7]) 118 +#define REG (REGWPTR[7])
119 #include "op_template.h" 119 #include "op_template.h"
120 120
121 #define REGNAME f0 121 #define REGNAME f0
@@ -215,10 +215,106 @@ @@ -215,10 +215,106 @@
215 #define REG (env->fpr[31]) 215 #define REG (env->fpr[31])
216 #include "fop_template.h" 216 #include "fop_template.h"
217 217
  218 +#ifdef TARGET_SPARC64
  219 +#define REGNAME f32
  220 +#define REG (env->fpr[32])
  221 +#include "fop_template.h"
  222 +#define REGNAME f34
  223 +#define REG (env->fpr[34])
  224 +#include "fop_template.h"
  225 +#define REGNAME f36
  226 +#define REG (env->fpr[36])
  227 +#include "fop_template.h"
  228 +#define REGNAME f38
  229 +#define REG (env->fpr[38])
  230 +#include "fop_template.h"
  231 +#define REGNAME f40
  232 +#define REG (env->fpr[40])
  233 +#include "fop_template.h"
  234 +#define REGNAME f42
  235 +#define REG (env->fpr[42])
  236 +#include "fop_template.h"
  237 +#define REGNAME f44
  238 +#define REG (env->fpr[44])
  239 +#include "fop_template.h"
  240 +#define REGNAME f46
  241 +#define REG (env->fpr[46])
  242 +#include "fop_template.h"
  243 +#define REGNAME f48
  244 +#define REG (env->fpr[47])
  245 +#include "fop_template.h"
  246 +#define REGNAME f50
  247 +#define REG (env->fpr[50])
  248 +#include "fop_template.h"
  249 +#define REGNAME f52
  250 +#define REG (env->fpr[52])
  251 +#include "fop_template.h"
  252 +#define REGNAME f54
  253 +#define REG (env->fpr[54])
  254 +#include "fop_template.h"
  255 +#define REGNAME f56
  256 +#define REG (env->fpr[56])
  257 +#include "fop_template.h"
  258 +#define REGNAME f58
  259 +#define REG (env->fpr[58])
  260 +#include "fop_template.h"
  261 +#define REGNAME f60
  262 +#define REG (env->fpr[60])
  263 +#include "fop_template.h"
  264 +#define REGNAME f62
  265 +#define REG (env->fpr[62])
  266 +#include "fop_template.h"
  267 +#endif
  268 +
  269 +#ifdef TARGET_SPARC64
  270 +#undef JUMP_TB
  271 +#define JUMP_TB(opname, tbparam, n, eip) \
  272 + do { \
  273 + GOTO_TB(opname, tbparam, n); \
  274 + T0 = (long)(tbparam) + (n); \
  275 + env->pc = (eip) & 0xffffffff; \
  276 + EXIT_TB(); \
  277 + } while (0)
  278 +
  279 +#ifdef WORDS_BIGENDIAN
  280 +typedef union UREG64 {
  281 + struct { uint16_t v3, v2, v1, v0; } w;
  282 + struct { uint32_t v1, v0; } l;
  283 + uint64_t q;
  284 +} UREG64;
  285 +#else
  286 +typedef union UREG64 {
  287 + struct { uint16_t v0, v1, v2, v3; } w;
  288 + struct { uint32_t v0, v1; } l;
  289 + uint64_t q;
  290 +} UREG64;
  291 +#endif
  292 +
  293 +#define PARAMQ1 \
  294 +({\
  295 + UREG64 __p;\
  296 + __p.l.v1 = PARAM1;\
  297 + __p.l.v0 = PARAM2;\
  298 + __p.q;\
  299 +})
  300 +
  301 +void OPPROTO op_movq_T0_im64(void)
  302 +{
  303 + T0 = PARAMQ1;
  304 +}
  305 +
  306 +void OPPROTO op_movq_T1_im64(void)
  307 +{
  308 + T1 = PARAMQ1;
  309 +}
  310 +
  311 +#define XFLAG_SET(x) ((env->xcc&x)?1:0)
  312 +
  313 +#else
218 #define EIP (env->pc) 314 #define EIP (env->pc)
  315 +#endif
219 316
220 #define FLAG_SET(x) ((env->psr&x)?1:0) 317 #define FLAG_SET(x) ((env->psr&x)?1:0)
221 -#define FFLAG_SET(x) ((env->fsr&x)?1:0)  
222 318
223 void OPPROTO op_movl_T0_0(void) 319 void OPPROTO op_movl_T0_0(void)
224 { 320 {
@@ -227,17 +323,52 @@ void OPPROTO op_movl_T0_0(void) @@ -227,17 +323,52 @@ void OPPROTO op_movl_T0_0(void)
227 323
228 void OPPROTO op_movl_T0_im(void) 324 void OPPROTO op_movl_T0_im(void)
229 { 325 {
230 - T0 = PARAM1; 326 + T0 = (uint32_t)PARAM1;
231 } 327 }
232 328
233 void OPPROTO op_movl_T1_im(void) 329 void OPPROTO op_movl_T1_im(void)
234 { 330 {
235 - T1 = PARAM1; 331 + T1 = (uint32_t)PARAM1;
236 } 332 }
237 333
238 void OPPROTO op_movl_T2_im(void) 334 void OPPROTO op_movl_T2_im(void)
239 { 335 {
240 - T2 = PARAM1; 336 + T2 = (uint32_t)PARAM1;
  337 +}
  338 +
  339 +void OPPROTO op_movl_T0_sim(void)
  340 +{
  341 + T0 = (int32_t)PARAM1;
  342 +}
  343 +
  344 +void OPPROTO op_movl_T1_sim(void)
  345 +{
  346 + T1 = (int32_t)PARAM1;
  347 +}
  348 +
  349 +void OPPROTO op_movl_T2_sim(void)
  350 +{
  351 + T2 = (int32_t)PARAM1;
  352 +}
  353 +
  354 +void OPPROTO op_movl_T0_env(void)
  355 +{
  356 + T0 = *(uint32_t *)((char *)env + PARAM1);
  357 +}
  358 +
  359 +void OPPROTO op_movl_env_T0(void)
  360 +{
  361 + *(uint32_t *)((char *)env + PARAM1) = T0;
  362 +}
  363 +
  364 +void OPPROTO op_movtl_T0_env(void)
  365 +{
  366 + T0 = *(target_ulong *)((char *)env + PARAM1);
  367 +}
  368 +
  369 +void OPPROTO op_movtl_env_T0(void)
  370 +{
  371 + *(target_ulong *)((char *)env + PARAM1) = T0;
241 } 372 }
242 373
243 void OPPROTO op_add_T1_T0(void) 374 void OPPROTO op_add_T1_T0(void)
@@ -252,6 +383,27 @@ void OPPROTO op_add_T1_T0_cc(void) @@ -252,6 +383,27 @@ void OPPROTO op_add_T1_T0_cc(void)
252 src1 = T0; 383 src1 = T0;
253 T0 += T1; 384 T0 += T1;
254 env->psr = 0; 385 env->psr = 0;
  386 +#ifdef TARGET_SPARC64
  387 + if (!(T0 & 0xffffffff))
  388 + env->psr |= PSR_ZERO;
  389 + if ((int32_t) T0 < 0)
  390 + env->psr |= PSR_NEG;
  391 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  392 + env->psr |= PSR_CARRY;
  393 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
  394 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  395 + env->psr |= PSR_OVF;
  396 +
  397 + env->xcc = 0;
  398 + if (!T0)
  399 + env->xcc |= PSR_ZERO;
  400 + if ((int64_t) T0 < 0)
  401 + env->xcc |= PSR_NEG;
  402 + if (T0 < src1)
  403 + env->xcc |= PSR_CARRY;
  404 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
  405 + env->xcc |= PSR_OVF;
  406 +#else
255 if (!T0) 407 if (!T0)
256 env->psr |= PSR_ZERO; 408 env->psr |= PSR_ZERO;
257 if ((int32_t) T0 < 0) 409 if ((int32_t) T0 < 0)
@@ -260,7 +412,7 @@ void OPPROTO op_add_T1_T0_cc(void) @@ -260,7 +412,7 @@ void OPPROTO op_add_T1_T0_cc(void)
260 env->psr |= PSR_CARRY; 412 env->psr |= PSR_CARRY;
261 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) 413 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
262 env->psr |= PSR_OVF; 414 env->psr |= PSR_OVF;
263 - /* V9 xcc */ 415 +#endif
264 FORCE_RET(); 416 FORCE_RET();
265 } 417 }
266 418
@@ -276,6 +428,27 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -276,6 +428,27 @@ void OPPROTO op_addx_T1_T0_cc(void)
276 src1 = T0; 428 src1 = T0;
277 T0 += T1 + FLAG_SET(PSR_CARRY); 429 T0 += T1 + FLAG_SET(PSR_CARRY);
278 env->psr = 0; 430 env->psr = 0;
  431 +#ifdef TARGET_SPARC64
  432 + if (!(T0 & 0xffffffff))
  433 + env->psr |= PSR_ZERO;
  434 + if ((int32_t) T0 < 0)
  435 + env->psr |= PSR_NEG;
  436 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  437 + env->psr |= PSR_CARRY;
  438 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
  439 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  440 + env->psr |= PSR_OVF;
  441 +
  442 + env->xcc = 0;
  443 + if (!T0)
  444 + env->xcc |= PSR_ZERO;
  445 + if ((int64_t) T0 < 0)
  446 + env->xcc |= PSR_NEG;
  447 + if (T0 < src1)
  448 + env->xcc |= PSR_CARRY;
  449 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
  450 + env->xcc |= PSR_OVF;
  451 +#else
279 if (!T0) 452 if (!T0)
280 env->psr |= PSR_ZERO; 453 env->psr |= PSR_ZERO;
281 if ((int32_t) T0 < 0) 454 if ((int32_t) T0 < 0)
@@ -284,7 +457,7 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -284,7 +457,7 @@ void OPPROTO op_addx_T1_T0_cc(void)
284 env->psr |= PSR_CARRY; 457 env->psr |= PSR_CARRY;
285 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) 458 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
286 env->psr |= PSR_OVF; 459 env->psr |= PSR_OVF;
287 - /* V9 xcc */ 460 +#endif
288 FORCE_RET(); 461 FORCE_RET();
289 } 462 }
290 463
@@ -300,6 +473,27 @@ void OPPROTO op_sub_T1_T0_cc(void) @@ -300,6 +473,27 @@ void OPPROTO op_sub_T1_T0_cc(void)
300 src1 = T0; 473 src1 = T0;
301 T0 -= T1; 474 T0 -= T1;
302 env->psr = 0; 475 env->psr = 0;
  476 +#ifdef TARGET_SPARC64
  477 + if (!(T0 & 0xffffffff))
  478 + env->psr |= PSR_ZERO;
  479 + if ((int32_t) T0 < 0)
  480 + env->psr |= PSR_NEG;
  481 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  482 + env->psr |= PSR_CARRY;
  483 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
  484 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  485 + env->psr |= PSR_OVF;
  486 +
  487 + env->xcc = 0;
  488 + if (!T0)
  489 + env->xcc |= PSR_ZERO;
  490 + if ((int64_t) T0 < 0)
  491 + env->xcc |= PSR_NEG;
  492 + if (T0 < src1)
  493 + env->xcc |= PSR_CARRY;
  494 + if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
  495 + env->xcc |= PSR_OVF;
  496 +#else
303 if (!T0) 497 if (!T0)
304 env->psr |= PSR_ZERO; 498 env->psr |= PSR_ZERO;
305 if ((int32_t) T0 < 0) 499 if ((int32_t) T0 < 0)
@@ -308,7 +502,7 @@ void OPPROTO op_sub_T1_T0_cc(void) @@ -308,7 +502,7 @@ void OPPROTO op_sub_T1_T0_cc(void)
308 env->psr |= PSR_CARRY; 502 env->psr |= PSR_CARRY;
309 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) 503 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
310 env->psr |= PSR_OVF; 504 env->psr |= PSR_OVF;
311 - /* V9 xcc */ 505 +#endif
312 FORCE_RET(); 506 FORCE_RET();
313 } 507 }
314 508
@@ -324,6 +518,27 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -324,6 +518,27 @@ void OPPROTO op_subx_T1_T0_cc(void)
324 src1 = T0; 518 src1 = T0;
325 T0 -= T1 + FLAG_SET(PSR_CARRY); 519 T0 -= T1 + FLAG_SET(PSR_CARRY);
326 env->psr = 0; 520 env->psr = 0;
  521 +#ifdef TARGET_SPARC64
  522 + if (!(T0 & 0xffffffff))
  523 + env->psr |= PSR_ZERO;
  524 + if ((int32_t) T0 < 0)
  525 + env->psr |= PSR_NEG;
  526 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  527 + env->psr |= PSR_CARRY;
  528 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
  529 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  530 + env->psr |= PSR_OVF;
  531 +
  532 + env->xcc = 0;
  533 + if (!T0)
  534 + env->xcc |= PSR_ZERO;
  535 + if ((int64_t) T0 < 0)
  536 + env->xcc |= PSR_NEG;
  537 + if (T0 < src1)
  538 + env->xcc |= PSR_CARRY;
  539 + if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
  540 + env->xcc |= PSR_OVF;
  541 +#else
327 if (!T0) 542 if (!T0)
328 env->psr |= PSR_ZERO; 543 env->psr |= PSR_ZERO;
329 if ((int32_t) T0 < 0) 544 if ((int32_t) T0 < 0)
@@ -332,7 +547,7 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -332,7 +547,7 @@ void OPPROTO op_subx_T1_T0_cc(void)
332 env->psr |= PSR_CARRY; 547 env->psr |= PSR_CARRY;
333 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) 548 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
334 env->psr |= PSR_OVF; 549 env->psr |= PSR_OVF;
335 - /* V9 xcc */ 550 +#endif
336 FORCE_RET(); 551 FORCE_RET();
337 } 552 }
338 553
@@ -449,24 +664,73 @@ void OPPROTO op_sdiv_T1_T0(void) @@ -449,24 +664,73 @@ void OPPROTO op_sdiv_T1_T0(void)
449 void OPPROTO op_div_cc(void) 664 void OPPROTO op_div_cc(void)
450 { 665 {
451 env->psr = 0; 666 env->psr = 0;
  667 +#ifdef TARGET_SPARC64
  668 + if (!T0)
  669 + env->psr |= PSR_ZERO;
  670 + if ((int32_t) T0 < 0)
  671 + env->psr |= PSR_NEG;
  672 + if (T1)
  673 + env->psr |= PSR_OVF;
  674 +
  675 + env->xcc = 0;
  676 + if (!T0)
  677 + env->xcc |= PSR_ZERO;
  678 + if ((int64_t) T0 < 0)
  679 + env->xcc |= PSR_NEG;
  680 +#else
452 if (!T0) 681 if (!T0)
453 env->psr |= PSR_ZERO; 682 env->psr |= PSR_ZERO;
454 if ((int32_t) T0 < 0) 683 if ((int32_t) T0 < 0)
455 env->psr |= PSR_NEG; 684 env->psr |= PSR_NEG;
456 if (T1) 685 if (T1)
457 env->psr |= PSR_OVF; 686 env->psr |= PSR_OVF;
458 - /* V9 xcc */ 687 +#endif
459 FORCE_RET(); 688 FORCE_RET();
460 } 689 }
461 690
  691 +#ifdef TARGET_SPARC64
  692 +void OPPROTO op_mulx_T1_T0(void)
  693 +{
  694 + T0 *= T1;
  695 + FORCE_RET();
  696 +}
  697 +
  698 +void OPPROTO op_udivx_T1_T0(void)
  699 +{
  700 + T0 /= T1;
  701 + FORCE_RET();
  702 +}
  703 +
  704 +void OPPROTO op_sdivx_T1_T0(void)
  705 +{
  706 + if (T0 == INT64_MIN && T1 == -1)
  707 + T0 = INT64_MIN;
  708 + else
  709 + T0 /= (target_long) T1;
  710 + FORCE_RET();
  711 +}
  712 +#endif
  713 +
462 void OPPROTO op_logic_T0_cc(void) 714 void OPPROTO op_logic_T0_cc(void)
463 { 715 {
464 env->psr = 0; 716 env->psr = 0;
  717 +#ifdef TARGET_SPARC64
  718 + if (!(T0 & 0xffffffff))
  719 + env->psr |= PSR_ZERO;
  720 + if ((int32_t) T0 < 0)
  721 + env->psr |= PSR_NEG;
  722 +
  723 + env->xcc = 0;
  724 + if (!T0)
  725 + env->xcc |= PSR_ZERO;
  726 + if ((int64_t) T0 < 0)
  727 + env->xcc |= PSR_NEG;
  728 +#else
465 if (!T0) 729 if (!T0)
466 env->psr |= PSR_ZERO; 730 env->psr |= PSR_ZERO;
467 if ((int32_t) T0 < 0) 731 if ((int32_t) T0 < 0)
468 env->psr |= PSR_NEG; 732 env->psr |= PSR_NEG;
469 - /* V9 xcc */ 733 +#endif
470 FORCE_RET(); 734 FORCE_RET();
471 } 735 }
472 736
@@ -475,6 +739,27 @@ void OPPROTO op_sll(void) @@ -475,6 +739,27 @@ void OPPROTO op_sll(void)
475 T0 <<= T1; 739 T0 <<= T1;
476 } 740 }
477 741
  742 +#ifdef TARGET_SPARC64
  743 +void OPPROTO op_srl(void)
  744 +{
  745 + T0 = (T0 & 0xffffffff) >> T1;
  746 +}
  747 +
  748 +void OPPROTO op_srlx(void)
  749 +{
  750 + T0 >>= T1;
  751 +}
  752 +
  753 +void OPPROTO op_sra(void)
  754 +{
  755 + T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;
  756 +}
  757 +
  758 +void OPPROTO op_srax(void)
  759 +{
  760 + T0 = ((int64_t) T0) >> T1;
  761 +}
  762 +#else
478 void OPPROTO op_srl(void) 763 void OPPROTO op_srl(void)
479 { 764 {
480 T0 >>= T1; 765 T0 >>= T1;
@@ -484,6 +769,7 @@ void OPPROTO op_sra(void) @@ -484,6 +769,7 @@ void OPPROTO op_sra(void)
484 { 769 {
485 T0 = ((int32_t) T0) >> T1; 770 T0 = ((int32_t) T0) >> T1;
486 } 771 }
  772 +#endif
487 773
488 /* Load and store */ 774 /* Load and store */
489 #define MEMSUFFIX _raw 775 #define MEMSUFFIX _raw
@@ -498,62 +784,137 @@ void OPPROTO op_sra(void) @@ -498,62 +784,137 @@ void OPPROTO op_sra(void)
498 784
499 void OPPROTO op_ldfsr(void) 785 void OPPROTO op_ldfsr(void)
500 { 786 {
501 - env->fsr = *((uint32_t *) &FT0); 787 + PUT_FSR32(env, *((uint32_t *) &FT0));
502 helper_ldfsr(); 788 helper_ldfsr();
503 } 789 }
504 790
505 void OPPROTO op_stfsr(void) 791 void OPPROTO op_stfsr(void)
506 { 792 {
507 - *((uint32_t *) &FT0) = env->fsr; 793 + *((uint32_t *) &FT0) = GET_FSR32(env);
508 } 794 }
509 795
510 -void OPPROTO op_wry(void) 796 +#ifndef TARGET_SPARC64
  797 +void OPPROTO op_rdpsr(void)
511 { 798 {
512 - env->y = T0; 799 + do_rdpsr();
513 } 800 }
514 801
515 -void OPPROTO op_rdy(void) 802 +void OPPROTO op_wrpsr(void)
516 { 803 {
517 - T0 = env->y; 804 + do_wrpsr();
  805 + FORCE_RET();
518 } 806 }
519 807
520 -void OPPROTO op_rdwim(void) 808 +void OPPROTO op_rett(void)
521 { 809 {
522 - T0 = env->wim; 810 + helper_rett();
  811 + FORCE_RET();
523 } 812 }
524 813
525 -void OPPROTO op_wrwim(void) 814 +/* XXX: use another pointer for %iN registers to avoid slow wrapping
  815 + handling ? */
  816 +void OPPROTO op_save(void)
526 { 817 {
527 - env->wim = T0; 818 + uint32_t cwp;
  819 + cwp = (env->cwp - 1) & (NWINDOWS - 1);
  820 + if (env->wim & (1 << cwp)) {
  821 + raise_exception(TT_WIN_OVF);
  822 + }
  823 + set_cwp(cwp);
528 FORCE_RET(); 824 FORCE_RET();
529 } 825 }
530 826
531 -void OPPROTO op_rdpsr(void) 827 +void OPPROTO op_restore(void)
532 { 828 {
533 - do_rdpsr(); 829 + uint32_t cwp;
  830 + cwp = (env->cwp + 1) & (NWINDOWS - 1);
  831 + if (env->wim & (1 << cwp)) {
  832 + raise_exception(TT_WIN_UNF);
  833 + }
  834 + set_cwp(cwp);
  835 + FORCE_RET();
  836 +}
  837 +#else
  838 +void OPPROTO op_rdccr(void)
  839 +{
  840 + T0 = GET_CCR(env);
534 } 841 }
535 842
536 -void OPPROTO op_wrpsr(void) 843 +void OPPROTO op_wrccr(void)
537 { 844 {
538 - do_wrpsr();  
539 - FORCE_RET(); 845 + PUT_CCR(env, T0);
540 } 846 }
541 847
542 -void OPPROTO op_rdtbr(void) 848 +void OPPROTO op_rdtick(void)
543 { 849 {
544 - T0 = env->tbr; 850 + T0 = 0; // XXX read cycle counter and bit 31
545 } 851 }
546 852
547 -void OPPROTO op_wrtbr(void) 853 +void OPPROTO op_wrtick(void)
548 { 854 {
549 - env->tbr = T0;  
550 - FORCE_RET(); 855 + // XXX write cycle counter and bit 31
551 } 856 }
552 857
553 -void OPPROTO op_rett(void) 858 +void OPPROTO op_rdtpc(void)
554 { 859 {
555 - helper_rett();  
556 - FORCE_RET(); 860 + T0 = env->tpc[env->tl];
  861 +}
  862 +
  863 +void OPPROTO op_wrtpc(void)
  864 +{
  865 + env->tpc[env->tl] = T0;
  866 +}
  867 +
  868 +void OPPROTO op_rdtnpc(void)
  869 +{
  870 + T0 = env->tnpc[env->tl];
  871 +}
  872 +
  873 +void OPPROTO op_wrtnpc(void)
  874 +{
  875 + env->tnpc[env->tl] = T0;
  876 +}
  877 +
  878 +void OPPROTO op_rdtstate(void)
  879 +{
  880 + T0 = env->tstate[env->tl];
  881 +}
  882 +
  883 +void OPPROTO op_wrtstate(void)
  884 +{
  885 + env->tstate[env->tl] = T0;
  886 +}
  887 +
  888 +void OPPROTO op_rdtt(void)
  889 +{
  890 + T0 = env->tt[env->tl];
  891 +}
  892 +
  893 +void OPPROTO op_wrtt(void)
  894 +{
  895 + env->tt[env->tl] = T0;
  896 +}
  897 +
  898 +void OPPROTO op_rdpstate(void)
  899 +{
  900 + T0 = env->pstate;
  901 +}
  902 +
  903 +void OPPROTO op_wrpstate(void)
  904 +{
  905 + env->pstate = T0 & 0x1f;
  906 +}
  907 +
  908 +// CWP handling is reversed in V9, but we still use the V8 register
  909 +// order.
  910 +void OPPROTO op_rdcwp(void)
  911 +{
  912 + T0 = NWINDOWS - 1 - env->cwp;
  913 +}
  914 +
  915 +void OPPROTO op_wrcwp(void)
  916 +{
  917 + env->cwp = NWINDOWS - 1 - T0;
557 } 918 }
558 919
559 /* XXX: use another pointer for %iN registers to avoid slow wrapping 920 /* XXX: use another pointer for %iN registers to avoid slow wrapping
@@ -562,10 +923,20 @@ void OPPROTO op_save(void) @@ -562,10 +923,20 @@ void OPPROTO op_save(void)
562 { 923 {
563 uint32_t cwp; 924 uint32_t cwp;
564 cwp = (env->cwp - 1) & (NWINDOWS - 1); 925 cwp = (env->cwp - 1) & (NWINDOWS - 1);
565 - if (env->wim & (1 << cwp)) {  
566 - raise_exception(TT_WIN_OVF); 926 + if (env->cansave == 0) {
  927 + raise_exception(TT_SPILL | (env->otherwin != 0 ?
  928 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  929 + ((env->wstate & 0x7) << 2)));
  930 + } else {
  931 + if (env->cleanwin - env->canrestore == 0) {
  932 + // XXX Clean windows without trap
  933 + raise_exception(TT_CLRWIN);
  934 + } else {
  935 + env->cansave--;
  936 + env->canrestore++;
  937 + set_cwp(cwp);
  938 + }
567 } 939 }
568 - set_cwp(cwp);  
569 FORCE_RET(); 940 FORCE_RET();
570 } 941 }
571 942
@@ -573,12 +944,18 @@ void OPPROTO op_restore(void) @@ -573,12 +944,18 @@ void OPPROTO op_restore(void)
573 { 944 {
574 uint32_t cwp; 945 uint32_t cwp;
575 cwp = (env->cwp + 1) & (NWINDOWS - 1); 946 cwp = (env->cwp + 1) & (NWINDOWS - 1);
576 - if (env->wim & (1 << cwp)) {  
577 - raise_exception(TT_WIN_UNF); 947 + if (env->canrestore == 0) {
  948 + raise_exception(TT_FILL | (env->otherwin != 0 ?
  949 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  950 + ((env->wstate & 0x7) << 2)));
  951 + } else {
  952 + env->cansave++;
  953 + env->canrestore--;
  954 + set_cwp(cwp);
578 } 955 }
579 - set_cwp(cwp);  
580 FORCE_RET(); 956 FORCE_RET();
581 } 957 }
  958 +#endif
582 959
583 void OPPROTO op_exception(void) 960 void OPPROTO op_exception(void)
584 { 961 {
@@ -629,6 +1006,11 @@ void OPPROTO op_exit_tb(void) @@ -629,6 +1006,11 @@ void OPPROTO op_exit_tb(void)
629 EXIT_TB(); 1006 EXIT_TB();
630 } 1007 }
631 1008
  1009 +void OPPROTO op_eval_ba(void)
  1010 +{
  1011 + T2 = 1;
  1012 +}
  1013 +
632 void OPPROTO op_eval_be(void) 1014 void OPPROTO op_eval_be(void)
633 { 1015 {
634 T2 = FLAG_SET(PSR_ZERO); 1016 T2 = FLAG_SET(PSR_ZERO);
@@ -665,6 +1047,11 @@ void OPPROTO op_eval_bvs(void) @@ -665,6 +1047,11 @@ void OPPROTO op_eval_bvs(void)
665 T2 = FLAG_SET(PSR_OVF); 1047 T2 = FLAG_SET(PSR_OVF);
666 } 1048 }
667 1049
  1050 +void OPPROTO op_eval_bn(void)
  1051 +{
  1052 + T2 = 0;
  1053 +}
  1054 +
668 void OPPROTO op_eval_bneg(void) 1055 void OPPROTO op_eval_bneg(void)
669 { 1056 {
670 T2 = FLAG_SET(PSR_NEG); 1057 T2 = FLAG_SET(PSR_NEG);
@@ -711,101 +1098,156 @@ void OPPROTO op_eval_bvc(void) @@ -711,101 +1098,156 @@ void OPPROTO op_eval_bvc(void)
711 T2 = !FLAG_SET(PSR_OVF); 1098 T2 = !FLAG_SET(PSR_OVF);
712 } 1099 }
713 1100
714 -/* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ 1101 +#ifdef TARGET_SPARC64
  1102 +void OPPROTO op_eval_xbe(void)
  1103 +{
  1104 + T2 = XFLAG_SET(PSR_ZERO);
  1105 +}
715 1106
716 -void OPPROTO op_eval_fbne(void) 1107 +void OPPROTO op_eval_xble(void)
717 { 1108 {
718 -// !0  
719 - T2 = (env->fsr & (FSR_FCC1 | FSR_FCC0)); /* L or G or U */ 1109 + target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1110 +
  1111 + T2 = Z | (N ^ V);
720 } 1112 }
721 1113
722 -void OPPROTO op_eval_fblg(void) 1114 +void OPPROTO op_eval_xbl(void)
723 { 1115 {
724 -// 1 or 2  
725 - T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1); 1116 + target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1117 +
  1118 + T2 = N ^ V;
726 } 1119 }
727 1120
728 -void OPPROTO op_eval_fbul(void) 1121 +void OPPROTO op_eval_xbleu(void)
729 { 1122 {
730 -// 1 or 3  
731 - T2 = FFLAG_SET(FSR_FCC0); 1123 + target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
  1124 +
  1125 + T2 = C | Z;
732 } 1126 }
733 1127
734 -void OPPROTO op_eval_fbl(void) 1128 +void OPPROTO op_eval_xbcs(void)
735 { 1129 {
736 -// 1  
737 - T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); 1130 + T2 = XFLAG_SET(PSR_CARRY);
738 } 1131 }
739 1132
740 -void OPPROTO op_eval_fbug(void) 1133 +void OPPROTO op_eval_xbvs(void)
741 { 1134 {
742 -// 2 or 3  
743 - T2 = FFLAG_SET(FSR_FCC1); 1135 + T2 = XFLAG_SET(PSR_OVF);
744 } 1136 }
745 1137
746 -void OPPROTO op_eval_fbg(void) 1138 +void OPPROTO op_eval_xbneg(void)
747 { 1139 {
748 -// 2  
749 - T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); 1140 + T2 = XFLAG_SET(PSR_NEG);
750 } 1141 }
751 1142
752 -void OPPROTO op_eval_fbu(void) 1143 +void OPPROTO op_eval_xbne(void)
753 { 1144 {
754 -// 3  
755 - T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); 1145 + T2 = !XFLAG_SET(PSR_ZERO);
756 } 1146 }
757 1147
758 -void OPPROTO op_eval_fbe(void) 1148 +void OPPROTO op_eval_xbg(void)
759 { 1149 {
760 -// 0  
761 - T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); 1150 + target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1151 +
  1152 + T2 = !(Z | (N ^ V));
762 } 1153 }
763 1154
764 -void OPPROTO op_eval_fbue(void) 1155 +void OPPROTO op_eval_xbge(void)
765 { 1156 {
766 -// 0 or 3  
767 - T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0));  
768 - FORCE_RET(); 1157 + target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1158 +
  1159 + T2 = !(N ^ V);
  1160 +}
  1161 +
  1162 +void OPPROTO op_eval_xbgu(void)
  1163 +{
  1164 + target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
  1165 +
  1166 + T2 = !(C | Z);
  1167 +}
  1168 +
  1169 +void OPPROTO op_eval_xbcc(void)
  1170 +{
  1171 + T2 = !XFLAG_SET(PSR_CARRY);
  1172 +}
  1173 +
  1174 +void OPPROTO op_eval_xbpos(void)
  1175 +{
  1176 + T2 = !XFLAG_SET(PSR_NEG);
  1177 +}
  1178 +
  1179 +void OPPROTO op_eval_xbvc(void)
  1180 +{
  1181 + T2 = !XFLAG_SET(PSR_OVF);
  1182 +}
  1183 +#endif
  1184 +
  1185 +#define FCC
  1186 +#define FFLAG_SET(x) (env->fsr & x? 1: 0)
  1187 +#include "fbranch_template.h"
  1188 +
  1189 +#ifdef TARGET_SPARC64
  1190 +#define FCC _fcc1
  1191 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
  1192 +#include "fbranch_template.h"
  1193 +#define FCC _fcc2
  1194 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
  1195 +#include "fbranch_template.h"
  1196 +#define FCC _fcc3
  1197 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
  1198 +#include "fbranch_template.h"
  1199 +#endif
  1200 +
  1201 +#ifdef TARGET_SPARC64
  1202 +void OPPROTO op_eval_brz(void)
  1203 +{
  1204 + T2 = T0;
769 } 1205 }
770 1206
771 -void OPPROTO op_eval_fbge(void) 1207 +void OPPROTO op_eval_brnz(void)
772 { 1208 {
773 -// 0 or 2  
774 - T2 = !FFLAG_SET(FSR_FCC0); 1209 + T2 = !T0;
775 } 1210 }
776 1211
777 -void OPPROTO op_eval_fbuge(void) 1212 +void OPPROTO op_eval_brlz(void)
778 { 1213 {
779 -// !1  
780 - T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1)); 1214 + T2 = ((int64_t)T0 < 0);
781 } 1215 }
782 1216
783 -void OPPROTO op_eval_fble(void) 1217 +void OPPROTO op_eval_brlez(void)
784 { 1218 {
785 -// 0 or 1  
786 - T2 = !FFLAG_SET(FSR_FCC1); 1219 + T2 = ((int64_t)T0 <= 0);
787 } 1220 }
788 1221
789 -void OPPROTO op_eval_fbule(void) 1222 +void OPPROTO op_eval_brgz(void)
790 { 1223 {
791 -// !2  
792 - T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); 1224 + T2 = ((int64_t)T0 > 0);
793 } 1225 }
794 1226
795 -void OPPROTO op_eval_fbo(void) 1227 +void OPPROTO op_eval_brgez(void)
796 { 1228 {
797 -// !3  
798 - T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); 1229 + T2 = ((int64_t)T0 >= 0);
799 } 1230 }
800 1231
  1232 +void OPPROTO op_jmp_im64(void)
  1233 +{
  1234 + env->pc = PARAMQ1;
  1235 +}
  1236 +
  1237 +void OPPROTO op_movq_npc_im64(void)
  1238 +{
  1239 + env->npc = PARAMQ1;
  1240 +}
  1241 +#endif
  1242 +
801 void OPPROTO op_jmp_im(void) 1243 void OPPROTO op_jmp_im(void)
802 { 1244 {
803 - env->pc = PARAM1; 1245 + env->pc = (uint32_t)PARAM1;
804 } 1246 }
805 1247
806 void OPPROTO op_movl_npc_im(void) 1248 void OPPROTO op_movl_npc_im(void)
807 { 1249 {
808 - env->npc = PARAM1; 1250 + env->npc = (uint32_t)PARAM1;
809 } 1251 }
810 1252
811 void OPPROTO op_movl_npc_T0(void) 1253 void OPPROTO op_movl_npc_T0(void)
@@ -826,17 +1268,17 @@ void OPPROTO op_next_insn(void) @@ -826,17 +1268,17 @@ void OPPROTO op_next_insn(void)
826 1268
827 void OPPROTO op_branch(void) 1269 void OPPROTO op_branch(void)
828 { 1270 {
829 - env->npc = PARAM3; /* XXX: optimize */ 1271 + env->npc = (uint32_t)PARAM3; /* XXX: optimize */
830 JUMP_TB(op_branch, PARAM1, 0, PARAM2); 1272 JUMP_TB(op_branch, PARAM1, 0, PARAM2);
831 } 1273 }
832 1274
833 void OPPROTO op_branch2(void) 1275 void OPPROTO op_branch2(void)
834 { 1276 {
835 if (T2) { 1277 if (T2) {
836 - env->npc = PARAM2 + 4; 1278 + env->npc = (uint32_t)PARAM2 + 4;
837 JUMP_TB(op_branch2, PARAM1, 0, PARAM2); 1279 JUMP_TB(op_branch2, PARAM1, 0, PARAM2);
838 } else { 1280 } else {
839 - env->npc = PARAM3 + 4; 1281 + env->npc = (uint32_t)PARAM3 + 4;
840 JUMP_TB(op_branch2, PARAM1, 1, PARAM3); 1282 JUMP_TB(op_branch2, PARAM1, 1, PARAM3);
841 } 1283 }
842 FORCE_RET(); 1284 FORCE_RET();
@@ -845,10 +1287,10 @@ void OPPROTO op_branch2(void) @@ -845,10 +1287,10 @@ void OPPROTO op_branch2(void)
845 void OPPROTO op_branch_a(void) 1287 void OPPROTO op_branch_a(void)
846 { 1288 {
847 if (T2) { 1289 if (T2) {
848 - env->npc = PARAM2; /* XXX: optimize */ 1290 + env->npc = (uint32_t)PARAM2; /* XXX: optimize */
849 JUMP_TB(op_branch_a, PARAM1, 0, PARAM3); 1291 JUMP_TB(op_branch_a, PARAM1, 0, PARAM3);
850 } else { 1292 } else {
851 - env->npc = PARAM3 + 8; /* XXX: optimize */ 1293 + env->npc = (uint32_t)PARAM3 + 8; /* XXX: optimize */
852 JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4); 1294 JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4);
853 } 1295 }
854 FORCE_RET(); 1296 FORCE_RET();
@@ -857,9 +1299,9 @@ void OPPROTO op_branch_a(void) @@ -857,9 +1299,9 @@ void OPPROTO op_branch_a(void)
857 void OPPROTO op_generic_branch(void) 1299 void OPPROTO op_generic_branch(void)
858 { 1300 {
859 if (T2) { 1301 if (T2) {
860 - env->npc = PARAM1; 1302 + env->npc = (uint32_t)PARAM1;
861 } else { 1303 } else {
862 - env->npc = PARAM2; 1304 + env->npc = (uint32_t)PARAM2;
863 } 1305 }
864 FORCE_RET(); 1306 FORCE_RET();
865 } 1307 }
@@ -879,6 +1321,18 @@ void OPPROTO op_fabss(void) @@ -879,6 +1321,18 @@ void OPPROTO op_fabss(void)
879 do_fabss(); 1321 do_fabss();
880 } 1322 }
881 1323
  1324 +#ifdef TARGET_SPARC64
  1325 +void OPPROTO op_fnegd(void)
  1326 +{
  1327 + DT0 = -DT1;
  1328 +}
  1329 +
  1330 +void OPPROTO op_fabsd(void)
  1331 +{
  1332 + do_fabsd();
  1333 +}
  1334 +#endif
  1335 +
882 void OPPROTO op_fsqrts(void) 1336 void OPPROTO op_fsqrts(void)
883 { 1337 {
884 do_fsqrts(); 1338 do_fsqrts();
@@ -944,6 +1398,38 @@ void OPPROTO op_fcmpd(void) @@ -944,6 +1398,38 @@ void OPPROTO op_fcmpd(void)
944 do_fcmpd(); 1398 do_fcmpd();
945 } 1399 }
946 1400
  1401 +#ifdef TARGET_SPARC64
  1402 +void OPPROTO op_fcmps_fcc1(void)
  1403 +{
  1404 + do_fcmps_fcc1();
  1405 +}
  1406 +
  1407 +void OPPROTO op_fcmpd_fcc1(void)
  1408 +{
  1409 + do_fcmpd_fcc1();
  1410 +}
  1411 +
  1412 +void OPPROTO op_fcmps_fcc2(void)
  1413 +{
  1414 + do_fcmps_fcc2();
  1415 +}
  1416 +
  1417 +void OPPROTO op_fcmpd_fcc2(void)
  1418 +{
  1419 + do_fcmpd_fcc2();
  1420 +}
  1421 +
  1422 +void OPPROTO op_fcmps_fcc3(void)
  1423 +{
  1424 + do_fcmps_fcc3();
  1425 +}
  1426 +
  1427 +void OPPROTO op_fcmpd_fcc3(void)
  1428 +{
  1429 + do_fcmpd_fcc3();
  1430 +}
  1431 +#endif
  1432 +
947 #ifdef USE_INT_TO_FLOAT_HELPERS 1433 #ifdef USE_INT_TO_FLOAT_HELPERS
948 void OPPROTO op_fitos(void) 1434 void OPPROTO op_fitos(void)
949 { 1435 {
@@ -964,6 +1450,18 @@ void OPPROTO op_fitod(void) @@ -964,6 +1450,18 @@ void OPPROTO op_fitod(void)
964 { 1450 {
965 DT0 = (double) *((int32_t *)&FT1); 1451 DT0 = (double) *((int32_t *)&FT1);
966 } 1452 }
  1453 +
  1454 +#ifdef TARGET_SPARC64
  1455 +void OPPROTO op_fxtos(void)
  1456 +{
  1457 + FT0 = (float) *((int64_t *)&DT1);
  1458 +}
  1459 +
  1460 +void OPPROTO op_fxtod(void)
  1461 +{
  1462 + DT0 = (double) *((int64_t *)&DT1);
  1463 +}
  1464 +#endif
967 #endif 1465 #endif
968 1466
969 void OPPROTO op_fdtos(void) 1467 void OPPROTO op_fdtos(void)
@@ -986,6 +1484,102 @@ void OPPROTO op_fdtoi(void) @@ -986,6 +1484,102 @@ void OPPROTO op_fdtoi(void)
986 *((int32_t *)&FT0) = (int32_t) DT1; 1484 *((int32_t *)&FT0) = (int32_t) DT1;
987 } 1485 }
988 1486
  1487 +#ifdef TARGET_SPARC64
  1488 +void OPPROTO op_fstox(void)
  1489 +{
  1490 + *((int64_t *)&DT0) = (int64_t) FT1;
  1491 +}
  1492 +
  1493 +void OPPROTO op_fdtox(void)
  1494 +{
  1495 + *((int64_t *)&DT0) = (int64_t) DT1;
  1496 +}
  1497 +
  1498 +void OPPROTO op_fmovs_cc(void)
  1499 +{
  1500 + if (T2)
  1501 + FT0 = FT1;
  1502 +}
  1503 +
  1504 +void OPPROTO op_fmovd_cc(void)
  1505 +{
  1506 + if (T2)
  1507 + DT0 = DT1;
  1508 +}
  1509 +
  1510 +void OPPROTO op_mov_cc(void)
  1511 +{
  1512 + if (T2)
  1513 + T0 = T1;
  1514 +}
  1515 +
  1516 +void OPPROTO op_flushw(void)
  1517 +{
  1518 + if (env->cansave != NWINDOWS - 2) {
  1519 + raise_exception(TT_SPILL | (env->otherwin != 0 ?
  1520 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  1521 + ((env->wstate & 0x7) << 2)));
  1522 + }
  1523 +}
  1524 +
  1525 +void OPPROTO op_saved(void)
  1526 +{
  1527 + env->cansave++;
  1528 + if (env->otherwin == 0)
  1529 + env->canrestore--;
  1530 +}
  1531 +
  1532 +void OPPROTO op_restored(void)
  1533 +{
  1534 + env->canrestore++;
  1535 + if (env->cleanwin < NWINDOWS - 1)
  1536 + env->cleanwin++;
  1537 + if (env->otherwin == 0)
  1538 + env->cansave--;
  1539 + else
  1540 + env->otherwin--;
  1541 +}
  1542 +
  1543 +void OPPROTO op_popc(void)
  1544 +{
  1545 + do_popc();
  1546 +}
  1547 +
  1548 +void OPPROTO op_done(void)
  1549 +{
  1550 + env->pc = env->tnpc[env->tl];
  1551 + env->npc = env->tnpc[env->tl] + 4;
  1552 + env->pstate = env->tstate[env->tl];
  1553 + env->tl--;
  1554 +}
  1555 +
  1556 +void OPPROTO op_retry(void)
  1557 +{
  1558 + env->pc = env->tpc[env->tl];
  1559 + env->npc = env->tnpc[env->tl];
  1560 + env->pstate = env->tstate[env->tl];
  1561 + env->tl--;
  1562 +}
  1563 +
  1564 +void OPPROTO op_sir(void)
  1565 +{
  1566 + // XXX
  1567 +
  1568 +}
  1569 +
  1570 +void OPPROTO op_ld_asi_reg()
  1571 +{
  1572 + T0 += PARAM1;
  1573 + helper_ld_asi(env->asi, PARAM2, PARAM3);
  1574 +}
  1575 +
  1576 +void OPPROTO op_st_asi_reg()
  1577 +{
  1578 + T0 += PARAM1;
  1579 + helper_st_asi(env->asi, PARAM2, PARAM3);
  1580 +}
  1581 +#endif
  1582 +
989 void OPPROTO op_ld_asi() 1583 void OPPROTO op_ld_asi()
990 { 1584 {
991 helper_ld_asi(PARAM1, PARAM2, PARAM3); 1585 helper_ld_asi(PARAM1, PARAM2, PARAM3);
target-sparc/op_helper.c
@@ -25,6 +25,13 @@ void do_fabss(void) @@ -25,6 +25,13 @@ void do_fabss(void)
25 FT0 = float32_abs(FT1); 25 FT0 = float32_abs(FT1);
26 } 26 }
27 27
  28 +#ifdef TARGET_SPARC64
  29 +void do_fabsd(void)
  30 +{
  31 + DT0 = float64_abs(DT1);
  32 +}
  33 +#endif
  34 +
28 void do_fsqrts(void) 35 void do_fsqrts(void)
29 { 36 {
30 FT0 = float32_sqrt(FT1, &env->fp_status); 37 FT0 = float32_sqrt(FT1, &env->fp_status);
@@ -35,48 +42,185 @@ void do_fsqrtd(void) @@ -35,48 +42,185 @@ void do_fsqrtd(void)
35 DT0 = float64_sqrt(DT1, &env->fp_status); 42 DT0 = float64_sqrt(DT1, &env->fp_status);
36 } 43 }
37 44
  45 +#define FS 0
38 void do_fcmps (void) 46 void do_fcmps (void)
39 { 47 {
  48 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
40 if (isnan(FT0) || isnan(FT1)) { 49 if (isnan(FT0) || isnan(FT1)) {
41 - T0 = FSR_FCC1 | FSR_FCC0;  
42 - env->fsr &= ~(FSR_FCC1 | FSR_FCC0);  
43 - env->fsr |= T0; 50 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
44 if (env->fsr & FSR_NVM) { 51 if (env->fsr & FSR_NVM) {
  52 + env->fsr |= T0;
45 raise_exception(TT_FP_EXCP); 53 raise_exception(TT_FP_EXCP);
46 } else { 54 } else {
47 env->fsr |= FSR_NVA; 55 env->fsr |= FSR_NVA;
48 } 56 }
49 } else if (FT0 < FT1) { 57 } else if (FT0 < FT1) {
50 - T0 = FSR_FCC0; 58 + T0 = FSR_FCC0 << FS;
51 } else if (FT0 > FT1) { 59 } else if (FT0 > FT1) {
52 - T0 = FSR_FCC1; 60 + T0 = FSR_FCC1 << FS;
53 } else { 61 } else {
54 T0 = 0; 62 T0 = 0;
55 } 63 }
56 - env->fsr = T0; 64 + env->fsr |= T0;
57 } 65 }
58 66
59 void do_fcmpd (void) 67 void do_fcmpd (void)
60 { 68 {
  69 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  70 + if (isnan(DT0) || isnan(DT1)) {
  71 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  72 + if (env->fsr & FSR_NVM) {
  73 + env->fsr |= T0;
  74 + raise_exception(TT_FP_EXCP);
  75 + } else {
  76 + env->fsr |= FSR_NVA;
  77 + }
  78 + } else if (DT0 < DT1) {
  79 + T0 = FSR_FCC0 << FS;
  80 + } else if (DT0 > DT1) {
  81 + T0 = FSR_FCC1 << FS;
  82 + } else {
  83 + T0 = 0;
  84 + }
  85 + env->fsr |= T0;
  86 +}
  87 +
  88 +#ifdef TARGET_SPARC64
  89 +#undef FS
  90 +#define FS 22
  91 +void do_fcmps_fcc1 (void)
  92 +{
  93 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  94 + if (isnan(FT0) || isnan(FT1)) {
  95 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  96 + if (env->fsr & FSR_NVM) {
  97 + env->fsr |= T0;
  98 + raise_exception(TT_FP_EXCP);
  99 + } else {
  100 + env->fsr |= FSR_NVA;
  101 + }
  102 + } else if (FT0 < FT1) {
  103 + T0 = FSR_FCC0 << FS;
  104 + } else if (FT0 > FT1) {
  105 + T0 = FSR_FCC1 << FS;
  106 + } else {
  107 + T0 = 0;
  108 + }
  109 + env->fsr |= T0;
  110 +}
  111 +
  112 +void do_fcmpd_fcc1 (void)
  113 +{
  114 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  115 + if (isnan(DT0) || isnan(DT1)) {
  116 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  117 + if (env->fsr & FSR_NVM) {
  118 + env->fsr |= T0;
  119 + raise_exception(TT_FP_EXCP);
  120 + } else {
  121 + env->fsr |= FSR_NVA;
  122 + }
  123 + } else if (DT0 < DT1) {
  124 + T0 = FSR_FCC0 << FS;
  125 + } else if (DT0 > DT1) {
  126 + T0 = FSR_FCC1 << FS;
  127 + } else {
  128 + T0 = 0;
  129 + }
  130 + env->fsr |= T0;
  131 +}
  132 +
  133 +#undef FS
  134 +#define FS 24
  135 +void do_fcmps_fcc2 (void)
  136 +{
  137 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  138 + if (isnan(FT0) || isnan(FT1)) {
  139 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  140 + if (env->fsr & FSR_NVM) {
  141 + env->fsr |= T0;
  142 + raise_exception(TT_FP_EXCP);
  143 + } else {
  144 + env->fsr |= FSR_NVA;
  145 + }
  146 + } else if (FT0 < FT1) {
  147 + T0 = FSR_FCC0 << FS;
  148 + } else if (FT0 > FT1) {
  149 + T0 = FSR_FCC1 << FS;
  150 + } else {
  151 + T0 = 0;
  152 + }
  153 + env->fsr |= T0;
  154 +}
  155 +
  156 +void do_fcmpd_fcc2 (void)
  157 +{
  158 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
61 if (isnan(DT0) || isnan(DT1)) { 159 if (isnan(DT0) || isnan(DT1)) {
62 - T0 = FSR_FCC1 | FSR_FCC0;  
63 - env->fsr &= ~(FSR_FCC1 | FSR_FCC0);  
64 - env->fsr |= T0; 160 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
65 if (env->fsr & FSR_NVM) { 161 if (env->fsr & FSR_NVM) {
  162 + env->fsr |= T0;
66 raise_exception(TT_FP_EXCP); 163 raise_exception(TT_FP_EXCP);
67 } else { 164 } else {
68 env->fsr |= FSR_NVA; 165 env->fsr |= FSR_NVA;
69 } 166 }
70 } else if (DT0 < DT1) { 167 } else if (DT0 < DT1) {
71 - T0 = FSR_FCC0; 168 + T0 = FSR_FCC0 << FS;
72 } else if (DT0 > DT1) { 169 } else if (DT0 > DT1) {
73 - T0 = FSR_FCC1; 170 + T0 = FSR_FCC1 << FS;
  171 + } else {
  172 + T0 = 0;
  173 + }
  174 + env->fsr |= T0;
  175 +}
  176 +
  177 +#undef FS
  178 +#define FS 26
  179 +void do_fcmps_fcc3 (void)
  180 +{
  181 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  182 + if (isnan(FT0) || isnan(FT1)) {
  183 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  184 + if (env->fsr & FSR_NVM) {
  185 + env->fsr |= T0;
  186 + raise_exception(TT_FP_EXCP);
  187 + } else {
  188 + env->fsr |= FSR_NVA;
  189 + }
  190 + } else if (FT0 < FT1) {
  191 + T0 = FSR_FCC0 << FS;
  192 + } else if (FT0 > FT1) {
  193 + T0 = FSR_FCC1 << FS;
74 } else { 194 } else {
75 T0 = 0; 195 T0 = 0;
76 } 196 }
77 - env->fsr = T0; 197 + env->fsr |= T0;
78 } 198 }
79 199
  200 +void do_fcmpd_fcc3 (void)
  201 +{
  202 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  203 + if (isnan(DT0) || isnan(DT1)) {
  204 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  205 + if (env->fsr & FSR_NVM) {
  206 + env->fsr |= T0;
  207 + raise_exception(TT_FP_EXCP);
  208 + } else {
  209 + env->fsr |= FSR_NVA;
  210 + }
  211 + } else if (DT0 < DT1) {
  212 + T0 = FSR_FCC0 << FS;
  213 + } else if (DT0 > DT1) {
  214 + T0 = FSR_FCC1 << FS;
  215 + } else {
  216 + T0 = 0;
  217 + }
  218 + env->fsr |= T0;
  219 +}
  220 +#undef FS
  221 +#endif
  222 +
  223 +#ifndef TARGET_SPARC64
80 void helper_ld_asi(int asi, int size, int sign) 224 void helper_ld_asi(int asi, int size, int sign)
81 { 225 {
82 uint32_t ret; 226 uint32_t ret;
@@ -235,6 +379,255 @@ void helper_st_asi(int asi, int size, int sign) @@ -235,6 +379,255 @@ void helper_st_asi(int asi, int size, int sign)
235 } 379 }
236 } 380 }
237 381
  382 +#else
  383 +
  384 +void helper_ld_asi(int asi, int size, int sign)
  385 +{
  386 + uint64_t ret;
  387 +
  388 + if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
  389 + raise_exception(TT_PRIV_INSN);
  390 +
  391 + switch (asi) {
  392 + case 0x14: // Bypass
  393 + case 0x15: // Bypass, non-cacheable
  394 + {
  395 + cpu_physical_memory_read(T0, (void *) &ret, size);
  396 + if (size == 8)
  397 + tswap64s(&ret);
  398 + if (size == 4)
  399 + tswap32s((uint32_t *)&ret);
  400 + else if (size == 2)
  401 + tswap16s((uint16_t *)&ret);
  402 + break;
  403 + }
  404 + case 0x1c: // Bypass LE
  405 + case 0x1d: // Bypass, non-cacheable LE
  406 + // XXX
  407 + break;
  408 + case 0x45: // LSU
  409 + ret = env->lsu;
  410 + break;
  411 + case 0x50: // I-MMU regs
  412 + {
  413 + int reg = (T0 >> 3) & 0xf;
  414 +
  415 + ret = env->immuregs[reg];
  416 + break;
  417 + }
  418 + case 0x51: // I-MMU 8k TSB pointer
  419 + case 0x52: // I-MMU 64k TSB pointer
  420 + case 0x55: // I-MMU data access
  421 + case 0x56: // I-MMU tag read
  422 + break;
  423 + case 0x58: // D-MMU regs
  424 + {
  425 + int reg = (T0 >> 3) & 0xf;
  426 +
  427 + ret = env->dmmuregs[reg];
  428 + break;
  429 + }
  430 + case 0x59: // D-MMU 8k TSB pointer
  431 + case 0x5a: // D-MMU 64k TSB pointer
  432 + case 0x5b: // D-MMU data pointer
  433 + case 0x5d: // D-MMU data access
  434 + case 0x5e: // D-MMU tag read
  435 + break;
  436 + case 0x54: // I-MMU data in, WO
  437 + case 0x57: // I-MMU demap, WO
  438 + case 0x5c: // D-MMU data in, WO
  439 + case 0x5f: // D-MMU demap, WO
  440 + default:
  441 + ret = 0;
  442 + break;
  443 + }
  444 + T1 = ret;
  445 +}
  446 +
  447 +void helper_st_asi(int asi, int size, int sign)
  448 +{
  449 + if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
  450 + raise_exception(TT_PRIV_INSN);
  451 +
  452 + switch(asi) {
  453 + case 0x14: // Bypass
  454 + case 0x15: // Bypass, non-cacheable
  455 + {
  456 + target_ulong temp = T1;
  457 + if (size == 8)
  458 + tswap64s(&temp);
  459 + else if (size == 4)
  460 + tswap32s((uint32_t *)&temp);
  461 + else if (size == 2)
  462 + tswap16s((uint16_t *)&temp);
  463 + cpu_physical_memory_write(T0, (void *) &temp, size);
  464 + }
  465 + return;
  466 + case 0x1c: // Bypass LE
  467 + case 0x1d: // Bypass, non-cacheable LE
  468 + // XXX
  469 + return;
  470 + case 0x45: // LSU
  471 + {
  472 + uint64_t oldreg;
  473 +
  474 + oldreg = env->lsu;
  475 + env->lsu = T1 & (DMMU_E | IMMU_E);
  476 + // Mappings generated during D/I MMU disabled mode are
  477 + // invalid in normal mode
  478 + if (oldreg != env->lsu)
  479 + tlb_flush(env, 1);
  480 + return;
  481 + }
  482 + case 0x50: // I-MMU regs
  483 + {
  484 + int reg = (T0 >> 3) & 0xf;
  485 + uint64_t oldreg;
  486 +
  487 + oldreg = env->immuregs[reg];
  488 + switch(reg) {
  489 + case 0: // RO
  490 + case 4:
  491 + return;
  492 + case 1: // Not in I-MMU
  493 + case 2:
  494 + case 7:
  495 + case 8:
  496 + return;
  497 + case 3: // SFSR
  498 + if ((T1 & 1) == 0)
  499 + T1 = 0; // Clear SFSR
  500 + break;
  501 + case 5: // TSB access
  502 + case 6: // Tag access
  503 + default:
  504 + break;
  505 + }
  506 + env->immuregs[reg] = T1;
  507 +#ifdef DEBUG_MMU
  508 + if (oldreg != env->immuregs[reg]) {
  509 + printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]);
  510 + }
  511 + dump_mmu();
  512 +#endif
  513 + return;
  514 + }
  515 + case 0x54: // I-MMU data in
  516 + {
  517 + unsigned int i;
  518 +
  519 + // Try finding an invalid entry
  520 + for (i = 0; i < 64; i++) {
  521 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
  522 + env->itlb_tag[i] = env->immuregs[6];
  523 + env->itlb_tte[i] = T1;
  524 + return;
  525 + }
  526 + }
  527 + // Try finding an unlocked entry
  528 + for (i = 0; i < 64; i++) {
  529 + if ((env->itlb_tte[i] & 0x40) == 0) {
  530 + env->itlb_tag[i] = env->immuregs[6];
  531 + env->itlb_tte[i] = T1;
  532 + return;
  533 + }
  534 + }
  535 + // error state?
  536 + return;
  537 + }
  538 + case 0x55: // I-MMU data access
  539 + {
  540 + unsigned int i = (T0 >> 3) & 0x3f;
  541 +
  542 + env->itlb_tag[i] = env->immuregs[6];
  543 + env->itlb_tte[i] = T1;
  544 + return;
  545 + }
  546 + case 0x57: // I-MMU demap
  547 + return;
  548 + case 0x58: // D-MMU regs
  549 + {
  550 + int reg = (T0 >> 3) & 0xf;
  551 + uint64_t oldreg;
  552 +
  553 + oldreg = env->dmmuregs[reg];
  554 + switch(reg) {
  555 + case 0: // RO
  556 + case 4:
  557 + return;
  558 + case 3: // SFSR
  559 + if ((T1 & 1) == 0) {
  560 + T1 = 0; // Clear SFSR, Fault address
  561 + env->dmmuregs[4] = 0;
  562 + }
  563 + env->dmmuregs[reg] = T1;
  564 + break;
  565 + case 1: // Primary context
  566 + case 2: // Secondary context
  567 + case 5: // TSB access
  568 + case 6: // Tag access
  569 + case 7: // Virtual Watchpoint
  570 + case 8: // Physical Watchpoint
  571 + default:
  572 + break;
  573 + }
  574 + env->dmmuregs[reg] = T1;
  575 +#ifdef DEBUG_MMU
  576 + if (oldreg != env->dmmuregs[reg]) {
  577 + printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]);
  578 + }
  579 + dump_mmu();
  580 +#endif
  581 + return;
  582 + }
  583 + case 0x5c: // D-MMU data in
  584 + {
  585 + unsigned int i;
  586 +
  587 + // Try finding an invalid entry
  588 + for (i = 0; i < 64; i++) {
  589 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
  590 + env->dtlb_tag[i] = env->dmmuregs[6];
  591 + env->dtlb_tte[i] = T1;
  592 + return;
  593 + }
  594 + }
  595 + // Try finding an unlocked entry
  596 + for (i = 0; i < 64; i++) {
  597 + if ((env->dtlb_tte[i] & 0x40) == 0) {
  598 + env->dtlb_tag[i] = env->dmmuregs[6];
  599 + env->dtlb_tte[i] = T1;
  600 + return;
  601 + }
  602 + }
  603 + // error state?
  604 + return;
  605 + }
  606 + case 0x5d: // D-MMU data access
  607 + {
  608 + unsigned int i = (T0 >> 3) & 0x3f;
  609 +
  610 + env->dtlb_tag[i] = env->dmmuregs[6];
  611 + env->dtlb_tte[i] = T1;
  612 + return;
  613 + }
  614 + case 0x5f: // D-MMU demap
  615 + return;
  616 + case 0x51: // I-MMU 8k TSB pointer, RO
  617 + case 0x52: // I-MMU 64k TSB pointer, RO
  618 + case 0x56: // I-MMU tag read, RO
  619 + case 0x59: // D-MMU 8k TSB pointer, RO
  620 + case 0x5a: // D-MMU 64k TSB pointer, RO
  621 + case 0x5b: // D-MMU data pointer, RO
  622 + case 0x5e: // D-MMU tag read, RO
  623 + default:
  624 + return;
  625 + }
  626 +}
  627 +
  628 +#endif
  629 +
  630 +#ifndef TARGET_SPARC64
238 void helper_rett() 631 void helper_rett()
239 { 632 {
240 unsigned int cwp; 633 unsigned int cwp;
@@ -247,6 +640,7 @@ void helper_rett() @@ -247,6 +640,7 @@ void helper_rett()
247 set_cwp(cwp); 640 set_cwp(cwp);
248 env->psrs = env->psrps; 641 env->psrs = env->psrps;
249 } 642 }
  643 +#endif
250 644
251 void helper_ldfsr(void) 645 void helper_ldfsr(void)
252 { 646 {
@@ -288,6 +682,7 @@ void helper_debug() @@ -288,6 +682,7 @@ void helper_debug()
288 cpu_loop_exit(); 682 cpu_loop_exit();
289 } 683 }
290 684
  685 +#ifndef TARGET_SPARC64
291 void do_wrpsr() 686 void do_wrpsr()
292 { 687 {
293 PUT_PSR(env, T0); 688 PUT_PSR(env, T0);
@@ -297,3 +692,16 @@ void do_rdpsr() @@ -297,3 +692,16 @@ void do_rdpsr()
297 { 692 {
298 T0 = GET_PSR(env); 693 T0 = GET_PSR(env);
299 } 694 }
  695 +
  696 +#else
  697 +
  698 +void do_popc()
  699 +{
  700 + T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
  701 + T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
  702 + T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
  703 + T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
  704 + T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
  705 + T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
  706 +}
  707 +#endif
target-sparc/op_mem.h
@@ -2,9 +2,15 @@ @@ -2,9 +2,15 @@
2 #define SPARC_LD_OP(name, qp) \ 2 #define SPARC_LD_OP(name, qp) \
3 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ 3 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
4 { \ 4 { \
5 - T1 = glue(qp, MEMSUFFIX)(T0); \ 5 + T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
6 } 6 }
7 7
  8 +#define SPARC_LD_OP_S(name, qp) \
  9 + void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
  10 + { \
  11 + T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
  12 + }
  13 +
8 #define SPARC_ST_OP(name, op) \ 14 #define SPARC_ST_OP(name, op) \
9 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ 15 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
10 { \ 16 { \
@@ -14,8 +20,8 @@ void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ @@ -14,8 +20,8 @@ void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
14 SPARC_LD_OP(ld, ldl); 20 SPARC_LD_OP(ld, ldl);
15 SPARC_LD_OP(ldub, ldub); 21 SPARC_LD_OP(ldub, ldub);
16 SPARC_LD_OP(lduh, lduw); 22 SPARC_LD_OP(lduh, lduw);
17 -SPARC_LD_OP(ldsb, ldsb);  
18 -SPARC_LD_OP(ldsh, ldsw); 23 +SPARC_LD_OP_S(ldsb, ldsb);
  24 +SPARC_LD_OP_S(ldsh, ldsw);
19 25
20 /*** Integer store ***/ 26 /*** Integer store ***/
21 SPARC_ST_OP(st, stl); 27 SPARC_ST_OP(st, stl);
@@ -68,4 +74,51 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void) @@ -68,4 +74,51 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void)
68 { 74 {
69 DT0 = glue(ldfq, MEMSUFFIX)(T0); 75 DT0 = glue(ldfq, MEMSUFFIX)(T0);
70 } 76 }
  77 +
  78 +#ifdef TARGET_SPARC64
  79 +/* XXX: Should be Atomically */
  80 +/* XXX: There are no cas[x] instructions, only cas[x]a */
  81 +void OPPROTO glue(op_cas, MEMSUFFIX)(void)
  82 +{
  83 + uint32_t tmp;
  84 +
  85 + tmp = glue(ldl, MEMSUFFIX)(T0);
  86 + T2 &= 0xffffffffULL;
  87 + if (tmp == (T1 & 0xffffffffULL)) {
  88 + glue(stl, MEMSUFFIX)(T0, T2);
  89 + }
  90 + T2 = tmp;
  91 +}
  92 +
  93 +void OPPROTO glue(op_casx, MEMSUFFIX)(void)
  94 +{
  95 + uint64_t tmp;
  96 +
  97 + // XXX
  98 + tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
  99 + tmp |= glue(ldl, MEMSUFFIX)(T0);
  100 + if (tmp == T1) {
  101 + glue(stq, MEMSUFFIX)(T0, T2);
  102 + }
  103 + T2 = tmp;
  104 +}
  105 +
  106 +void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
  107 +{
  108 + T1 = (int64_t)glue(ldl, MEMSUFFIX)(T0);
  109 +}
  110 +
  111 +void OPPROTO glue(op_ldx, MEMSUFFIX)(void)
  112 +{
  113 + // XXX
  114 + T1 = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
  115 + T1 |= glue(ldl, MEMSUFFIX)(T0);
  116 +}
  117 +
  118 +void OPPROTO glue(op_stx, MEMSUFFIX)(void)
  119 +{
  120 + glue(stl, MEMSUFFIX)(T0, T1 >> 32);
  121 + glue(stl, MEMSUFFIX)(T0, T1 & 0xffffffff);
  122 +}
  123 +#endif
71 #undef MEMSUFFIX 124 #undef MEMSUFFIX