Commit 4e3b1ea1b87237827905292fdb59917ccd252f5c
1 parent
4f6200f0
sparc merge (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1578 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
63 additions
and
6 deletions
hw/iommu.c
| ... | ... | @@ -33,9 +33,11 @@ do { printf("IOMMU: " fmt , ##args); } while (0) |
| 33 | 33 | #define DPRINTF(fmt, args...) |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | -#define IOMMU_NREGS (3*4096) | |
| 36 | +#define IOMMU_NREGS (3*4096/4) | |
| 37 | +#define IOMMU_CTRL (0x0000 >> 2) | |
| 37 | 38 | #define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */ |
| 38 | 39 | #define IOMMU_CTRL_VERS 0x0f000000 /* Version */ |
| 40 | +#define IOMMU_VERSION 0x04000000 | |
| 39 | 41 | #define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */ |
| 40 | 42 | #define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */ |
| 41 | 43 | #define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */ |
| ... | ... | @@ -46,6 +48,32 @@ do { printf("IOMMU: " fmt , ##args); } while (0) |
| 46 | 48 | #define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */ |
| 47 | 49 | #define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */ |
| 48 | 50 | #define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */ |
| 51 | +#define IOMMU_CTRL_MASK 0x0000001d | |
| 52 | + | |
| 53 | +#define IOMMU_BASE (0x0004 >> 2) | |
| 54 | +#define IOMMU_BASE_MASK 0x07fffc00 | |
| 55 | + | |
| 56 | +#define IOMMU_TLBFLUSH (0x0014 >> 2) | |
| 57 | +#define IOMMU_TLBFLUSH_MASK 0xffffffff | |
| 58 | + | |
| 59 | +#define IOMMU_PGFLUSH (0x0018 >> 2) | |
| 60 | +#define IOMMU_PGFLUSH_MASK 0xffffffff | |
| 61 | + | |
| 62 | +#define IOMMU_SBCFG0 (0x1010 >> 2) /* SBUS configration per-slot */ | |
| 63 | +#define IOMMU_SBCFG1 (0x1014 >> 2) /* SBUS configration per-slot */ | |
| 64 | +#define IOMMU_SBCFG2 (0x1018 >> 2) /* SBUS configration per-slot */ | |
| 65 | +#define IOMMU_SBCFG3 (0x101c >> 2) /* SBUS configration per-slot */ | |
| 66 | +#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */ | |
| 67 | +#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */ | |
| 68 | +#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */ | |
| 69 | +#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses | |
| 70 | + produced by this device as pure | |
| 71 | + physical. */ | |
| 72 | +#define IOMMU_SBCFG_MASK 0x00010003 | |
| 73 | + | |
| 74 | +#define IOMMU_ARBEN (0x2000 >> 2) /* SBUS arbitration enable */ | |
| 75 | +#define IOMMU_ARBEN_MASK 0x001f0000 | |
| 76 | +#define IOMMU_MID 0x00000008 | |
| 49 | 77 | |
| 50 | 78 | /* The format of an iopte in the page tables */ |
| 51 | 79 | #define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */ |
| ... | ... | @@ -87,7 +115,7 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
| 87 | 115 | saddr = (addr - s->addr) >> 2; |
| 88 | 116 | DPRINTF("write reg[%d] = %x\n", saddr, val); |
| 89 | 117 | switch (saddr) { |
| 90 | - case 0: | |
| 118 | + case IOMMU_CTRL: | |
| 91 | 119 | switch (val & IOMMU_CTRL_RNGE) { |
| 92 | 120 | case IOMMU_RNGE_16MB: |
| 93 | 121 | s->iostart = 0xff000000; |
| ... | ... | @@ -116,7 +144,30 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
| 116 | 144 | break; |
| 117 | 145 | } |
| 118 | 146 | DPRINTF("iostart = %x\n", s->iostart); |
| 119 | - /* Fall through */ | |
| 147 | + s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | IOMMU_VERSION); | |
| 148 | + break; | |
| 149 | + case IOMMU_BASE: | |
| 150 | + s->regs[saddr] = val & IOMMU_BASE_MASK; | |
| 151 | + break; | |
| 152 | + case IOMMU_TLBFLUSH: | |
| 153 | + DPRINTF("tlb flush %x\n", val); | |
| 154 | + s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK; | |
| 155 | + break; | |
| 156 | + case IOMMU_PGFLUSH: | |
| 157 | + DPRINTF("page flush %x\n", val); | |
| 158 | + s->regs[saddr] = val & IOMMU_PGFLUSH_MASK; | |
| 159 | + break; | |
| 160 | + case IOMMU_SBCFG0: | |
| 161 | + case IOMMU_SBCFG1: | |
| 162 | + case IOMMU_SBCFG2: | |
| 163 | + case IOMMU_SBCFG3: | |
| 164 | + s->regs[saddr] = val & IOMMU_SBCFG_MASK; | |
| 165 | + break; | |
| 166 | + case IOMMU_ARBEN: | |
| 167 | + // XXX implement SBus probing: fault when reading unmapped | |
| 168 | + // addresses, fault cause and address stored to MMU/IOMMU | |
| 169 | + s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID; | |
| 170 | + break; | |
| 120 | 171 | default: |
| 121 | 172 | s->regs[saddr] = val; |
| 122 | 173 | break; |
| ... | ... | @@ -184,6 +235,7 @@ static void iommu_reset(void *opaque) |
| 184 | 235 | |
| 185 | 236 | memset(s->regs, 0, IOMMU_NREGS * 4); |
| 186 | 237 | s->iostart = 0; |
| 238 | + s->regs[0] = IOMMU_VERSION; | |
| 187 | 239 | } |
| 188 | 240 | |
| 189 | 241 | void *iommu_init(uint32_t addr) | ... | ... |
hw/slavio_misc.c
| ... | ... | @@ -44,7 +44,7 @@ typedef struct MiscState { |
| 44 | 44 | int irq; |
| 45 | 45 | uint8_t config; |
| 46 | 46 | uint8_t aux1, aux2; |
| 47 | - uint8_t diag, mctrl; | |
| 47 | + uint8_t diag, mctrl, sysctrl; | |
| 48 | 48 | } MiscState; |
| 49 | 49 | |
| 50 | 50 | #define MISC_MAXADDR 1 |
| ... | ... | @@ -64,7 +64,7 @@ static void slavio_misc_reset(void *opaque) |
| 64 | 64 | { |
| 65 | 65 | MiscState *s = opaque; |
| 66 | 66 | |
| 67 | - // Diagnostic register not cleared in reset | |
| 67 | + // Diagnostic and system control registers not cleared in reset | |
| 68 | 68 | s->config = s->aux1 = s->aux2 = s->mctrl = 0; |
| 69 | 69 | } |
| 70 | 70 | |
| ... | ... | @@ -116,8 +116,10 @@ static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32 |
| 116 | 116 | break; |
| 117 | 117 | case 0x1f00000: |
| 118 | 118 | MISC_DPRINTF("Write system control %2.2x\n", val & 0xff); |
| 119 | - if (val & 1) | |
| 119 | + if (val & 1) { | |
| 120 | + s->sysctrl = 0x2; | |
| 120 | 121 | qemu_system_reset_request(); |
| 122 | + } | |
| 121 | 123 | break; |
| 122 | 124 | case 0xa000000: |
| 123 | 125 | MISC_DPRINTF("Write power management %2.2x\n", val & 0xff); |
| ... | ... | @@ -158,6 +160,7 @@ static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr) |
| 158 | 160 | break; |
| 159 | 161 | case 0x1f00000: |
| 160 | 162 | MISC_DPRINTF("Read system control %2.2x\n", ret); |
| 163 | + ret = s->sysctrl; | |
| 161 | 164 | break; |
| 162 | 165 | case 0xa000000: |
| 163 | 166 | MISC_DPRINTF("Read power management %2.2x\n", ret); |
| ... | ... | @@ -188,6 +191,7 @@ static void slavio_misc_save(QEMUFile *f, void *opaque) |
| 188 | 191 | qemu_put_8s(f, &s->aux2); |
| 189 | 192 | qemu_put_8s(f, &s->diag); |
| 190 | 193 | qemu_put_8s(f, &s->mctrl); |
| 194 | + qemu_put_8s(f, &s->sysctrl); | |
| 191 | 195 | } |
| 192 | 196 | |
| 193 | 197 | static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id) |
| ... | ... | @@ -203,6 +207,7 @@ static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id) |
| 203 | 207 | qemu_get_8s(f, &s->aux2); |
| 204 | 208 | qemu_get_8s(f, &s->diag); |
| 205 | 209 | qemu_get_8s(f, &s->mctrl); |
| 210 | + qemu_get_8s(f, &s->sysctrl); | |
| 206 | 211 | return 0; |
| 207 | 212 | } |
| 208 | 213 | ... | ... |