1 /* _NVRM_COPYRIGHT_BEGIN_
3 * Copyright 2001 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.
11 #ifndef __NV_FREEBSD_H__
12 #define __NV_FREEBSD_H__
22 #include <sys/param.h>
24 #if __FreeBSD_version >= 800000
25 #error This driver does not support FreeBSD 8.x/-CURRENT!
27 #if __FreeBSD_version >= 700000 && __FreeBSD_version < 700055
28 #error This driver does not support FreeBSD 7.x/-CURRENT!
30 #if __FreeBSD_version >= 600000 && __FreeBSD_version < 600034
31 #error This driver does not support FreeBSD 6.x/-CURRENT!
33 #if __FreeBSD_version < 503000
34 #error This driver requires FreeBSD 5.3 or later!
37 #include <sys/systm.h>
38 #include <sys/types.h>
39 #include <sys/queue.h>
40 #include <sys/pciio.h>
41 #include <sys/vnode.h>
43 #include <sys/kernel.h>
44 #include <sys/module.h>
45 #include <sys/ioccom.h>
46 #include <sys/malloc.h>
47 #include <sys/socket.h>
48 #include <sys/sysent.h>
49 #include <sys/ctype.h>
50 #include <sys/sysctl.h>
52 #include <machine/cpu.h>
53 #include <machine/resource.h>
54 #include <machine/clock.h>
55 #include <machine/stdarg.h>
56 #include <machine/bus.h>
57 #include <machine/specialreg.h>
67 #include <sys/syscall.h>
69 #include <sys/memrange.h>
70 #include <sys/sysproto.h>
71 #include <sys/signalvar.h>
74 #include <vm/vm_param.h>
75 #include <vm/vm_kern.h>
76 #include <vm/vm_page.h>
77 #include <vm/vm_extern.h>
78 #include <vm/vm_object.h>
80 #include <vm/vm_map.h>
83 #include <pci/agpvar.h>
84 #include <sys/agpio.h>
86 #if defined(NVCPU_X86_64)
87 #define NV_MMAP_TO_VM_OFFSET(_off) ((_off) | 0xfffff00000000000)
88 #define NV_VM_TO_MMAP_OFFSET(_off) ((_off) & 0x00000fffffffffff)
90 #define NV_MMAP_TO_VM_OFFSET(_off) ((_off) + VM_MIN_KERNEL_ADDRESS)
91 #define NV_VM_TO_MMAP_OFFSET(_off) ((_off) - VM_MIN_KERNEL_ADDRESS)
95 #include <dev/pci/pcireg.h>
96 #include <dev/pci/pcivar.h>
98 #include <sys/filedesc.h>
100 #if __FreeBSD_version >= 700055
101 #include <sys/priv.h>
104 #include <sys/lock.h>
105 #include <sys/mutex.h>
107 #include <sys/condvar.h>
109 #if defined(NVCPU_X86) && defined(PAE)
110 #error This driver does not support PAE enabled kernels!
113 #define CURTHREAD curthread
116 * The resource manager client tracking needs an identifier that uniquely
117 * represents a client connection across threads. It needs to be specific
118 * to the thread that allocated the client. The Linux struct file pointer
119 * is such an identifier. The per-process file descriptor table is enough
120 * on FreeBSD, due to its thread-aware reference counting.
123 #define __TD_FDT(_td) (void *)((_td)->td_proc->p_fd)
125 #if __FreeBSD_version >= 601100
126 #define __NV_ITHREAD() (curthread->td_pflags & TDP_ITHREAD)
128 #define __NV_ITHREAD() (curthread->td_ithd != NULL)
132 * The NVIDIA kernel module's malloc identifier, needed for both tracking
133 * and actual allocation/freeing purposes - declared here, but defined in
137 MALLOC_DECLARE(M_NVIDIA);
139 RM_STATUS os_alloc_contig_pages(void **, U032);
140 void os_free_contig_pages(void *, U032);
143 * Enable/Disable support for FreeBSD's AGP GART driver. Please note that
144 * agp.ko may need to be preloaded from loader.conf; this define does not
145 * influence support for NVIDIA's builtin AGP GART driver.
148 #undef NV_SUPPORT_OS_AGP
151 * This option decides if the driver will be built with support for Linux
152 * or Linux 32-bit (FreeBSD/amd64) compatibility. This makes nvidia.ko
153 * dependent on linux.ko; if you don't need Linux compatibility, then you
154 * can safely unset this flag.
157 #define NV_SUPPORT_LINUX_COMPAT
160 * Enable/Disable support for ACPI Power Management. This is untested and
161 * thus disabled by default (this is 5.x/-CURRENT only).
164 #undef NV_SUPPORT_ACPI_PM
168 * The DMA memory allocation tracking structure. DMA memory alloctions on
169 * FreeBSD are tracked with their base address and size. Since PCI memory
170 * is allocated from kernel virtual memory and since AGP allocations have
171 * a contiguous range of addresses in the AGP aperture, base and size are
172 * sufficient to track allocations.
176 struct nvidia_alloc {
177 SLIST_ENTRY(nvidia_alloc) list;
181 int alloc_type_contiguous;
186 struct nvidia_event {
187 STAILQ_ENTRY(nvidia_event) queue;
192 struct nvidia_filep {
193 STAILQ_ENTRY(nvidia_filep) queue;
199 struct nvidia_softc {
203 struct resource *BAR_recs[NV_GPU_NUM_BARS];
204 int BAR_rids[NV_GPU_NUM_BARS];
206 struct resource *irq;
210 nv_stack_t *attach_sp;
212 nv_stack_t *pci_cfgchk_sp;
214 nv_stack_t *timer_sp;
216 struct resource *iop;
219 bus_space_handle_t bs_handle;
220 bus_space_tag_t bs_tag;
223 nv_state_t *nv_state;
225 /* queue of OS events */
226 STAILQ_HEAD(event_queue, nvidia_event) event_queue;
228 /* queue of fd table references */
229 STAILQ_HEAD(filep_queue, nvidia_filep) filep_queue;
231 struct sysctl_ctx_list sysctl_ctx;
234 struct callout_handle timer_ch;
236 /* list of allocations */
237 SLIST_HEAD(alloc_list, nvidia_alloc) alloc_list;
246 #define CDEV_CTL_MINOR 255
248 extern devclass_t nvidia_devclass;
250 extern struct nvidia_softc nvidia_ctl_sc;
251 extern nv_state_t nvidia_ctl_state;
253 extern const char *pNVRM_ID;
255 #define PCIR_CAP_LIST_ID 0x00
256 #define PCIR_CAP_LIST_NEXT 0x01
257 #define PCIR_CAP_ID_AGP 0x02
258 #define PCIR_CAP_ID_EXP 0x10
260 #if !defined(PCIS_DISPLAY_3D)
261 #define PCIS_DISPLAY_3D 0x002
263 #if !defined(PCIM_CMD_INTXDIS)
264 #define PCIM_CMD_INTXDIS 0x400
267 #if !defined(PAT_UNCACHEABLE)
268 #define PAT_UNCACHEABLE 0x00
270 #if !defined(PAT_WRITE_COMBINING)
271 #define PAT_WRITE_COMBINING 0x01
273 #if !defined(PAT_WRITE_BACK)
274 #define PAT_WRITE_BACK 0x06
277 #if __FreeBSD_version < 602110 || __FreeBSD_version >= 700000 && __FreeBSD_version < 700055
278 static inline int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
283 if (mode == PAT_UNCACHEABLE) {
284 for (tmp = va; tmp < (va + size); tmp += PAGE_SIZE) {
286 pte_store(ptep, pte_load(ptep) | PG_N);
288 pmap_invalidate_range(kernel_pmap, va, tmp);
294 static inline void *pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
299 va = kmem_alloc_nofault(kernel_map, size);
301 cache_bits = (mode != PAT_WRITE_BACK) ? PG_N : 0;
302 for (tmp = va; tmp < (va + size); tmp += PAGE_SIZE) {
303 pt_entry_t *ptep = vtopte(tmp);
304 pte_store(ptep, pa | PG_RW | PG_V | PG_G | cache_bits);
307 pmap_invalidate_range(kernel_pmap, va, tmp);
314 static inline void pmap_unmapdev_attr(vm_offset_t va, vm_size_t size)
316 #if __FreeBSD_version < 602110 || __FreeBSD_version >= 700000 && __FreeBSD_version < 700055
320 size = NV_ALIGN_UP(size, PAGE_SIZE);
321 for (tmp = va; tmp < (va + size); tmp += PAGE_SIZE)
322 pte_clear(vtopte(tmp));
323 pmap_invalidate_range(kernel_pmap, va, tmp);
324 kmem_free(kernel_map, va, size);
327 pmap_unmapdev(va, size);
332 * Entries in the NVIDIA glue-layer registry are now described by the new
333 * shared nv_parm_t structure; please review nvidia_os_registry.c in case
334 * you need to make low-level configuration changes. The entries are also
335 * mapped into the SYSCTL hierarchy and thus easily accessible.
338 extern nv_parm_t nv_parms[];
341 * These macros extract the encoded ioctl type and number from the
342 * command; we inspect the type to verify that device/control ioctls
343 * originate from NVIDIA RM clients and use the number to allow the
344 * core resource manager's ioctl handler to be ignorant of operating
345 * specific ioctl encodings.
348 #define __NV_IOC_TYPE(_cmd) (((_cmd) >> 8) & 0xff)
349 #define __NV_IOC_NR(_cmd) (((_cmd) >> 0) & 0xff)
350 #define __NV_IOC_SIZE(_cmd) (((_cmd) >> 16) & 0x1fff)
352 extern uma_zone_t nvidia_stack_t_zone;
354 #define NV_UMA_ZONE_ALLOC_STACK(ptr) \
356 (ptr) = uma_zalloc(nvidia_stack_t_zone, M_WAITOK); \
359 (ptr)->size = sizeof((ptr)->stack); \
360 (ptr)->top = (ptr)->stack + (ptr)->size; \
364 #define NV_UMA_ZONE_FREE_STACK(ptr) \
366 uma_zfree(nvidia_stack_t_zone, (ptr)); \
371 int nvidia_dev_attach (struct nvidia_softc *);
372 int nvidia_dev_detach (struct nvidia_softc *);
375 int nvidia_ctl_attach (void);
376 int nvidia_ctl_detach (void);
379 void nvidia_pci_check_config_space (nv_stack_t *, device_t dev, BOOL, BOOL, BOOL);
380 int nvidia_pci_setup_intr (device_t dev);
381 int nvidia_pci_teardown_intr (device_t dev);
382 U008 nvidia_pci_find_capability (device_t dev, U008);
384 #define NV_PCI_CHECK_CONFIG_SPACE(_sp,_nv,_cb,_as,_mb) \
386 struct nvidia_softc *__sc; \
387 if (((_nv)->flags & NV_FLAG_CONTROL) == 0) { \
388 __sc = (_nv)->os_state; \
389 nvidia_pci_check_config_space(_sp,__sc->dev,_cb,_as,_mb); \
394 int nvidia_attach (device_t);
395 int nvidia_detach (device_t);
396 int nvidia_suspend (device_t);
397 int nvidia_resume (device_t);
398 int nvidia_alloc_hardware (device_t);
399 void nvidia_free_hardware (device_t);
400 void nvidia_intr (void *);
401 int nvidia_modevent (module_t, int, void *);
403 void nvidia_rc_timer (void *);
405 void nv_lock_api (nv_state_t *);
406 void nv_unlock_api (nv_state_t *);
408 S032 nv_alloc_contig_pages (nv_state_t *, U032, U032, NvU64 *, void **);
409 S032 nv_free_contig_pages (nv_state_t *, void *);
410 S032 nv_alloc_system_pages (nv_state_t *, U032, U032, NvU64 *, void **);
411 S032 nv_free_system_pages (nv_state_t *, void *);
413 S032 nv_os_agp_init (nv_stack_t *sp, nv_state_t *, void **, U032 *);
414 S032 nv_os_agp_teardown (nv_stack_t *sp, nv_state_t *);
415 S032 nv_alloc_agp_pages (nv_state_t *, U032, U032, void **);
416 S032 nv_free_agp_pages (nv_state_t *, U032, void *, U032 *);
418 /* nvidia_sysctl.c */
419 void nvidia_sysctl_init (void);
420 void nvidia_sysctl_exit (void);
422 int nvidia_sysctl_dev_model (SYSCTL_HANDLER_ARGS);
423 int nvidia_sysctl_dev_vbios (SYSCTL_HANDLER_ARGS);
424 int nvidia_sysctl_bus_type (SYSCTL_HANDLER_ARGS);
426 int nvidia_sysctl_registry_key (SYSCTL_HANDLER_ARGS);
427 int nvidia_sysctl_registry_dwords (SYSCTL_HANDLER_ARGS);
429 int nvidia_sysctl_agp_rates (SYSCTL_HANDLER_ARGS);
430 int nvidia_sysctl_agp_fw (SYSCTL_HANDLER_ARGS);
431 int nvidia_sysctl_agp_sba (SYSCTL_HANDLER_ARGS);
432 int nvidia_sysctl_agp_registers (SYSCTL_HANDLER_ARGS);
433 int nvidia_sysctl_agp_driver (SYSCTL_HANDLER_ARGS);
435 int nvidia_sysctl_agp_status (SYSCTL_HANDLER_ARGS);
436 int nvidia_sysctl_agp_rate_status (SYSCTL_HANDLER_ARGS);
437 int nvidia_sysctl_agp_fw_status (SYSCTL_HANDLER_ARGS);
438 int nvidia_sysctl_agp_sba_status (SYSCTL_HANDLER_ARGS);
440 void nv_sysctl_init (nv_state_t *);
441 void nv_sysctl_exit (nv_state_t *);
444 void nvidia_linux_init (void);
445 void nvidia_linux_exit (void);
447 /* nvidia_os_registry.c */
449 void nvidia_update_registry (char *);
452 int nvidia_get_card_info (struct nv_ioctl_card_info *);
453 int nvidia_handle_ioctl (struct cdev *, u_long, caddr_t, int, d_thread_t *);
456 int nvidia_open_ctl (struct cdev *, d_thread_t *);
457 int nvidia_open_dev (struct nvidia_softc *, struct cdev *, d_thread_t *);
458 int nvidia_close_ctl (struct cdev *, d_thread_t *);
459 int nvidia_close_dev (struct nvidia_softc *, struct cdev *, d_thread_t *);
460 int nvidia_mmap_dev (struct nvidia_softc *, vm_offset_t, vm_offset_t *);
462 #endif /* __NV_FREEBSD_H__ */