summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2000-05-25 10:10:54 +0000
committerbouyer <bouyer@NetBSD.org>2000-05-25 10:10:54 +0000
commitb063b2ec3643129d343b0b72e5bb5e3cac4ea4f0 (patch)
tree46175835151c3a9489d81284c0ce97ddabf0cb86 /sys/dev
parent4a42668b31614f8cf9b4e62e4fa3f72dd25383d7 (diff)
Separate the sheduler from the main script, allocate another DMA-safe
memory page for the sheduler. Put the main script in the on-chip RAM when available. Avoid a null-pointer dereference when DSA is invalid.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/siop.c163
-rw-r--r--sys/dev/ic/siopvar.h7
-rw-r--r--sys/dev/microcode/siop/siop.ss13
-rw-r--r--sys/dev/pci/siop_pci_common.c31
4 files changed, 142 insertions, 72 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c
index 4badae00310..f81676b1363 100644
--- a/sys/dev/ic/siop.c
+++ b/sys/dev/ic/siop.c
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.16 2000/05/23 17:08:07 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.17 2000/05/25 10:10:56 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -125,13 +125,13 @@ siop_table_sync(siop_cmd, ops)
sizeof(struct siop_xfer), ops);
}
-static __inline__ void siop_script_sync __P((struct siop_softc *, int));
+static __inline__ void siop_shed_sync __P((struct siop_softc *, int));
static __inline__ void
-siop_script_sync(sc, ops)
+siop_shed_sync(sc, ops)
struct siop_softc *sc;
int ops;
{
- bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG, ops);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_sheddma, 0, NBPG, ops);
}
void
@@ -143,34 +143,66 @@ siop_attach(sc)
int rseg;
/*
- * Allocate DMA-safe memory for the script itself and internal
- * variables and map it.
+ * Allocate DMA-safe memory for the script and script sheduler
+ * and map it.
*/
+ if ((sc->features & SF_CHIP_RAM) == 0) {
+ error = bus_dmamem_alloc(sc->sc_dmat, NBPG,
+ NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT);
+ if (error) {
+ printf("%s: unable to allocate script DMA memory, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ return;
+ }
+ error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
+ (caddr_t *)&sc->sc_script, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ if (error) {
+ printf("%s: unable to map script DMA memory, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ return;
+ }
+ error = bus_dmamap_create(sc->sc_dmat, NBPG, 1,
+ NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_scriptdma);
+ if (error) {
+ printf("%s: unable to create script DMA map, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ return;
+ }
+ error = bus_dmamap_load(sc->sc_dmat, sc->sc_scriptdma,
+ sc->sc_script,
+ NBPG, NULL, BUS_DMA_NOWAIT);
+ if (error) {
+ printf("%s: unable to load script DMA map, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
+ return;
+ }
+ sc->sc_scriptaddr = sc->sc_scriptdma->dm_segs[0].ds_addr;
+ }
error = bus_dmamem_alloc(sc->sc_dmat, NBPG,
NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT);
if (error) {
- printf("%s: unable to allocate script DMA memory, error = %d\n",
- sc->sc_dev.dv_xname, error);
+ printf("%s: unable to allocate sheduler DMA memory, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
return;
}
error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
- (caddr_t *)&sc->sc_script, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ (caddr_t *)&sc->sc_shed, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
if (error) {
- printf("%s: unable to map script DMA memory, error = %d\n",
+ printf("%s: unable to map sheduler DMA memory, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
error = bus_dmamap_create(sc->sc_dmat, NBPG, 1,
- NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_scriptdma);
+ NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_sheddma);
if (error) {
- printf("%s: unable to create script DMA map, error = %d\n",
+ printf("%s: unable to create sheduler DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
- error = bus_dmamap_load(sc->sc_dmat, sc->sc_scriptdma, sc->sc_script,
+ error = bus_dmamap_load(sc->sc_dmat, sc->sc_sheddma, sc->sc_shed,
NBPG, NULL, BUS_DMA_NOWAIT);
if (error) {
- printf("%s: unable to load script DMA map, error = %d\n",
+ printf("%s: unable to load sheduler DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
@@ -178,17 +210,14 @@ siop_attach(sc)
TAILQ_INIT(&sc->cmds);
/* compute number of sheduler slots */
sc->sc_nshedslots = (
- NBPG /* memory size allocated for scripts */
- - sizeof(siop_script) /* memory for main script */
- + 8 /* extra NOP at end of main script */
+ NBPG /* memory size allocated for sheduler */
- sizeof(endslot_script) /* memory needed at end of sheduler */
) / (sizeof(slot_script) - 8);
sc->sc_currshedslot = 0;
#ifdef DEBUG
printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p nslots %d\n",
sc->sc_dev.dv_xname, (int)sizeof(siop_script),
- (u_int)sc->sc_scriptdma->dm_segs[0].ds_addr, sc->sc_script,
- sc->sc_nshedslots);
+ sc->sc_ramaddr, sc->sc_script, sc->sc_nshedslots);
#endif
sc->sc_link.adapter_softc = sc;
@@ -243,14 +272,35 @@ siop_reset(sc)
siop_common_reset(sc);
/* copy and patch the script */
- for (j = 0; j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
- sc->sc_script[j] = htole32(siop_script[j]);
+ if (sc->features & SF_CHIP_RAM) {
+ bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, 0,
+ siop_script, sizeof(siop_script) / sizeof(siop_script[0]));
+ for (j = 0; j <
+ (sizeof(E_script_abs_shed_Used) /
+ sizeof(E_script_abs_shed_Used[0]));
+ j++) {
+ bus_space_write_4(sc->sc_ramt, sc->sc_ramh,
+ E_script_abs_shed_Used[j] * 4,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
+ }
+ } else {
+ for (j = 0;
+ j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
+ sc->sc_script[j] = htole32(siop_script[j]);
+ }
+ for (j = 0; j <
+ (sizeof(E_script_abs_shed_Used) /
+ sizeof(E_script_abs_shed_Used[0]));
+ j++) {
+ sc->sc_script[E_script_abs_shed_Used[j]] =
+ htole32(sc->sc_sheddma->dm_segs[0].ds_addr);
+ }
}
- /* copy the sheduler slots script */
+ /* copy and init the sheduler slots script */
for (i = 0; i < sc->sc_nshedslots; i++) {
- scr = &sc->sc_script[Ent_sheduler / 4 + (Ent_nextslot / 4) * i];
- physaddr = sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_sheduler
- + Ent_nextslot * i;
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * i];
+ physaddr = sc->sc_sheddma->dm_segs[0].ds_addr +
+ Ent_nextslot * i;
for (j = 0; j < (sizeof(slot_script) / sizeof(slot_script[0]));
j++) {
scr[j] = htole32(slot_script[j]);
@@ -265,37 +315,38 @@ siop_reset(sc)
Ent_slotdata + 4);
/* JUMP selected, in main script */
scr[E_slot_abs_selected_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_selected);
+ htole32(sc->sc_scriptaddr + Ent_selected);
/* JUMP addr if SELECT fail */
scr[E_slot_abs_reselect_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ htole32(sc->sc_scriptaddr + Ent_reselect);
}
/* Now the final JUMP */
- scr = &sc->sc_script[Ent_sheduler / 4 +
- (Ent_nextslot / 4) * sc->sc_nshedslots];
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * sc->sc_nshedslots];
for (j = 0; j < (sizeof(endslot_script) / sizeof(endslot_script[0]));
j++) {
scr[j] = htole32(endslot_script[j]);
}
scr[E_endslot_abs_reselect_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ htole32(sc->sc_scriptaddr + Ent_reselect);
/* start script */
- siop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ siop_shed_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
- sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ sc->sc_scriptaddr + Ent_reselect);
}
#if 0
#define CALL_SCRIPT(ent) do {\
printf ("start script DSA 0x%lx DSP 0x%lx\n", \
siop_cmd->dsa, \
- sc->sc_scriptdma->dm_segs[0].ds_addr + ent); \
-bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptdma->dm_segs[0].ds_addr + ent); \
+ sc->sc_scriptaddr + ent); \
+bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \
} while (0)
#else
#define CALL_SCRIPT(ent) do {\
-bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptdma->dm_segs[0].ds_addr + ent); \
+bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \
} while (0)
#endif
@@ -346,7 +397,7 @@ siop_intr(v)
if (dstat & DSTAT_SSI) {
printf("single step dsp 0x%08x dsa 0x08%x\n",
(int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr),
+ sc->sc_scriptaddr),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
if ((dstat & ~(DSTAT_DFE | DSTAT_SSI)) == 0 &&
(istat & ISTAT_SIP) == 0) {
@@ -370,11 +421,11 @@ siop_intr(v)
printf(" dma fifo empty");
printf(", DSP=0x%x DSA=0x%x: ",
(int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr),
+ sc->sc_scriptaddr),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
p = sc->sc_script +
(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr - 8) / 4;
+ sc->sc_scriptaddr - 8) / 4;
printf("0x%x 0x%x 0x%x 0x%x\n", le32toh(p[0]), le32toh(p[1]),
le32toh(p[2]), le32toh(p[3]));
if (siop_cmd)
@@ -389,7 +440,7 @@ siop_intr(v)
* SCSI interrupt. If current command is not active,
* we don't need siop_cmd
*/
- if (siop_cmd->status != CMDST_ACTIVE &&
+ if (siop_cmd && siop_cmd->status != CMDST_ACTIVE &&
siop_cmd->status != CMDST_SENSE_ACTIVE) {
siop_cmd = NULL;
}
@@ -405,7 +456,7 @@ siop_intr(v)
bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA),
(u_long)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr));
+ sc->sc_scriptaddr));
#endif
if (siop_cmd) {
xs = siop_cmd->xs;
@@ -519,7 +570,7 @@ siop_intr(v)
bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA),
(int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr));
+ sc->sc_scriptaddr));
if (siop_cmd) {
siop_cmd->status = CMDST_DONE;
xs->error = XS_SELTIMEOUT;
@@ -571,8 +622,8 @@ reset:
switch(irqcode) {
case A_int_err:
printf("error, DSP=0x%x\n",
- (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr));
+ (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh,
+ SIOP_DSP) - sc->sc_scriptaddr));
if (xs) {
xs->error = XS_SELTIMEOUT;
goto end;
@@ -815,18 +866,22 @@ reset:
siop_table_sync(siop_cmd,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
}
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
return 1;
case A_int_resfail:
printf("reselect failed\n");
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
return 1;
case A_int_done:
if (xs == NULL) {
printf("%s: done without command, DSA=0x%lx\n",
sc->sc_dev.dv_xname, (u_long)siop_cmd->dsa);
siop_cmd->status = CMDST_FREE;
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh,
+ SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
siop_start(sc);
return 1;
}
@@ -885,7 +940,7 @@ check_sense:
return 1;
end:
bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
- sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_sheduler);
+ sc->sc_sheddma->dm_segs[0].ds_addr);
lun = siop_cmd->xs->sc_link->scsipi_scsi.lun;
siop_scsicmd_end(siop_cmd);
if (siop_cmd->status == CMDST_FREE) {
@@ -1192,7 +1247,7 @@ siop_start(sc)
/*
* first make sure to read valid data
*/
- siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ siop_shed_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/*
* The queue management here is a bit tricky: the script always looks
@@ -1206,8 +1261,7 @@ siop_start(sc)
* A mid-way solution could be to implement 2 queues and swap orders.
*/
slot = sc->sc_currshedslot;
- scr = &sc->sc_script[Ent_sheduler / 4 +
- (Ent_nextslot / 4) * slot];
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * slot];
/*
* if relative addr of first jump is not 0 the slot is free. As this is
* the last used slot, all previous slots are free, we can restart
@@ -1233,8 +1287,7 @@ siop_start(sc)
continue;
/* find a free sheduler slot and load it */
for (; slot < sc->sc_nshedslots; slot++) {
- scr = &sc->sc_script[Ent_sheduler / 4 +
- (Ent_nextslot / 4) * slot];
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * slot];
/*
* if relative addr of first jump is 0 the
* slot isn't free
@@ -1307,7 +1360,7 @@ end:
if (newcmd == 0)
return;
/* make sure SCRIPT processor will read valid data */
- siop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ siop_shed_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Signal script it has some work to do */
bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_SIGP);
/* and wait for IRQ */
@@ -1354,7 +1407,7 @@ siop_dump_script(sc)
struct siop_softc *sc;
{
int i;
- siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ siop_shed_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
for (i = 0; i < NBPG / 4; i += 2) {
printf("0x%04x: 0x%08x 0x%08x", i * 4,
le32toh(sc->sc_script[i]), le32toh(sc->sc_script[i+1]));
@@ -1416,7 +1469,7 @@ siop_morecbd(sc)
error = bus_dmamap_load(sc->sc_dmat, newcbd->xferdma, newcbd->xfers,
NBPG, NULL, BUS_DMA_NOWAIT);
if (error) {
- printf("%s: unable to load script DMA map, error = %d\n",
+ printf("%s: unable to load cbd DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
goto bad0;
}
diff --git a/sys/dev/ic/siopvar.h b/sys/dev/ic/siopvar.h
index eba07c2f0e2..b6192e1b116 100644
--- a/sys/dev/ic/siopvar.h
+++ b/sys/dev/ic/siopvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: siopvar.h,v 1.6 2000/05/23 17:08:07 bouyer Exp $ */
+/* $NetBSD: siopvar.h,v 1.7 2000/05/25 10:10:56 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -49,10 +49,15 @@ struct siop_softc {
bus_space_tag_t sc_rt; /* bus_space registers tag */
bus_space_handle_t sc_rh; /* bus_space registers handle */
bus_addr_t sc_raddr; /* register adresses */
+ bus_space_tag_t sc_ramt; /* bus_space ram tag */
+ bus_space_handle_t sc_ramh; /* bus_space ram handle */
+ bus_addr_t sc_scriptaddr; /* on-board ram or physical adress */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
void (*sc_reset) __P((struct siop_softc*)); /* reset callback */
bus_dmamap_t sc_scriptdma; /* DMA map for script */
+ bus_dmamap_t sc_sheddma; /* DMA map for sheduler script */
u_int32_t *sc_script; /* script location in memory */
+ u_int32_t *sc_shed; /* script sheduler location in memory */
int sc_nshedslots; /* number of sheduler slots */
int sc_currshedslot; /* current sheduler slot */
struct cbd_list cmds; /* list of command block descriptors */
diff --git a/sys/dev/microcode/siop/siop.ss b/sys/dev/microcode/siop/siop.ss
index 79f3ff7afd1..6d222ed9fd5 100644
--- a/sys/dev/microcode/siop/siop.ss
+++ b/sys/dev/microcode/siop/siop.ss
@@ -1,4 +1,4 @@
-; $NetBSD: siop.ss,v 1.5 2000/05/15 07:43:45 bouyer Exp $
+; $NetBSD: siop.ss,v 1.6 2000/05/25 10:10:54 bouyer Exp $
;
; Copyright (c) 2000 Manuel Bouyer.
@@ -70,7 +70,6 @@ ENTRY disconnect;
ENTRY reselect;
ENTRY selected;
ENTRY get_extmsgdata;
-ENTRY sheduler;
ENTRY slot;
ENTRY idsa0;
ENTRY idsa1;
@@ -80,6 +79,7 @@ ENTRY slotdata;
ENTRY nextslot;
ENTRY endslot;
+EXTERN script_abs_shed;
EXTERN slot_nextp;
EXTERN slot_shed_addrsrc;
EXTERN slot_abs_reselect;
@@ -116,7 +116,7 @@ reselect_fail:
; check that host asserted SIGP, this'll clear SIGP in ISTAT
MOVE CTEST2 & 0x40 TO SFBR;
INT int_resfail, IF 0x00;
- JUMP REL(sheduler);
+ JUMP script_abs_shed;
msgin:
CLEAR ATN
@@ -207,9 +207,9 @@ handle_dis:
CALL REL(disconnect);
; if we didn't get sdp, or if offset is 0, no need to interrupt
MOVE SCRATCHA0 & flag_sdp TO SFBR;
- JUMP REL(sheduler), if 0x00;
+ JUMP script_abs_shed, if 0x00;
MOVE SCRATCHA1 TO SFBR;
- JUMP REL(sheduler), if 0x00;
+ JUMP script_abs_shed, if 0x00;
; Ok, we need to save data pointers
INT int_disc;
@@ -232,9 +232,6 @@ get_extmsgdata:
MOVE FROM t_ext_msg_data, WHEN MSG_IN;
INT int_extmsgdata;
-sheduler:
- NOP; /* will be changed by the slot scripts */
-
; script used for the sheduler: when a slot is free the JUMP points to
; the next slot so that instructions for this slot are not run.
; once the CPU has set up the slot variables (DSA address) it changes
diff --git a/sys/dev/pci/siop_pci_common.c b/sys/dev/pci/siop_pci_common.c
index 86b14e10a81..92d5f4b6d94 100644
--- a/sys/dev/pci/siop_pci_common.c
+++ b/sys/dev/pci/siop_pci_common.c
@@ -1,4 +1,4 @@
-/* $NetBSD: siop_pci_common.c,v 1.1 2000/05/15 07:53:18 bouyer Exp $ */
+/* $NetBSD: siop_pci_common.c,v 1.2 2000/05/25 10:10:56 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -199,6 +199,14 @@ siop_pci_attach_common(sc, pa)
printf("sym: broken match/attach!!\n");
return 0;
}
+ /* copy interesting infos about the chip */
+ sc->siop.features = sc->sc_pp->features;
+ sc->siop.maxburst = sc->sc_pp->maxburst;
+ sc->siop.maxoff = sc->sc_pp->maxoff;
+ sc->siop.clock_div = sc->sc_pp->clock_div;
+ sc->siop.clock_period = sc->sc_pp->clock_period;
+
+ sc->siop.sc_reset = siop_pci_reset;
printf(": %s\n", sc->sc_pp->name);
sc->sc_pc = pc;
sc->sc_tag = tag;
@@ -232,6 +240,20 @@ siop_pci_attach_common(sc, pa)
return 0;
}
+ if (sc->siop.features & SF_CHIP_RAM) {
+ if (pci_mapreg_map(pa, 0x18,
+ PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
+ &sc->siop.sc_ramt, &sc->siop.sc_ramh,
+ &sc->siop.sc_scriptaddr, NULL) == 0) {
+ printf("%s: using on-board RAM\n",
+ sc->siop.sc_dev.dv_xname);
+ } else {
+ printf("%s: can't map on-board RAM\n",
+ sc->siop.sc_dev.dv_xname);
+ sc->siop.features &= ~SF_CHIP_RAM;
+ }
+ }
+
if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &intrhandle) != 0) {
printf("%s: couldn't map interrupt\n",
@@ -253,13 +275,6 @@ siop_pci_attach_common(sc, pa)
printf("\n");
return 0;
}
- /* copy interesting infos about the chip */
- sc->siop.features = sc->sc_pp->features;
- sc->siop.maxburst = sc->sc_pp->maxburst;
- sc->siop.maxoff = sc->sc_pp->maxoff;
- sc->siop.clock_div = sc->sc_pp->clock_div;
- sc->siop.clock_period = sc->sc_pp->clock_period;
- sc->siop.sc_reset = siop_pci_reset;
return 1;
}