Commit 66321a11a4ef45942b3bee7377a36bb94831365a
1 parent
c44644bb
sparc update (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1350 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
153 additions
and
169 deletions
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,9 +285,18 @@ int cpu_exec(CPUState *env1) |
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; | ... | ... |
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,30 +26,14 @@ |
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,43 +47,6 @@ struct iommu_regs { |
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,7 +60,7 @@ struct iommu_regs { |
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,6 +72,7 @@ static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) |
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,6 +85,7 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
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,6 +115,7 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
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,13 +138,17 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = { |
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,7 +157,7 @@ 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,7 +171,7 @@ static int iommu_load(QEMUFile *f, void *opaque, int version_id) |
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,7 +182,7 @@ static void iommu_reset(void *opaque) |
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,8 +198,7 @@ void *iommu_init(uint32_t addr) |
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); | ... | ... |
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,20 +26,24 @@ |
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,21 +152,12 @@ struct lance_init_block { |
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,7 +172,7 @@ static void lance_reset(void *opaque) |
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,10 +185,13 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) |
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,6 +206,7 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
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,12 +241,6 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
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,10 +256,12 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
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,7 +287,7 @@ static int lance_can_receive(void *opaque) |
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,18 +295,13 @@ static int lance_can_receive(void *opaque) |
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,9 +312,11 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size) |
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,27 +324,19 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size) |
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,40 +347,36 @@ static void lance_send(void *opaque) |
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,7 +416,7 @@ static void lance_save(QEMUFile *f, void *opaque) |
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,7 +434,7 @@ static int lance_load(QEMUFile *f, void *opaque, int version_id) |
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,7 +456,7 @@ void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr) |
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); | ... | ... |
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,6 +23,14 @@ |
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,6 +57,7 @@ typedef struct SLAVIO_INTCTLState { |
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,10 +91,12 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint |
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,15 +146,19 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uin |
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,6 +211,36 @@ static const uint32_t intbit_to_level[32] = { |
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,6 +249,7 @@ void slavio_pic_set_irq(void *opaque, int irq, int 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,19 +262,9 @@ void slavio_pic_set_irq(void *opaque, int irq, int level) |
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) | ... | ... |
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,6 +25,13 @@ |
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,9 +97,8 @@ static void slavio_timer_get_out(SLAVIO_TIMERState *s) |
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 | } | ... | ... |