1 /* _NVRM_COPYRIGHT_BEGIN_
3 * Copyright 2001-2002 by NVIDIA Corporation. All rights reserved. All
4 * information contained herein is proprietary and confidential to NVIDIA
5 * Corporation. Any use, reproduction, or disclosure without the written
6 * permission of NVIDIA Corporation is prohibited.
12 #include "os-interface.h"
14 #include "nv-freebsd.h"
16 struct sysctl_ctx_list sysctl_ctx;
18 struct sysctl_oid *oid_nvidia;
19 struct sysctl_oid *oid_agp;
20 struct sysctl_oid *oid_registry;
22 static char *option_string = NULL;
24 static void* nvidia_find_bridge (void);
25 static U032 nvidia_dev_agp_cmd (device_t dev);
26 static U032 nvidia_dev_agp_status (device_t dev);
27 static U032 nvidia_sys_agp_cmd (device_t dev);
29 void nvidia_sysctl_init(void)
32 struct sysctl_oid *oid;
35 sysctl_ctx_init(&sysctl_ctx);
37 oid_nvidia = SYSCTL_ADD_NODE(&sysctl_ctx,
38 SYSCTL_STATIC_CHILDREN(_hw),
41 CTLFLAG_RD | CTLFLAG_DYN,
43 "NVIDIA SYSCTL Master Node");
45 oid_agp = SYSCTL_ADD_NODE(&sysctl_ctx,
46 SYSCTL_CHILDREN(oid_nvidia),
49 CTLFLAG_RD | CTLFLAG_DYN,
51 "NVIDIA SYSCTL AGP Node");
53 SYSCTL_ADD_STRING(&sysctl_ctx,
54 SYSCTL_CHILDREN(oid_nvidia),
57 CTLFLAG_RD | CTLFLAG_DYN,
58 (char *)(uintptr_t) pNVRM_ID,
60 "NVIDIA Resource Manager (NVRM) Version");
62 oid_registry = SYSCTL_ADD_NODE(&sysctl_ctx,
63 SYSCTL_CHILDREN(oid_nvidia),
66 CTLFLAG_RD | CTLFLAG_DYN,
68 "NVIDIA SYSCTL Registry Node");
72 SYSCTL_ADD_PROC(&sysctl_ctx,
73 SYSCTL_CHILDREN(oid_registry),
76 CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_DYN,
78 nvidia_sysctl_registry_key,
81 } while(entry->name != NULL);
83 option_string = malloc(1, M_NVIDIA, M_WAITOK | M_ZERO);
85 SYSCTL_ADD_PROC(&sysctl_ctx,
86 SYSCTL_CHILDREN(oid_registry),
88 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_DYN,
90 nvidia_sysctl_registry_dwords,
93 if ((dev = nvidia_find_bridge()) != NULL) {
95 * Assume this is the only AGP capable bridge in the system
96 * and report its capabilities (hw.nvidia.agp.bridge).
98 oid = SYSCTL_ADD_NODE(&sysctl_ctx,
99 SYSCTL_CHILDREN(oid_agp),
102 CTLFLAG_RD | CTLFLAG_DYN,
104 "NVIDIA AGP Bridge Node");
106 SYSCTL_ADD_PROC(&sysctl_ctx,
107 SYSCTL_CHILDREN(oid),
110 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_DYN,
112 nvidia_sysctl_agp_rates,
114 "NVIDIA AGP Bridge Rates Info");
116 SYSCTL_ADD_PROC(&sysctl_ctx,
117 SYSCTL_CHILDREN(oid),
120 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_DYN,
122 nvidia_sysctl_agp_fw,
124 "NVIDIA AGP Bridge FW Info");
126 SYSCTL_ADD_PROC(&sysctl_ctx,
127 SYSCTL_CHILDREN(oid),
130 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_DYN,
132 nvidia_sysctl_agp_sba,
134 "NVIDIA AGP Bridge SBA Info");
136 SYSCTL_ADD_PROC(&sysctl_ctx,
137 SYSCTL_CHILDREN(oid),
140 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_DYN,
142 nvidia_sysctl_agp_registers,
144 "NVIDIA AGP Bridge Registers");
148 void nvidia_sysctl_exit(void)
150 sysctl_ctx_free(&sysctl_ctx);
151 if (option_string != NULL)
152 free((void *)option_string, M_NVIDIA);
156 static U032 nvidia_dev_agp_cmd(device_t dev)
161 cap_ptr = nvidia_pci_find_capability(dev, PCIR_CAP_ID_AGP);
162 tmp = pci_read_config(dev, cap_ptr + 8, 4);
167 static U032 nvidia_dev_agp_status(device_t dev)
172 cap_ptr = nvidia_pci_find_capability(dev, PCIR_CAP_ID_AGP);
173 tmp = pci_read_config(dev, cap_ptr + 4, 4);
178 static U032 nvidia_sys_agp_cmd(device_t dev)
182 tmp = nvidia_dev_agp_cmd(dev);
183 tmp &= nvidia_dev_agp_cmd(nvidia_find_bridge());
188 static void* nvidia_find_bridge(void)
197 for (bus = 0; bus < 5; bus++) {
198 for (device = 0; device < 32; device++) {
199 for (func = 0; func < 8; func++) {
201 * We're not interested in non-bridge PCI devices, nor do
202 * care for devices with our own or an invalid vendor ID.
204 dev = pci_find_bsf(bus, device, func);
210 // If a read to function zero of a specified bus/device master aborts,
211 // then it is assumed that no such device exists on the bus since
212 // devices are required to implement function number zero.
213 // In this case reads to the remaining functions are not necessary.
222 if (pci_get_class(dev) != PCIC_BRIDGE)
225 if (pci_get_vendor(dev) == 0xffff)
228 if (nvidia_pci_find_capability(dev, PCIR_CAP_ID_AGP) != 0)
232 * It also doesn't make sense to to iterate over multiple
233 * functions if this isn't a multi-function device.
235 hdrtype = pci_read_config(dev, PCIR_HDRTYPE, 1);
237 if ((hdrtype & PCIM_MFDEV) == 0)
247 int nvidia_sysctl_dev_model(SYSCTL_HANDLER_ARGS)
249 nv_state_t *nv = arg1;
252 char model_name[NV_DEVICE_NAME_LENGTH+1];
253 U016 id = nv->device_id;
255 NV_UMA_ZONE_ALLOC_STACK(sp);
259 if (rm_get_device_name(sp, nv, id, NV_DEVICE_NAME_LENGTH, model_name)
261 strcpy(model_name, "Unknown");
264 NV_UMA_ZONE_FREE_STACK(sp);
266 return SYSCTL_OUT(req, model_name, strlen(model_name) + 1);
269 int nvidia_sysctl_dev_vbios(SYSCTL_HANDLER_ARGS)
271 nv_state_t *nv = arg1;
275 U008 vbios_version[16];
277 NV_UMA_ZONE_ALLOC_STACK(sp);
281 if (rm_get_vbios_version(sp, nv, &vbios[0], &vbios[1], &vbios[2],
282 &vbios[3], &vbios[4]) != RM_OK) {
284 * The VBIOS version is only accessible after the device has been
285 * initialized with rm_init_adapter.
287 sprintf(vbios_version, "??.??.??.??.??");
289 sprintf(vbios_version, "%02x.%02x.%02x.%02x.%02x", vbios[0],
290 vbios[1], vbios[2], vbios[3], vbios[4]);
293 NV_UMA_ZONE_FREE_STACK(sp);
295 return SYSCTL_OUT(req, vbios_version, strlen(vbios_version) + 1);
298 int nvidia_sysctl_bus_type(SYSCTL_HANDLER_ARGS)
300 struct nvidia_softc *sc = arg1;
303 if (nvidia_pci_find_capability(sc->dev, PCIR_CAP_ID_AGP) != 0)
304 sprintf(bus_type, "AGP");
306 if (nvidia_pci_find_capability(sc->dev, PCIR_CAP_ID_EXP) != 0)
307 sprintf(bus_type, "PCI-E");
309 sprintf(bus_type, "PCI");
311 return SYSCTL_OUT(req, bus_type, strlen(bus_type) + 1);
314 int nvidia_sysctl_registry_key(SYSCTL_HANDLER_ARGS)
318 error = sysctl_handle_int(oidp, arg1, 0, req);
320 if (error || !req->newptr)
323 /* refresh the registry with the updated option table */
329 int nvidia_sysctl_registry_dwords(SYSCTL_HANDLER_ARGS)
332 char *new_option_string;
334 len = strlen(option_string) + 1;
335 error = SYSCTL_OUT(req, option_string, len);
337 if (error || !req->newptr)
340 len = (req->newlen - req->newidx);
342 new_option_string = malloc((len + 1), M_NVIDIA, M_WAITOK);
343 if (!new_option_string)
346 error = SYSCTL_IN(req, new_option_string, len);
350 free(option_string, M_NVIDIA);
352 option_string = new_option_string;
353 option_string[len] = '\0';
355 nvidia_update_registry(new_option_string);
360 int nvidia_sysctl_agp_rates(SYSCTL_HANDLER_ARGS)
365 U032 tmp = nvidia_dev_agp_status(dev);
367 if ((tmp & 0x08) != 0)
368 tmp = (tmp & 0x07) << 2;
370 sprintf(agp_rates, "%s%s%s%s",
371 (tmp & 0x0008) ? "8x " : "",
372 (tmp & 0x0004) ? "4x " : "",
373 (tmp & 0x0002) ? "2x " : "",
374 (tmp & 0x0001) ? "1x " : "");
376 return SYSCTL_OUT(req, agp_rates, strlen(agp_rates) + 1);
379 int nvidia_sysctl_agp_fw(SYSCTL_HANDLER_ARGS)
384 sprintf(agp_fw, "%ssupported",
385 ((nvidia_dev_agp_status(dev) & 0x10) == 0x10) ? "" : "not ");
387 return SYSCTL_OUT(req, agp_fw, strlen(agp_fw) + 1);
390 int nvidia_sysctl_agp_sba(SYSCTL_HANDLER_ARGS)
395 sprintf(agp_sba, "%ssupported",
396 ((nvidia_dev_agp_status(dev) & 0x200) == 0x200) ? "" : "not ");
398 return SYSCTL_OUT(req, agp_sba, strlen(agp_sba) + 1);
401 int nvidia_sysctl_agp_registers(SYSCTL_HANDLER_ARGS)
404 U008 agp_registers[24];
406 sprintf(agp_registers, "0x%08x:0x%08x",
407 nvidia_dev_agp_status(dev), nvidia_dev_agp_cmd(dev));
409 return SYSCTL_OUT(req, agp_registers, strlen(agp_registers) + 1);
412 int nvidia_sysctl_agp_driver(SYSCTL_HANDLER_ARGS)
414 nv_state_t *nv = arg1;
417 switch (nv->agp_config) {
418 case NVOS_AGP_CONFIG_DISABLE_AGP:
419 sprintf(agp_driver, "n/a (unused)");
421 case NVOS_AGP_CONFIG_OSAGP:
422 sprintf(agp_driver, "freebsd (agp.ko)");
424 case NVOS_AGP_CONFIG_NVAGP:
425 sprintf(agp_driver, "nvidia");
429 return SYSCTL_OUT(req, agp_driver, strlen(agp_driver) + 1);
432 int nvidia_sysctl_agp_rate_status(SYSCTL_HANDLER_ARGS)
437 U032 tmp = nvidia_sys_agp_cmd(dev);
439 if ((tmp & 0x100) && (tmp &= 0x07)) {
440 sprintf(agp_rate, "%1dx",
441 (nvidia_dev_agp_status(dev) & 0x08) ? (tmp << 2) : tmp);
443 sprintf(agp_rate, "n/a (disabled)");
446 return SYSCTL_OUT(req, agp_rate, strlen(agp_rate) + 1);
449 int nvidia_sysctl_agp_fw_status(SYSCTL_HANDLER_ARGS)
454 U032 tmp = nvidia_sys_agp_cmd(dev);
456 if ((tmp & 0x100) == 0x100) {
457 sprintf(agp_fw, "%s",
458 ((tmp & 0x10) == 0x10) ? "enabled" : "disabled");
460 sprintf(agp_fw, "n/a (disabled)");
463 return SYSCTL_OUT(req, agp_fw, strlen(agp_fw) + 1);
466 int nvidia_sysctl_agp_sba_status(SYSCTL_HANDLER_ARGS)
471 U032 tmp = nvidia_sys_agp_cmd(dev);
473 if ((tmp & 0x100) == 0x100) {
474 sprintf(agp_sba, "%s",
475 ((tmp & 0x200) == 0x200) ? "enabled" : "disabled");
477 sprintf(agp_sba, "n/a (disabled)");
480 return SYSCTL_OUT(req, agp_sba, strlen(agp_sba) + 1);
483 int nvidia_sysctl_agp_status(SYSCTL_HANDLER_ARGS)
488 sprintf(agp_cmd, "%s",
489 (nvidia_sys_agp_cmd(dev) & 0x100) ? "enabled" : "disabled");
491 return SYSCTL_OUT(req, agp_cmd, strlen(agp_cmd) + 1);
494 void nv_sysctl_init(nv_state_t *nv)
496 struct sysctl_oid *oid;
497 struct nvidia_softc *sc = nv->os_state;
500 sprintf(name, "%d", device_get_unit(sc->dev));
502 sysctl_ctx_init(&sc->sysctl_ctx);
504 oid = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
505 SYSCTL_CHILDREN(oid_nvidia),
508 CTLFLAG_RD | CTLFLAG_DYN,
510 "NVIDIA SYSCTL Cards Node");
512 oid = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
513 SYSCTL_CHILDREN(oid),
516 CTLFLAG_RD | CTLFLAG_DYN,
518 "NVIDIA SYSCTL Device Node");
520 SYSCTL_ADD_PROC(&sc->sysctl_ctx,
521 SYSCTL_CHILDREN(oid),
524 CTLFLAG_RD | CTLFLAG_DYN,
526 nvidia_sysctl_dev_model,
528 "NVIDIA Device Model Name");
530 SYSCTL_ADD_UINT(&sc->sysctl_ctx,
531 SYSCTL_CHILDREN(oid),
534 CTLFLAG_RD | CTLFLAG_DYN,
537 "NVIDIA Device IRQ Number");
539 SYSCTL_ADD_PROC(&sc->sysctl_ctx,
540 SYSCTL_CHILDREN(oid),
543 CTLFLAG_RD | CTLFLAG_DYN,
545 nvidia_sysctl_dev_vbios,
547 "NVIDIA Device VBIOS Version");
549 SYSCTL_ADD_PROC(&sc->sysctl_ctx,
550 SYSCTL_CHILDREN(oid),
553 CTLFLAG_RD | CTLFLAG_DYN,
555 nvidia_sysctl_bus_type,
557 "NVIDIA Device Bus Type");
560 if (nvidia_pci_find_capability(sc->dev, PCIR_CAP_ID_AGP) != 0) {
562 * Assume this is the only AGP VGA device in the system
563 * and report its capabilities (hw.nvidia.agp.card).
565 oid = SYSCTL_ADD_NODE(&sysctl_ctx,
566 SYSCTL_CHILDREN(oid_agp),
569 CTLFLAG_RD | CTLFLAG_DYN,
571 "NVIDIA AGP Device Node");
573 SYSCTL_ADD_PROC(&sysctl_ctx,
574 SYSCTL_CHILDREN(oid),
577 CTLFLAG_RD | CTLFLAG_DYN,
579 nvidia_sysctl_agp_rates,
581 "NVIDIA AGP Device Rates Info");
583 SYSCTL_ADD_PROC(&sysctl_ctx,
584 SYSCTL_CHILDREN(oid),
587 CTLFLAG_RD | CTLFLAG_DYN,
589 nvidia_sysctl_agp_fw,
591 "NVIDIA AGP Device FW Info");
593 SYSCTL_ADD_PROC(&sysctl_ctx,
594 SYSCTL_CHILDREN(oid),
597 CTLFLAG_RD | CTLFLAG_DYN,
599 nvidia_sysctl_agp_sba,
601 "NVIDIA AGP Device SBA Info");
603 SYSCTL_ADD_PROC(&sysctl_ctx,
604 SYSCTL_CHILDREN(oid),
607 CTLFLAG_RD | CTLFLAG_DYN,
609 nvidia_sysctl_agp_registers,
611 "NVIDIA AGP Device Registers");
614 if (nvidia_find_bridge() != NULL) {
616 * If we can find a bridge and what assume to be the
617 * only AGP VGA device, report the AGP status.
619 oid = SYSCTL_ADD_NODE(&sysctl_ctx,
620 SYSCTL_CHILDREN(oid_agp),
623 CTLFLAG_RD | CTLFLAG_DYN,
625 "NVIDIA AGP Status Node");
627 SYSCTL_ADD_PROC(&sysctl_ctx,
628 SYSCTL_CHILDREN(oid),
631 CTLFLAG_RD | CTLFLAG_DYN,
633 nvidia_sysctl_agp_status,
635 "NVIDIA AGP Status Information");
637 SYSCTL_ADD_PROC(&sysctl_ctx,
638 SYSCTL_CHILDREN(oid),
641 CTLFLAG_RD | CTLFLAG_DYN,
643 nvidia_sysctl_agp_driver,
645 "NVIDIA AGP Driver Information");
647 SYSCTL_ADD_PROC(&sysctl_ctx,
648 SYSCTL_CHILDREN(oid),
651 CTLFLAG_RD | CTLFLAG_DYN,
653 nvidia_sysctl_agp_rate_status,
655 "NVIDIA AGP Rate Status Information");
657 SYSCTL_ADD_PROC(&sysctl_ctx,
658 SYSCTL_CHILDREN(oid),
661 CTLFLAG_RD | CTLFLAG_DYN,
663 nvidia_sysctl_agp_fw_status,
665 "NVIDIA AGP FW Status Information");
667 SYSCTL_ADD_PROC(&sysctl_ctx,
668 SYSCTL_CHILDREN(oid),
671 CTLFLAG_RD | CTLFLAG_DYN,
673 nvidia_sysctl_agp_sba_status,
675 "NVIDIA AGP SBA Status Information");
680 void nv_sysctl_exit(nv_state_t *nv)
682 struct nvidia_softc *sc = nv->os_state;
683 sysctl_ctx_free(&sc->sysctl_ctx);