Revision e80cfcfc hw/iommu.c
b/hw/iommu.c | ||
---|---|---|
117 | 117 |
uint32_t iostart; |
118 | 118 |
} IOMMUState; |
119 | 119 |
|
120 |
static IOMMUState *ps; |
|
121 |
|
|
122 | 120 |
static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) |
123 | 121 |
{ |
124 | 122 |
IOMMUState *s = opaque; |
... | ... | |
187 | 185 |
iommu_mem_writew, |
188 | 186 |
}; |
189 | 187 |
|
190 |
uint32_t iommu_translate(uint32_t addr)
|
|
188 |
uint32_t iommu_translate_local(void *opaque, uint32_t addr)
|
|
191 | 189 |
{ |
192 |
uint32_t *iopte = (void *)(ps->regs[1] << 4), pa; |
|
190 |
IOMMUState *s = opaque; |
|
191 |
uint32_t *iopte = (void *)(s->regs[1] << 4), pa; |
|
193 | 192 |
|
194 |
iopte += ((addr - ps->iostart) >> PAGE_SHIFT);
|
|
195 |
cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0);
|
|
193 |
iopte += ((addr - s->iostart) >> PAGE_SHIFT); |
|
194 |
cpu_physical_memory_read((uint32_t)iopte, (void *) &pa, 4);
|
|
196 | 195 |
bswap32s(&pa); |
197 | 196 |
pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */ |
198 | 197 |
return pa + (addr & PAGE_MASK); |
199 | 198 |
} |
200 | 199 |
|
201 |
void iommu_init(uint32_t addr) |
|
200 |
static void iommu_save(QEMUFile *f, void *opaque) |
|
201 |
{ |
|
202 |
IOMMUState *s = opaque; |
|
203 |
int i; |
|
204 |
|
|
205 |
qemu_put_be32s(f, &s->addr); |
|
206 |
for (i = 0; i < sizeof(struct iommu_regs); i += 4) |
|
207 |
qemu_put_be32s(f, &s->regs[i]); |
|
208 |
qemu_put_be32s(f, &s->iostart); |
|
209 |
} |
|
210 |
|
|
211 |
static int iommu_load(QEMUFile *f, void *opaque, int version_id) |
|
212 |
{ |
|
213 |
IOMMUState *s = opaque; |
|
214 |
int i; |
|
215 |
|
|
216 |
if (version_id != 1) |
|
217 |
return -EINVAL; |
|
218 |
|
|
219 |
qemu_get_be32s(f, &s->addr); |
|
220 |
for (i = 0; i < sizeof(struct iommu_regs); i += 4) |
|
221 |
qemu_put_be32s(f, &s->regs[i]); |
|
222 |
qemu_get_be32s(f, &s->iostart); |
|
223 |
|
|
224 |
return 0; |
|
225 |
} |
|
226 |
|
|
227 |
static void iommu_reset(void *opaque) |
|
228 |
{ |
|
229 |
IOMMUState *s = opaque; |
|
230 |
|
|
231 |
memset(s->regs, 0, sizeof(struct iommu_regs)); |
|
232 |
s->iostart = 0; |
|
233 |
} |
|
234 |
|
|
235 |
void *iommu_init(uint32_t addr) |
|
202 | 236 |
{ |
203 | 237 |
IOMMUState *s; |
204 | 238 |
int iommu_io_memory; |
205 | 239 |
|
206 | 240 |
s = qemu_mallocz(sizeof(IOMMUState)); |
207 | 241 |
if (!s) |
208 |
return; |
|
242 |
return NULL;
|
|
209 | 243 |
|
210 | 244 |
s->addr = addr; |
211 | 245 |
|
... | ... | |
213 | 247 |
cpu_register_physical_memory(addr, sizeof(struct iommu_regs), |
214 | 248 |
iommu_io_memory); |
215 | 249 |
|
216 |
ps = s; |
|
250 |
register_savevm("iommu", addr, 1, iommu_save, iommu_load, s); |
|
251 |
qemu_register_reset(iommu_reset, s); |
|
252 |
return s; |
|
217 | 253 |
} |
218 | 254 |
|
Also available in: Unified diff