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