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 | } | ... | ... |