1*3446Smrj /*
2*3446Smrj * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3*3446Smrj * Use is subject to license terms.
4*3446Smrj */
5*3446Smrj
6*3446Smrj #pragma ident "%Z%%M% %I% %E% SMI"
7*3446Smrj
8*3446Smrj #include <sys/kstat.h>
9*3446Smrj #include <sys/ddi.h>
10*3446Smrj #include <sys/sunddi.h>
11*3446Smrj #include <sys/sunldi.h>
12*3446Smrj #include <sys/agpgart.h>
13*3446Smrj #include <sys/agp/agpdefs.h>
14*3446Smrj #include <sys/agp/agpgart_impl.h>
15*3446Smrj
16*3446Smrj /*
17*3446Smrj * The values of type agp_arc_type_t are used as indices into arc_name
18*3446Smrj * So if agp_arc_type_t's values are changed in the future, the content
19*3446Smrj * of arc_name must be changed accordingly.
20*3446Smrj */
21*3446Smrj static const char *arc_name[] = {
22*3446Smrj "IGD_810",
23*3446Smrj "IGD_830",
24*3446Smrj "INTEL_AGP",
25*3446Smrj "AMD64_AGP",
26*3446Smrj "AMD64_NONAGP",
27*3446Smrj "UNKNOWN"
28*3446Smrj };
29*3446Smrj
30*3446Smrj static char *agpkstat_name[] = {
31*3446Smrj "&arc_type",
32*3446Smrj "master_dev_id",
33*3446Smrj "master_dev_version",
34*3446Smrj "master_dev_status",
35*3446Smrj "$prealloc_size",
36*3446Smrj "target_dev_id",
37*3446Smrj "target_dev_version",
38*3446Smrj "target_dev_status",
39*3446Smrj "$aper_base",
40*3446Smrj "$aper_size",
41*3446Smrj "&agp_enabled",
42*3446Smrj "agp_mode_set",
43*3446Smrj "$aper_used",
44*3446Smrj NULL
45*3446Smrj };
46*3446Smrj
47*3446Smrj static void
agp_set_char_kstat(kstat_named_t * knp,const char * s)48*3446Smrj agp_set_char_kstat(kstat_named_t *knp, const char *s)
49*3446Smrj {
50*3446Smrj (void) strlcpy(knp->value.c, s, sizeof (knp->value.c));
51*3446Smrj }
52*3446Smrj
53*3446Smrj static int
agp_kstat_update(kstat_t * ksp,int flag)54*3446Smrj agp_kstat_update(kstat_t *ksp, int flag)
55*3446Smrj {
56*3446Smrj agpgart_softstate_t *sc;
57*3446Smrj kstat_named_t *knp;
58*3446Smrj int tmp;
59*3446Smrj
60*3446Smrj if (flag != KSTAT_READ)
61*3446Smrj return (EACCES);
62*3446Smrj
63*3446Smrj sc = ksp->ks_private;
64*3446Smrj knp = ksp->ks_data;
65*3446Smrj
66*3446Smrj agp_set_char_kstat(knp++, arc_name[sc->asoft_devreg.agprd_arctype]);
67*3446Smrj (knp++)->value.ui32 = sc->asoft_info.agpki_mdevid;
68*3446Smrj (knp++)->value.ui32 = (sc->asoft_info.agpki_mver.agpv_major<<16) |
69*3446Smrj sc->asoft_info.agpki_mver.agpv_minor;
70*3446Smrj (knp++)->value.ui32 = sc->asoft_info.agpki_mstatus;
71*3446Smrj (knp++)->value.ui64 = (sc->asoft_info.agpki_presize << 10) & UI32_MASK;
72*3446Smrj (knp++)->value.ui32 = sc->asoft_info.agpki_tdevid;
73*3446Smrj (knp++)->value.ui32 = (sc->asoft_info.agpki_tver.agpv_major<<16) |
74*3446Smrj sc->asoft_info.agpki_tver.agpv_minor;
75*3446Smrj (knp++)->value.ui32 = sc->asoft_info.agpki_tstatus;
76*3446Smrj (knp++)->value.ui64 = sc->asoft_info.agpki_aperbase;
77*3446Smrj (knp++)->value.ui64 =
78*3446Smrj (sc->asoft_info.agpki_apersize << 20) & UI32_MASK;
79*3446Smrj
80*3446Smrj tmp = sc->asoft_agpen;
81*3446Smrj agp_set_char_kstat(knp++, (tmp > 0) ? "yes" : "no");
82*3446Smrj
83*3446Smrj (knp++)->value.ui32 = sc->asoft_mode;
84*3446Smrj (knp++)->value.ui64 = (sc->asoft_pgused << 12) & UI32_MASK;
85*3446Smrj
86*3446Smrj return (0);
87*3446Smrj }
88*3446Smrj
89*3446Smrj int
agp_init_kstats(agpgart_softstate_t * sc)90*3446Smrj agp_init_kstats(agpgart_softstate_t *sc)
91*3446Smrj {
92*3446Smrj int instance;
93*3446Smrj kstat_t *ksp;
94*3446Smrj kstat_named_t *knp;
95*3446Smrj char *np;
96*3446Smrj int type;
97*3446Smrj char **aknp;
98*3446Smrj
99*3446Smrj instance = ddi_get_instance(sc->asoft_dip);
100*3446Smrj aknp = agpkstat_name;
101*3446Smrj ksp = kstat_create(AGPGART_DEVNODE, instance, "agpinfo", "agp",
102*3446Smrj KSTAT_TYPE_NAMED, sizeof (agpkstat_name)/sizeof (char *) - 1,
103*3446Smrj KSTAT_FLAG_PERSISTENT);
104*3446Smrj if (ksp == NULL)
105*3446Smrj return (NULL);
106*3446Smrj
107*3446Smrj ksp->ks_private = sc;
108*3446Smrj ksp->ks_update = agp_kstat_update;
109*3446Smrj for (knp = ksp->ks_data; (np = (*aknp)) != NULL; knp++, aknp++) {
110*3446Smrj switch (*np) {
111*3446Smrj case '$':
112*3446Smrj np += 1;
113*3446Smrj type = KSTAT_DATA_UINT64;
114*3446Smrj break;
115*3446Smrj case '&':
116*3446Smrj np += 1;
117*3446Smrj type = KSTAT_DATA_CHAR;
118*3446Smrj break;
119*3446Smrj default:
120*3446Smrj type = KSTAT_DATA_UINT32;
121*3446Smrj break;
122*3446Smrj
123*3446Smrj }
124*3446Smrj kstat_named_init(knp, np, type);
125*3446Smrj }
126*3446Smrj kstat_install(ksp);
127*3446Smrj
128*3446Smrj sc->asoft_ksp = ksp;
129*3446Smrj
130*3446Smrj return (0);
131*3446Smrj }
132*3446Smrj
133*3446Smrj void
agp_fini_kstats(agpgart_softstate_t * sc)134*3446Smrj agp_fini_kstats(agpgart_softstate_t *sc)
135*3446Smrj {
136*3446Smrj ASSERT(sc->asoft_ksp);
137*3446Smrj kstat_delete(sc->asoft_ksp);
138*3446Smrj }
139