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