Revision 66321a11 hw/iommu.c

b/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 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 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 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 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 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 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 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 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 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 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 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);

Also available in: Unified diff