25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_sh4.c,v 1.29 2007/01/29 18:06:37 debug Exp $ |
* $Id: dev_sh4.c,v 1.32 2007/03/16 18:47:26 debug Exp $ |
29 |
* |
* |
30 |
* SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff). |
* SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff). |
31 |
* |
* |
78 |
uint16_t scif_smr; |
uint16_t scif_smr; |
79 |
uint8_t scif_brr; |
uint8_t scif_brr; |
80 |
uint16_t scif_scr; |
uint16_t scif_scr; |
81 |
|
uint16_t scif_ssr; |
82 |
uint16_t scif_fcr; |
uint16_t scif_fcr; |
83 |
|
int scif_delayed_tx; |
84 |
int scif_console_handle; |
int scif_console_handle; |
85 |
|
struct interrupt scif_tx_irq; |
86 |
|
struct interrupt scif_rx_irq; |
87 |
|
|
88 |
/* Bus State Controller: */ |
/* Bus State Controller: */ |
89 |
uint32_t bsc_bcr1; |
uint32_t bsc_bcr1; |
147 |
exit(1); |
exit(1); |
148 |
} |
} |
149 |
|
|
150 |
|
/* Timer interrupts: */ |
151 |
for (i=0; i<N_SH4_TIMERS; i++) { |
for (i=0; i<N_SH4_TIMERS; i++) { |
152 |
int32_t old = d->tcnt[i]; |
int32_t old = d->tcnt[i]; |
153 |
|
|
184 |
} |
} |
185 |
|
|
186 |
|
|
187 |
|
static void scif_reassert_interrupts(struct sh4_data *d) |
188 |
|
{ |
189 |
|
if (d->scif_scr & SCSCR2_RIE) { |
190 |
|
if (d->scif_ssr & SCSSR2_DR) |
191 |
|
INTERRUPT_ASSERT(d->scif_rx_irq); |
192 |
|
} else { |
193 |
|
INTERRUPT_DEASSERT(d->scif_rx_irq); |
194 |
|
} |
195 |
|
if (d->scif_scr & SCSCR2_TIE) { |
196 |
|
if (d->scif_ssr & (SCSSR2_TDFE | SCSSR2_TEND)) |
197 |
|
INTERRUPT_ASSERT(d->scif_tx_irq); |
198 |
|
} else { |
199 |
|
INTERRUPT_DEASSERT(d->scif_tx_irq); |
200 |
|
} |
201 |
|
} |
202 |
|
|
203 |
|
|
204 |
DEVICE_TICK(sh4) |
DEVICE_TICK(sh4) |
205 |
{ |
{ |
206 |
struct sh4_data *d = (struct sh4_data *) extra; |
struct sh4_data *d = (struct sh4_data *) extra; |
207 |
int i; |
int i; |
208 |
|
|
209 |
|
/* Serial controller interrupts: */ |
210 |
|
/* TODO: Which bits go to which interrupt? */ |
211 |
|
if (console_charavail(d->scif_console_handle)) |
212 |
|
d->scif_ssr |= SCSSR2_DR; |
213 |
|
else |
214 |
|
d->scif_ssr &= SCSSR2_DR; |
215 |
|
if (d->scif_delayed_tx) { |
216 |
|
if (--d->scif_delayed_tx == 0) |
217 |
|
d->scif_ssr |= SCSSR2_TDFE | SCSSR2_TEND; |
218 |
|
} |
219 |
|
|
220 |
|
scif_reassert_interrupts(d); |
221 |
|
|
222 |
|
/* Timer interrupts: */ |
223 |
for (i=0; i<N_SH4_TIMERS; i++) |
for (i=0; i<N_SH4_TIMERS; i++) |
224 |
if (d->timer_interrupts_pending[i] > 0) { |
if (d->timer_interrupts_pending[i] > 0) { |
225 |
INTERRUPT_ASSERT(d->timer_irq[i]); |
INTERRUPT_ASSERT(d->timer_irq[i]); |
1011 |
case SH4_SCIF_BASE + SCIF_SCR: |
case SH4_SCIF_BASE + SCIF_SCR: |
1012 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
1013 |
d->scif_scr = idata; |
d->scif_scr = idata; |
1014 |
|
scif_reassert_interrupts(d); |
1015 |
} else { |
} else { |
1016 |
odata = d->scif_scr; |
odata = d->scif_scr; |
1017 |
} |
} |
1018 |
break; |
break; |
1019 |
|
|
1020 |
case SH4_SCIF_BASE + SCIF_FTDR: |
case SH4_SCIF_BASE + SCIF_FTDR: |
1021 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) { |
1022 |
console_putchar(d->scif_console_handle, idata); |
console_putchar(d->scif_console_handle, idata); |
1023 |
|
d->scif_delayed_tx = 1; |
1024 |
|
} |
1025 |
break; |
break; |
1026 |
|
|
1027 |
case SH4_SCIF_BASE + SCIF_SSR: |
case SH4_SCIF_BASE + SCIF_SSR: |
1028 |
/* TODO: Implement more of this. */ |
if (writeflag == MEM_READ) { |
1029 |
odata = SCSSR2_TDFE | SCSSR2_TEND; |
odata = d->scif_ssr; |
1030 |
if (console_charavail(d->scif_console_handle)) |
} else { |
1031 |
odata |= SCSSR2_DR; |
d->scif_ssr &= ~idata; |
1032 |
|
scif_reassert_interrupts(d); |
1033 |
|
} |
1034 |
break; |
break; |
1035 |
|
|
1036 |
case SH4_SCIF_BASE + SCIF_FRDR: |
case SH4_SCIF_BASE + SCIF_FRDR: |
1039 |
if (x == 13) |
if (x == 13) |
1040 |
x = 10; |
x = 10; |
1041 |
odata = x < 0? 0 : x; |
odata = x < 0? 0 : x; |
1042 |
|
d->scif_ssr &= ~SCSSR2_DR; |
1043 |
} |
} |
1044 |
break; |
break; |
1045 |
|
|
1127 |
d->scif_console_handle = console_start_slave(devinit->machine, |
d->scif_console_handle = console_start_slave(devinit->machine, |
1128 |
"SH4 SCIF", 1); |
"SH4 SCIF", 1); |
1129 |
|
|
1130 |
|
snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]", |
1131 |
|
devinit->interrupt_path, SH4_INTEVT_SCIF_RXI); |
1132 |
|
INTERRUPT_CONNECT(tmp, d->scif_rx_irq); |
1133 |
|
snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]", |
1134 |
|
devinit->interrupt_path, SH4_INTEVT_SCIF_TXI); |
1135 |
|
INTERRUPT_CONNECT(tmp, d->scif_tx_irq); |
1136 |
|
|
1137 |
memory_device_register(machine->memory, devinit->name, |
memory_device_register(machine->memory, devinit->name, |
1138 |
SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL); |
SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL); |
1139 |
|
|
1151 |
* |
* |
1152 |
* TODO: Implement more correct cache behaviour? |
* TODO: Implement more correct cache behaviour? |
1153 |
*/ |
*/ |
1154 |
dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0); |
dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE * 2, DEV_RAM_RAM, 0x0); |
1155 |
dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0); |
dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0); |
1156 |
dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0); |
dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE * 2, DEV_RAM_RAM, 0x0); |
1157 |
dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0); |
dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0); |
1158 |
|
|
1159 |
/* 0xf2000000 SH4_ITLB_AA */ |
/* 0xf2000000 SH4_ITLB_AA */ |
1160 |
memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA, |
memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA, |