Revision 66321a11
b/cpu-exec.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* i386 emulator main execution loop |
3 | 3 |
* |
4 |
* Copyright (c) 2003 Fabrice Bellard |
|
4 |
* Copyright (c) 2003-2005 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* This library is free software; you can redistribute it and/or |
7 | 7 |
* modify it under the terms of the GNU Lesser General Public |
... | ... | |
285 | 285 |
} |
286 | 286 |
} |
287 | 287 |
#elif defined(TARGET_SPARC) |
288 |
if (interrupt_request & CPU_INTERRUPT_HARD) { |
|
289 |
do_interrupt(env->interrupt_index); |
|
290 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
|
288 |
if ((interrupt_request & CPU_INTERRUPT_HARD) && |
|
289 |
(env->psret != 0)) { |
|
290 |
int pil = env->interrupt_index & 15; |
|
291 |
int type = env->interrupt_index & 0xf0; |
|
292 |
|
|
293 |
if (((type == TT_EXTINT) && |
|
294 |
(pil == 15 || pil > env->psrpil)) || |
|
295 |
type != TT_EXTINT) { |
|
296 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
|
297 |
do_interrupt(env->interrupt_index); |
|
298 |
env->interrupt_index = 0; |
|
299 |
} |
|
291 | 300 |
} else if (interrupt_request & CPU_INTERRUPT_TIMER) { |
292 | 301 |
//do_interrupt(0, 0, 0, 0, 0); |
293 | 302 |
env->interrupt_request &= ~CPU_INTERRUPT_TIMER; |
b/hw/iommu.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU SPARC iommu emulation |
3 | 3 |
* |
4 |
* Copyright (c) 2003 Fabrice Bellard |
|
4 |
* Copyright (c) 2003-2005 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
26 | 26 |
/* debug iommu */ |
27 | 27 |
//#define DEBUG_IOMMU |
28 | 28 |
|
29 |
/* The IOMMU registers occupy three pages in IO space. */ |
|
30 |
struct iommu_regs { |
|
31 |
/* First page */ |
|
32 |
volatile unsigned long control; /* IOMMU control */ |
|
33 |
volatile unsigned long base; /* Physical base of iopte page table */ |
|
34 |
volatile unsigned long _unused1[3]; |
|
35 |
volatile unsigned long tlbflush; /* write only */ |
|
36 |
volatile unsigned long pageflush; /* write only */ |
|
37 |
volatile unsigned long _unused2[1017]; |
|
38 |
/* Second page */ |
|
39 |
volatile unsigned long afsr; /* Async-fault status register */ |
|
40 |
volatile unsigned long afar; /* Async-fault physical address */ |
|
41 |
volatile unsigned long _unused3[2]; |
|
42 |
volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */ |
|
43 |
volatile unsigned long sbuscfg1; |
|
44 |
volatile unsigned long sbuscfg2; |
|
45 |
volatile unsigned long sbuscfg3; |
|
46 |
volatile unsigned long mfsr; /* Memory-fault status register */ |
|
47 |
volatile unsigned long mfar; /* Memory-fault physical address */ |
|
48 |
volatile unsigned long _unused4[1014]; |
|
49 |
/* Third page */ |
|
50 |
volatile unsigned long mid; /* IOMMU module-id */ |
|
51 |
}; |
|
29 |
#ifdef DEBUG_IOMMU |
|
30 |
#define DPRINTF(fmt, args...) \ |
|
31 |
do { printf("IOMMU: " fmt , ##args); } while (0) |
|
32 |
#else |
|
33 |
#define DPRINTF(fmt, args...) |
|
34 |
#endif |
|
52 | 35 |
|
36 |
#define IOMMU_NREGS (3*4096) |
|
53 | 37 |
#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */ |
54 | 38 |
#define IOMMU_CTRL_VERS 0x0f000000 /* Version */ |
55 | 39 |
#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */ |
... | ... | |
63 | 47 |
#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */ |
64 | 48 |
#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */ |
65 | 49 |
|
66 |
#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */ |
|
67 |
#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */ |
|
68 |
#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */ |
|
69 |
#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */ |
|
70 |
#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */ |
|
71 |
#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */ |
|
72 |
#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */ |
|
73 |
#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */ |
|
74 |
#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */ |
|
75 |
#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */ |
|
76 |
|
|
77 |
#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */ |
|
78 |
#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */ |
|
79 |
#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */ |
|
80 |
#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses |
|
81 |
produced by this device as pure |
|
82 |
physical. */ |
|
83 |
|
|
84 |
#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */ |
|
85 |
#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */ |
|
86 |
#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */ |
|
87 |
#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */ |
|
88 |
#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred |
|
89 |
on the even word of the access, low bit |
|
90 |
indicated odd word caused the parity error */ |
|
91 |
#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */ |
|
92 |
#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */ |
|
93 |
#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */ |
|
94 |
|
|
95 |
#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */ |
|
96 |
#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */ |
|
97 |
#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */ |
|
98 |
#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */ |
|
99 |
#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */ |
|
100 |
#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */ |
|
101 |
#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */ |
|
102 |
|
|
103 | 50 |
/* The format of an iopte in the page tables */ |
104 | 51 |
#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */ |
105 | 52 |
#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */ |
... | ... | |
113 | 60 |
|
114 | 61 |
typedef struct IOMMUState { |
115 | 62 |
uint32_t addr; |
116 |
uint32_t regs[sizeof(struct iommu_regs)];
|
|
63 |
uint32_t regs[IOMMU_NREGS];
|
|
117 | 64 |
uint32_t iostart; |
118 | 65 |
} IOMMUState; |
119 | 66 |
|
... | ... | |
125 | 72 |
saddr = (addr - s->addr) >> 2; |
126 | 73 |
switch (saddr) { |
127 | 74 |
default: |
75 |
DPRINTF("read reg[%d] = %x\n", saddr, s->regs[saddr]); |
|
128 | 76 |
return s->regs[saddr]; |
129 | 77 |
break; |
130 | 78 |
} |
... | ... | |
137 | 85 |
uint32_t saddr; |
138 | 86 |
|
139 | 87 |
saddr = (addr - s->addr) >> 2; |
88 |
DPRINTF("write reg[%d] = %x\n", saddr, val); |
|
140 | 89 |
switch (saddr) { |
141 | 90 |
case 0: |
142 | 91 |
switch (val & IOMMU_CTRL_RNGE) { |
... | ... | |
166 | 115 |
s->iostart = 0x80000000; |
167 | 116 |
break; |
168 | 117 |
} |
118 |
DPRINTF("iostart = %x\n", s->iostart); |
|
169 | 119 |
/* Fall through */ |
170 | 120 |
default: |
171 | 121 |
s->regs[saddr] = val; |
... | ... | |
188 | 138 |
uint32_t iommu_translate_local(void *opaque, uint32_t addr) |
189 | 139 |
{ |
190 | 140 |
IOMMUState *s = opaque; |
191 |
uint32_t *iopte = (void *)(s->regs[1] << 4), pa;
|
|
141 |
uint32_t iopte, pa, tmppte;
|
|
192 | 142 |
|
193 |
iopte += ((addr - s->iostart) >> PAGE_SHIFT); |
|
194 |
cpu_physical_memory_read((uint32_t)iopte, (void *) &pa, 4); |
|
143 |
iopte = s->regs[1] << 4; |
|
144 |
addr &= ~s->iostart; |
|
145 |
iopte += (addr >> (PAGE_SHIFT - 2)) & ~3; |
|
146 |
cpu_physical_memory_read(iopte, (void *) &pa, 4); |
|
195 | 147 |
bswap32s(&pa); |
196 |
pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */ |
|
197 |
return pa + (addr & PAGE_MASK); |
|
148 |
tmppte = pa; |
|
149 |
pa = ((pa & IOPTE_PAGE) << 4) + (addr & PAGE_MASK); |
|
150 |
DPRINTF("xlate dva %x => pa %x (iopte[%x] = %x)\n", addr, pa, iopte, tmppte); |
|
151 |
return pa; |
|
198 | 152 |
} |
199 | 153 |
|
200 | 154 |
static void iommu_save(QEMUFile *f, void *opaque) |
... | ... | |
203 | 157 |
int i; |
204 | 158 |
|
205 | 159 |
qemu_put_be32s(f, &s->addr); |
206 |
for (i = 0; i < sizeof(struct iommu_regs); i += 4)
|
|
160 |
for (i = 0; i < IOMMU_NREGS; i++)
|
|
207 | 161 |
qemu_put_be32s(f, &s->regs[i]); |
208 | 162 |
qemu_put_be32s(f, &s->iostart); |
209 | 163 |
} |
... | ... | |
217 | 171 |
return -EINVAL; |
218 | 172 |
|
219 | 173 |
qemu_get_be32s(f, &s->addr); |
220 |
for (i = 0; i < sizeof(struct iommu_regs); i += 4)
|
|
174 |
for (i = 0; i < IOMMU_NREGS; i++)
|
|
221 | 175 |
qemu_put_be32s(f, &s->regs[i]); |
222 | 176 |
qemu_get_be32s(f, &s->iostart); |
223 | 177 |
|
... | ... | |
228 | 182 |
{ |
229 | 183 |
IOMMUState *s = opaque; |
230 | 184 |
|
231 |
memset(s->regs, 0, sizeof(struct iommu_regs));
|
|
185 |
memset(s->regs, 0, IOMMU_NREGS * 4);
|
|
232 | 186 |
s->iostart = 0; |
233 | 187 |
} |
234 | 188 |
|
... | ... | |
244 | 198 |
s->addr = addr; |
245 | 199 |
|
246 | 200 |
iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s); |
247 |
cpu_register_physical_memory(addr, sizeof(struct iommu_regs), |
|
248 |
iommu_io_memory); |
|
201 |
cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory); |
|
249 | 202 |
|
250 | 203 |
register_savevm("iommu", addr, 1, iommu_save, iommu_load, s); |
251 | 204 |
qemu_register_reset(iommu_reset, s); |
b/hw/lance.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU Lance emulation |
3 | 3 |
* |
4 |
* Copyright (c) 2003-2004 Fabrice Bellard
|
|
4 |
* Copyright (c) 2003-2005 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
26 | 26 |
/* debug LANCE card */ |
27 | 27 |
//#define DEBUG_LANCE |
28 | 28 |
|
29 |
#ifdef DEBUG_LANCE |
|
30 |
#define DPRINTF(fmt, args...) \ |
|
31 |
do { printf("LANCE: " fmt , ##args); } while (0) |
|
32 |
#else |
|
33 |
#define DPRINTF(fmt, args...) |
|
34 |
#endif |
|
35 |
|
|
29 | 36 |
#ifndef LANCE_LOG_TX_BUFFERS |
30 | 37 |
#define LANCE_LOG_TX_BUFFERS 4 |
31 | 38 |
#define LANCE_LOG_RX_BUFFERS 4 |
32 | 39 |
#endif |
33 | 40 |
|
34 |
#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ |
|
35 |
#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ |
|
36 |
|
|
37 |
|
|
38 | 41 |
#define LE_CSR0 0 |
39 | 42 |
#define LE_CSR1 1 |
40 | 43 |
#define LE_CSR2 2 |
41 | 44 |
#define LE_CSR3 3 |
42 |
#define LE_MAXREG (LE_CSR3 + 1) |
|
45 |
#define LE_NREGS (LE_CSR3 + 1) |
|
46 |
#define LE_MAXREG LE_CSR3 |
|
43 | 47 |
|
44 | 48 |
#define LE_RDP 0 |
45 | 49 |
#define LE_RAP 1 |
... | ... | |
148 | 152 |
|
149 | 153 |
#define LEDMA_REGS 4 |
150 | 154 |
#define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1) |
151 |
#if 0 |
|
152 |
/* Structure to describe the current status of DMA registers on the Sparc */ |
|
153 |
struct sparc_dma_registers { |
|
154 |
uint32_t cond_reg; /* DMA condition register */ |
|
155 |
uint32_t st_addr; /* Start address of this transfer */ |
|
156 |
uint32_t cnt; /* How many bytes to transfer */ |
|
157 |
uint32_t dma_test; /* DMA test register */ |
|
158 |
}; |
|
159 |
#endif |
|
160 | 155 |
|
161 | 156 |
typedef struct LANCEState { |
162 | 157 |
NetDriverState *nd; |
163 | 158 |
uint32_t leptr; |
164 | 159 |
uint16_t addr; |
165 |
uint16_t regs[LE_MAXREG];
|
|
160 |
uint16_t regs[LE_NREGS];
|
|
166 | 161 |
uint8_t phys[6]; /* mac address */ |
167 | 162 |
int irq; |
168 | 163 |
unsigned int rxptr, txptr; |
... | ... | |
177 | 172 |
memcpy(s->phys, s->nd->macaddr, 6); |
178 | 173 |
s->rxptr = 0; |
179 | 174 |
s->txptr = 0; |
180 |
memset(s->regs, 0, LE_MAXREG * 2);
|
|
175 |
memset(s->regs, 0, LE_NREGS * 2);
|
|
181 | 176 |
s->regs[LE_CSR0] = LE_C0_STOP; |
182 | 177 |
memset(s->ledmaregs, 0, LEDMA_REGS * 4); |
183 | 178 |
} |
... | ... | |
190 | 185 |
saddr = addr & LE_MAXREG; |
191 | 186 |
switch (saddr >> 1) { |
192 | 187 |
case LE_RDP: |
188 |
DPRINTF("read dreg[%d] = %4.4x\n", s->addr, s->regs[s->addr]); |
|
193 | 189 |
return s->regs[s->addr]; |
194 | 190 |
case LE_RAP: |
191 |
DPRINTF("read areg = %4.4x\n", s->addr); |
|
195 | 192 |
return s->addr; |
196 | 193 |
default: |
194 |
DPRINTF("read unknown(%d)\n", saddr>>1); |
|
197 | 195 |
break; |
198 | 196 |
} |
199 | 197 |
return 0; |
... | ... | |
208 | 206 |
saddr = addr & LE_MAXREG; |
209 | 207 |
switch (saddr >> 1) { |
210 | 208 |
case LE_RDP: |
209 |
DPRINTF("write dreg[%d] = %4.4x\n", s->addr, val); |
|
211 | 210 |
switch(s->addr) { |
212 | 211 |
case LE_CSR0: |
213 | 212 |
if (val & LE_C0_STOP) { |
... | ... | |
242 | 241 |
} |
243 | 242 |
|
244 | 243 |
s->regs[LE_CSR0] = reg; |
245 |
|
|
246 |
// trigger bits |
|
247 |
//if (val & LE_C0_TDMD) |
|
248 |
|
|
249 |
if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA)) |
|
250 |
pic_set_irq(s->irq, 1); |
|
251 | 244 |
break; |
252 | 245 |
case LE_CSR1: |
253 | 246 |
s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff); |
... | ... | |
263 | 256 |
} |
264 | 257 |
break; |
265 | 258 |
case LE_RAP: |
266 |
if (val < LE_MAXREG) |
|
259 |
DPRINTF("write areg = %4.4x\n", val); |
|
260 |
if (val < LE_NREGS) |
|
267 | 261 |
s->addr = val; |
268 | 262 |
break; |
269 | 263 |
default: |
264 |
DPRINTF("write unknown(%d) = %4.4x\n", saddr>>1, val); |
|
270 | 265 |
break; |
271 | 266 |
} |
272 | 267 |
lance_send(s); |
... | ... | |
292 | 287 |
uint32_t dmaptr = s->leptr + s->ledmaregs[3]; |
293 | 288 |
struct lance_init_block *ib; |
294 | 289 |
int i; |
295 |
uint16_t temp;
|
|
290 |
uint8_t temp8;
|
|
296 | 291 |
|
297 | 292 |
if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP) |
298 | 293 |
return 0; |
... | ... | |
300 | 295 |
ib = (void *) iommu_translate(dmaptr); |
301 | 296 |
|
302 | 297 |
for (i = 0; i < RX_RING_SIZE; i++) { |
303 |
cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); |
|
304 |
temp &= 0xff; |
|
305 |
if (temp == (LE_R1_OWN)) { |
|
306 |
#ifdef DEBUG_LANCE |
|
307 |
fprintf(stderr, "lance: can receive %d\n", RX_BUFF_SIZE); |
|
308 |
#endif |
|
298 |
cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1); |
|
299 |
if (temp8 == (LE_R1_OWN)) { |
|
300 |
DPRINTF("can receive %d\n", RX_BUFF_SIZE); |
|
309 | 301 |
return RX_BUFF_SIZE; |
310 | 302 |
} |
311 | 303 |
} |
312 |
#ifdef DEBUG_LANCE |
|
313 |
fprintf(stderr, "lance: cannot receive\n"); |
|
314 |
#endif |
|
304 |
DPRINTF("cannot receive\n"); |
|
315 | 305 |
return 0; |
316 | 306 |
} |
317 | 307 |
|
... | ... | |
322 | 312 |
LANCEState *s = opaque; |
323 | 313 |
uint32_t dmaptr = s->leptr + s->ledmaregs[3]; |
324 | 314 |
struct lance_init_block *ib; |
325 |
unsigned int i, old_rxptr, j; |
|
326 |
uint16_t temp; |
|
315 |
unsigned int i, old_rxptr; |
|
316 |
uint16_t temp16; |
|
317 |
uint8_t temp8; |
|
327 | 318 |
|
319 |
DPRINTF("receive size %d\n", size); |
|
328 | 320 |
if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP) |
329 | 321 |
return; |
330 | 322 |
|
... | ... | |
332 | 324 |
|
333 | 325 |
old_rxptr = s->rxptr; |
334 | 326 |
for (i = s->rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) { |
335 |
cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); |
|
336 |
if (temp == (LE_R1_OWN)) { |
|
327 |
cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
|
|
328 |
if (temp8 == (LE_R1_OWN)) {
|
|
337 | 329 |
s->rxptr = (s->rxptr + 1) & RX_RING_MOD_MASK; |
338 |
temp = size; |
|
339 |
bswap16s(&temp); |
|
340 |
cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp, 2); |
|
341 |
#if 0 |
|
330 |
temp16 = size + 4; |
|
331 |
bswap16s(&temp16); |
|
332 |
cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp16, 2); |
|
342 | 333 |
cpu_physical_memory_write((uint32_t)&ib->rx_buf[i], buf, size); |
343 |
#else |
|
344 |
for (j = 0; j < size; j++) { |
|
345 |
cpu_physical_memory_write(((uint32_t)&ib->rx_buf[i]) + j, &buf[j], 1); |
|
346 |
} |
|
347 |
#endif |
|
348 |
temp = LE_R1_POK; |
|
349 |
cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); |
|
334 |
temp8 = LE_R1_POK; |
|
335 |
cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1); |
|
350 | 336 |
s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR; |
351 |
if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
|
|
337 |
if (s->regs[LE_CSR0] & LE_C0_INEA)
|
|
352 | 338 |
pic_set_irq(s->irq, 1); |
353 |
#ifdef DEBUG_LANCE |
|
354 |
fprintf(stderr, "lance: got packet, len %d\n", size); |
|
355 |
#endif |
|
339 |
DPRINTF("got packet, len %d\n", size); |
|
356 | 340 |
return; |
357 | 341 |
} |
358 | 342 |
} |
... | ... | |
363 | 347 |
LANCEState *s = opaque; |
364 | 348 |
uint32_t dmaptr = s->leptr + s->ledmaregs[3]; |
365 | 349 |
struct lance_init_block *ib; |
366 |
unsigned int i, old_txptr, j; |
|
367 |
uint16_t temp; |
|
350 |
unsigned int i, old_txptr; |
|
351 |
uint16_t temp16; |
|
352 |
uint8_t temp8; |
|
368 | 353 |
char pkt_buf[PKT_BUF_SZ]; |
369 | 354 |
|
355 |
DPRINTF("sending packet? (csr0 %4.4x)\n", s->regs[LE_CSR0]); |
|
370 | 356 |
if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP) |
371 | 357 |
return; |
372 | 358 |
|
373 | 359 |
ib = (void *) iommu_translate(dmaptr); |
374 | 360 |
|
361 |
DPRINTF("sending packet? (dmaptr %8.8x) (ib %p) (btx_ring %p)\n", dmaptr, ib, &ib->btx_ring); |
|
375 | 362 |
old_txptr = s->txptr; |
376 | 363 |
for (i = s->txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) { |
377 |
cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1); |
|
378 |
if (temp == (LE_T1_POK|LE_T1_OWN)) { |
|
379 |
cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp, 2); |
|
380 |
bswap16s(&temp); |
|
381 |
temp = (~temp) + 1; |
|
382 |
#if 0 |
|
383 |
cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp); |
|
384 |
#else |
|
385 |
for (j = 0; j < temp; j++) { |
|
386 |
cpu_physical_memory_read((uint32_t)&ib->tx_buf[i] + j, &pkt_buf[j], 1); |
|
387 |
} |
|
388 |
#endif |
|
389 |
|
|
390 |
#ifdef DEBUG_LANCE |
|
391 |
fprintf(stderr, "lance: sending packet, len %d\n", temp); |
|
392 |
#endif |
|
393 |
qemu_send_packet(s->nd, pkt_buf, temp); |
|
394 |
temp = LE_T1_POK; |
|
395 |
cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1); |
|
364 |
cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1); |
|
365 |
if (temp8 == (LE_T1_POK|LE_T1_OWN)) { |
|
366 |
cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp16, 2); |
|
367 |
bswap16s(&temp16); |
|
368 |
temp16 = (~temp16) + 1; |
|
369 |
cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16); |
|
370 |
DPRINTF("sending packet, len %d\n", temp16); |
|
371 |
qemu_send_packet(s->nd, pkt_buf, temp16); |
|
372 |
temp8 = LE_T1_POK; |
|
373 |
cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1); |
|
396 | 374 |
s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK; |
397 | 375 |
s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR; |
398 | 376 |
} |
399 | 377 |
} |
378 |
if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA)) |
|
379 |
pic_set_irq(s->irq, 1); |
|
400 | 380 |
} |
401 | 381 |
|
402 | 382 |
static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr) |
... | ... | |
436 | 416 |
|
437 | 417 |
qemu_put_be32s(f, &s->leptr); |
438 | 418 |
qemu_put_be16s(f, &s->addr); |
439 |
for (i = 0; i < LE_MAXREG; i ++)
|
|
419 |
for (i = 0; i < LE_NREGS; i ++)
|
|
440 | 420 |
qemu_put_be16s(f, &s->regs[i]); |
441 | 421 |
qemu_put_buffer(f, s->phys, 6); |
442 | 422 |
qemu_put_be32s(f, &s->irq); |
... | ... | |
454 | 434 |
|
455 | 435 |
qemu_get_be32s(f, &s->leptr); |
456 | 436 |
qemu_get_be16s(f, &s->addr); |
457 |
for (i = 0; i < LE_MAXREG; i ++)
|
|
437 |
for (i = 0; i < LE_NREGS; i ++)
|
|
458 | 438 |
qemu_get_be16s(f, &s->regs[i]); |
459 | 439 |
qemu_get_buffer(f, s->phys, 6); |
460 | 440 |
qemu_get_be32s(f, &s->irq); |
... | ... | |
476 | 456 |
s->irq = irq; |
477 | 457 |
|
478 | 458 |
lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s); |
479 |
cpu_register_physical_memory(leaddr, 8, lance_io_memory);
|
|
459 |
cpu_register_physical_memory(leaddr, 4, lance_io_memory);
|
|
480 | 460 |
|
481 | 461 |
ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s); |
482 | 462 |
cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); |
b/hw/slavio_intctl.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU Sparc SLAVIO interrupt controller emulation |
3 | 3 |
* |
4 |
* Copyright (c) 2003-2004 Fabrice Bellard
|
|
4 |
* Copyright (c) 2003-2005 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
23 | 23 |
*/ |
24 | 24 |
#include "vl.h" |
25 | 25 |
//#define DEBUG_IRQ_COUNT |
26 |
//#define DEBUG_IRQ |
|
27 |
|
|
28 |
#ifdef DEBUG_IRQ |
|
29 |
#define DPRINTF(fmt, args...) \ |
|
30 |
do { printf("IRQ: " fmt , ##args); } while (0) |
|
31 |
#else |
|
32 |
#define DPRINTF(fmt, args...) |
|
33 |
#endif |
|
26 | 34 |
|
27 | 35 |
/* |
28 | 36 |
* Registers of interrupt controller in sun4m. |
... | ... | |
49 | 57 |
|
50 | 58 |
#define INTCTL_MAXADDR 0xf |
51 | 59 |
#define INTCTLM_MAXADDR 0xf |
60 |
static void slavio_check_interrupts(void *opaque); |
|
52 | 61 |
|
53 | 62 |
// per-cpu interrupt controller |
54 | 63 |
static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr) |
... | ... | |
82 | 91 |
val |= 80000000; |
83 | 92 |
val &= 0xfffe0000; |
84 | 93 |
s->intreg_pending[cpu] &= ~val; |
94 |
DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
|
85 | 95 |
break; |
86 | 96 |
case 2: // set softint |
87 | 97 |
val &= 0xfffe0000; |
88 | 98 |
s->intreg_pending[cpu] |= val; |
99 |
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
|
89 | 100 |
break; |
90 | 101 |
default: |
91 | 102 |
break; |
... | ... | |
135 | 146 |
// Force clear unused bits |
136 | 147 |
val &= ~0x7fb2007f; |
137 | 148 |
s->intregm_disabled &= ~val; |
149 |
DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); |
|
150 |
slavio_check_interrupts(s); |
|
138 | 151 |
break; |
139 | 152 |
case 3: // set (disable, clear pending) |
140 | 153 |
// Force clear unused bits |
141 | 154 |
val &= ~0x7fb2007f; |
142 | 155 |
s->intregm_disabled |= val; |
143 | 156 |
s->intregm_pending &= ~val; |
157 |
DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); |
|
144 | 158 |
break; |
145 | 159 |
case 4: |
146 | 160 |
s->target_cpu = val & (MAX_CPUS - 1); |
161 |
DPRINTF("Set master irq cpu %d\n", s->target_cpu); |
|
147 | 162 |
break; |
148 | 163 |
default: |
149 | 164 |
break; |
... | ... | |
196 | 211 |
6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0, |
197 | 212 |
}; |
198 | 213 |
|
214 |
static void slavio_check_interrupts(void *opaque) |
|
215 |
{ |
|
216 |
SLAVIO_INTCTLState *s = opaque; |
|
217 |
uint32_t pending = s->intregm_pending; |
|
218 |
unsigned int i, max = 0; |
|
219 |
|
|
220 |
pending &= ~s->intregm_disabled; |
|
221 |
|
|
222 |
if (pending && !(s->intregm_disabled & 0x80000000)) { |
|
223 |
for (i = 0; i < 32; i++) { |
|
224 |
if (pending & (1 << i)) { |
|
225 |
if (max < intbit_to_level[i]) |
|
226 |
max = intbit_to_level[i]; |
|
227 |
} |
|
228 |
} |
|
229 |
if (cpu_single_env->interrupt_index == 0) { |
|
230 |
DPRINTF("Triggered pil %d\n", max); |
|
231 |
#ifdef DEBUG_IRQ_COUNT |
|
232 |
s->irq_count[max]++; |
|
233 |
#endif |
|
234 |
cpu_single_env->interrupt_index = TT_EXTINT | max; |
|
235 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
|
236 |
} |
|
237 |
else |
|
238 |
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, cpu_single_env->interrupt_index); |
|
239 |
} |
|
240 |
else |
|
241 |
DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled); |
|
242 |
} |
|
243 |
|
|
199 | 244 |
/* |
200 | 245 |
* "irq" here is the bit number in the system interrupt register to |
201 | 246 |
* separate serial and keyboard interrupts sharing a level. |
... | ... | |
204 | 249 |
{ |
205 | 250 |
SLAVIO_INTCTLState *s = opaque; |
206 | 251 |
|
252 |
DPRINTF("Set irq %d level %d\n", irq, level); |
|
207 | 253 |
if (irq < 32) { |
208 | 254 |
uint32_t mask = 1 << irq; |
209 | 255 |
uint32_t pil = intbit_to_level[irq]; |
... | ... | |
216 | 262 |
s->intregm_pending &= ~mask; |
217 | 263 |
s->intreg_pending[s->target_cpu] &= ~(1 << pil); |
218 | 264 |
} |
219 |
if (level && |
|
220 |
!(s->intregm_disabled & mask) && |
|
221 |
!(s->intregm_disabled & 0x80000000) && |
|
222 |
(pil == 15 || (pil > cpu_single_env->psrpil && cpu_single_env->psret == 1))) { |
|
223 |
#ifdef DEBUG_IRQ_COUNT |
|
224 |
if (level == 1) |
|
225 |
s->irq_count[pil]++; |
|
226 |
#endif |
|
227 |
cpu_single_env->interrupt_index = TT_EXTINT | pil; |
|
228 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
|
229 |
} |
|
230 | 265 |
} |
231 | 266 |
} |
267 |
slavio_check_interrupts(s); |
|
232 | 268 |
} |
233 | 269 |
|
234 | 270 |
static void slavio_intctl_save(QEMUFile *f, void *opaque) |
b/hw/slavio_timer.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU Sparc SLAVIO timer controller emulation |
3 | 3 |
* |
4 |
* Copyright (c) 2003-2004 Fabrice Bellard
|
|
4 |
* Copyright (c) 2003-2005 Fabrice Bellard
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
25 | 25 |
|
26 | 26 |
//#define DEBUG_TIMER |
27 | 27 |
|
28 |
#ifdef DEBUG_TIMER |
|
29 |
#define DPRINTF(fmt, args...) \ |
|
30 |
do { printf("TIMER: " fmt , ##args); } while (0) |
|
31 |
#else |
|
32 |
#define DPRINTF(fmt, args...) |
|
33 |
#endif |
|
34 |
|
|
28 | 35 |
/* |
29 | 36 |
* Registers of hardware timer in sun4m. |
30 | 37 |
* |
... | ... | |
90 | 97 |
// Convert remaining counter ticks to CPU ticks |
91 | 98 |
s->expire_time = ticks + muldiv64(limit - count, ticks_per_sec, CNT_FREQ); |
92 | 99 |
|
93 |
#ifdef DEBUG_TIMER |
|
94 |
term_printf("timer: irq %d limit %d reached %d d %lld count %d s->c %x diff %lld stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode); |
|
95 |
#endif |
|
100 |
DPRINTF("irq %d limit %d reached %d d %lld count %d s->c %x diff %lld stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode); |
|
101 |
|
|
96 | 102 |
if (s->mode != 1) |
97 | 103 |
pic_set_irq(s->irq, out); |
98 | 104 |
} |
Also available in: Unified diff