Update sti(4) from OpenBSD bringing across support for sti @ pci.

Thanks to Adam Hoka for testing.
This commit is contained in:
skrll 2010-11-09 12:24:47 +00:00
parent 92603a1ff0
commit f2dcf75998
10 changed files with 1615 additions and 536 deletions

View File

@ -1,5 +1,5 @@
.\" $NetBSD: sti.4,v 1.1 2004/09/22 16:38:26 jkunz Exp $
.\" $OpenBSD: sti.4,v 1.14 2004/06/08 02:54:53 mickey Exp $
.\" $NetBSD: sti.4,v 1.2 2010/11/09 12:24:47 skrll Exp $
.\" $OpenBSD: sti.4,v 1.19 2007/05/31 19:19:52 jmc Exp $
.\"
.\" Copyright (c) 2001 Michael Shalayeff
.\" All rights reserved.
@ -25,17 +25,17 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 11, 2001
.Dd November 9, 2010
.Dt STI 4
.Os
.Sh NAME
.Nm sti
.Nd HP Standard Text Interface
.Sh SYNOPSIS
.Cd "sti* at mainbus0 irq ?"
.Cd "sti* at phantomas0 irq ?"
.\" .Cd "sti* at pci? device ? function ?"
.Cd "wsdisplay* at sti? console ?"
.Cd "sti* at mainbus0"
.Cd "sti* at phantomas?"
.Cd "sti* at pci?"
.Cd "wsdisplay* at sti?"
.Sh DESCRIPTION
The
.Nm
@ -46,6 +46,7 @@ The following models are supported
(though not all features or frame buffer depths may be available):
.Bl -column "Visualize FX10pro" "Bits" "Mem" "3D" "machines" -offset left
.It "Model" Ta "Bits" Ta "Mem" Ta "3D" Ta "Machines/Cards"
.It "EVRX" Ta "8" Ta "2" Ta "" Ta "HP9000/425e"
.\" .It "Timber" Ta "8" Ta "2" Ta "" Ta "HP9000/705/710"
.It "GRX" Ta "8g" Ta "2" Ta "" Ta "SGC"
.It "CRX" Ta "8" Ta "2" Ta "" Ta "SGC"
@ -64,9 +65,9 @@ The following models are supported
.\" .It "Visualize 24" Ta "24" Ta "16" Ta "y" Ta "GSC"
.\" .It "Visualize 48" Ta "24" Ta "16" Ta "y" Ta "GSC"
.\" .It "Visualize 48XP" Ta "24" Ta "16" Ta "y" Ta "GSC"
.\" .It "Visualize FXE" Ta "24" Ta "24" Ta "y" Ta "PCI 32/66"
.\" .It "Visualize FX2" Ta "24" Ta "24" Ta "y" Ta "PCI 64/66"
.\" .It "Visualize FX4/FX6" Ta "24" Ta "32" Ta "y" Ta "PCI 64/66"
.It "Visualize FXE" Ta "24" Ta "24" Ta "y" Ta "PCI 32/66"
.It "Visualize FX2" Ta "24" Ta "24" Ta "y" Ta "PCI 64/66"
.It "Visualize FX4/FX6" Ta "24" Ta "32" Ta "y" Ta "PCI 64/66"
.\" .It "Visualize FX5pro" Ta "24" Ta "64" Ta "y" Ta "PCI 64/66"
.\" .It "Visualize FX10pro" Ta "24" Ta "128" Ta "y" Ta "PCI 64/66"
.El

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.102 2010/08/17 00:02:28 dyoung Exp $
# $NetBSD: GENERIC,v 1.103 2010/11/09 12:24:47 skrll Exp $
#
# GENERIC machine description file
#
@ -23,7 +23,7 @@ include "arch/hp700/conf/std.hp700"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel
#ident "GENERIC-$Revision: 1.102 $"
#ident "GENERIC-$Revision: 1.103 $"
maxusers 32 # estimated number of users
@ -231,6 +231,8 @@ lcd0 at mainbus0 # LCD
# STI graphics
sti* at mainbus0 # [H]CRX-{8,24,48}[Z] and Visualize graphics
sti* at phantomas? # [H]CRX-{8,24,48}[Z] and Visualize graphics
#sti* at uturn?
sti* at pci? # EG-PCI, FX*
# Basic Bus Support
lasi* at mainbus0 # LASI host adapter ( LSI PN??? )

View File

@ -1,4 +1,4 @@
# $NetBSD: files.hp700,v 1.23 2010/06/01 10:20:28 skrll Exp $
# $NetBSD: files.hp700,v 1.24 2010/11/09 12:24:47 skrll Exp $
#
# $OpenBSD: files.hp700,v 1.31 2001/06/26 02:41:25 mickey Exp $
#
@ -150,7 +150,8 @@ file arch/hp700/dev/elroy.c elroy
file arch/hp700/dev/apic.c elroy
attach sti at gedoens with sti_gedoens
file arch/hp700/dev/sti_sgc.c sti_gedoens
file arch/hp700/dev/sti_sgc.c sti_gedoens
file arch/hp700/dev/sti_pci_machdep.c sti_pci
attach siop at gedoens with siop_gedoens
file arch/hp700/dev/siop_sgc.c siop_gedoens

View File

@ -0,0 +1,88 @@
/* $NetBSD: sti_pci_machdep.c,v 1.1 2010/11/09 12:24:47 skrll Exp $ */
/* $OpenBSD: sti_pci_machdep.c,v 1.2 2009/04/10 17:11:27 miod Exp $ */
/*
* Copyright (c) 2007, 2009 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice, this permission notice, and the disclaimer below
* appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>
#include <dev/pci/pcivar.h>
#include <hp700/hp700/machdep.h>
int sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);
int
sti_pci_is_console(struct pci_attach_args *paa, bus_addr_t *bases)
{
hppa_hpa_t consaddr;
uint32_t cf;
int pagezero_cookie;
int bar;
int rc;
KASSERT(paa != NULL);
pagezero_cookie = hp700_pagezero_map();
consaddr = (hppa_hpa_t)PAGE0->mem_cons.pz_hpa;
hp700_pagezero_unmap(pagezero_cookie);
/*
* PAGE0 console information will point to one of our BARs,
* but depending on the particular sti model, this might not
* be the BAR mapping the rom (region #0).
*
* For example, on Visualize FXe, regions #0, #2 and #3 are
* mapped by BAR 0x18, while region #1 is mapped by BAR 0x10,
* which matches PAGE0 console address.
*
* Rather than trying to be smart, reread the region->BAR array
* again, and compare the BAR mapping region #1 against PAGE0
* values, we simply try all the valid BARs; if any of them
* matches what PAGE0 says, then we are the console, and it
* doesn't matter which BAR matched.
*/
for (bar = PCI_MAPREG_START; bar <= PCI_MAPREG_PPB_END; ) {
bus_addr_t addr;
bus_size_t size;
cf = pci_conf_read(paa->pa_pc, paa->pa_tag, bar);
rc = pci_mapreg_info(paa->pa_pc, paa->pa_tag, bar,
PCI_MAPREG_TYPE(cf), &addr, &size, NULL);
if (PCI_MAPREG_TYPE(cf) == PCI_MAPREG_TYPE_IO) {
bar += 4;
} else {
if (PCI_MAPREG_MEM_TYPE(cf) ==
PCI_MAPREG_MEM_TYPE_64BIT)
bar += 8;
else
bar += 4;
}
if (rc == 0 && (hppa_hpa_t)addr == consaddr)
return 1;
}
return 0;
}

View File

@ -1,6 +1,6 @@
/* $NetBSD: sti_sgc.c,v 1.19 2010/03/06 19:36:33 skrll Exp $ */
/* $NetBSD: sti_sgc.c,v 1.20 2010/11/09 12:24:47 skrll Exp $ */
/* $OpenBSD: sti_sgc.c,v 1.21 2003/12/22 23:39:06 mickey Exp $ */
/* $OpenBSD: sti_sgc.c,v 1.38 2009/02/06 22:51:04 miod Exp $ */
/*
* Copyright (c) 2000-2003 Michael Shalayeff
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.19 2010/03/06 19:36:33 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.20 2010/11/09 12:24:47 skrll Exp $");
#include "opt_cputype.h"
@ -59,6 +59,17 @@ __KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.19 2010/03/06 19:36:33 skrll Exp $");
#include <hp700/dev/cpudevs.h>
#include <hp700/hp700/machdep.h>
#ifdef STIDEBUG
#define DPRINTF(s) do { \
if (stidebug) \
printf s; \
} while(0)
extern int stidebug;
#else
#define DPRINTF(s) /* */
#endif
#define STI_ROMSIZE (sizeof(struct sti_dd) * 4)
#define STI_ID_FDDI 0x280b31af /* Medusa FDDI ROM id */
@ -71,15 +82,25 @@ __KERNEL_RCSID(0, "$NetBSD: sti_sgc.c,v 1.19 2010/03/06 19:36:33 skrll Exp $");
#define STI_GOPT6_REV 0x40
#define STI_GOPT7_REV 0x30
/* internal EG */
#define STI_INEG_REV 0x60
#define STI_INEG_PROM 0xf0011000
const char sti_sgc_opt[] = {
STI_GOPT1_REV,
STI_GOPT2_REV,
STI_GOPT3_REV,
STI_GOPT4_REV,
STI_GOPT5_REV,
STI_GOPT6_REV,
STI_GOPT7_REV
};
int sti_sgc_probe(device_t, cfdata_t, void *);
void sti_sgc_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(sti_gedoens, sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach,
NULL, NULL);
void sti_sgc_end_attach(device_t);
extern struct cfdriver sti_cd;
CFATTACH_DECL_NEW(sti_gedoens, sizeof(struct sti_softc), sti_sgc_probe,
sti_sgc_attach, NULL, NULL);
paddr_t sti_sgc_getrom(struct confargs *);
@ -93,30 +114,26 @@ sti_sgc_getrom(struct confargs *ca)
paddr_t rom;
int pagezero_cookie;
rom = ca->ca_hpa;
pagezero_cookie = hp700_pagezero_map();
rom = PAGE0->pd_resv2[1];
hp700_pagezero_unmap(pagezero_cookie);
if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC) {
return rom;
if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC) {
int i;
for (i = sizeof(sti_sgc_opt); i--; )
if (sti_sgc_opt[i] == ca->ca_type.iodc_revision)
break;
if (i < 0)
rom = 0;
}
if (rom < HPPA_IOBEGIN) {
if (ca->ca_naddrs > 0)
rom = ca->ca_addrs[0].addr;
else
rom = ca->ca_hpa;
}
switch (ca->ca_type.iodc_revision) {
case STI_GOPT1_REV:
case STI_GOPT2_REV:
case STI_GOPT3_REV:
case STI_GOPT4_REV:
case STI_GOPT5_REV:
case STI_GOPT6_REV:
case STI_GOPT7_REV:
/* these share the onboard's prom */
pagezero_cookie = hp700_pagezero_map();
rom = PAGE0->pd_resv2[1];
hp700_pagezero_unmap(pagezero_cookie);
break;
case STI_INEG_REV:
rom = STI_INEG_PROM;
break;
}
return rom;
}
@ -130,24 +147,26 @@ sti_sgc_probe(device_t parent, cfdata_t cf, void *aux)
u_char devtype;
int rv = 0, romunmapped = 0;
if (ca->ca_type.iodc_type != HPPA_TYPE_FIO)
return (0);
/* due to the graphic nature of this program do probe only one */
if (cf->cf_unit > sti_cd.cd_ndevs)
return 0;
/* these need futher checking for the graphics id */
if (ca->ca_type.iodc_type != HPPA_TYPE_FIO)
return 0;
/* these need further checking for the graphics id */
if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC &&
ca->ca_type.iodc_sv_model != HPPA_FIO_SGC)
return 0;
rom = sti_sgc_getrom(ca);
#ifdef STIDEBUG
printf ("sti: hpa=%x, rom=%x\n", (uint)ca->ca_hpa, (uint)rom);
#endif
DPRINTF(("%s: hpa=%x, rom=%x\n", __func__, (uint)ca->ca_hpa,
(uint)rom));
/* if it does not map, probably part of the lasi space */
if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) {
#ifdef STIDEBUG
printf ("sti: can't map rom space (%d)\n", rv);
#endif
DPRINTF(("%s: can't map rom space (%d)\n", __func__, rv));
if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) {
romh = rom;
romunmapped++;
@ -159,14 +178,11 @@ sti_sgc_probe(device_t parent, cfdata_t cf, void *aux)
devtype = bus_space_read_1(ca->ca_iot, romh, 3);
#ifdef STIDEBUG
printf("sti: devtype=%d\n", devtype);
#endif
DPRINTF(("%s: devtype=%d\n", __func__, devtype));
rv = 1;
switch (devtype) {
case STI_DEVTYPE4:
id = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_GRID);
romend = bus_space_read_4(ca->ca_iot, romh, STI_DEV4_DD_ROMEND);
break;
case STI_DEVTYPE1:
id = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
@ -177,43 +193,31 @@ sti_sgc_probe(device_t parent, cfdata_t cf, void *aux)
+ 11) << 8) |
(bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_GRID
+ 15));
romend = (bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND
+ 3) << 24) |
(bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND
+ 7) << 16) |
(bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND
+ 11) << 8) |
(bus_space_read_1(ca->ca_iot, romh, STI_DEV1_DD_ROMEND
+ 15));
break;
default:
#ifdef STIDEBUG
printf("sti: unknown type (%x)\n", devtype);
#endif
DPRINTF(("%s: unknown type (%x)\n", __func__, devtype));
rv = 0;
romend = 0;
}
if (rv &&
ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) {
#ifdef STIDEBUG
printf("sti: not a graphics device\n");
#endif
DPRINTF(("%s: not a graphics device\n", __func__));
rv = 0;
}
if (ca->ca_naddrs >= sizeof(ca->ca_addrs) / sizeof(ca->ca_addrs[0])) {
printf("sti: address list overflow\n");
return (0);
return 0;
}
ca->ca_addrs[ca->ca_naddrs].addr = rom;
ca->ca_addrs[ca->ca_naddrs].size = round_page(romend);
ca->ca_addrs[ca->ca_naddrs].size = sti_rom_size(ca->ca_iot, romh);
ca->ca_naddrs++;
if (!romunmapped)
bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE);
return (rv);
return rv;
}
void
@ -221,28 +225,39 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
{
struct sti_softc *sc = device_private(self);
struct confargs *ca = aux;
bus_space_handle_t romh;
hppa_hpa_t consaddr;
int pagezero_cookie;
paddr_t rom;
uint32_t romlen;
int rv;
int pagezero_cookie;
int i;
pagezero_cookie = hp700_pagezero_map();
consaddr = (hppa_hpa_t)PAGE0->mem_cons.pz_hpa;
hp700_pagezero_unmap(pagezero_cookie);
sc->sc_dev = self;
sc->memt = sc->iot = ca->ca_iot;
sc->base = ca->ca_hpa;
sc->sc_enable_rom = NULL;
sc->sc_disable_rom = NULL;
/* we stashed rom addr/len into the last slot during probe */
rom = ca->ca_addrs[ca->ca_naddrs - 1].addr;
romlen = ca->ca_addrs[ca->ca_naddrs - 1].size;
if ((rv = bus_space_map(ca->ca_iot, rom, romlen, 0, &sc->romh))) {
if ((rv = bus_space_map(ca->ca_iot, rom, romlen, 0, &romh))) {
if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN)
sc->romh = rom;
romh = rom;
else {
aprint_error(": can't map rom space (%d)\n", rv);
return;
}
}
sc->bases[0] = romh;
for (i = 1; i < STI_REGION_MAX; i++)
sc->bases[i] = ca->ca_hpa;
#ifdef HP7300LC_CPU
/*
* PCXL2: enable accel I/O for this space, see PCX-L2 ERS "ACCEL_IO".
@ -255,9 +270,17 @@ sti_sgc_attach(device_t parent, device_t self, void *aux)
eaio_l2(PCXL2_ACCEL_IO_ADDR2MASK(ca->ca_hpa));
#endif /* HP7300LC_CPU */
sc->sc_devtype = bus_space_read_1(sc->iot, sc->romh, 3);
if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa)
if (ca->ca_hpa == consaddr)
sc->sc_flags |= STI_CONSOLE;
hp700_pagezero_unmap(pagezero_cookie);
sti_attach_common(sc);
if (sti_attach_common(sc, ca->ca_iot, ca->ca_iot, romh,
STI_CODEBASE_PA) == 0)
config_interrupts(self, sti_sgc_end_attach);
}
void
sti_sgc_end_attach(device_t dev)
{
struct sti_softc *sc = device_private(dev);
sti_end_attach(sc);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* $NetBSD: stireg.h,v 1.4 2010/11/01 06:41:50 skrll Exp $ */
/* $NetBSD: stireg.h,v 1.5 2010/11/09 12:24:48 skrll Exp $ */
/* $OpenBSD: stireg.h,v 1.8 2003/08/19 02:52:38 mickey Exp $ */
/* $OpenBSD: stireg.h,v 1.13 2009/01/28 17:37:40 miod Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@ -56,6 +56,13 @@
#define STI_END 13
#define STI_CODECNT 16
#define STI_CODEBASE_MAIN 0x40
#define STI_CODEBASE_ALT 0x80
#define STI_CODEBASE_PA STI_CODEBASE_MAIN
#define STI_CODEBASE_M68K STI_CODEBASE_ALT
#define STI_CODEBASE_PA64 STI_CODEBASE_ALT
/* sti returns */
#define STI_OK 0
#define STI_FAIL -1
@ -66,12 +73,12 @@
#define STI_BADREENTLVL 1 /* bad reentry level */
#define STI_NOREGIONSDEF 2 /* region table is not setup */
#define STI_ILLNPLANES 3 /* invalid num of text planes */
#define STI_ILLINDEX 4 /* invalid fond index */
#define STI_ILLINDEX 4 /* invalid font index */
#define STI_ILLLOC 5 /* invalid font location */
#define STI_ILLCOLOUR 6 /* invalid colour */
#define STI_ILLBLKMVFROM 7 /* invalid from in blkmv */
#define STI_ILLBLKMVTO 8 /* invalid to in blkmv */
#define STI_ILLBLKMVSIZE 9 /* invalid siz in blkmv */
#define STI_ILLBLKMVSIZE 9 /* invalid size in blkmv */
#define STI_BEIUNSUPP 10 /* bus error ints unsupported */
#define STI_UNXPBE 11 /* unexpected bus error */
#define STI_UNXHWF 12 /* unexpected hardware failure */
@ -106,8 +113,6 @@
#define STI_COLOUR_BLUE 6
#define STI_COLOUR_MAGENTA 7
#pragma pack(1)
/* LSB high */
struct sti_dd {
uint32_t dd_type; /* 0x00 device type */
@ -117,7 +122,7 @@ struct sti_dd {
uint8_t dd_nmon; /* 0x05 number monitor rates */
uint8_t dd_grrev; /* 0x06 global rom revision */
uint8_t dd_lrrev; /* 0x07 local rom revision */
uint8_t dd_grid[8]; /* 0x08 graphics id */
uint32_t dd_grid[2]; /* 0x08 graphics id */
#define STI_DEV4_DD_GRID 0x08 /* offset for STI_DEVTYPE4 */
#define STI_DEV1_DD_GRID 0x10 /* offset for STI_DEVTYPE1 */
uint32_t dd_fntaddr; /* 0x10 font start address */
@ -155,7 +160,9 @@ struct sti_dd {
servers w/o accel */
uint32_t dd_pacode[16]; /* 0x40 routines for pa-risc */
uint32_t dd_altcode[16]; /* 0x80 routines for m68k/i386 */
};
} __packed;
#define STI_REVISION(maj, min) (((maj) << 4) | ((min) & 0x0f))
/* after the last region there is one indirect list ptr */
struct sti_region {
@ -165,7 +172,7 @@ struct sti_region {
u_int btlb : 1; /* should use BTLB if available */
u_int last : 1; /* last region in the list */
u_int length :14; /* size in pages */
};
} __packed;
struct sti_font {
uint16_t first;
@ -180,7 +187,7 @@ struct sti_font {
uint8_t uheight;
uint8_t uoffset;
uint8_t unused[2];
};
} __packed;
struct sti_fontcfg {
uint16_t first;
@ -191,7 +198,23 @@ struct sti_fontcfg {
uint8_t bpc;
uint8_t uheight;
uint8_t uoffset;
};
} __packed;
typedef struct sti_mon {
uint32_t width: 12;
uint32_t height: 12;
uint32_t hz: 7; /* low 7 bits of refresh rate */
uint32_t flat: 1; /* flatpanel */
uint32_t vesa: 1; /* vesa mode */
uint32_t grey: 1; /* greyscale */
uint32_t dblbuf: 1; /* double buffered */
uint32_t user: 1; /* user-defined mode */
uint32_t stereo: 1; /* stereo display */
uint32_t sam: 1; /* ? */
uint32_t : 15;
uint32_t hz_upper: 3; /* upper 3 bits of refresh rate */
uint32_t font: 8; /* rom font index */
} __packed *sti_mon_t;
typedef struct sti_ecfg {
uint8_t current_monitor;
@ -200,7 +223,7 @@ typedef struct sti_ecfg {
uint32_t freq_ref;
uint32_t *addr; /* memory block of size dd_stimemreq */
void *future;
} *sti_ecfg_t;
} __packed *sti_ecfg_t;
typedef struct sti_cfg {
uint32_t text_planes;
@ -214,7 +237,7 @@ typedef struct sti_cfg {
uint32_t reent_level;
uint32_t *save_addr;
sti_ecfg_t ext_cfg;
} *sti_cfg_t;
} __packed *sti_cfg_t;
/* routine types */
@ -240,25 +263,25 @@ typedef struct sti_initflags {
#define STI_INITF_SCMT 0x00040000 /* change current monitor type */
#define STI_INITF_RIE 0x00020000 /* retain int enables */
void *future;
} *sti_initflags_t;
} __packed *sti_initflags_t;
typedef struct sti_einitin {
uint8_t mon_type;
uint8_t pad;
uint16_t inflight; /* possible on pci */
void *future;
} *sti_einitin_t;
} __packed *sti_einitin_t;
typedef struct sti_initin {
uint32_t text_planes; /* number of planes for text */
sti_einitin_t ext_in;
} *sti_initin_t;
} __packed *sti_initin_t;
typedef struct sti_initout {
int32_t errno;
uint32_t text_planes; /* number of planes used for text */
void *future;
} *sti_initout_t;
} __packed *sti_initout_t;
STI_DEP(init);
@ -268,17 +291,17 @@ typedef struct sti_mgmtflags {
#define STI_MGMTF_SAVE 0x40000000
#define STI_MGMTF_RALL 0x20000000 /* restore all display planes */
void *future;
} *sti_mgmtflags_t;
} __packed *sti_mgmtflags_t;
typedef struct sti_mgmtin {
void *addr;
void *future;
} *sti_mgmtin_t;
} __packed *sti_mgmtin_t;
typedef struct sti_mgmtout {
int32_t errno;
void *future;
} *sti_mgmtout_t;
} __packed *sti_mgmtout_t;
STI_DEP(mgmt);
@ -287,7 +310,7 @@ typedef struct sti_unpmvflags {
#define STI_UNPMVF_WAIT 0x80000000
#define STI_UNPMVF_NTXT 0x40000000 /* intp non-text planes */
void *future;
} *sti_unpmvflags_t;
} __packed *sti_unpmvflags_t;
typedef struct sti_unpmvin {
uint32_t *font_addr; /* font */
@ -296,12 +319,12 @@ typedef struct sti_unpmvin {
uint8_t bg_colour;
uint16_t x, y;
void *future;
} *sti_unpmvin_t;
} __packed *sti_unpmvin_t;
typedef struct sti_unpmvout {
uint32_t errno;
void *future;
} *sti_unpmvout_t;
} __packed *sti_unpmvout_t;
STI_DEP(unpmv);
@ -312,7 +335,7 @@ typedef struct sti_blkmvflags {
#define STI_BLKMVF_CLR 0x20000000 /* clear on move */
#define STI_BLKMVF_NTXT 0x10000000 /* move in non-text planes */
void *future;
} *sti_blkmvflags_t;
} __packed *sti_blkmvflags_t;
typedef struct sti_blkmvin {
uint8_t fg_colour;
@ -321,12 +344,12 @@ typedef struct sti_blkmvin {
uint16_t width, height;
uint16_t pad;
void *future;
} *sti_blkmvin_t;
} __packed *sti_blkmvin_t;
typedef struct sti_blkmvout {
uint32_t errno;
void *future;
} *sti_blkmvout_t;
} __packed *sti_blkmvout_t;
STI_DEP(blkmv);
@ -335,17 +358,17 @@ typedef struct sti_testflags {
#define STI_TESTF_WAIT 0x80000000
#define STI_TESTF_ETST 0x40000000
void *future;
} *sti_testflags_t;
} __packed *sti_testflags_t;
typedef struct sti_testin {
void *future;
} *sti_testin_t;
} __packed *sti_testin_t;
typedef struct sti_testout {
uint32_t errno;
uint32_t result;
void *future;
} *sti_testout_t;
} __packed *sti_testout_t;
STI_DEP(test);
@ -366,7 +389,7 @@ typedef struct sti_exhdlflags {
#define STI_EXHDLF_EIC 0x00080000 /* end int cycle */
#define STI_EXHDLF_RIE 0x00040000 /* reset do not clear int enables */
void *future;
} *sti_exhdlflags_t;
} __packed *sti_exhdlflags_t;
typedef struct sti_eexhdlin {
uint32_t eim_addr;
@ -374,7 +397,7 @@ typedef struct sti_eexhdlin {
uint32_t iem; /* enable mask */
uint32_t icm; /* clear mask */
void *future;
} *sti_eexhdlin_t;
} __packed *sti_eexhdlin_t;
typedef struct sti_exhdlint {
uint32_t flags;
@ -387,12 +410,12 @@ typedef struct sti_exhdlint {
#define STI_EXHDLINT_BDC 0x02000000 /* buffered dma complete */
#define STI_EXHDLINT_UDPC 0x01000000 /* unbuf priv dma complete */
#define STI_EXHDLINT_BDPC 0x00800000 /* buffered priv dma complete */
} *sti_exhdlint_t;
} __packed *sti_exhdlint_t;
typedef struct sti_exhdlin {
sti_exhdlint_t addr;
sti_eexhdlin_t ext;
} *sti_exhdlin_t;
} __packed *sti_exhdlin_t;
typedef struct sti_eexhdlout {
uint32_t eim_addr;
@ -400,7 +423,7 @@ typedef struct sti_eexhdlout {
uint32_t iem; /* enable mask */
uint32_t icm; /* clear mask */
void *future;
} *sti_eexhdlout_t;
} __packed *sti_eexhdlout_t;
typedef struct sti_exhdlout {
uint32_t errno;
@ -409,7 +432,7 @@ typedef struct sti_exhdlout {
#define STI_EXHDLO_IP 0x40000000 /* there is int pending */
#define STI_EXHDLO_IE 0x20000000 /* global enable set */
sti_eexhdlout_t ext;
} *sti_exhdlout_t;
} __packed *sti_exhdlout_t;
STI_DEP(exhdl);
@ -417,17 +440,17 @@ typedef struct sti_inqconfflags {
uint32_t flags;
#define STI_INQCONFF_WAIT 0x80000000
void *future;
} *sti_inqconfflags_t;
} __packed *sti_inqconfflags_t;
typedef struct sti_inqconfin {
void *future;
} *sti_inqconfin_t;
} __packed *sti_inqconfin_t;
typedef struct sti_einqconfout {
uint32_t crt_config[3];
uint32_t crt_hw[3];
void *future;
} *sti_einqconfout_t;
} __packed *sti_einqconfout_t;
typedef struct sti_inqconfout {
uint32_t errno;
@ -437,7 +460,7 @@ typedef struct sti_inqconfout {
uint32_t planes;
uint8_t name[STI_DEVNAME_LEN];
uint32_t attributes;
#define STI_INQCONF_Y2X 0x0001 /* pixel is higher tan wider */
#define STI_INQCONF_Y2X 0x0001 /* pixel is higher than wider */
#define STI_INQCONF_HWBLKMV 0x0002 /* hw blkmv is present */
#define STI_INQCONF_AHW 0x0004 /* adv hw accel */
#define STI_INQCONF_INT 0x0008 /* can interrupt */
@ -454,7 +477,7 @@ typedef struct sti_inqconfout {
"\020\001y2x\002hwblkmv\003ahw\004int\005gonoff\006aonoff\007vary"\
"\010oddb\011flush\012dma\013vdma\016yuv1\017yuv2"
sti_einqconfout_t ext;
} *sti_inqconfout_t;
} __packed *sti_inqconfout_t;
STI_DEP(inqconf);
@ -462,18 +485,18 @@ typedef struct sti_scmentflags {
uint32_t flags;
#define STI_SCMENTF_WAIT 0x80000000
void *future;
} *sti_scmentflags_t;
} __packed *sti_scmentflags_t;
typedef struct sti_scmentin {
uint32_t entry;
uint32_t value;
void *future;
} *sti_scmentin_t;
} __packed *sti_scmentin_t;
typedef struct sti_scmentout {
uint32_t errno;
void *future;
} *sti_scmentout_t;
} __packed *sti_scmentout_t;
STI_DEP(scment);
@ -486,7 +509,7 @@ typedef struct sti_dmacflags {
#define STI_DMACF_MRK 0x08000000 /* write a marker */
#define STI_DMACF_ABRT 0x04000000 /* abort dma xfer */
void *future;
} *sti_dmacflags_t;
} __packed *sti_dmacflags_t;
typedef struct sti_dmacin {
uint32_t pa_upper;
@ -495,12 +518,12 @@ typedef struct sti_dmacin {
uint32_t mrk_data;
uint32_t mrk_off;
void *future;
} *sti_dmacin_t;
} __packed *sti_dmacin_t;
typedef struct sti_dmacout {
uint32_t errno;
void *future;
} *sti_dmacout_t;
} __packed *sti_dmacout_t;
STI_DEP(dmac);
@ -516,7 +539,7 @@ typedef struct sti_flowcflags {
#define STI_FLOWCF_CSWC 0x01000000 /* cs write coarse */
#define STI_FLOWCF_CSWQ 0x00800000 /* cs write fifo */
void *future;
} *sti_flowcflags_t;
} __packed *sti_flowcflags_t;
typedef struct sti_flowcin {
uint32_t retry;
@ -527,14 +550,14 @@ typedef struct sti_flowcin {
uint32_t cscv; /* cs coarse value */
uint32_t csqc; /* cs fifo count */
void *future;
} *sti_flowcin_t;
} __packed *sti_flowcin_t;
typedef struct sti_flowcout {
uint32_t errno;
uint32_t retry_result;
uint32_t fifo_size;
void *future;
} *sti_flowcout_t;
} __packed *sti_flowcout_t;
STI_DEP(flowc);
@ -543,19 +566,19 @@ typedef struct sti_utimingflags {
#define STI_UTIMF_WAIT 0x80000000
#define STI_UTIMF_HKS 0x40000000 /* has kbuf_size */
void *future;
} *sti_utimingflags_t;
} __packed *sti_utimingflags_t;
typedef struct sti_utimingin {
void *data;
void *kbuf;
void *future;
} *sti_utimingin_t;
} __packed *sti_utimingin_t;
typedef struct sti_utimingout {
uint32_t errno;
uint32_t kbuf_size; /* buffer required size */
void *future;
} *sti_utimingout_t;
} __packed *sti_utimingout_t;
STI_DEP(utiming);
@ -568,17 +591,17 @@ typedef struct sti_pmgrflags {
#define STI_UTIMF_BUFF 0x02000000
#define STI_UTIMF_IBUFF 0x01000000
void *future;
} *sti_pmgrflags_t;
} __packed *sti_pmgrflags_t;
typedef struct sti_pmgrin {
uint32_t reserved[4];
void *future;
} *sti_pmgrin_t;
} __packed *sti_pmgrin_t;
typedef struct sti_pmgrout {
int32_t errno;
void *future;
} *sti_pmgrout_t;
} __packed *sti_pmgrout_t;
STI_DEP(pmgr);
@ -586,21 +609,19 @@ typedef struct sti_utilflags {
uint32_t flags;
#define STI_UTILF_ROOT 0x80000000 /* was called as root */
void *future;
} *sti_utilflags_t;
} __packed *sti_utilflags_t;
typedef struct sti_utilin {
uint32_t in_size;
uint32_t out_size;
uint8_t *buf;
} *sti_utilin_t;
} __packed *sti_utilin_t;
typedef struct sti_utilout {
int32_t errno;
void *future;
} *sti_utilout_t;
} __packed *sti_utilout_t;
STI_DEP(util);
#pragma pack()
#endif /* _IC_STIREG_H_ */

View File

@ -1,6 +1,6 @@
/* $NetBSD: stivar.h,v 1.5 2010/11/01 06:41:50 skrll Exp $ */
/* $NetBSD: stivar.h,v 1.6 2010/11/09 12:24:48 skrll Exp $ */
/* $OpenBSD: stivar.h,v 1.15 2003/12/16 06:07:13 mickey Exp $ */
/* $OpenBSD: stivar.h,v 1.24 2009/02/06 22:51:04 miod Exp $ */
/*
* Copyright (c) 2000-2003 Michael Shalayeff
@ -31,52 +31,104 @@
#ifndef _IC_STIVAR_H_
#define _IC_STIVAR_H_
struct sti_softc {
device_t sc_dev;
void *sc_ih;
struct sti_softc;
u_int sc_wsmode;
u_int sc_flags;
#define STI_TEXTMODE 0x0001
#define STI_CLEARSCR 0x0002
#define STI_CONSOLE 0x0004
int sc_devtype;
int sc_nscreens;
int sc_bpp;
/*
* STI ROM information - one per device
*/
struct sti_rom {
struct sti_softc *rom_softc; /* backpointer to device */
int rom_devtype;
bus_space_tag_t iot, memt;
bus_space_handle_t romh;
bus_addr_t base, fbaddr;
bus_size_t fblen;
bus_space_tag_t iot, memt; /* XXX iot unused */
bus_space_handle_t romh;
bus_addr_t *bases;
struct sti_dd sc_dd; /* in word format */
struct sti_font sc_curfont;
struct sti_cfg sc_cfg;
struct sti_ecfg sc_ecfg;
struct sti_dd rom_dd; /* in word format */
void *sc_romfont; /* ROM font copy, either in memory... */
u_int sc_fontmaxcol; /* ...or in off-screen frame buffer */
u_int sc_fontbase;
uint8_t sc_rcmap[STI_NCMAP], sc_gcmap[STI_NCMAP], sc_bcmap[STI_NCMAP];
vaddr_t sc_code;
sti_init_t init;
sti_mgmt_t mgmt;
sti_unpmv_t unpmv;
sti_blkmv_t blkmv;
sti_test_t test;
sti_exhdl_t exhdl;
sti_inqconf_t inqconf;
sti_scment_t scment;
sti_dmac_t dmac;
sti_flowc_t flowc;
sti_utiming_t utiming;
sti_pmgr_t pmgr;
sti_util_t util;
vaddr_t rom_code;
sti_init_t init;
sti_mgmt_t mgmt;
sti_unpmv_t unpmv;
sti_blkmv_t blkmv;
sti_test_t test;
sti_exhdl_t exhdl;
sti_inqconf_t inqconf;
sti_scment_t scment;
sti_dmac_t dmac;
sti_flowc_t flowc;
sti_utiming_t utiming;
sti_pmgr_t pmgr;
sti_util_t util;
};
void sti_attach_common(struct sti_softc *sc);
int sti_intr(void *v);
/*
* STI screen information - one per head
*/
struct sti_screen {
struct sti_rom *scr_rom;
#ifdef notyet
u_int scr_flags;
#endif
int scr_bpp;
struct sti_font scr_curfont;
struct sti_cfg scr_cfg;
struct sti_ecfg scr_ecfg;
char name[STI_DEVNAME_LEN];
void *scr_romfont; /* ROM font copy in memory... */
u_int scr_fontmaxcol;/* ...or in off-screen area */
u_int scr_fontbase;
uint8_t scr_rcmap[STI_NCMAP],
scr_gcmap[STI_NCMAP],
scr_bcmap[STI_NCMAP];
uint16_t fbheight, fbwidth;
uint16_t oheight, owidth; /* offscreen size */
bus_addr_t fbaddr;
bus_size_t fblen;
/* wsdisplay information */
int scr_nscreens;
u_int scr_wsmode;
struct wsscreen_descr scr_wsd;
struct wsscreen_descr *scr_scrlist[1];
struct wsscreen_list scr_screenlist;
};
/*
* STI Device state
*/
struct sti_softc {
device_t sc_dev;
#if notyet
void *sc_ih;
#endif
u_int sc_flags;
#define STI_CONSOLE 0x0001 /* first head is console... */
#define STI_ATTACHED 0x0002 /* ... and wsdisplay_cnattach() has been done */
#define STI_ROM_ENABLED 0x0004 /* PCI ROM is enabled */
bus_addr_t bases[STI_REGION_MAX];
struct sti_rom *sc_rom;
struct sti_screen *sc_scr;
/* optional, required for PCI */
void (*sc_enable_rom)(struct sti_softc *);
void (*sc_disable_rom)(struct sti_softc *);
};
int sti_attach_common(struct sti_softc *, bus_space_tag_t, bus_space_tag_t,
bus_space_handle_t, u_int);
int sti_cnattach(struct sti_rom *, struct sti_screen *, bus_space_tag_t,
bus_addr_t *, u_int);
void sti_describe(struct sti_softc *);
void sti_end_attach(struct sti_softc *);
u_int sti_rom_size(bus_space_tag_t, bus_space_handle_t);
#endif /* _IC_STIVAR_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.pci,v 1.331 2010/11/06 14:56:12 jakllsch Exp $
# $NetBSD: files.pci,v 1.332 2010/11/09 12:24:48 skrll Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@ -426,6 +426,10 @@ file dev/ic/bt485.c tga
file dev/ic/bt463.c tga
file dev/ic/ibm561.c tga
# HP Visualize
attach sti at pci with sti_pci
file dev/pci/sti_pci.c sti_pci needs-flag
# Integraphics Systems IGA168x and CyberPro framebuffers (linear non-VGA mode)
# device declaration in sys/conf/files
attach igsfb at pci with igsfb_pci

431
sys/dev/pci/sti_pci.c Normal file
View File

@ -0,0 +1,431 @@
/* $NetBSD: sti_pci.c,v 1.1 2010/11/09 12:24:48 skrll Exp $ */
/* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */
/*
* Copyright (c) 2006, 2007 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice, this permission notice, and the disclaimer below
* appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/ic/stireg.h>
#include <dev/ic/stivar.h>
#ifdef STIDEBUG
#define DPRINTF(s) do { \
if (stidebug) \
printf s; \
} while(0)
extern int stidebug;
#else
#define DPRINTF(s) /* */
#endif
int sti_pci_match(device_t, cfdata_t, void *);
void sti_pci_attach(device_t, device_t, void *);
void sti_pci_end_attach(device_t dev);
struct sti_pci_softc {
device_t sc_dev;
struct sti_softc sc_base;
pci_chipset_tag_t sc_pc;
pcitag_t sc_tag;
bus_space_handle_t sc_romh;
};
CFATTACH_DECL_NEW(sti_pci, sizeof(struct sti_pci_softc),
sti_pci_match, sti_pci_attach, NULL, NULL);
int sti_readbar(struct sti_softc *, struct pci_attach_args *, u_int, int);
int sti_check_rom(struct sti_pci_softc *, struct pci_attach_args *);
void sti_pci_enable_rom(struct sti_softc *);
void sti_pci_disable_rom(struct sti_softc *);
void sti_pci_enable_rom_internal(struct sti_pci_softc *);
void sti_pci_disable_rom_internal(struct sti_pci_softc *);
int sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);
#define PCI_ROM_ENABLE 0x00000001
#define PCI_ROM_ADDR_MASK 0xfffff800
#define PCI_ROM_ADDR(mr) \
((mr) & PCI_ROM_ADDR_MASK)
#define PCI_ROM_SIZE(mr) \
(PCI_ROM_ADDR(mr) & -PCI_ROM_ADDR(mr))
int
sti_pci_match(device_t parent, cfdata_t cf, void *aux)
{
struct pci_attach_args *paa = aux;
if (PCI_VENDOR(paa->pa_id) != PCI_VENDOR_HP)
return 0;
if (PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_EG ||
PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX2 ||
PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX4 ||
PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FX6 ||
PCI_PRODUCT(paa->pa_id) == PCI_PRODUCT_HP_VISUALIZE_FXE)
return 1;
return 0;
}
void
sti_pci_attach(device_t parent, device_t self, void *aux)
{
struct sti_pci_softc *spc = device_private(self);
struct pci_attach_args *paa = aux;
int ret;
spc->sc_dev = self;
spc->sc_pc = paa->pa_pc;
spc->sc_tag = paa->pa_tag;
spc->sc_base.sc_dev = self;
spc->sc_base.sc_enable_rom = sti_pci_enable_rom;
spc->sc_base.sc_disable_rom = sti_pci_disable_rom;
aprint_normal("\n");
if (sti_check_rom(spc, paa) != 0)
return;
aprint_normal("%s", device_xname(self));
ret = sti_pci_is_console(paa, spc->sc_base. bases);
if (ret != 0)
spc->sc_base.sc_flags |= STI_CONSOLE;
ret = sti_attach_common(&spc->sc_base, paa->pa_iot, paa->pa_memt,
spc->sc_romh, STI_CODEBASE_MAIN);
if (ret == 0)
config_interrupts(self, sti_pci_end_attach);
}
void sti_pci_end_attach(device_t dev)
{
struct sti_pci_softc *spc = device_private(dev);
struct sti_softc *sc = &spc->sc_base;
sti_end_attach(sc);
}
/*
* Grovel the STI ROM image.
*/
int
sti_check_rom(struct sti_pci_softc *spc, struct pci_attach_args *pa)
{
struct sti_softc *sc = &spc->sc_base;
pcireg_t address, mask;
bus_space_handle_t romh;
bus_size_t romsize, subsize, stiromsize;
bus_addr_t selected, offs, suboffs;
uint32_t tmp;
int i;
int rc;
/* sort of inline sti_pci_enable_rom(sc) */
address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, ~PCI_ROM_ENABLE);
mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM);
address |= PCI_ROM_ENABLE;
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM, address);
sc->sc_flags |= STI_ROM_ENABLED;
/*
* Map the complete ROM for now.
*/
romsize = PCI_ROM_SIZE(mask);
DPRINTF(("%s: mapping rom @ %lx for %lx\n", __func__,
(long)PCI_ROM_ADDR(address), (long)romsize));
rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address), romsize,
0, &romh);
if (rc != 0) {
aprint_error_dev(sc->sc_dev, "can't map PCI ROM (%d)\n", rc);
goto fail2;
}
sti_pci_disable_rom_internal(spc);
/*
* Iterate over the ROM images, pick the best candidate.
*/
selected = (bus_addr_t)-1;
for (offs = 0; offs < romsize; offs += subsize) {
sti_pci_enable_rom_internal(spc);
/*
* Check for a valid ROM header.
*/
tmp = bus_space_read_4(pa->pa_memt, romh, offs + 0);
tmp = le32toh(tmp);
if (tmp != 0x55aa0000) {
sti_pci_disable_rom_internal(spc);
if (offs == 0) {
aprint_error_dev(sc->sc_dev,
"invalid PCI ROM header signature (%08x)\n",
tmp);
rc = EINVAL;
}
break;
}
/*
* Check ROM type.
*/
tmp = bus_space_read_4(pa->pa_memt, romh, offs + 4);
tmp = le32toh(tmp);
if (tmp != 0x00000001) { /* 1 == STI ROM */
sti_pci_disable_rom_internal(spc);
if (offs == 0) {
aprint_error_dev(sc->sc_dev,
"invalid PCI ROM type (%08x)\n", tmp);
rc = EINVAL;
}
break;
}
subsize = (bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
offs + 0x0c);
subsize <<= 9;
#ifdef STIDEBUG
sti_pci_disable_rom_internal(spc);
DPRINTF(("ROM offset %08x size %08x type %08x",
(u_int)offs, (u_int)subsize, tmp));
sti_pci_enable_rom_internal(spc);
#endif
/*
* Check for a valid ROM data structure.
* We do not need it except to know what architecture the ROM
* code is for.
*/
suboffs = offs +(bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
offs + 0x18);
tmp = bus_space_read_4(pa->pa_memt, romh, suboffs + 0);
tmp = le32toh(tmp);
if (tmp != 0x50434952) { /* PCIR */
sti_pci_disable_rom_internal(spc);
if (offs == 0) {
aprint_error_dev(sc->sc_dev, "invalid PCI data"
" signature (%08x)\n", tmp);
rc = EINVAL;
} else {
DPRINTF((" invalid PCI data signature %08x\n",
tmp));
continue;
}
}
tmp = bus_space_read_1(pa->pa_memt, romh, suboffs + 0x14);
sti_pci_disable_rom_internal(spc);
DPRINTF((" code %02x", tmp));
switch (tmp) {
#ifdef __hppa__
case 0x10:
if (selected == (bus_addr_t)-1)
selected = offs;
break;
#endif
#ifdef __i386__
case 0x00:
if (selected == (bus_addr_t)-1)
selected = offs;
break;
#endif
default:
#ifdef STIDEBUG
DPRINTF((" (wrong architecture)"));
#endif
break;
}
DPRINTF(("%s\n", selected == offs ? " -> SELECTED" : ""));
}
if (selected == (bus_addr_t)-1) {
if (rc == 0) {
aprint_error_dev(sc->sc_dev, "found no ROM with "
"correct microcode architecture\n");
rc = ENOEXEC;
}
goto fail;
}
/*
* Read the STI region BAR assignments.
*/
sti_pci_enable_rom_internal(spc);
offs = selected +
(bus_addr_t)bus_space_read_2(pa->pa_memt, romh, selected + 0x0e);
for (i = 0; i < STI_REGION_MAX; i++) {
rc = sti_readbar(sc, pa, i,
bus_space_read_1(pa->pa_memt, romh, offs + i));
if (rc != 0)
goto fail;
}
/*
* Find out where the STI ROM itself lies, and its size.
*/
offs = selected +
(bus_addr_t)bus_space_read_4(pa->pa_memt, romh, selected + 0x08);
stiromsize = (bus_addr_t)bus_space_read_4(pa->pa_memt, romh,
offs + 0x18);
stiromsize = le32toh(stiromsize);
sti_pci_disable_rom_internal(spc);
/*
* Replace our mapping with a smaller mapping of only the area
* we are interested in.
*/
DPRINTF(("remapping rom @ %lx for %lx\n",
(long)(PCI_ROM_ADDR(address) + offs), (long)stiromsize));
bus_space_unmap(pa->pa_memt, romh, romsize);
rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address) + offs,
stiromsize, 0, &spc->sc_romh);
if (rc != 0) {
aprint_error_dev(sc->sc_dev, "can't map STI ROM (%d)\n",
rc);
goto fail2;
}
sti_pci_disable_rom_internal(spc);
sc->sc_flags &= ~STI_ROM_ENABLED;
return 0;
fail:
bus_space_unmap(pa->pa_memt, romh, romsize);
fail2:
sti_pci_disable_rom_internal(spc);
return rc;
}
/*
* Decode a BAR register.
*/
int
sti_readbar(struct sti_softc *sc, struct pci_attach_args *pa, u_int region,
int bar)
{
bus_addr_t addr;
bus_size_t size;
uint32_t cf;
int rc;
if (bar == 0) {
sc->bases[region] = 0;
return (0);
}
#ifdef DIAGNOSTIC
if (bar < PCI_MAPREG_START || bar > PCI_MAPREG_PPB_END) {
sti_pci_disable_rom(sc);
printf("%s: unexpected bar %02x for region %d\n",
device_xname(sc->sc_dev), bar, region);
sti_pci_enable_rom(sc);
}
#endif
cf = pci_conf_read(pa->pa_pc, pa->pa_tag, bar);
rc = pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, PCI_MAPREG_TYPE(cf),
&addr, &size, NULL);
if (rc != 0) {
sti_pci_disable_rom(sc);
aprint_error_dev(sc->sc_dev, "invalid bar %02x for region %d\n",
bar, region);
sti_pci_enable_rom(sc);
return (rc);
}
sc->bases[region] = addr;
return (0);
}
/*
* Enable PCI ROM.
*/
void
sti_pci_enable_rom_internal(struct sti_pci_softc *spc)
{
pcireg_t address;
KASSERT(spc != NULL);
address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
address |= PCI_ROM_ENABLE;
pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
}
void
sti_pci_enable_rom(struct sti_softc *sc)
{
struct sti_pci_softc *spc = device_private(sc->sc_dev);
if (!ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
sti_pci_enable_rom_internal(spc);
}
SET(sc->sc_flags, STI_ROM_ENABLED);
}
/*
* Disable PCI ROM.
*/
void
sti_pci_disable_rom_internal(struct sti_pci_softc *spc)
{
pcireg_t address;
KASSERT(spc != NULL);
address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM);
address &= ~PCI_ROM_ENABLE;
pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_MAPREG_ROM, address);
}
void
sti_pci_disable_rom(struct sti_softc *sc)
{
struct sti_pci_softc *spc = device_private(sc->sc_dev);
if (ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
sti_pci_disable_rom_internal(spc);
}
CLR(sc->sc_flags, STI_ROM_ENABLED);
}