Revision 83fa1010

b/hw/etraxfs.c
1
/*
2
 * QEMU ETRAX System Emulator
3
 *
4
 * Copyright (c) 2007 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
#include <time.h>
25
#include <sys/time.h>
26
#include "vl.h"
27

  
28
extern FILE *logfile;
29

  
30
static void main_cpu_reset(void *opaque)
31
{
32
    CPUState *env = opaque;
33
    cpu_reset(env);
34
}
35

  
36
static uint32_t fs_mmio_readb (void *opaque, target_phys_addr_t addr)
37
{
38
	CPUState *env = opaque;
39
	uint32_t r = 0;
40
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
41
	return r;
42
}
43
static uint32_t fs_mmio_readw (void *opaque, target_phys_addr_t addr)
44
{
45
	CPUState *env = opaque;
46
	uint32_t r = 0;
47
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
48
	return r;
49
}
50

  
51
static uint32_t fs_mmio_readl (void *opaque, target_phys_addr_t addr)
52
{
53
	CPUState *env = opaque;
54
	uint32_t r = 0;
55
	printf ("%s %x p=%x\n", __func__, addr, env->pc);
56
	return r;
57
}
58

  
59
static void
60
fs_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
61
{
62
	CPUState *env = opaque;
63
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
64
}
65
static void
66
fs_mmio_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
67
{
68
	CPUState *env = opaque;
69
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
70
}
71
static void
72
fs_mmio_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
73
{
74
	CPUState *env = opaque;
75
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
76
}
77

  
78
static CPUReadMemoryFunc *fs_mmio_read[] = {
79
    &fs_mmio_readb,
80
    &fs_mmio_readw,
81
    &fs_mmio_readl,
82
};
83

  
84
static CPUWriteMemoryFunc *fs_mmio_write[] = {
85
    &fs_mmio_writeb,
86
    &fs_mmio_writew,
87
    &fs_mmio_writel,
88
};
89

  
90

  
91
/* Init functions for different blocks.  */
92
extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs);
93
extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs);
94

  
95
void etrax_ack_irq(CPUState *env, uint32_t mask)
96
{
97
	env->pending_interrupts &= ~mask;
98
}
99

  
100
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
101
{
102
	CPUState *env = opaque;
103

  
104
	/* Hmm, should this really be done here?  */
105
	env->pending_interrupts |= 1 << irq;
106
	cpu_interrupt(env, CPU_INTERRUPT_HARD);
107
}
108

  
109
static
110
void bareetraxfs_init (int ram_size, int vga_ram_size, int boot_device,
111
                       DisplayState *ds, const char **fd_filename, int snapshot,
112
                       const char *kernel_filename, const char *kernel_cmdline,
113
                       const char *initrd_filename, const char *cpu_model)
114
{
115
    CPUState *env;
116
    qemu_irq *irqs;
117
    int kernel_size;
118
    int internal_regs;
119

  
120
    /* init CPUs */
121
    if (cpu_model == NULL) {
122
        cpu_model = "crisv32";
123
    }
124
    env = cpu_init();
125
/*    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */
126
    qemu_register_reset(main_cpu_reset, env);
127
    irqs = qemu_allocate_irqs(dummy_cpu_set_irq, env, 32);
128

  
129
    internal_regs = cpu_register_io_memory(0,
130
					   fs_mmio_read, fs_mmio_write, env);
131
    /* 0xb0050000 is the last reg.  */
132
    cpu_register_physical_memory (0xac000000, 0x4010000, internal_regs);
133
    /* allocate RAM */
134
    cpu_register_physical_memory(0x40000000, ram_size, IO_MEM_RAM);
135

  
136
    etraxfs_timer_init(env, irqs);
137
    etraxfs_ser_init(env, irqs);
138

  
139
    kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000);
140
    /* magic for boot.  */
141
    env->regs[8] = 0x56902387;
142
    env->regs[9] = 0x40004000 + kernel_size;
143
    env->pc = 0x40004000;
144

  
145
    {
146
       unsigned char *ptr = phys_ram_base + 0x4000;
147
       int i;
148
       for (i = 0; i < 8; i++)
149
       {
150
		printf ("%2.2x ", ptr[i]);
151
       }
152
	printf("\n");
153
    }
154

  
155
    printf ("pc =%x\n", env->pc);
156
    printf ("ram size =%d\n", ram_size);
157
    printf ("kernel name =%s\n", kernel_filename);
158
    printf ("kernel size =%d\n", kernel_size);
159
    printf ("cpu haltd =%d\n", env->halted);
160
}
161

  
162
void DMA_run(void)
163
{
164
}
165

  
166
void pic_info()
167
{
168
}
169

  
170
void irq_info()
171
{
172
}
173

  
174
QEMUMachine bareetraxfs_machine = {
175
    "bareetraxfs",
176
    "Bare ETRAX FS board",
177
    bareetraxfs_init,
178
};
b/hw/etraxfs_ser.c
1
/*
2
 * QEMU ETRAX System Emulator
3
 *
4
 * Copyright (c) 2007 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 <ctype.h>
27
#include "vl.h"
28

  
29
#define RW_TR_DMA_EN 0xb0026004
30
#define RW_DOUT 0xb002601c
31
#define RW_STAT_DIN 0xb0026020
32
#define R_STAT_DIN 0xb0026024
33

  
34
static uint32_t ser_readb (void *opaque, target_phys_addr_t addr)
35
{
36
	CPUState *env = opaque;
37
	uint32_t r = 0;
38
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
39
	return r;
40
}
41
static uint32_t ser_readw (void *opaque, target_phys_addr_t addr)
42
{
43
	CPUState *env = opaque;
44
	uint32_t r = 0;
45
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
46
	return r;
47
}
48

  
49
static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
50
{
51
	CPUState *env = opaque;
52
	uint32_t r = 0;
53

  
54
	switch (addr)
55
	{
56
		case RW_TR_DMA_EN:
57
			break;
58
		case R_STAT_DIN:
59
			r |= 1 << 24; /* set tr_rdy.  */
60
			r |= 1 << 22; /* set tr_idle.  */
61
			break;
62

  
63
		default:
64
			printf ("%s %x p=%x\n", __func__, addr, env->pc);
65
			break;
66
	}
67
	return r;
68
}
69

  
70
static void
71
ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
72
{
73
	CPUState *env = opaque;
74
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
75
}
76
static void
77
ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
78
{
79
	CPUState *env = opaque;
80
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
81
}
82
static void
83
ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
84
{
85
	CPUState *env = opaque;
86

  
87
	switch (addr)
88
	{
89
		case RW_TR_DMA_EN:
90
			break;
91
		case RW_DOUT:
92
			if (isprint(value) || isspace(value))
93
				putchar(value);
94
			else
95
				putchar('.');
96
			break;
97
		default:
98
			printf ("%s %x %x pc=%x\n",
99
				__func__, addr, value, env->pc);
100
			break;
101
	}
102
}
103

  
104
static CPUReadMemoryFunc *ser_read[] = {
105
    &ser_readb,
106
    &ser_readw,
107
    &ser_readl,
108
};
109

  
110
static CPUWriteMemoryFunc *ser_write[] = {
111
    &ser_writeb,
112
    &ser_writew,
113
    &ser_writel,
114
};
115

  
116
void etraxfs_ser_init(CPUState *env, qemu_irq *irqs)
117
{
118
	int ser_regs;
119

  
120
	ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env);
121
	cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs);
122
}
b/hw/etraxfs_timer.c
1
/*
2
 * QEMU ETRAX System Emulator
3
 *
4
 * Copyright (c) 2007 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
#include <stdio.h>
25
#include <sys/time.h>
26
#include "vl.h"
27

  
28
void etrax_ack_irq(CPUState *env, uint32_t mask);
29

  
30
#define R_TIME 0xb001e038
31
#define RW_TMR0_DIV 0xb001e000
32
#define R_TMR0_DATA 0xb001e004
33
#define RW_TMR0_CTRL 0xb001e008
34
#define RW_TMR1_DIV 0xb001e010
35
#define R_TMR1_DATA 0xb001e014
36
#define RW_TMR1_CTRL 0xb001e018
37

  
38
#define RW_INTR_MASK 0xb001e048
39
#define RW_ACK_INTR 0xb001e04c
40
#define R_INTR 0xb001e050
41
#define R_MASKED_INTR 0xb001e054
42

  
43

  
44
uint32_t rw_intr_mask;
45
uint32_t rw_ack_intr;
46
uint32_t r_intr;
47

  
48
struct fs_timer_t {
49
	QEMUBH *bh;
50
	unsigned int limit;
51
	int scale;
52
	ptimer_state *ptimer;
53
	CPUState *env;
54
	qemu_irq *irq;
55
	uint32_t mask;
56
};
57

  
58
static struct fs_timer_t timer0;
59

  
60
/* diff two timevals.  Return a single int in us. */
61
int diff_timeval_us(struct timeval *a, struct timeval *b)
62
{
63
        int diff;
64

  
65
        /* assume these values are signed.  */
66
        diff = (a->tv_sec - b->tv_sec) * 1000 * 1000;
67
        diff += (a->tv_usec - b->tv_usec);
68
        return diff;
69
}
70

  
71
static uint32_t timer_readb (void *opaque, target_phys_addr_t addr)
72
{
73
	CPUState *env = opaque;
74
	uint32_t r = 0;
75
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
76
	return r;
77
}
78
static uint32_t timer_readw (void *opaque, target_phys_addr_t addr)
79
{
80
	CPUState *env = opaque;
81
	uint32_t r = 0;
82
	printf ("%s %x pc=%x\n", __func__, addr, env->pc);
83
	return r;
84
}
85

  
86
static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
87
{
88
	CPUState *env = opaque;
89
	uint32_t r = 0;
90

  
91
	switch (addr) {
92
	case R_TMR0_DATA:
93
		break;
94
	case R_TMR1_DATA:
95
		printf ("R_TMR1_DATA\n");
96
		break;
97
	case R_TIME:
98
	{
99
		static struct timeval last;
100
		struct timeval now;
101
		gettimeofday(&now, NULL);
102
		if (!(last.tv_sec == 0 && last.tv_usec == 0)) {
103
			r = diff_timeval_us(&now, &last);
104
			r *= 1000; /* convert to ns.  */
105
			r++; /* make sure we increase for each call.  */
106
		}
107
		last = now;
108
		break;
109
	}
110

  
111
	case RW_INTR_MASK:
112
		r = rw_intr_mask;
113
		break;
114
	case R_MASKED_INTR:
115
		r = r_intr & rw_intr_mask;
116
		break;
117
	default:
118
		printf ("%s %x p=%x\n", __func__, addr, env->pc);
119
		break;
120
	}
121
	return r;
122
}
123

  
124
static void
125
timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
126
{
127
	CPUState *env = opaque;
128
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
129
}
130
static void
131
timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
132
{
133
	CPUState *env = opaque;
134
	printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
135
}
136

  
137
static void write_ctrl(struct fs_timer_t *t, uint32_t v)
138
{
139
	int op;
140
	int freq;
141
	int freq_hz;
142

  
143
	op = v & 3;
144
	freq = v >> 2;
145
	freq_hz = 32000000;
146

  
147
	switch (freq)
148
	{
149
	case 0:
150
	case 1:
151
		printf ("extern or disabled timer clock?\n");
152
		break;
153
	case 4: freq_hz =  29493000; break;
154
	case 5: freq_hz =  32000000; break;
155
	case 6: freq_hz =  32768000; break;
156
	case 7: freq_hz = 100000000; break;
157
	default:
158
		abort();
159
		break;
160
	}
161

  
162
	printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit);
163
	t->scale = 0;
164
	if (t->limit > 2048)
165
	{
166
		t->scale = 2048;
167
		ptimer_set_period(timer0.ptimer, freq_hz / t->scale);
168
	}
169

  
170
	printf ("op=%d\n", op);
171
	switch (op)
172
	{
173
		case 0:
174
			printf ("limit=%d %d\n", t->limit, t->limit/t->scale);
175
			ptimer_set_limit(t->ptimer, t->limit / t->scale, 1);
176
			break;
177
		case 1:
178
			ptimer_stop(t->ptimer);
179
			break;
180
		case 2:
181
			ptimer_run(t->ptimer, 0);
182
			break;
183
		default:
184
			abort();
185
			break;
186
	}
187
}
188

  
189
static void timer_ack_irq(void)
190
{
191
	if (!(r_intr & timer0.mask & rw_intr_mask)) {
192
		qemu_irq_lower(timer0.irq[0]);
193
		etrax_ack_irq(timer0.env, 1 << 0x1b);
194
	}
195
}
196

  
197
static void
198
timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
199
{
200
	CPUState *env = opaque;
201
	printf ("%s %x %x pc=%x\n",
202
		__func__, addr, value, env->pc);
203
	switch (addr)
204
	{
205
		case RW_TMR0_DIV:
206
			printf ("RW_TMR0_DIV=%x\n", value);
207
			timer0.limit = value;
208
			break;
209
		case RW_TMR0_CTRL:
210
			printf ("RW_TMR0_CTRL=%x\n", value);
211
			write_ctrl(&timer0, value);
212
			break;
213
		case RW_TMR1_DIV:
214
			printf ("RW_TMR1_DIV=%x\n", value);
215
			break;
216
		case RW_TMR1_CTRL:
217
			printf ("RW_TMR1_CTRL=%x\n", value);
218
			break;
219
		case RW_INTR_MASK:
220
			printf ("RW_INTR_MASK=%x\n", value);
221
			rw_intr_mask = value;
222
			break;
223
		case RW_ACK_INTR:
224
			r_intr &= ~value;
225
			timer_ack_irq();
226
			break;
227
		default:
228
			printf ("%s %x %x pc=%x\n",
229
				__func__, addr, value, env->pc);
230
			break;
231
	}
232
}
233

  
234
static CPUReadMemoryFunc *timer_read[] = {
235
    &timer_readb,
236
    &timer_readw,
237
    &timer_readl,
238
};
239

  
240
static CPUWriteMemoryFunc *timer_write[] = {
241
    &timer_writeb,
242
    &timer_writew,
243
    &timer_writel,
244
};
245

  
246
static void timer_irq(void *opaque)
247
{
248
	struct fs_timer_t *t = opaque;
249

  
250
	r_intr |= t->mask;
251
	if (t->mask & rw_intr_mask) {
252
		qemu_irq_raise(t->irq[0]);
253
	}
254
}
255

  
256
void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
257
{
258
	int timer_regs;
259

  
260
	timer0.bh = qemu_bh_new(timer_irq, &timer0);
261
	timer0.ptimer = ptimer_init(timer0.bh);
262
	timer0.irq = irqs + 0x1b;
263
	timer0.mask = 1;
264
	timer0.env = env;
265

  
266
	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env);
267
	cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs);
268
}

Also available in: Unified diff