Revision d47ede60 hw/r2d.c
b/hw/r2d.c | ||
---|---|---|
34 | 34 |
|
35 | 35 |
#define SM501_VRAM_SIZE 0x800000 |
36 | 36 |
|
37 |
#define PA_IRLMSK 0x00 |
|
37 | 38 |
#define PA_POWOFF 0x30 |
38 | 39 |
#define PA_VERREG 0x32 |
39 | 40 |
#define PA_OUTPORT 0x36 |
40 | 41 |
|
41 | 42 |
typedef struct { |
42 | 43 |
uint16_t bcr; |
44 |
uint16_t irlmsk; |
|
43 | 45 |
uint16_t irlmon; |
44 | 46 |
uint16_t cfctl; |
45 | 47 |
uint16_t cfpow; |
... | ... | |
60 | 62 |
uint16_t inport; |
61 | 63 |
uint16_t outport; |
62 | 64 |
uint16_t bverreg; |
65 |
|
|
66 |
/* output pin */ |
|
67 |
qemu_irq irl; |
|
63 | 68 |
} r2d_fpga_t; |
64 | 69 |
|
70 |
enum r2d_fpga_irq { |
|
71 |
PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T, |
|
72 |
SDCARD, PCI_INTA, PCI_INTB, EXT, TP, |
|
73 |
NR_IRQS |
|
74 |
}; |
|
75 |
|
|
76 |
static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = { |
|
77 |
[CF_IDE] = { 1, 1<<9 }, |
|
78 |
[CF_CD] = { 2, 1<<8 }, |
|
79 |
[PCI_INTA] = { 9, 1<<14 }, |
|
80 |
[PCI_INTB] = { 10, 1<<13 }, |
|
81 |
[PCI_INTC] = { 3, 1<<12 }, |
|
82 |
[PCI_INTD] = { 0, 1<<11 }, |
|
83 |
[SM501] = { 4, 1<<10 }, |
|
84 |
[KEY] = { 5, 1<<6 }, |
|
85 |
[RTC_A] = { 6, 1<<5 }, |
|
86 |
[RTC_T] = { 7, 1<<4 }, |
|
87 |
[SDCARD] = { 8, 1<<7 }, |
|
88 |
[EXT] = { 11, 1<<0 }, |
|
89 |
[TP] = { 12, 1<<15 }, |
|
90 |
}; |
|
91 |
|
|
92 |
static void update_irl(r2d_fpga_t *fpga) |
|
93 |
{ |
|
94 |
int i, irl = 15; |
|
95 |
for (i = 0; i < NR_IRQS; i++) |
|
96 |
if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk) |
|
97 |
if (irqtab[i].irl < irl) |
|
98 |
irl = irqtab[i].irl; |
|
99 |
qemu_set_irq(fpga->irl, irl ^ 15); |
|
100 |
} |
|
101 |
|
|
102 |
static void r2d_fpga_irq_set(void *opaque, int n, int level) |
|
103 |
{ |
|
104 |
r2d_fpga_t *fpga = opaque; |
|
105 |
if (level) |
|
106 |
fpga->irlmon |= irqtab[n].msk; |
|
107 |
else |
|
108 |
fpga->irlmon &= ~irqtab[n].msk; |
|
109 |
update_irl(fpga); |
|
110 |
} |
|
111 |
|
|
65 | 112 |
static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr) |
66 | 113 |
{ |
67 | 114 |
r2d_fpga_t *s = opaque; |
68 | 115 |
|
69 | 116 |
switch (addr) { |
117 |
case PA_IRLMSK: |
|
118 |
return s->irlmsk; |
|
70 | 119 |
case PA_OUTPORT: |
71 | 120 |
return s->outport; |
72 | 121 |
case PA_POWOFF: |
... | ... | |
84 | 133 |
r2d_fpga_t *s = opaque; |
85 | 134 |
|
86 | 135 |
switch (addr) { |
136 |
case PA_IRLMSK: |
|
137 |
s->irlmsk = value; |
|
138 |
update_irl(s); |
|
139 |
break; |
|
87 | 140 |
case PA_OUTPORT: |
88 | 141 |
s->outport = value; |
89 | 142 |
break; |
... | ... | |
108 | 161 |
NULL, |
109 | 162 |
}; |
110 | 163 |
|
111 |
static void r2d_fpga_init(target_phys_addr_t base)
|
|
164 |
static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
|
|
112 | 165 |
{ |
113 | 166 |
int iomemtype; |
114 | 167 |
r2d_fpga_t *s; |
115 | 168 |
|
116 | 169 |
s = qemu_mallocz(sizeof(r2d_fpga_t)); |
117 | 170 |
if (!s) |
118 |
return; |
|
171 |
return NULL; |
|
172 |
|
|
173 |
s->irl = irl; |
|
119 | 174 |
|
120 | 175 |
iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn, |
121 | 176 |
r2d_fpga_writefn, s); |
122 | 177 |
cpu_register_physical_memory(base, 0x40, iomemtype); |
178 |
return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS); |
|
123 | 179 |
} |
124 | 180 |
|
125 | 181 |
static void r2d_init(ram_addr_t ram_size, int vga_ram_size, |
... | ... | |
130 | 186 |
CPUState *env; |
131 | 187 |
struct SH7750State *s; |
132 | 188 |
ram_addr_t sdram_addr, sm501_vga_ram_addr; |
189 |
qemu_irq *irq; |
|
133 | 190 |
|
134 | 191 |
if (!cpu_model) |
135 | 192 |
cpu_model = "SH7751R"; |
... | ... | |
144 | 201 |
sdram_addr = qemu_ram_alloc(SDRAM_SIZE); |
145 | 202 |
cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr); |
146 | 203 |
/* Register peripherals */ |
147 |
r2d_fpga_init(0x04000000); |
|
148 | 204 |
s = sh7750_init(env); |
205 |
irq = r2d_fpga_init(0x04000000, sh7750_irl(s)); |
|
206 |
|
|
149 | 207 |
sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE); |
150 | 208 |
sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE, |
151 | 209 |
serial_hds[2]); |
152 | 210 |
|
153 | 211 |
/* onboard CF (True IDE mode, Master only). */ |
154 |
mmio_ide_init(0x14001000, 0x1400080c, NULL, 1,
|
|
155 |
drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
|
|
212 |
mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
|
|
213 |
drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL); |
|
156 | 214 |
|
157 | 215 |
/* Todo: register on board registers */ |
158 | 216 |
{ |
Also available in: Unified diff