summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/sys/Makefile18
-rw-r--r--usr/src/uts/common/sys/THIRDPARTYLICENSE.agpgart1
-rw-r--r--usr/src/uts/common/sys/agp/agpdefs.h19
-rw-r--r--usr/src/uts/common/sys/agp/agpgart_impl.h1
-rw-r--r--usr/src/uts/common/sys/agp/agpmaster_io.h7
-rw-r--r--usr/src/uts/common/sys/agp/agptarget_io.h2
-rw-r--r--usr/src/uts/common/sys/agpgart.h24
-rw-r--r--usr/src/uts/intel/agpgart/Makefile10
-rw-r--r--usr/src/uts/intel/agpmaster/Makefile10
-rw-r--r--usr/src/uts/intel/agptarget/Makefile10
-rw-r--r--usr/src/uts/intel/amd64_gart/Makefile11
-rw-r--r--usr/src/uts/intel/io/agpgart/agpgart.c227
-rw-r--r--usr/src/uts/intel/io/agpgart/agptarget.c97
-rw-r--r--usr/src/uts/intel/io/agpmaster/agpmaster.c127
14 files changed, 376 insertions, 188 deletions
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index 40ba9fb..c43bcf2 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -34,7 +34,15 @@ FILEMODE=644
# unix_bb_info.h: Private interface to kcov
#
-i386_HDRS=
+i386_HDRS= \
+ agp/agpamd64gart_io.h \
+ agp/agpdefs.h \
+ agp/agpgart_impl.h \
+ agp/agpmaster_io.h \
+ agp/agptarget_io.h \
+ agpgart.h \
+ gfx_private.h
+
sparc_HDRS=
# Generated headers
@@ -49,7 +57,7 @@ HDRS= $(GENHDRS) $(CHKHDRS)
# from Makefile.syshdrs
ROOTDIR= $(ROOT)/usr/include/sys
sparc_ROOTDIRS=
-i386_ROOTDIRS=
+i386_ROOTDIRS= $(ROOTDIR)/agp
sparc_ROOTHDRS=
i386_ROOTHDRS=
@@ -61,9 +69,15 @@ ROOTHDRS= \
$($(MACH)_HDRS:%=$(ROOTDIR)/%) \
$(HDRS:%=$(ROOTDIR)/%)
+agp/%.check: agp/%.h
+ $(DOT_H_CHECK)
+
$(ROOTDIR)/%: %
$(INS.file)
+$(ROOTDIR)/agp/%: agp/%
+ $(INS.file)
+
$(ROOTDIRS):
$(INS.dir)
diff --git a/usr/src/uts/common/sys/THIRDPARTYLICENSE.agpgart b/usr/src/uts/common/sys/THIRDPARTYLICENSE.agpgart
index 3bcf0d3..8bf5829 100644
--- a/usr/src/uts/common/sys/THIRDPARTYLICENSE.agpgart
+++ b/usr/src/uts/common/sys/THIRDPARTYLICENSE.agpgart
@@ -1,4 +1,5 @@
* Copyright (c) 2000 Doug Rabson
+ * Copyright (c) 2009, Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/usr/src/uts/common/sys/agp/agpdefs.h b/usr/src/uts/common/sys/agp/agpdefs.h
index adda870..3d7caa5 100644
--- a/usr/src/uts/common/sys/agp/agpdefs.h
+++ b/usr/src/uts/common/sys/agp/agpdefs.h
@@ -187,14 +187,16 @@ extern "C" {
#define INTEL_IGD_B43 0x2e428086
/* Intel 915 and 945 series */
-#define IS_INTEL_915(device) ((device == INTEL_IGD_915) || \
+#define IS_INTEL_915(device) ( \
+ (device == INTEL_IGD_915) || \
(device == INTEL_IGD_915GM) || \
(device == INTEL_IGD_945) || \
(device == INTEL_IGD_945GM) || \
(device == INTEL_IGD_945GME))
/* Intel 965 series */
-#define IS_INTEL_965(device) ((device == INTEL_IGD_946GZ) || \
+#define IS_INTEL_965(device) ( \
+ (device == INTEL_IGD_946GZ) || \
(device == INTEL_IGD_965G1) || \
(device == INTEL_IGD_965Q) || \
(device == INTEL_IGD_965G2) || \
@@ -204,20 +206,23 @@ extern "C" {
IS_INTEL_G4X(device))
/* Intel G33 series */
-#define IS_INTEL_X33(device) ((device == INTEL_IGD_Q35) || \
+#define IS_INTEL_X33(device) ( \
+ (device == INTEL_IGD_Q35) || \
(device == INTEL_IGD_G33) || \
(device == INTEL_IGD_Q33))
/* IGDNG */
-#define IS_IGDNG(device) ((device == INTEL_IGD_IGDNG_D) || \
- (device == INTEL_IGD_IGDNG_M))
+#define IS_INTEL_IGDNG(device) ( \
+ (device == INTEL_IGD_IGDNG_D) || \
+ (device == INTEL_IGD_IGDNG_M))
/* Intel G4X series */
-#define IS_INTEL_G4X(device) ((device == INTEL_IGD_EL) || \
+#define IS_INTEL_G4X(device) ( \
+ (device == INTEL_IGD_EL) || \
(device == INTEL_IGD_Q45) || \
(device == INTEL_IGD_G45) || \
(device == INTEL_IGD_G41) || \
- IS_IGDNG(device) || \
+ IS_INTEL_IGDNG(device) || \
(device == INTEL_IGD_B43))
/* register offsets in PCI config space */
diff --git a/usr/src/uts/common/sys/agp/agpgart_impl.h b/usr/src/uts/common/sys/agp/agpgart_impl.h
index a8f5b6b..5c93eb7 100644
--- a/usr/src/uts/common/sys/agp/agpgart_impl.h
+++ b/usr/src/uts/common/sys/agp/agpgart_impl.h
@@ -156,7 +156,6 @@ typedef struct agpgart_softstate {
/* all registered agp device in here */
agp_registered_dev_t asoft_devreg;
kstat_t *asoft_ksp;
- struct list_head mapped_list;
} agpgart_softstate_t;
typedef struct agpgart_ctx {
diff --git a/usr/src/uts/common/sys/agp/agpmaster_io.h b/usr/src/uts/common/sys/agp/agpmaster_io.h
index 1202e76..e492fae 100644
--- a/usr/src/uts/common/sys/agp/agpmaster_io.h
+++ b/usr/src/uts/common/sys/agp/agpmaster_io.h
@@ -48,16 +48,21 @@ extern "C" {
#define I810_SET_GTT_BASE _IOW(AGPMASTERIOC_BASE, 12, uint32_t)
#define I8XX_ADD2GTT _IOW(AGPMASTERIOC_BASE, 13, igd_gtt_seg_t)
#define I8XX_REM_GTT _IOW(AGPMASTERIOC_BASE, 14, igd_gtt_seg_t)
+#define I8XX_RW_GTT _IOW(AGPMASTERIOC_BASE, 15, igd_gtt_seg_t)
#define I8XX_UNCONFIG _IO(AGPMASTERIOC_BASE, 16)
#define AGP_MASTER_GETINFO _IOR(AGPMASTERIOC_BASE, 20, agp_info_t)
#define AGP_MASTER_SETCMD _IOW(AGPMASTERIOC_BASE, 21, uint32_t)
-/* used for IGD to bind/unbind gtt entries */
+/*
+ * used for IGD to bind/unbind gtt entries, and RW_GTT
+ */
typedef struct igd_gtt_seg {
uint32_t igs_pgstart;
uint32_t igs_npage;
uint32_t *igs_phyaddr; /* pointer to address array */
uint32_t igs_type; /* reserved for other memory type */
+ uint32_t igs_flags;
+ uint32_t igs_scratch;
} igd_gtt_seg_t;
/* used for IGD to get info */
diff --git a/usr/src/uts/common/sys/agp/agptarget_io.h b/usr/src/uts/common/sys/agp/agptarget_io.h
index 316e2ab..c68e3d7 100644
--- a/usr/src/uts/common/sys/agp/agptarget_io.h
+++ b/usr/src/uts/common/sys/agp/agptarget_io.h
@@ -28,6 +28,8 @@ extern "C" {
#define INTEL_CHIPSET_FLUSH_SETUP _IO(AGPTARGETIOC_BASE, 38)
#define INTEL_CHIPSET_FLUSH _IO(AGPTARGETIOC_BASE, 39)
#define INTEL_CHIPSET_FLUSH_FREE _IO(AGPTARGETIOC_BASE, 40)
+#define AGP_TARGET_PCICONFIG_GET16 _IOWR(AGPTARGETIOC_BASE, 41, uint16_t)
+#define AGP_TARGET_PCICONFIG_SET16 _IOW(AGPTARGETIOC_BASE, 42, uint32_t)
/* Internal agp info struct */
typedef struct _i_agp_info {
diff --git a/usr/src/uts/common/sys/agpgart.h b/usr/src/uts/common/sys/agpgart.h
index c8770ae..cf25bf0 100644
--- a/usr/src/uts/common/sys/agpgart.h
+++ b/usr/src/uts/common/sys/agpgart.h
@@ -70,14 +70,16 @@ typedef struct _agp_allocate {
typedef struct _agp_bind_pages {
uint32_t agpb_pgstart;
+ uint32_t agpb_pgcount;
pfn_t *agpb_pages;
- unsigned long agpb_pgcount;
+ uint32_t agpb_type; /* AGP_USER_MEMORY */
} agp_bind_pages_t;
typedef struct _agp_unbind_pages {
- uint32_t agpb_pgstart;
- unsigned long agpb_pgcount;
- uint32_t agpb_type;
+ uint32_t agpu_pgstart;
+ uint32_t agpu_pgcount;
+ pfn_t agpu_scratch;
+ uint32_t agpu_flags;
} agp_unbind_pages_t;
typedef struct _agp_bind {
@@ -90,6 +92,13 @@ typedef struct _agp_unbind {
uint32_t agpu_pri; /* no use in solaris */
} agp_unbind_t;
+typedef struct _agp_rw_gtt {
+ uint32_t agprw_pgstart;
+ uint32_t agprw_pgcount;
+ void *agprw_addr; /* buffer */
+ uint32_t agprw_flags; /* 0:read, 1:write */
+} agp_rw_gtt_t;
+
#define AGPIOC_BASE 'G'
#define AGPIOC_INFO _IOR(AGPIOC_BASE, 0, 100)
#define AGPIOC_ACQUIRE _IO(AGPIOC_BASE, 1)
@@ -106,7 +115,12 @@ typedef struct _agp_unbind {
#define AGPIOC_FLUSHCHIPSET _IO(AGPIOC_BASE, 12)
#define AGPIOC_PAGES_BIND _IOW(AGPIOC_BASE, 13, agp_bind_pages_t)
#define AGPIOC_PAGES_UNBIND _IOW(AGPIOC_BASE, 14, agp_unbind_pages_t)
-#define AGPIOC_PAGES_REBIND _IO(AGPIOC_BASE, 15)
+#define AGPIOC_RW_GTT _IOW(AGPIOC_BASE, 15, agp_rw_gtt_t)
+
+/* AGP bind pages type values */
+#define AGP_USER_TYPES (1 << 16)
+#define AGP_USER_MEMORY (AGP_USER_TYPES)
+#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1)
/* AGP status register bits definition */
#define AGPSTAT_RQ_MASK 0xff000000 /* target only */
diff --git a/usr/src/uts/intel/agpgart/Makefile b/usr/src/uts/intel/agpgart/Makefile
index e80b1db..eb0c20d 100644
--- a/usr/src/uts/intel/agpgart/Makefile
+++ b/usr/src/uts/intel/agpgart/Makefile
@@ -27,6 +27,7 @@ CONF_SRCDIR = $(UTSBASE)/intel/io/agpgart
# Include common rules.
#
include $(UTSBASE)/intel/Makefile.intel
+AGPGART_OBJS += agpgart.o agp_kstat.o
#
# Define targets
@@ -35,9 +36,7 @@ ALL_TARGET = $(BINARY) $(SRC_CONFILE)
LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-CERRWARN += -_gcc=-Wno-switch
CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
#
# For now, disable these lint checks; maintainers should endeavor
@@ -67,6 +66,13 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpgart/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpgart/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
#
# Include common targets.
#
diff --git a/usr/src/uts/intel/agpmaster/Makefile b/usr/src/uts/intel/agpmaster/Makefile
index c6a25d3..826608b 100644
--- a/usr/src/uts/intel/agpmaster/Makefile
+++ b/usr/src/uts/intel/agpmaster/Makefile
@@ -24,7 +24,7 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
+
#
# This makefile drives the production of the common graphics
# interface kernel module.
@@ -55,6 +55,7 @@ LDFLAGS += -dy -Nmisc/pci_autoconfig
# Include common rules.
#
include $(UTSBASE)/intel/Makefile.intel
+AGP_OBJS += agpmaster.o
#
# Define targets
@@ -91,6 +92,13 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpmaster/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpmaster/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
#
# Include common targets.
#
diff --git a/usr/src/uts/intel/agptarget/Makefile b/usr/src/uts/intel/agptarget/Makefile
index 8cf479a..74bda0e 100644
--- a/usr/src/uts/intel/agptarget/Makefile
+++ b/usr/src/uts/intel/agptarget/Makefile
@@ -30,8 +30,7 @@ LDFLAGS += -dy -Nmisc/busra
# Include common rules.
#
include $(UTSBASE)/intel/Makefile.intel
-
-CERRWARN += -_gcc=-Wno-uninitialized
+AGPTARGET_OBJS += agptarget.o
#
# Define targets
@@ -61,6 +60,13 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpgart/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpgart/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
#
# Include common targets.
#
diff --git a/usr/src/uts/intel/amd64_gart/Makefile b/usr/src/uts/intel/amd64_gart/Makefile
index f2a2200..9aa5df8 100644
--- a/usr/src/uts/intel/amd64_gart/Makefile
+++ b/usr/src/uts/intel/amd64_gart/Makefile
@@ -4,8 +4,7 @@
#
# uts/intel/amd64_gart/Makefile
#
-#
-#ident "%Z%%M% %I% %E% SMI"
+
#
# This makefile drives the framework of agp protocol
# (amd64_gart) kernel module.
@@ -27,6 +26,7 @@ ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
# Include common rules.
#
include $(UTSBASE)/intel/Makefile.intel
+AMD64GART_OBJS += amd64_gart.o
#
# Define targets
@@ -56,6 +56,13 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
+$(OBJS_DIR)/%.o: $(UTSBASE)/intel/io/agpgart/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
+$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/io/agpgart/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
#
# Include common targets.
#
diff --git a/usr/src/uts/intel/io/agpgart/agpgart.c b/usr/src/uts/intel/io/agpgart/agpgart.c
index 7df0518..34f5ca5 100644
--- a/usr/src/uts/intel/io/agpgart/agpgart.c
+++ b/usr/src/uts/intel/io/agpgart/agpgart.c
@@ -64,52 +64,6 @@ static void *agpgart_glob_soft_handle;
#define IS_TRUE_AGP(type) (((type) == ARC_INTELAGP) || \
((type) == ARC_AMD64AGP))
-#define AGP_HASH_NODE 1024
-
-static void
-list_head_init(struct list_head *head) {
- struct list_head *entry, *tmp;
- /* HASH for accelerate */
- entry = kmem_zalloc(AGP_HASH_NODE *
- sizeof (struct list_head), KM_SLEEP);
- head->next = entry;
- for (int i = 0; i < AGP_HASH_NODE; i++) {
- tmp = &entry[i];
- tmp->next = tmp;
- tmp->prev = tmp;
- tmp->gttseg = NULL;
- }
-}
-
-static void
-list_head_add_new(struct list_head *head,
- igd_gtt_seg_t *gttseg)
-{
- struct list_head *entry, *tmp;
- int key;
- entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
- key = gttseg->igs_pgstart % AGP_HASH_NODE;
- tmp = &head->next[key];
- tmp->next->prev = entry;
- entry->next = tmp->next;
- entry->prev = tmp;
- tmp->next = entry;
- entry->gttseg = gttseg;
-}
-
-static void
-list_head_del(struct list_head *entry) {
- (entry)->next->prev = (entry)->prev; \
- (entry)->prev->next = (entry)->next; \
- (entry)->gttseg = NULL; \
-}
-
-#define list_head_for_each_safe(entry, temp, head) \
- for (int key = 0; key < AGP_HASH_NODE; key++) \
- for (entry = (&(head)->next[key])->next, temp = (entry)->next; \
- entry != &(head)->next[key]; \
- entry = temp, temp = temp->next)
-
#define agpinfo_default_to_32(v, v32) \
{ \
@@ -1472,6 +1426,9 @@ agp_unbind_key(agpgart_softstate_t *softstate, keytable_ent_t *entryp)
lyr_flush_gart_cache(&softstate->asoft_devreg);
break;
+ default:
+ /* Never happens, but avoid gcc switch warning. */
+ return (EIO);
}
entryp->kte_bound = 0;
@@ -2494,8 +2451,6 @@ agpgart_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
AGP_MAXKEYS * (sizeof (keytable_ent_t)),
KM_SLEEP);
- list_head_init(&softstate->mapped_list);
-
return (DDI_SUCCESS);
err4:
agp_fini_kstats(softstate);
@@ -2542,21 +2497,6 @@ agpgart_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
st->asoft_table = 0;
}
- struct list_head *entry, *temp, *head;
- igd_gtt_seg_t *gttseg;
- list_head_for_each_safe(entry, temp, &st->mapped_list) {
- gttseg = entry->gttseg;
- list_head_del(entry);
- kmem_free(entry, sizeof (*entry));
- kmem_free(gttseg->igs_phyaddr,
- sizeof (uint32_t) * gttseg->igs_npage);
- kmem_free(gttseg, sizeof (igd_gtt_seg_t));
- }
- head = &st->mapped_list;
- kmem_free(head->next,
- AGP_HASH_NODE * sizeof (struct list_head));
- head->next = NULL;
-
ddi_remove_minor_node(dip, AGPGART_DEVNODE);
agp_fini_kstats(st);
ldi_ident_release(st->asoft_li);
@@ -3144,122 +3084,124 @@ ioctl_agpgart_flush_chipset(agpgart_softstate_t *st)
static int
ioctl_agpgart_pages_bind(agpgart_softstate_t *st, void *arg, int flags)
{
- agp_bind_pages_t bind_info;
- uint32_t pg_offset;
- int err = 0;
- ldi_handle_t hdl;
- uint32_t npages;
- igd_gtt_seg_t *gttseg;
- uint32_t i;
- int rval;
- if (ddi_copyin(arg, &bind_info,
- sizeof (agp_bind_pages_t), flags) != 0) {
+ agp_bind_pages_t bind_info;
+ igd_gtt_seg_t gttseg;
+ size_t array_size;
+ ulong_t paddr;
+ uint32_t igs_type;
+ ldi_handle_t hdl;
+ int i, rval;
+ int rc = 0;
+
+ if (ddi_copyin(arg, &bind_info, sizeof (bind_info), flags) != 0) {
return (EFAULT);
}
- gttseg = (igd_gtt_seg_t *)kmem_zalloc(sizeof (igd_gtt_seg_t),
- KM_SLEEP);
-
- pg_offset = bind_info.agpb_pgstart;
+ /*
+ * Convert agp_type to something the igs layer understands.
+ */
+ switch (bind_info.agpb_type) {
+ case AGP_USER_MEMORY:
+ case AGP_USER_CACHED_MEMORY: /* Todo */
+ igs_type = AGP_NORMAL;
+ break;
+ default:
+ return (EINVAL);
+ }
- gttseg->igs_pgstart = pg_offset;
- npages = (uint32_t)bind_info.agpb_pgcount;
- gttseg->igs_npage = npages;
+ if (bind_info.agpb_pgcount == 0)
+ return (0);
- gttseg->igs_type = AGP_NORMAL;
- gttseg->igs_phyaddr = (uint32_t *)kmem_zalloc
- (sizeof (uint32_t) * gttseg->igs_npage, KM_SLEEP);
+ gttseg.igs_pgstart = bind_info.agpb_pgstart;
+ gttseg.igs_npage = bind_info.agpb_pgcount;
- for (i = 0; i < npages; i++) {
- gttseg->igs_phyaddr[i] = bind_info.agpb_pages[i] <<
- GTT_PAGE_SHIFT;
+ array_size = bind_info.agpb_pgcount * sizeof (uint32_t);
+ gttseg.igs_phyaddr = kmem_zalloc(array_size, KM_SLEEP);
+ if (bind_info.agpb_pages != NULL) {
+ for (i = 0; i < bind_info.agpb_pgcount; i++) {
+ paddr = bind_info.agpb_pages[i] << GTT_PAGE_SHIFT;
+ gttseg.igs_phyaddr[i] = (uint32_t)paddr;
+ }
}
+ gttseg.igs_type = igs_type;
+ gttseg.igs_flags = 0; /* not used */
+ gttseg.igs_scratch = 0; /* not used */
+
+ /* See i8xx_add_to_gtt */
hdl = st->asoft_devreg.agprd_masterhdl;
- if (ldi_ioctl(hdl, I8XX_ADD2GTT, (intptr_t)gttseg, FKIOCTL,
+ if (ldi_ioctl(hdl, I8XX_ADD2GTT, (intptr_t)&gttseg, FKIOCTL,
kcred, &rval)) {
- AGPDB_PRINT2((CE_WARN, "ioctl_agpgart_pages_bind: start0x%x",
- gttseg->igs_pgstart));
- AGPDB_PRINT2((CE_WARN, "ioctl_agpgart_pages_bind: pages=0x%x",
- gttseg->igs_npage));
- AGPDB_PRINT2((CE_WARN, "ioctl_agpgart_pages_bind: type=0x%x",
- gttseg->igs_type));
- err = -1;
+ rc = -1;
}
- list_head_add_new(&st->mapped_list, gttseg);
- return (err);
+ kmem_free(gttseg.igs_phyaddr, array_size);
+
+ return (rc);
}
static int
ioctl_agpgart_pages_unbind(agpgart_softstate_t *st, void *arg, int flags)
{
agp_unbind_pages_t unbind_info;
- int rval;
+ igd_gtt_seg_t gttseg;
ldi_handle_t hdl;
- igd_gtt_seg_t *gttseg;
+ int rval;
if (ddi_copyin(arg, &unbind_info, sizeof (unbind_info), flags) != 0) {
return (EFAULT);
}
- struct list_head *entry, *temp;
- list_head_for_each_safe(entry, temp, &st->mapped_list) {
- if (entry->gttseg->igs_pgstart == unbind_info.agpb_pgstart) {
- gttseg = entry->gttseg;
- /* not unbind if VT switch */
- if (unbind_info.agpb_type) {
- list_head_del(entry);
- kmem_free(entry, sizeof (*entry));
- }
- break;
- }
- }
- ASSERT(gttseg != NULL);
- gttseg->igs_pgstart = unbind_info.agpb_pgstart;
- ASSERT(gttseg->igs_npage == unbind_info.agpb_pgcount);
+ gttseg.igs_pgstart = unbind_info.agpu_pgstart;
+ gttseg.igs_npage = unbind_info.agpu_pgcount;
+ gttseg.igs_phyaddr = NULL; /* not used */
+ gttseg.igs_type = AGP_NORMAL;
+ gttseg.igs_flags = unbind_info.agpu_flags;
+ gttseg.igs_scratch = (uint32_t) unbind_info.agpu_scratch;
+ /* See i8xx_remove_from_gtt */
hdl = st->asoft_devreg.agprd_masterhdl;
- if (ldi_ioctl(hdl, I8XX_REM_GTT, (intptr_t)gttseg, FKIOCTL,
+ if (ldi_ioctl(hdl, I8XX_REM_GTT, (intptr_t)&gttseg, FKIOCTL,
kcred, &rval))
return (-1);
- if (unbind_info.agpb_type) {
- kmem_free(gttseg->igs_phyaddr, sizeof (uint32_t) *
- gttseg->igs_npage);
- kmem_free(gttseg, sizeof (igd_gtt_seg_t));
- }
-
return (0);
}
+/*
+ * Read or write GTT registers. In the DRM code, see:
+ * i915_gem_gtt.c:intel_rw_gtt
+ *
+ * Used to save/restore GTT state.
+ */
static int
-ioctl_agpgart_pages_rebind(agpgart_softstate_t *st)
+ioctl_agpgart_rw_gtt(agpgart_softstate_t *st, void *arg, int flags)
{
- int rval;
+ agp_rw_gtt_t rw_info;
+ igd_gtt_seg_t gttseg;
ldi_handle_t hdl;
- igd_gtt_seg_t *gttseg;
- int err = 0;
+ int rval;
- hdl = st->asoft_devreg.agprd_masterhdl;
- struct list_head *entry, *temp;
- list_head_for_each_safe(entry, temp, &st->mapped_list) {
- gttseg = entry->gttseg;
- list_head_del(entry);
- kmem_free(entry, sizeof (*entry));
- if (ldi_ioctl(hdl, I8XX_ADD2GTT, (intptr_t)gttseg, FKIOCTL,
- kcred, &rval)) {
- AGPDB_PRINT2((CE_WARN, "agpgart_pages_rebind errori"));
- err = -1;
- break;
- }
- kmem_free(gttseg->igs_phyaddr, sizeof (uint32_t) *
- gttseg->igs_npage);
- kmem_free(gttseg, sizeof (igd_gtt_seg_t));
+ if (ddi_copyin(arg, &rw_info, sizeof (rw_info), flags) != 0) {
+ return (EFAULT);
+ }
+
+ gttseg.igs_pgstart = rw_info.agprw_pgstart;
+ gttseg.igs_npage = rw_info.agprw_pgcount;
+ gttseg.igs_phyaddr = rw_info.agprw_addr;
+ gttseg.igs_type = 0; /* not used */
+ gttseg.igs_flags = rw_info.agprw_flags;
+ gttseg.igs_scratch = 0; /* not used */
+ /* See: i8xx_read_gtt, i8xx_write_gtt */
+ hdl = st->asoft_devreg.agprd_masterhdl;
+ if (ldi_ioctl(hdl, I8XX_RW_GTT, (intptr_t)&gttseg, FKIOCTL,
+ kcred, &rval)) {
+ AGPDB_PRINT2((CE_WARN, "agpgart_rw_gtt error"));
+ return (-1);
}
- return (err);
+ return (0);
}
/*ARGSUSED*/
@@ -3316,9 +3258,10 @@ agpgart_ioctl(dev_t dev, int cmd, intptr_t intarg, int flags,
case AGPIOC_PAGES_UNBIND:
retval = ioctl_agpgart_pages_unbind(softstate, arg, flags);
break;
- case AGPIOC_PAGES_REBIND:
- retval = ioctl_agpgart_pages_rebind(softstate);
+ case AGPIOC_RW_GTT:
+ retval = ioctl_agpgart_rw_gtt(softstate, arg, flags);
break;
+
default:
AGPDB_PRINT2((CE_WARN, "agpgart_ioctl: wrong argument"));
retval = ENXIO;
diff --git a/usr/src/uts/intel/io/agpgart/agptarget.c b/usr/src/uts/intel/io/agpgart/agptarget.c
index d1366d6..5c19a7c 100644
--- a/usr/src/uts/intel/io/agpgart/agptarget.c
+++ b/usr/src/uts/intel/io/agpgart/agptarget.c
@@ -176,7 +176,7 @@ agp_target_cap_find(ddi_acc_handle_t pci_handle)
static uint64_t
agp_target_get_apbase(agp_target_softstate_t *softstate)
{
- uint64_t aper_base;
+ uint64_t aper_base = 0;
if (is_intel_br(softstate)) {
aper_base = pci_config_get32(softstate->tsoft_pcihdl,
@@ -224,6 +224,12 @@ agp_target_get_apsize(agp_target_softstate_t *softstate)
} else if (is_64bit_aper(softstate)) {
value = pci_config_get16(softstate->tsoft_pcihdl,
cap + AGP_CONF_APERSIZE);
+ } else {
+ /*
+ * Never happens, but avoid gcc warnings re.
+ * value used uninitialized.
+ */
+ return (0);
}
if (value & AGP_APER_128M_MASK) {
@@ -400,7 +406,13 @@ static gms_mode_t gms_modes[] = {
GMS_SIZE(gms_G4X), gms_G4X},
{INTEL_BR_B43, I8XX_CONF_GC, I8XX_GC_MODE_MASK,
GMS_SIZE(gms_G4X), gms_G4X}
+ /*
+ * Note: This module is not used for Intel Gen6 or later
+ * devices (Sandy Bridge etc.) so no need to add any
+ * PCI IDs here for those devices.
+ */
};
+
static int
get_chip_gms(uint32_t devid)
{
@@ -411,10 +423,10 @@ get_chip_gms(uint32_t devid)
for (i = 0; i < num_modes; i++) {
if (gms_modes[i].gm_devid == devid)
- break;
+ return (i);
}
- return ((i == num_modes) ? -1 : i);
+ return (-1);
}
/* Returns the size (kbytes) of pre-allocated graphics memory */
@@ -557,8 +569,8 @@ agp_target_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
PCI_CONF_VENID);
softstate->tsoft_gms_off = get_chip_gms(softstate->tsoft_devid);
if (softstate->tsoft_gms_off < 0) {
- TARGETDB_PRINT2((CE_WARN, "agp_target_attach:"
- "read gms offset failed"));
+ TARGETDB_PRINT2((CE_WARN, "agp_target_attach: "
+ "unknown bridge ID 0x%x", softstate->tsoft_devid));
pci_config_teardown(&softstate->tsoft_pcihdl);
ddi_soft_state_free(agptarget_glob_soft_handle,
instance);
@@ -627,6 +639,7 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
cred_t *cred, int *rval)
{
int instance = DEV2INST(dev);
+ int ret = 0;
agp_target_softstate_t *st;
static char kernel_only[] =
"amd64_gart_ioctl: is a kernel only ioctl";
@@ -657,8 +670,8 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
}
if (ddi_copyout(&type, (void *)data, sizeof (int), mode)) {
- mutex_exit(&st->tsoft_lock);
- return (EFAULT);
+ ret = EFAULT;
+ break;
}
break;
@@ -668,15 +681,15 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
size_t prealloc_size;
if (!is_intel_br(st)) {
- mutex_exit(&st->tsoft_lock);
- return (EINVAL);
+ ret = EINVAL;
+ break;
}
prealloc_size = i8xx_biosmem_detect(st);
if (ddi_copyout(&prealloc_size, (void *)data,
sizeof (size_t), mode)) {
- mutex_exit(&st->tsoft_lock);
- return (EFAULT);
+ ret = EFAULT;
+ break;
}
break;
@@ -701,8 +714,8 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
if (ddi_copyout(&info, (void *)data,
sizeof (i_agp_info_t), mode)) {
- mutex_exit(&st->tsoft_lock);
- return (EFAULT);
+ ret = EFAULT;
+ break;
}
break;
@@ -721,8 +734,8 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
if (ddi_copyin((void *)data, &gartaddr,
sizeof (uint32_t), mode)) {
- mutex_exit(&st->tsoft_lock);
- return (EFAULT);
+ ret = EFAULT;
+ break;
}
agp_target_set_gartaddr(st, gartaddr);
@@ -734,8 +747,8 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
if (ddi_copyin((void *)data, &command,
sizeof (uint32_t), mode)) {
- mutex_exit(&st->tsoft_lock);
- return (EFAULT);
+ ret = EFAULT;
+ break;
}
ASSERT(st->tsoft_acaptr);
@@ -822,14 +835,58 @@ agp_target_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
case INTEL_CHIPSET_FLUSH:
case INTEL_CHIPSET_FLUSH_FREE:
break;
+
+ /* See i915_bridge_dev_read_config_word */
+ case AGP_TARGET_PCICONFIG_GET16:
+ {
+ uint16_t offset, value;
+
+ if (ddi_copyin(
+ (void *)data, &offset, sizeof (uint16_t), mode)) {
+ ret = EFAULT;
+ break;
+ }
+
+ value = pci_config_get16(st->tsoft_pcihdl, offset);
+
+ if (ddi_copyout(
+ &value, (void *)data, sizeof (uint16_t), mode)) {
+ ret = EFAULT;
+ break;
+ }
+
+ break;
+ }
+
+ /*
+ * See i915_bridge_dev_write_config_word
+ * Offset + value come in as 32 bits:
+ * data = (offset << 16) | value;
+ */
+ case AGP_TARGET_PCICONFIG_SET16:
+ {
+ uint32_t off_val;
+ uint16_t offset, value;
+
+ if (ddi_copyin((void *)data, &off_val,
+ sizeof (off_val), mode)) {
+ ret = EFAULT;
+ break;
+ }
+ offset = (off_val >> 16) & 0xffff;
+ value = off_val & 0xffff;
+ pci_config_put16(st->tsoft_pcihdl, offset, value);
+ break;
+ }
+
default:
- mutex_exit(&st->tsoft_lock);
- return (ENXIO);
+ ret = ENXIO;
+ break;
} /* end switch */
mutex_exit(&st->tsoft_lock);
- return (0);
+ return (ret);
}
/*ARGSUSED*/
diff --git a/usr/src/uts/intel/io/agpmaster/agpmaster.c b/usr/src/uts/intel/io/agpmaster/agpmaster.c
index 7a4de1e..a67094e 100644
--- a/usr/src/uts/intel/io/agpmaster/agpmaster.c
+++ b/usr/src/uts/intel/io/agpmaster/agpmaster.c
@@ -111,6 +111,8 @@ static int detect_i8xx_device(agp_master_softc_t *);
static int detect_agp_devcice(agp_master_softc_t *, ddi_acc_handle_t);
static int i8xx_add_to_gtt(gtt_impl_t *, igd_gtt_seg_t);
static void i8xx_remove_from_gtt(gtt_impl_t *, igd_gtt_seg_t);
+static int i8xx_read_gtt(gtt_impl_t *, igd_gtt_seg_t);
+static int i8xx_write_gtt(gtt_impl_t *, igd_gtt_seg_t);
int
_init(void)
@@ -439,6 +441,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
(void *)data, sizeof (int), mode))
return (EFAULT);
break;
+
case AGP_MASTER_SETCMD:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "AGP_MASTER_SETCMD"));
@@ -456,6 +459,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
softc->agpm_data.agpm_acaptr + AGP_CONF_COMMAND,
command);
break;
+
case AGP_MASTER_GETINFO:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only,
@@ -478,6 +482,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
sizeof (agp_info_t), mode))
return (EFAULT);
break;
+
case I810_SET_GTT_BASE:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "I810_SET_GTT_ADDR"));
@@ -494,6 +499,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
AGPM_WRITE(softc, PGTBL_CTL, addr);
break;
+
case I8XX_GET_INFO:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_GET_INFO"));
@@ -506,6 +512,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
(void *)data, sizeof (igd_info_t), mode))
return (EFAULT);
break;
+
case I8XX_ADD2GTT:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_ADD2GTT"));
@@ -521,6 +528,7 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
if (i8xx_add_to_gtt(&softc->agpm_data.agpm_gtt, seg))
return (EINVAL);
break;
+
case I8XX_REM_GTT:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_REM_GTT"));
@@ -535,6 +543,33 @@ agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
i8xx_remove_from_gtt(&softc->agpm_data.agpm_gtt, seg);
break;
+
+ case I8XX_RW_GTT:
+ if (!(mode & FKIOCTL)) {
+ AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_RW_GTT"));
+ return (ENXIO);
+ }
+
+ CONFIRM(IS_IGD(softc));
+
+ if (ddi_copyin((void *)data, &seg,
+ sizeof (igd_gtt_seg_t), mode))
+ return (EFAULT);
+
+ /*
+ * Read or write based on flags set in
+ * ioctl_agpgart_rw_gtt()
+ * Used to save/restore GTT state.
+ */
+ if (seg.igs_flags == 0) {
+ if (i8xx_read_gtt(&softc->agpm_data.agpm_gtt, seg))
+ return (EINVAL);
+ } else {
+ if (i8xx_write_gtt(&softc->agpm_data.agpm_gtt, seg))
+ return (EINVAL);
+ }
+ break;
+
case I8XX_UNCONFIG:
if (!(mode & FKIOCTL)) {
AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_UNCONFIG"));
@@ -629,9 +664,16 @@ detect_i8xx_device(agp_master_softc_t *master_softc)
case INTEL_IGD_IGDNG_D:
case INTEL_IGD_IGDNG_M:
case INTEL_IGD_B43:
+ /*
+ * Note: This module is not used for Intel Gen6 or later
+ * devices (Sandy Bridge etc.) so no need to add any
+ * PCI IDs here for those devices.
+ */
master_softc->agpm_dev_type = DEVICE_IS_I830;
break;
default: /* unknown id */
+ AGPM_DEBUG((CE_CONT, "unknown i8xx_device 0x%x",
+ master_softc->agpm_id));
return (-1);
}
@@ -674,6 +716,7 @@ phys2entry(uint32_t type, uint32_t physaddr, uint32_t *entry)
value = (physaddr & GTT_PTE_MASK) | GTT_PTE_VALID;
break;
default:
+ AGPM_DEBUG((CE_WARN, "phys2entry type %d", type));
return (-1);
}
@@ -693,12 +736,14 @@ i8xx_add_to_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
maxpages = gtt->gtt_info.igd_apersize;
maxpages = GTT_MB_TO_PAGES(maxpages);
- paddr = seg.igs_phyaddr;
-
/* check if gtt max page number is reached */
if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
return (-1);
+ /*
+ * Note: Caller supplies a gtt address from which we
+ * extract a uint32_t gtt_pte_t to set in the GTT.
+ */
paddr = seg.igs_phyaddr;
for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage);
i++, paddr++) {
@@ -717,16 +762,92 @@ i8xx_remove_from_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
{
int i;
uint32_t maxpages;
+ uint32_t entry;
maxpages = gtt->gtt_info.igd_apersize;
maxpages = GTT_MB_TO_PAGES(maxpages);
+ /*
+ * If non-zero, seg.igs_scratch is the pfn_t for a
+ * "scratch" page to use instead of zero.
+ */
+ if (seg.igs_scratch == 0 ||
+ phys2entry(seg.igs_type, seg.igs_scratch, &entry) != 0) {
+ entry = 0;
+ }
+
/* check if gtt max page number is reached */
if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
return;
for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage); i++) {
ddi_put32(gtt->gtt_handle,
- (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)), 0);
+ (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)),
+ entry);
}
}
+
+/*
+ * Low-level read GTT
+ */
+static int
+i8xx_read_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
+{
+ int i;
+ uint32_t *paddr;
+ uint32_t maxpages;
+
+ maxpages = gtt->gtt_info.igd_apersize;
+ maxpages = GTT_MB_TO_PAGES(maxpages);
+
+ /* Buffer into which we'll read. */
+ paddr = seg.igs_phyaddr;
+ if (paddr == NULL)
+ return (-1);
+
+ /* check if gtt max page number is reached */
+ if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
+ return (-1);
+
+ paddr = seg.igs_phyaddr;
+ for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage);
+ i++, paddr++) {
+ *paddr = ddi_get32(gtt->gtt_handle,
+ (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)));
+ }
+
+ return (0);
+}
+
+/*
+ * Low-level write GTT
+ */
+static int
+i8xx_write_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
+{
+ int i;
+ uint32_t *paddr;
+ uint32_t maxpages;
+
+ maxpages = gtt->gtt_info.igd_apersize;
+ maxpages = GTT_MB_TO_PAGES(maxpages);
+
+ /* Buffer from which we'll write. */
+ paddr = seg.igs_phyaddr;
+ if (paddr == NULL)
+ return (-1);
+
+ /* check if gtt max page number is reached */
+ if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
+ return (-1);
+
+ paddr = seg.igs_phyaddr;
+ for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage);
+ i++, paddr++) {
+ ddi_put32(gtt->gtt_handle,
+ (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)),
+ *paddr);
+ }
+
+ return (0);
+}