Commit e62b5b133b97e07711741e2a4e2bf3e4dbc254f8

Authored by edgar_igl
1 parent 1ec6d2ea

* Add a model of the ETRAX interrupt controller.

* Clean up the interrupt handling a bit.
* Connect some NOR flash to the test board.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4055 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -565,9 +565,12 @@ CPPFLAGS += -DHAS_AUDIO @@ -565,9 +565,12 @@ CPPFLAGS += -DHAS_AUDIO
565 endif 565 endif
566 ifeq ($(TARGET_BASE_ARCH), cris) 566 ifeq ($(TARGET_BASE_ARCH), cris)
567 OBJS+= etraxfs.o 567 OBJS+= etraxfs.o
568 -OBJS+= ptimer.o 568 +OBJS+= etraxfs_pic.o
569 OBJS+= etraxfs_timer.o 569 OBJS+= etraxfs_timer.o
570 OBJS+= etraxfs_ser.o 570 OBJS+= etraxfs_ser.o
  571 +
  572 +OBJS+= ptimer.o
  573 +OBJS+= pflash_cfi01.o
571 endif 574 endif
572 ifeq ($(TARGET_BASE_ARCH), sparc) 575 ifeq ($(TARGET_BASE_ARCH), sparc)
573 ifeq ($(TARGET_ARCH), sparc64) 576 ifeq ($(TARGET_ARCH), sparc64)
cpu-exec.c
@@ -556,7 +556,6 @@ int cpu_exec(CPUState *env1) @@ -556,7 +556,6 @@ int cpu_exec(CPUState *env1)
556 #elif defined(TARGET_CRIS) 556 #elif defined(TARGET_CRIS)
557 if (interrupt_request & CPU_INTERRUPT_HARD) { 557 if (interrupt_request & CPU_INTERRUPT_HARD) {
558 do_interrupt(env); 558 do_interrupt(env);
559 - env->interrupt_request &= ~CPU_INTERRUPT_HARD;  
560 BREAK_CHAIN; 559 BREAK_CHAIN;
561 } 560 }
562 #elif defined(TARGET_M68K) 561 #elif defined(TARGET_M68K)
@@ -1181,10 +1180,6 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1181,10 +1180,6 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1181 a virtual CPU fault */ 1180 a virtual CPU fault */
1182 cpu_restore_state(tb, env, pc, puc); 1181 cpu_restore_state(tb, env, pc, puc);
1183 } 1182 }
1184 -#if 0  
1185 - printf("PF exception: NIP=0x%08x error=0x%x %p\n",  
1186 - env->nip, env->error_code, tb);  
1187 -#endif  
1188 /* we restore the process signal mask as the sigreturn should 1183 /* we restore the process signal mask as the sigreturn should
1189 do it (XXX: use sigsetjmp) */ 1184 do it (XXX: use sigsetjmp) */
1190 sigprocmask(SIG_SETMASK, old_set, NULL); 1185 sigprocmask(SIG_SETMASK, old_set, NULL);
hw/etraxfs.c
@@ -25,89 +25,21 @@ @@ -25,89 +25,21 @@
25 #include <sys/time.h> 25 #include <sys/time.h>
26 #include "hw.h" 26 #include "hw.h"
27 #include "sysemu.h" 27 #include "sysemu.h"
  28 +#include "flash.h"
28 #include "boards.h" 29 #include "boards.h"
29 30
30 -extern FILE *logfile;  
31 -  
32 static void main_cpu_reset(void *opaque) 31 static void main_cpu_reset(void *opaque)
33 { 32 {
34 CPUState *env = opaque; 33 CPUState *env = opaque;
35 cpu_reset(env); 34 cpu_reset(env);
36 } 35 }
37 36
38 -static uint32_t fs_mmio_readb (void *opaque, target_phys_addr_t addr)  
39 -{  
40 - CPUState *env = opaque;  
41 - uint32_t r = 0;  
42 - printf ("%s %x pc=%x\n", __func__, addr, env->pc);  
43 - return r;  
44 -}  
45 -static uint32_t fs_mmio_readw (void *opaque, target_phys_addr_t addr)  
46 -{  
47 - CPUState *env = opaque;  
48 - uint32_t r = 0;  
49 - printf ("%s %x pc=%x\n", __func__, addr, env->pc);  
50 - return r;  
51 -}  
52 -  
53 -static uint32_t fs_mmio_readl (void *opaque, target_phys_addr_t addr)  
54 -{  
55 - CPUState *env = opaque;  
56 - uint32_t r = 0;  
57 - printf ("%s %x p=%x\n", __func__, addr, env->pc);  
58 - return r;  
59 -}  
60 -  
61 -static void  
62 -fs_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)  
63 -{  
64 - CPUState *env = opaque;  
65 - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);  
66 -}  
67 -static void  
68 -fs_mmio_writew (void *opaque, target_phys_addr_t addr, uint32_t value)  
69 -{  
70 - CPUState *env = opaque;  
71 - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);  
72 -}  
73 -static void  
74 -fs_mmio_writel (void *opaque, target_phys_addr_t addr, uint32_t value)  
75 -{  
76 - CPUState *env = opaque;  
77 - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);  
78 -}  
79 -  
80 -static CPUReadMemoryFunc *fs_mmio_read[] = {  
81 - &fs_mmio_readb,  
82 - &fs_mmio_readw,  
83 - &fs_mmio_readl,  
84 -};  
85 -  
86 -static CPUWriteMemoryFunc *fs_mmio_write[] = {  
87 - &fs_mmio_writeb,  
88 - &fs_mmio_writew,  
89 - &fs_mmio_writel,  
90 -};  
91 -  
92 -  
93 /* Init functions for different blocks. */ 37 /* Init functions for different blocks. */
  38 +extern qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base);
  39 +/* TODO: Make these blocks relocate:able. */
94 extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs); 40 extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs);
95 extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs); 41 extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs);
96 42
97 -void etrax_ack_irq(CPUState *env, uint32_t mask)  
98 -{  
99 - env->pending_interrupts &= ~mask;  
100 -}  
101 -  
102 -static void dummy_cpu_set_irq(void *opaque, int irq, int level)  
103 -{  
104 - CPUState *env = opaque;  
105 -  
106 - /* Hmm, should this really be done here? */  
107 - env->pending_interrupts |= 1 << irq;  
108 - cpu_interrupt(env, CPU_INTERRUPT_HARD);  
109 -}  
110 -  
111 static 43 static
112 void bareetraxfs_init (int ram_size, int vga_ram_size, 44 void bareetraxfs_init (int ram_size, int vga_ram_size,
113 const char *boot_device, DisplayState *ds, 45 const char *boot_device, DisplayState *ds,
@@ -115,9 +47,12 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, @@ -115,9 +47,12 @@ void bareetraxfs_init (int ram_size, int vga_ram_size,
115 const char *initrd_filename, const char *cpu_model) 47 const char *initrd_filename, const char *cpu_model)
116 { 48 {
117 CPUState *env; 49 CPUState *env;
118 - qemu_irq *irqs; 50 + qemu_irq *pic;
119 int kernel_size; 51 int kernel_size;
120 - int internal_regs; 52 + int flash_size = 0x800000;
  53 + int index;
  54 + ram_addr_t phys_flash;
  55 + ram_addr_t phys_ram;
121 56
122 /* init CPUs */ 57 /* init CPUs */
123 if (cpu_model == NULL) { 58 if (cpu_model == NULL) {
@@ -126,17 +61,31 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, @@ -126,17 +61,31 @@ void bareetraxfs_init (int ram_size, int vga_ram_size,
126 env = cpu_init(cpu_model); 61 env = cpu_init(cpu_model);
127 /* register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */ 62 /* register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */
128 qemu_register_reset(main_cpu_reset, env); 63 qemu_register_reset(main_cpu_reset, env);
129 - irqs = qemu_allocate_irqs(dummy_cpu_set_irq, env, 32);  
130 64
131 - internal_regs = cpu_register_io_memory(0,  
132 - fs_mmio_read, fs_mmio_write, env);  
133 - /* 0xb0050000 is the last reg. */  
134 - cpu_register_physical_memory (0xac000000, 0x4010000, internal_regs);  
135 /* allocate RAM */ 65 /* allocate RAM */
136 - cpu_register_physical_memory(0x40000000, ram_size, IO_MEM_RAM);  
137 -  
138 - etraxfs_timer_init(env, irqs);  
139 - etraxfs_ser_init(env, irqs); 66 + phys_ram = qemu_ram_alloc(ram_size);
  67 + cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
  68 + /* Unached mapping. */
  69 + cpu_register_physical_memory(0xc0000000, ram_size, phys_ram | IO_MEM_RAM);
  70 +
  71 + phys_flash = qemu_ram_alloc(flash_size);
  72 + cpu_register_physical_memory(0,flash_size, IO_MEM_ROM);
  73 + cpu_register_physical_memory(0x80000000, flash_size, IO_MEM_ROM);
  74 + cpu_register_physical_memory(0x04000000, flash_size, IO_MEM_ROM);
  75 + cpu_register_physical_memory(0x84000000, flash_size,
  76 + 0x04000000 | IO_MEM_ROM);
  77 + index = drive_get_index(IF_PFLASH, 0, 0);
  78 + pflash_cfi01_register(0x80000000, flash_size,
  79 + drives_table[index].bdrv, 65536, flash_size >> 16,
  80 + 4, 0x0000, 0x0000, 0x0000, 0x0000);
  81 + index = drive_get_index(IF_PFLASH, 0, 1);
  82 + pflash_cfi01_register(0x84000000, flash_size,
  83 + drives_table[index].bdrv, 65536, flash_size >> 16,
  84 + 4, 0x0000, 0x0000, 0x0000, 0x0000);
  85 +
  86 + pic = etraxfs_pic_init(env, 0xb001c000);
  87 + etraxfs_timer_init(env, pic);
  88 + etraxfs_ser_init(env, pic);
140 89
141 kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); 90 kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000);
142 /* magic for boot. */ 91 /* magic for boot. */
@@ -165,14 +114,6 @@ void DMA_run(void) @@ -165,14 +114,6 @@ void DMA_run(void)
165 { 114 {
166 } 115 }
167 116
168 -void pic_info()  
169 -{  
170 -}  
171 -  
172 -void irq_info()  
173 -{  
174 -}  
175 -  
176 QEMUMachine bareetraxfs_machine = { 117 QEMUMachine bareetraxfs_machine = {
177 "bareetraxfs", 118 "bareetraxfs",
178 "Bare ETRAX FS board", 119 "Bare ETRAX FS board",
hw/etraxfs_pic.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU ETRAX Interrupt Controller.
  3 + *
  4 + * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
  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 +
  25 +#include <stdio.h>
  26 +#include "hw.h"
  27 +
  28 +#define D(x)
  29 +
  30 +struct fs_pic_state_t
  31 +{
  32 + CPUState *env;
  33 + target_ulong base;
  34 +
  35 + uint32_t rw_mask;
  36 + /* Active interrupt lines. */
  37 + uint32_t r_vect;
  38 + /* Active lines, gated through the mask. */
  39 + uint32_t r_masked_vect;
  40 + uint32_t r_nmi;
  41 + uint32_t r_guru;
  42 +};
  43 +
  44 +static uint32_t pic_readb (void *opaque, target_phys_addr_t addr)
  45 +{
  46 + return 0;
  47 +}
  48 +static uint32_t pic_readw (void *opaque, target_phys_addr_t addr)
  49 +{
  50 + return 0;
  51 +}
  52 +
  53 +static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
  54 +{
  55 + struct fs_pic_state_t *fs = opaque;
  56 + uint32_t rval;
  57 +
  58 + /* Transform this to a relative addr. */
  59 + addr -= fs->base;
  60 + switch (addr)
  61 + {
  62 + case 0x0:
  63 + rval = fs->rw_mask;
  64 + break;
  65 + case 0x4:
  66 + rval = fs->r_vect;
  67 + break;
  68 + case 0x8:
  69 + rval = fs->r_masked_vect;
  70 + break;
  71 + case 0xc:
  72 + rval = fs->r_nmi;
  73 + break;
  74 + case 0x10:
  75 + rval = fs->r_guru;
  76 + break;
  77 + default:
  78 + cpu_abort(fs->env, "invalid PIC register.\n");
  79 + break;
  80 +
  81 + }
  82 + D(printf("%s %x=%x\n", __func__, addr, rval));
  83 + return rval;
  84 +}
  85 +
  86 +static void
  87 +pic_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
  88 +{
  89 +}
  90 +
  91 +static void
  92 +pic_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
  93 +{
  94 +}
  95 +
  96 +static void
  97 +pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  98 +{
  99 + struct fs_pic_state_t *fs = opaque;
  100 + D(printf("%s addr=%x val=%x\n", __func__, addr, value));
  101 + /* Transform this to a relative addr. */
  102 + addr -= fs->base;
  103 + switch (addr)
  104 + {
  105 + case 0x0:
  106 + fs->rw_mask = value;
  107 + break;
  108 + case 0x4:
  109 + fs->r_vect = value;
  110 + break;
  111 + case 0x8:
  112 + fs->r_masked_vect = value;
  113 + break;
  114 + case 0xc:
  115 + fs->r_nmi = value;
  116 + break;
  117 + case 0x10:
  118 + fs->r_guru = value;
  119 + break;
  120 + default:
  121 + cpu_abort(fs->env, "invalid PIC register.\n");
  122 + break;
  123 + }
  124 +}
  125 +
  126 +static CPUReadMemoryFunc *pic_read[] = {
  127 + &pic_readb,
  128 + &pic_readw,
  129 + &pic_readl,
  130 +};
  131 +
  132 +static CPUWriteMemoryFunc *pic_write[] = {
  133 + &pic_writeb,
  134 + &pic_writew,
  135 + &pic_writel,
  136 +};
  137 +
  138 +void pic_info(void)
  139 +{
  140 +}
  141 +
  142 +void irq_info(void)
  143 +{
  144 +}
  145 +
  146 +static void etraxfs_pic_handler(void *opaque, int irq, int level)
  147 +{
  148 + struct fs_pic_state_t *fs = (void *)opaque;
  149 + CPUState *env = fs->env;
  150 + int i;
  151 + uint32_t vector = 0;
  152 +
  153 + D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n",
  154 + __func__, irq, level,
  155 + fs->rw_mask, fs->r_vect, fs->r_masked_vect));
  156 +
  157 + fs->r_vect &= ~(1 << irq);
  158 + fs->r_vect |= (!!level << irq);
  159 + fs->r_masked_vect = fs->r_vect & fs->rw_mask;
  160 +
  161 + /* The ETRAX interrupt controller signals interrupts to teh core
  162 + through an interrupt request wire and an irq vector bus. If
  163 + multiple interrupts are simultaneously active it chooses vector
  164 + 0x30 and lets the sw choose the priorities. */
  165 + if (fs->r_masked_vect) {
  166 + uint32_t mv = fs->r_masked_vect;
  167 + for (i = 0; i < 31; i++) {
  168 + if (mv & 1) {
  169 + vector = 0x31 + i;
  170 + /* Check for multiple interrupts. */
  171 + if (mv > 1)
  172 + vector = 0x30;
  173 + break;
  174 + }
  175 + mv >>= 1;
  176 + }
  177 + if (vector) {
  178 + env->interrupt_vector = vector;
  179 + D(printf("%s vector=%x\n", __func__, vector));
  180 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  181 + }
  182 + } else {
  183 + env->interrupt_vector = 0;
  184 + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
  185 + D(printf("%s reset irqs\n", __func__));
  186 + }
  187 +}
  188 +
  189 +qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base)
  190 +{
  191 + struct fs_pic_state_t *fs;
  192 + qemu_irq *pic;
  193 + int intr_vect_regs;
  194 +
  195 + fs = qemu_mallocz(sizeof *fs);
  196 + if (!fs)
  197 + return NULL;
  198 + fs->env = env;
  199 +
  200 + pic = qemu_allocate_irqs(etraxfs_pic_handler, fs, 30);
  201 +
  202 + intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
  203 + cpu_register_physical_memory(base, 0x14, intr_vect_regs);
  204 + fs->base = base;
  205 +
  206 + return pic;
  207 +}
hw/etraxfs_ser.c
@@ -66,7 +66,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) @@ -66,7 +66,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
66 break; 66 break;
67 67
68 default: 68 default:
69 - printf ("%s %x p=%x\n", __func__, addr, env->pc); 69 + D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
70 break; 70 break;
71 } 71 }
72 return r; 72 return r;
@@ -100,10 +100,11 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -100,10 +100,11 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
100 putchar(value); 100 putchar(value);
101 else 101 else
102 putchar('.'); 102 putchar('.');
  103 + fflush(stdout);
103 break; 104 break;
104 default: 105 default:
105 - printf ("%s %x %x pc=%x\n",  
106 - __func__, addr, value, env->pc); 106 + D(printf ("%s %x %x pc=%x\n",
  107 + __func__, addr, value, env->pc));
107 break; 108 break;
108 } 109 }
109 } 110 }
hw/etraxfs_timer.c
1 /* 1 /*
2 - * QEMU ETRAX System Emulator 2 + * QEMU ETRAX Timers
3 * 3 *
4 * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB. 4 * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
5 * 5 *
@@ -28,8 +28,6 @@ @@ -28,8 +28,6 @@
28 28
29 #define D(x) 29 #define D(x)
30 30
31 -void etrax_ack_irq(CPUState *env, uint32_t mask);  
32 -  
33 #define R_TIME 0xb001e038 31 #define R_TIME 0xb001e038
34 #define RW_TMR0_DIV 0xb001e000 32 #define RW_TMR0_DIV 0xb001e000
35 #define R_TMR0_DATA 0xb001e004 33 #define R_TMR0_DATA 0xb001e004
@@ -38,16 +36,12 @@ void etrax_ack_irq(CPUState *env, uint32_t mask); @@ -38,16 +36,12 @@ void etrax_ack_irq(CPUState *env, uint32_t mask);
38 #define R_TMR1_DATA 0xb001e014 36 #define R_TMR1_DATA 0xb001e014
39 #define RW_TMR1_CTRL 0xb001e018 37 #define RW_TMR1_CTRL 0xb001e018
40 38
  39 +#define RW_WD_CTRL 0xb001e040
41 #define RW_INTR_MASK 0xb001e048 40 #define RW_INTR_MASK 0xb001e048
42 #define RW_ACK_INTR 0xb001e04c 41 #define RW_ACK_INTR 0xb001e04c
43 #define R_INTR 0xb001e050 42 #define R_INTR 0xb001e050
44 #define R_MASKED_INTR 0xb001e054 43 #define R_MASKED_INTR 0xb001e054
45 44
46 -  
47 -uint32_t rw_intr_mask;  
48 -uint32_t rw_ack_intr;  
49 -uint32_t r_intr;  
50 -  
51 struct fs_timer_t { 45 struct fs_timer_t {
52 QEMUBH *bh; 46 QEMUBH *bh;
53 unsigned int limit; 47 unsigned int limit;
@@ -57,6 +51,10 @@ struct fs_timer_t { @@ -57,6 +51,10 @@ struct fs_timer_t {
57 qemu_irq *irq; 51 qemu_irq *irq;
58 uint32_t mask; 52 uint32_t mask;
59 struct timeval last; 53 struct timeval last;
  54 +
  55 + uint32_t rw_intr_mask;
  56 + uint32_t rw_ack_intr;
  57 + uint32_t r_intr;
60 }; 58 };
61 59
62 static struct fs_timer_t timer[2]; 60 static struct fs_timer_t timer[2];
@@ -126,13 +124,13 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) @@ -126,13 +124,13 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
126 } 124 }
127 125
128 case RW_INTR_MASK: 126 case RW_INTR_MASK:
129 - r = rw_intr_mask; 127 + r = timer[t].rw_intr_mask;
130 break; 128 break;
131 case R_MASKED_INTR: 129 case R_MASKED_INTR:
132 - r = r_intr & rw_intr_mask; 130 + r = timer[t].r_intr & timer[t].rw_intr_mask;
133 break; 131 break;
134 default: 132 default:
135 - printf ("%s %x p=%x\n", __func__, addr, env->pc); 133 + D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
136 break; 134 break;
137 } 135 }
138 return r; 136 return r;
@@ -167,7 +165,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) @@ -167,7 +165,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v)
167 { 165 {
168 case 0: 166 case 0:
169 case 1: 167 case 1:
170 - printf ("extern or disabled timer clock?\n"); 168 + D(printf ("extern or disabled timer clock?\n"));
171 break; 169 break;
172 case 4: freq_hz = 29493000; break; 170 case 4: freq_hz = 29493000; break;
173 case 5: freq_hz = 32000000; break; 171 case 5: freq_hz = 32000000; break;
@@ -178,7 +176,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) @@ -178,7 +176,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v)
178 break; 176 break;
179 } 177 }
180 178
181 - printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit); 179 + D(printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit));
182 t->scale = 0; 180 t->scale = 0;
183 if (t->limit > 2048) 181 if (t->limit > 2048)
184 { 182 {
@@ -186,11 +184,11 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) @@ -186,11 +184,11 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v)
186 ptimer_set_period(t->ptimer, freq_hz / t->scale); 184 ptimer_set_period(t->ptimer, freq_hz / t->scale);
187 } 185 }
188 186
189 - printf ("op=%d\n", op);  
190 switch (op) 187 switch (op)
191 { 188 {
192 case 0: 189 case 0:
193 - printf ("limit=%d %d\n", t->limit, t->limit/t->scale); 190 + D(printf ("limit=%d %d\n",
  191 + t->limit, t->limit/t->scale));
194 ptimer_set_limit(t->ptimer, t->limit / t->scale, 1); 192 ptimer_set_limit(t->ptimer, t->limit / t->scale, 1);
195 break; 193 break;
196 case 1: 194 case 1:
@@ -207,10 +205,8 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) @@ -207,10 +205,8 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v)
207 205
208 static void timer_ack_irq(struct fs_timer_t *t) 206 static void timer_ack_irq(struct fs_timer_t *t)
209 { 207 {
210 - if (!(r_intr & t->mask & rw_intr_mask)) { 208 + if (!(t->r_intr & t->mask & t->rw_intr_mask))
211 qemu_irq_lower(t->irq[0]); 209 qemu_irq_lower(t->irq[0]);
212 - etrax_ack_irq(t->env, 1 << 0x1b);  
213 - }  
214 } 210 }
215 211
216 static void 212 static void
@@ -239,10 +235,13 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -239,10 +235,13 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
239 break; 235 break;
240 case RW_INTR_MASK: 236 case RW_INTR_MASK:
241 D(printf ("RW_INTR_MASK=%x\n", value)); 237 D(printf ("RW_INTR_MASK=%x\n", value));
242 - rw_intr_mask = value; 238 + timer[t].rw_intr_mask = value;
  239 + break;
  240 + case RW_WD_CTRL:
  241 + D(printf ("RW_WD_CTRL=%x\n", value));
243 break; 242 break;
244 case RW_ACK_INTR: 243 case RW_ACK_INTR:
245 - r_intr &= ~value; 244 + timer[t].r_intr &= ~value;
246 timer_ack_irq(&timer[t]); 245 timer_ack_irq(&timer[t]);
247 break; 246 break;
248 default: 247 default:
@@ -267,8 +266,9 @@ static CPUWriteMemoryFunc *timer_write[] = { @@ -267,8 +266,9 @@ static CPUWriteMemoryFunc *timer_write[] = {
267 static void timer_irq(void *opaque) 266 static void timer_irq(void *opaque)
268 { 267 {
269 struct fs_timer_t *t = opaque; 268 struct fs_timer_t *t = opaque;
270 - r_intr |= t->mask;  
271 - if (t->mask & rw_intr_mask) { 269 + t->r_intr |= t->mask;
  270 + if (t->mask & t->rw_intr_mask) {
  271 + D(printf("%s raise\n", __func__));
272 qemu_irq_raise(t->irq[0]); 272 qemu_irq_raise(t->irq[0]);
273 } 273 }
274 } 274 }
@@ -279,13 +279,13 @@ void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) @@ -279,13 +279,13 @@ void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
279 279
280 timer[0].bh = qemu_bh_new(timer_irq, &timer[0]); 280 timer[0].bh = qemu_bh_new(timer_irq, &timer[0]);
281 timer[0].ptimer = ptimer_init(timer[0].bh); 281 timer[0].ptimer = ptimer_init(timer[0].bh);
282 - timer[0].irq = irqs + 0x1b; 282 + timer[0].irq = irqs + 26;
283 timer[0].mask = 1; 283 timer[0].mask = 1;
284 timer[0].env = env; 284 timer[0].env = env;
285 285
286 timer[1].bh = qemu_bh_new(timer_irq, &timer[1]); 286 timer[1].bh = qemu_bh_new(timer_irq, &timer[1]);
287 timer[1].ptimer = ptimer_init(timer[1].bh); 287 timer[1].ptimer = ptimer_init(timer[1].bh);
288 - timer[1].irq = irqs + 0x1b; 288 + timer[1].irq = irqs + 26;
289 timer[1].mask = 1; 289 timer[1].mask = 1;
290 timer[1].env = env; 290 timer[1].env = env;
291 291
target-cris/helper.c
@@ -28,6 +28,8 @@ @@ -28,6 +28,8 @@
28 #include "exec-all.h" 28 #include "exec-all.h"
29 #include "host-utils.h" 29 #include "host-utils.h"
30 30
  31 +#define D(x)
  32 +
31 #if defined(CONFIG_USER_ONLY) 33 #if defined(CONFIG_USER_ONLY)
32 34
33 void do_interrupt (CPUState *env) 35 void do_interrupt (CPUState *env)
@@ -53,71 +55,68 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) @@ -53,71 +55,68 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
53 55
54 #else /* !CONFIG_USER_ONLY */ 56 #else /* !CONFIG_USER_ONLY */
55 57
  58 +
  59 +static void cris_shift_ccs(CPUState *env)
  60 +{
  61 + uint32_t ccs;
  62 + /* Apply the ccs shift. */
  63 + ccs = env->pregs[PR_CCS];
  64 + ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
  65 + env->pregs[PR_CCS] = ccs;
  66 +}
  67 +
56 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 68 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
57 int mmu_idx, int is_softmmu) 69 int mmu_idx, int is_softmmu)
58 { 70 {
59 struct cris_mmu_result_t res; 71 struct cris_mmu_result_t res;
60 int prot, miss; 72 int prot, miss;
  73 + int r = -1;
61 target_ulong phy; 74 target_ulong phy;
62 75
  76 + D(printf ("%s addr=%x pc=%x\n", __func__, address, env->pc));
63 address &= TARGET_PAGE_MASK; 77 address &= TARGET_PAGE_MASK;
64 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 78 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
65 miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); 79 miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
66 if (miss) 80 if (miss)
67 { 81 {
68 - /* handle the miss. */  
69 - phy = 0;  
70 - env->exception_index = EXCP_MMU_MISS; 82 + env->exception_index = EXCP_MMU_FAULT;
  83 + env->fault_vector = res.bf_vec;
  84 + r = 1;
71 } 85 }
72 else 86 else
73 { 87 {
74 phy = res.phy; 88 phy = res.phy;
  89 + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  90 + r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
75 } 91 }
76 - return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);  
77 -}  
78 -  
79 -  
80 -static void cris_shift_ccs(CPUState *env)  
81 -{  
82 - uint32_t ccs;  
83 - /* Apply the ccs shift. */  
84 - ccs = env->pregs[PR_CCS];  
85 - ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);  
86 - env->pregs[PR_CCS] = ccs; 92 + D(printf("%s returns %d irqreq=%x addr=%x ismmu=%d\n",
  93 + __func__, r, env->interrupt_request,
  94 + address, is_softmmu));
  95 + return r;
87 } 96 }
88 97
89 void do_interrupt(CPUState *env) 98 void do_interrupt(CPUState *env)
90 { 99 {
91 - uint32_t ebp, isr;  
92 - int irqnum;  
93 -  
94 - fflush(NULL); 100 + int ex_vec = -1;
95 101
96 -#if 0  
97 - printf ("exception index=%d interrupt_req=%d\n",  
98 - env->exception_index,  
99 - env->interrupt_request);  
100 -#endif 102 + D(fprintf (stderr, "exception index=%d interrupt_req=%d\n",
  103 + env->exception_index,
  104 + env->interrupt_request));
101 105
102 switch (env->exception_index) 106 switch (env->exception_index)
103 { 107 {
104 case EXCP_BREAK: 108 case EXCP_BREAK:
105 - irqnum = env->trapnr;  
106 - ebp = env->pregs[PR_EBP];  
107 - isr = ldl_code(ebp + irqnum * 4); 109 + /* These exceptions are genereated by the core itself.
  110 + ERP should point to the insn following the brk. */
  111 + ex_vec = env->trap_vector;
108 env->pregs[PR_ERP] = env->pc + 2; 112 env->pregs[PR_ERP] = env->pc + 2;
109 - env->pc = isr;  
110 -  
111 - cris_shift_ccs(env);  
112 -  
113 break; 113 break;
114 - case EXCP_MMU_MISS:  
115 - irqnum = 4;  
116 - ebp = env->pregs[PR_EBP];  
117 - isr = ldl_code(ebp + irqnum * 4);  
118 - env->pregs[PR_ERP] = env->pc;  
119 - env->pc = isr;  
120 - cris_shift_ccs(env); 114 +
  115 + case EXCP_MMU_FAULT:
  116 + /* ERP is already setup by translate-all.c through
  117 + re-translation of the aborted TB combined with
  118 + pc searching. */
  119 + ex_vec = env->fault_vector;
121 break; 120 break;
122 121
123 default: 122 default:
@@ -125,34 +124,29 @@ void do_interrupt(CPUState *env) @@ -125,34 +124,29 @@ void do_interrupt(CPUState *env)
125 /* Maybe the irq was acked by sw before we got a 124 /* Maybe the irq was acked by sw before we got a
126 change to take it. */ 125 change to take it. */
127 if (env->interrupt_request & CPU_INTERRUPT_HARD) { 126 if (env->interrupt_request & CPU_INTERRUPT_HARD) {
128 - if (!env->pending_interrupts) 127 + /* Vectors below 0x30 are internal
  128 + exceptions, i.e not interrupt requests
  129 + from the interrupt controller. */
  130 + if (env->interrupt_vector < 0x30)
129 return; 131 return;
  132 + /* Is the core accepting interrupts? */
130 if (!(env->pregs[PR_CCS] & I_FLAG)) { 133 if (!(env->pregs[PR_CCS] & I_FLAG)) {
131 return; 134 return;
132 } 135 }
133 -  
134 - irqnum = 31 - clz32(env->pending_interrupts);  
135 - irqnum += 0x30;  
136 - ebp = env->pregs[PR_EBP];  
137 - isr = ldl_code(ebp + irqnum * 4); 136 + /* The interrupt controller gives us the
  137 + vector. */
  138 + ex_vec = env->interrupt_vector;
  139 + /* Normal interrupts are taken between
  140 + TB's. env->pc is valid here. */
138 env->pregs[PR_ERP] = env->pc; 141 env->pregs[PR_ERP] = env->pc;
139 - env->pc = isr;  
140 -  
141 - cris_shift_ccs(env);  
142 -#if 0  
143 - printf ("%s ebp=%x %x isr=%x %d"  
144 - " ir=%x pending=%x\n",  
145 - __func__,  
146 - ebp, ebp + irqnum * 4,  
147 - isr, env->exception_index,  
148 - env->interrupt_request,  
149 - env->pending_interrupts);  
150 -#endif  
151 } 142 }
152 -  
153 } 143 }
154 break; 144 break;
155 } 145 }
  146 + env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
  147 + /* Apply the CRIS CCS shift. */
  148 + cris_shift_ccs(env);
  149 + D(printf ("%s ebp=%x isr=%x vec=%x\n", __func__, ebp, isr, ex_vec));
156 } 150 }
157 151
158 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) 152 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
@@ -163,6 +157,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) @@ -163,6 +157,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
163 miss = cris_mmu_translate(&res, env, addr, 0, 0); 157 miss = cris_mmu_translate(&res, env, addr, 0, 0);
164 if (!miss) 158 if (!miss)
165 phy = res.phy; 159 phy = res.phy;
  160 + D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
166 return phy; 161 return phy;
167 } 162 }
168 #endif 163 #endif
translate-all.c
@@ -286,6 +286,8 @@ int cpu_restore_state(TranslationBlock *tb, @@ -286,6 +286,8 @@ int cpu_restore_state(TranslationBlock *tb,
286 #elif defined(TARGET_SH4) 286 #elif defined(TARGET_SH4)
287 env->pc = gen_opc_pc[j]; 287 env->pc = gen_opc_pc[j];
288 env->flags = gen_opc_hflags[j]; 288 env->flags = gen_opc_hflags[j];
  289 +#elif defined(TARGET_CRIS)
  290 + env->pregs[PR_ERP] = gen_opc_pc[j];
289 #endif 291 #endif
290 292
291 #ifdef CONFIG_PROFILER 293 #ifdef CONFIG_PROFILER