import NVIDIA-FreeBSD-x86-180.29
[nvidia.git] / src / nv-freebsd.h
1 /* _NVRM_COPYRIGHT_BEGIN_
2  *
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.
7  *
8  * _NVRM_COPYRIGHT_END_
9  */
10
11 #ifndef __NV_FREEBSD_H__
12 #define __NV_FREEBSD_H__
13
14 #ifdef TRUE
15 #undef TRUE
16 #endif
17
18 #ifdef FALSE
19 #undef FALSE
20 #endif
21
22 #include <sys/param.h>
23
24 #if __FreeBSD_version >= 800000
25 #error This driver does not support FreeBSD 8.x/-CURRENT!
26 #endif
27 #if __FreeBSD_version >= 700000 && __FreeBSD_version < 700055
28 #error This driver does not support FreeBSD 7.x/-CURRENT!
29 #endif
30 #if __FreeBSD_version >= 600000 && __FreeBSD_version < 600034
31 #error This driver does not support FreeBSD 6.x/-CURRENT!
32 #endif
33 #if __FreeBSD_version < 503000
34 #error This driver requires FreeBSD 5.3 or later!
35 #endif
36
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>
42
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>
51
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>
58
59 #include <sys/conf.h>
60 #include <sys/rman.h>
61 #include <sys/proc.h>
62 #include <sys/lock.h>
63 #include <sys/mman.h>
64 #include <sys/file.h>
65 #include <sys/poll.h>
66
67 #include <sys/syscall.h>
68 #include <sys/bus.h>
69 #include <sys/memrange.h>
70 #include <sys/sysproto.h>
71 #include <sys/signalvar.h>
72
73 #include <vm/vm.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>
79 #include <vm/pmap.h>
80 #include <vm/vm_map.h>
81 #include <vm/uma.h>
82
83 #include <pci/agpvar.h>
84 #include <sys/agpio.h>
85
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)
89 #else
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)
92 #endif
93
94 #include <sys/smp.h>
95 #include <dev/pci/pcireg.h>
96 #include <dev/pci/pcivar.h>
97 #include <sys/kdb.h>
98 #include <sys/filedesc.h>
99
100 #if __FreeBSD_version >= 700055
101 #include <sys/priv.h>
102 #endif
103
104 #include <sys/lock.h>
105 #include <sys/mutex.h>
106 #include <sys/sx.h>
107 #include <sys/condvar.h>
108
109 #if defined(NVCPU_X86) && defined(PAE)
110 #error This driver does not support PAE enabled kernels!
111 #endif
112
113 #define CURTHREAD curthread
114
115 /*
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.
121  */
122
123 #define __TD_FDT(_td) (void *)((_td)->td_proc->p_fd)
124
125 #if __FreeBSD_version >= 601100
126 #define __NV_ITHREAD() (curthread->td_pflags & TDP_ITHREAD)
127 #else
128 #define __NV_ITHREAD() (curthread->td_ithd != NULL)
129 #endif
130
131 /*
132  * The NVIDIA kernel module's malloc identifier, needed for both tracking
133  * and actual allocation/freeing purposes - declared here, but defined in
134  * nvidia_os.c.
135  */
136
137 MALLOC_DECLARE(M_NVIDIA);
138
139 RM_STATUS os_alloc_contig_pages(void **, U032);
140 void os_free_contig_pages(void *, U032);
141
142 /*
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.
146  */
147
148 #undef NV_SUPPORT_OS_AGP
149
150 /*
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.
155  */
156
157 #define NV_SUPPORT_LINUX_COMPAT
158
159 /*
160  * Enable/Disable support for ACPI Power Management. This is untested and
161  * thus disabled by default (this is 5.x/-CURRENT only).
162  */
163
164 #undef NV_SUPPORT_ACPI_PM
165
166
167 /*
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.
173  */
174
175 typedef
176 struct nvidia_alloc {
177     SLIST_ENTRY(nvidia_alloc) list;
178     uint32_t cache_type;
179     u_int32_t size;
180     vm_offset_t address;
181     int alloc_type_contiguous;
182     NvU64 *pte_array;
183 } nvidia_alloc_t;
184
185 typedef
186 struct nvidia_event {
187     STAILQ_ENTRY(nvidia_event) queue;
188     nv_event_t event;
189 } nvidia_event_t;
190
191 typedef
192 struct nvidia_filep {
193     STAILQ_ENTRY(nvidia_filep) queue;
194     void *fd_table;
195     u_int32_t fd_refcnt;
196 } nvidia_filep_t;
197
198 typedef
199 struct nvidia_softc {
200     device_t dev;
201     device_t agp_dev;
202
203     struct resource *BAR_recs[NV_GPU_NUM_BARS];
204     int BAR_rids[NV_GPU_NUM_BARS];
205
206     struct resource *irq;
207     void *irq_ih;
208     int   irq_rid;
209
210     nv_stack_t *attach_sp;
211     nv_stack_t *api_sp;
212     nv_stack_t *pci_cfgchk_sp;
213     nv_stack_t *isr_sp;
214     nv_stack_t *timer_sp;
215
216     struct resource *iop;
217     int iop_rid;
218
219     bus_space_handle_t bs_handle;
220     bus_space_tag_t bs_tag;
221
222     struct cdev *cdev;
223     nv_state_t *nv_state;
224
225     /* queue of OS events */
226     STAILQ_HEAD(event_queue, nvidia_event) event_queue;
227
228     /* queue of fd table references */
229     STAILQ_HEAD(filep_queue, nvidia_filep) filep_queue;
230
231     struct sysctl_ctx_list sysctl_ctx;
232     struct selinfo rsel;
233
234     struct callout_handle timer_ch;
235
236     /* list of allocations */
237     SLIST_HEAD(alloc_list, nvidia_alloc) alloc_list;
238
239     uint32_t refcnt;
240
241     struct mtx rm_mtx;
242     struct sx api_sx;
243
244 } nvidia_softc_t;
245
246 #define CDEV_CTL_MINOR  255
247
248 extern devclass_t nvidia_devclass;
249
250 extern struct nvidia_softc nvidia_ctl_sc;
251 extern nv_state_t nvidia_ctl_state;
252
253 extern const char *pNVRM_ID;
254
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
259
260 #if !defined(PCIS_DISPLAY_3D)
261 #define PCIS_DISPLAY_3D    0x002
262 #endif
263 #if !defined(PCIM_CMD_INTXDIS)
264 #define PCIM_CMD_INTXDIS   0x400
265 #endif
266
267 #if !defined(PAT_UNCACHEABLE)
268 #define PAT_UNCACHEABLE         0x00
269 #endif
270 #if !defined(PAT_WRITE_COMBINING)
271 #define PAT_WRITE_COMBINING     0x01
272 #endif
273 #if !defined(PAT_WRITE_BACK)
274 #define PAT_WRITE_BACK          0x06
275 #endif
276
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)
279 {
280     vm_offset_t tmp;
281     pt_entry_t *ptep;
282
283     if (mode == PAT_UNCACHEABLE) {
284         for (tmp = va; tmp < (va + size); tmp += PAGE_SIZE) {
285             ptep = vtopte(tmp);
286             pte_store(ptep, pte_load(ptep) | PG_N);
287         }
288         pmap_invalidate_range(kernel_pmap, va, tmp);
289     }
290
291     return 0;
292 }
293
294 static inline void *pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
295 {
296     vm_offset_t tmp, va;
297     uint32_t cache_bits;
298
299     va = kmem_alloc_nofault(kernel_map, size);
300     if (va != 0) {
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);
305             pa += PAGE_SIZE;
306         }
307         pmap_invalidate_range(kernel_pmap, va, tmp);
308     }
309
310     return (void *)va;
311 }
312 #endif
313
314 static inline void pmap_unmapdev_attr(vm_offset_t va, vm_size_t size)
315 {
316 #if __FreeBSD_version < 602110 || __FreeBSD_version >= 700000 && __FreeBSD_version < 700055
317     vm_offset_t tmp;
318
319     if (va != 0) {
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);
325     }
326 #else
327     pmap_unmapdev(va, size);
328 #endif
329 }
330
331 /*
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.
336  */
337
338 extern nv_parm_t nv_parms[];
339
340 /*
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.
346  */
347
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)
351
352 extern uma_zone_t nvidia_stack_t_zone;
353
354 #define NV_UMA_ZONE_ALLOC_STACK(ptr)                             \
355     {                                                            \
356         (ptr) = uma_zalloc(nvidia_stack_t_zone, M_WAITOK);       \
357         if ((ptr) != NULL)                                       \
358         {                                                        \
359             (ptr)->size = sizeof((ptr)->stack);                  \
360             (ptr)->top = (ptr)->stack + (ptr)->size;             \
361         }                                                        \
362     }
363
364 #define NV_UMA_ZONE_FREE_STACK(ptr)                              \
365     {                                                            \
366         uma_zfree(nvidia_stack_t_zone, (ptr));                   \
367         (ptr) = NULL;                                            \
368     }
369
370 /* nvidia_dev.c */
371 int    nvidia_dev_attach     (struct nvidia_softc *);
372 int    nvidia_dev_detach     (struct nvidia_softc *);
373
374 /* nvidia_ctl.c */
375 int    nvidia_ctl_attach     (void);
376 int    nvidia_ctl_detach     (void);
377
378 /* nvidia_pci.c */
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);
383
384 #define NV_PCI_CHECK_CONFIG_SPACE(_sp,_nv,_cb,_as,_mb)                   \
385     {                                                                    \
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);    \
390         }                                                                \
391     }
392
393 /* nvidia_subr.c */
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 *);
402
403 void   nvidia_rc_timer       (void *);
404
405 void   nv_lock_api           (nv_state_t *);
406 void   nv_unlock_api         (nv_state_t *);
407
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 *);
412
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 *);
417
418 /* nvidia_sysctl.c */
419 void   nvidia_sysctl_init    (void);
420 void   nvidia_sysctl_exit    (void);
421
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);
425
426 int    nvidia_sysctl_registry_key     (SYSCTL_HANDLER_ARGS);
427 int    nvidia_sysctl_registry_dwords  (SYSCTL_HANDLER_ARGS);
428
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);
434
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);
439
440 void   nv_sysctl_init        (nv_state_t *);
441 void   nv_sysctl_exit        (nv_state_t *);
442
443 /* nvidia_linux.c */
444 void   nvidia_linux_init     (void);
445 void   nvidia_linux_exit     (void);
446
447 /* nvidia_os_registry.c */
448
449 void   nvidia_update_registry (char *);
450
451 /* ioctl helpers */
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 *);
454
455 /* device helpers */
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 *);
461
462 #endif /* __NV_FREEBSD_H__ */