import NVIDIA-FreeBSD-x86-180.29
[nvidia.git] / src / nvidia_subr.c
1 /* _NVRM_COPYRIGHT_BEGIN_
2  *
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.
7  *
8  * _NVRM_COPYRIGHT_END_
9  */
10
11 #include "nv-misc.h"
12 #include "os-interface.h"
13 #include "nv.h"
14 #include "nv-freebsd.h"
15
16 #if defined(NVCPU_X86) && defined(NV_USE_OS_VM86_INT10CALL)
17 #include <machine/vm86.h>
18 #endif
19
20 uma_zone_t nvidia_stack_t_zone;
21 static nv_stack_t *__nvidia_init_sp = NULL;
22
23 devclass_t nvidia_devclass;
24 nv_state_t nvidia_ctl_state;
25
26 int nvidia_attach(device_t dev)
27 {
28     int status;
29     U032 i;
30     struct nvidia_softc *sc;
31     nv_state_t *nv;
32
33     sc = device_get_softc(dev);
34     nv = sc->nv_state;
35
36     nv->os_state         = sc;
37     nv->flags            = 0;
38     nv->bus              = pci_get_bus(dev);
39     nv->slot             = pci_get_slot(dev);
40     nv->vendor_id        = pci_get_vendor(dev);
41     nv->device_id        = pci_get_device(dev);
42     nv->interrupt_line   = pci_get_irq(dev);
43     nv->handle           = dev;
44
45     for (i = 0; i < NV_GPU_NUM_BARS; i++) {
46         if (sc->BAR_recs[i] != NULL) {
47             nv->bars[i].address = rman_get_start(sc->BAR_recs[i]);
48             nv->bars[i].size = rman_get_size(sc->BAR_recs[i]);
49         }
50     }
51
52     nv->fb   = &nv->bars[NV_GPU_BAR_INDEX_FB];
53     nv->regs = &nv->bars[NV_GPU_BAR_INDEX_REGS];
54
55     pci_enable_io(dev, SYS_RES_MEMORY);
56
57     if ((status = rm_is_supported_device(sc->attach_sp, nv)) != RM_OK) {
58         nv_printf(NV_DBG_ERRORS,
59             "NVRM: The NVIDIA GPU %02x:%02x (PCI ID: %04x:%04x) installed\n"
60             "NVRM: in this system is not supported by the %s NVIDIA FreeBSD\n"
61             "NVRM: graphics driver release.  Please see 'Appendix A -\n"
62             "NVRM: Supported NVIDIA GPU Products' in this release's README,\n"
63             "NVRM: available on the FreeBSD graphics driver download page at\n"
64             "NVRM: www.nvidia.com.\n",
65             nv->bus, nv->slot, nv->vendor_id, nv->device_id, NV_VERSION_STRING);
66         return ENXIO;
67     }
68
69     if ((status = nvidia_dev_attach(sc)) != 0)
70         return status;
71
72     if ((status = nvidia_ctl_attach()) != 0)
73         return status;
74
75     nv_sysctl_init(nv);
76     return 0;
77 }
78
79 int nvidia_detach(device_t dev)
80 {
81     int status;
82     struct nvidia_softc *sc;
83
84     sc = device_get_softc(dev);
85     nv_sysctl_exit(sc->nv_state);
86
87     status = nvidia_dev_detach(sc);
88     if (status) {
89         device_printf(dev, "NVRM: NVIDIA driver DEV detach failed.\n");
90         goto fail;
91     }
92
93     status = nvidia_ctl_detach();
94     if (status) {
95         device_printf(dev, "NVRM: NVIDIA driver CTL detach failed.\n");
96         goto fail;
97     }
98
99 fail:
100     /* XXX Fix me? (state) */
101     return status;
102 }
103
104
105 #ifdef NV_SUPPORT_ACPI_PM
106 int nvidia_suspend(device_t dev)
107 {
108     nv_stack_t *sp;
109     struct nvidia_softc *sc;
110     nv_state_t *nv;
111     int status = RM_ERROR;
112
113     /* Only if ACPI is running */
114     if (devclass_get_softc(devclass_find("ACPI"), 0) == NULL)
115         return ENODEV;
116
117     NV_UMA_ZONE_ALLOC_STACK(sp);
118     if (sp == NULL)
119         return ENOMEM;
120
121     sc = device_get_softc(dev);
122     nv = sc->nv_state;
123
124     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
125     status = rm_power_management(sp, nv, 0, NV_PM_ACPI_STANDBY);
126
127     NV_UMA_ZONE_FREE_STACK(sp);
128
129     return status;
130 }
131
132 int nvidia_resume(device_t dev)
133 {
134     nv_stack_t *sp;
135     struct nvidia_softc *sc;
136     nv_state_t *nv;
137     int status = RM_ERROR;
138
139     NV_UMA_ZONE_ALLOC_STACK(sp);
140     if (sp == NULL)
141         return ENOMEM;
142
143     sc = device_get_softc(dev);
144     nv = sc->nv_state;
145
146     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
147     status = rm_power_management(sp, nv, 0, NV_PM_ACPI_RESUME);
148
149     NV_UMA_ZONE_FREE_STACK(sp);
150
151     return status;
152 }
153 #endif /* NV_SUPPORT_ACPI_PM */
154
155
156 int nvidia_alloc_hardware(device_t dev)
157 {
158     int error = 0;
159     struct nvidia_softc *sc;
160     U032 flags, i;
161
162     sc = device_get_softc(dev);
163     sc->dev = dev;
164
165     flags = 0; /* not RF_ACTIVE */
166     for (i = 0; i < NV_GPU_NUM_BARS && sc->BAR_rids[i] != 0; i++) {
167         struct resource *res;
168         res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->BAR_rids[i], flags);
169         if (res == NULL) {
170             /*
171              * The most likely reason for this failure is that the SBIOS failed
172              * to assign a valid address range to this BAR; FreeBSD is unable to
173              * correct the problem and fails this BUS resource allocation. We
174              * trust the kernel with BAR validation at this point, but later try
175              * to catch cases where the X server "corrects" "invalid" BAR's.
176              *
177              * Please see to nvidia_pci_check_config_space() in nvidia_pci.c for
178              * additional information.
179              */
180             device_printf(dev,
181                 "NVRM: NVIDIA MEM resource alloc failed, BAR%d @ 0x%02x.\n",
182                 i, sc->nv_state->bars[i].offset);
183             error = ENXIO;
184             goto fail;
185         }
186         sc->BAR_recs[i] = res;
187     }
188
189     flags = RF_SHAREABLE | RF_ACTIVE;
190     sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, flags);
191     if (sc->irq == NULL) {
192         device_printf(dev, "NVRM: NVIDIA IRQ resource alloc failed.\n");
193         error = ENXIO;
194         goto fail;
195     }
196
197 fail:
198     return (error);
199 }
200
201 void nvidia_free_hardware(device_t dev)
202 {
203     struct nvidia_softc *sc;
204     U032 i;
205
206     sc = device_get_softc(dev);
207
208     for (i = 0; i < NV_GPU_NUM_BARS && sc->BAR_recs[i] != NULL; i++)
209         bus_release_resource(dev, SYS_RES_MEMORY, sc->BAR_rids[i], sc->BAR_recs[i]);
210     if (sc->irq != NULL)
211         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
212     if (sc->iop != NULL)
213         bus_release_resource(dev, SYS_RES_IOPORT, sc->iop_rid, sc->iop);
214 }
215
216 void nvidia_intr(void *xsc)
217 {
218     struct nvidia_softc *sc;
219     nv_state_t *nv;
220     U032 run_bottom_half = 0;
221     nv_stack_t *sp;
222
223     sc = (struct nvidia_softc *) xsc;
224     nv = sc->nv_state;
225
226     sp = sc->isr_sp;
227
228     if (sp == NULL)
229         return;
230
231     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, FALSE);
232     rm_isr(sp, nv, &run_bottom_half);
233
234     if (run_bottom_half) {
235         /* We're not executing in an HW ISR context */
236         rm_isr_bh(sp, nv);
237     }
238 }
239
240 int nvidia_get_card_info(struct nv_ioctl_card_info *ci)
241 {
242     unsigned int i;
243     struct nvidia_softc *sc;
244     nv_state_t *nv;
245
246     /*
247      * Clients supporting versioning will pass version magic in the first
248      * card information field.
249      */
250     struct nv_ioctl_rm_api_old_version *av = (void *) ci;
251     int status = 0;
252
253     switch (av->magic) {
254         case NV_RM_API_OLD_VERSION_MAGIC_OVERRIDE_REQ:
255         case NV_RM_API_OLD_VERSION_MAGIC_LAX_REQ:
256         case NV_RM_API_OLD_VERSION_MAGIC_REQ:
257             /*
258              * the client is using the old major-minor-patch API
259              * version check; reject it.
260              */
261             nv_printf(NV_DBG_ERRORS,
262                       "NVRM: API mismatch: the client has the version %d.%d-%d, but\n"
263                       "NVRM: this kernel module has the version %s.  Please\n"
264                       "NVRM: make sure that this kernel module and all NVIDIA driver\n"
265                       "NVRM: components have the same version.\n",
266                       av->major, av->minor, av->patch,
267                       NV_VERSION_STRING);
268             status = -EINVAL;
269             break;
270
271         case NV_RM_API_OLD_VERSION_MAGIC_IGNORE:
272             /*
273              * the client is telling us to ignore the old version
274              * scheme; it will do a version check via
275              * NV_ESC_CHECK_VERSION_STR
276              */
277             break;
278         default:
279             status = -EINVAL;
280             break;
281     }
282
283     /* clear card information structure */
284     memset(ci, 0, sizeof(ci));
285
286     for (i = 0; i < NV_MAX_DEVICES; i++) {
287         sc = devclass_get_softc(nvidia_devclass, i);
288         if (!sc)
289             continue;
290         nv = sc->nv_state;
291
292         ci[i].flags          = (NV_IOCTL_CARD_INFO_FLAG_PRESENT |
293                                 NV_IOCTL_CARD_INFO_FLAG_NEED_MSYNC);
294         ci[i].bus            = nv->bus;
295         ci[i].slot           = nv->slot;
296         ci[i].vendor_id      = nv->vendor_id;
297         ci[i].device_id      = nv->device_id;
298         ci[i].interrupt_line = nv->interrupt_line;
299         ci[i].fb_address     = nv->fb->address;
300         ci[i].fb_size        = nv->fb->size;
301         ci[i].reg_address    = nv->regs->address;
302         ci[i].reg_size       = nv->regs->size;
303     }
304
305     return status;
306 }
307
308 int nvidia_handle_ioctl(
309     struct cdev *dev,
310     u_long cmd,
311     caddr_t data,
312     int fflag,
313     d_thread_t *td
314 )
315 {
316     struct nvidia_softc *sc;
317     nv_state_t *nv;
318     int unit = minor(dev);
319     nv_stack_t *sp;
320     void *args;
321     nv_ioctl_xfer_t *xfer = NULL;
322     int status;
323     int nr, size;
324
325     if (unit == CDEV_CTL_MINOR) {
326         nv = &nvidia_ctl_state;
327         sc = nv->os_state;
328     } else {
329         sc = devclass_get_softc(nvidia_devclass, unit);
330         if (!sc)
331             return ENXIO;
332         nv = sc->nv_state;
333     }
334
335     sp = sc->api_sp;
336
337     size = __NV_IOC_SIZE(cmd);
338     nr = __NV_IOC_NR(cmd);
339
340     args = (void *)data;
341
342     if (nr == NV_ESC_IOCTL_XFER_CMD) {
343         if (__NV_IOC_SIZE(cmd) != sizeof(nv_ioctl_xfer_t))
344             return EINVAL;
345
346         xfer = args;
347         size = xfer->size;
348
349         if (size > NV_ABSOLUTE_MAX_IOCTL_SIZE)
350             return EINVAL;
351
352         args = malloc(size, M_NVIDIA, M_WAITOK);
353         if (args == NULL)
354             return ENOMEM;
355
356         if (copyin(NvP64_VALUE(xfer->ptr), args, size) != 0) {
357             free(args, M_NVIDIA);
358             return EFAULT;
359         }
360
361         nr = xfer->cmd;
362     }
363
364     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
365
366     switch (nr) {
367         case NV_ESC_CHECK_VERSION_STR:
368             status = (rm_perform_version_check(sp, args) == RM_OK)
369                 ? 0 : EINVAL;
370             break;
371
372         case NV_ESC_CARD_INFO:
373             status = nvidia_get_card_info(args);
374             break;
375
376         default:
377             status = rm_ioctl(sp, nv, __TD_FDT(td), nr, args)
378                 ? 0 : EINVAL;
379             break;
380     }
381
382     if (args != (void *)data) {
383         if (copyout(args, NvP64_VALUE(xfer->ptr), size) != 0)
384             status = EFAULT;
385         free(args, M_NVIDIA);
386     }
387
388     return status;
389 }
390
391 int nvidia_open_ctl(
392     struct cdev *dev,
393     d_thread_t *td
394 )
395 {
396     struct nvidia_softc *sc;
397     nv_state_t *nv = &nvidia_ctl_state;
398     BOOL new_filep = FALSE;
399     struct nvidia_filep *filep;
400
401     sc = nv->os_state;
402
403     STAILQ_FOREACH(filep, &sc->filep_queue, queue) {
404         if (filep->fd_table == __TD_FDT(td)) 
405             break;
406     }
407
408     if (filep == NULL) {
409         filep = malloc(sizeof(nvidia_filep_t), M_NVIDIA, M_NOWAIT | M_ZERO);
410         if (filep == NULL)
411             return ENOMEM;
412         filep->fd_table = __TD_FDT(td);
413         filep->fd_refcnt = 0;
414         STAILQ_INSERT_HEAD(&sc->filep_queue, filep, queue);
415         new_filep = TRUE;
416     }
417
418     filep->fd_refcnt++;
419
420     if (sc->refcnt == 0) {
421         NV_UMA_ZONE_ALLOC_STACK(sc->api_sp);
422         if (sc->api_sp == NULL) {
423             if (new_filep)
424                 free(filep, M_NVIDIA);
425             return ENOMEM;
426         }
427
428         STAILQ_INIT(&sc->event_queue);
429         nv->flags |= (NV_FLAG_OPEN | NV_FLAG_CONTROL);
430     }
431
432     sc->refcnt++;
433
434     return 0;
435 }
436
437 int nvidia_close_ctl(
438     struct cdev *dev,
439     d_thread_t *td
440 )
441 {
442     struct nvidia_softc *sc;
443     nv_state_t *nv = &nvidia_ctl_state;
444     struct nvidia_event *et;
445     struct nvidia_filep *filep;
446     nv_stack_t *sp;
447
448     sc = nv->os_state;
449
450     STAILQ_FOREACH(filep, &sc->filep_queue, queue) {
451         if (filep->fd_table == __TD_FDT(td)) 
452             break;
453     }
454
455     if (filep == NULL)
456         return EINVAL;
457
458     sp = sc->api_sp;
459
460     if (--filep->fd_refcnt == 0) {
461         rm_free_unused_clients(sp, nv, __TD_FDT(td));
462         STAILQ_REMOVE(&sc->filep_queue, filep, nvidia_filep, queue);
463         free(filep, M_NVIDIA);
464     }
465
466     if (--sc->refcnt == 0) {
467         while ((et = STAILQ_FIRST(&sc->event_queue))) {
468             STAILQ_REMOVE(&sc->event_queue, et, nvidia_event, queue);
469             free(et, M_NVIDIA);
470         }
471
472         NV_UMA_ZONE_FREE_STACK(sp);
473
474         nv->flags &= ~NV_FLAG_OPEN;
475     }
476
477     return 0;
478 }
479
480 int nvidia_open_dev(
481     struct nvidia_softc *sc,
482     struct cdev *dev,
483     d_thread_t *td
484 )
485 {
486     int status = ENOMEM;
487     nv_state_t *nv = sc->nv_state;
488     BOOL new_filep = FALSE;
489     struct nvidia_filep *filep;
490     nv_stack_t *sp = NULL;
491
492     STAILQ_FOREACH(filep, &sc->filep_queue, queue) {
493         if (filep->fd_table == __TD_FDT(td)) 
494             break;
495     }
496
497     if (filep == NULL) {
498         filep = malloc(sizeof(nvidia_filep_t), M_NVIDIA, M_NOWAIT | M_ZERO);
499         if (filep == NULL)
500             return ENOMEM;
501         filep->fd_table = __TD_FDT(td);
502         filep->fd_refcnt = 0;
503         new_filep = TRUE;
504     }
505
506     if (sc->refcnt == 0) {
507         NV_UMA_ZONE_ALLOC_STACK(sc->api_sp);
508         if (sc->api_sp == NULL)
509             goto failed;
510
511         NV_UMA_ZONE_ALLOC_STACK(sc->pci_cfgchk_sp);
512         if (sc->pci_cfgchk_sp == NULL)
513             goto failed;
514
515         NV_UMA_ZONE_ALLOC_STACK(sc->isr_sp);
516         if (sc->isr_sp == NULL)
517             goto failed;
518
519         NV_UMA_ZONE_ALLOC_STACK(sc->timer_sp);
520         if (sc->timer_sp == NULL)
521             goto failed;
522     }
523
524     sp = sc->api_sp;
525     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
526
527     if (sc->refcnt == 0) {
528         if (!rm_init_adapter(sp, nv)) {
529             device_printf(sc->dev, "NVRM: rm_init_adapter() failed!\n");
530             status = EIO;
531             goto failed;
532         }
533
534         STAILQ_INIT(&sc->event_queue);
535         nv->flags |= NV_FLAG_OPEN;
536     }
537
538     filep->fd_refcnt++;
539     if (new_filep)
540         STAILQ_INSERT_HEAD(&sc->filep_queue, filep, queue);
541
542     sc->refcnt++;
543
544     return 0;
545
546 failed:
547     if (sc->refcnt == 0) {
548         if (sc->timer_sp != NULL)
549             NV_UMA_ZONE_FREE_STACK(sc->timer_sp);
550         if (sc->isr_sp != NULL)
551             NV_UMA_ZONE_FREE_STACK(sc->isr_sp);
552         if (sc->pci_cfgchk_sp != NULL)
553             NV_UMA_ZONE_FREE_STACK(sc->pci_cfgchk_sp);
554         if (sc->api_sp != NULL)
555             NV_UMA_ZONE_FREE_STACK(sc->api_sp);
556     }
557
558     if (new_filep)
559         free(filep, M_NVIDIA);
560
561     return status;
562 }
563
564 int nvidia_close_dev(
565     struct nvidia_softc *sc,
566     struct cdev *dev,
567     d_thread_t *td
568 )
569 {
570     nv_state_t *nv = sc->nv_state;
571     struct nvidia_event *et;
572     struct nvidia_filep *filep;
573     nv_stack_t *sp;
574
575     STAILQ_FOREACH(filep, &sc->filep_queue, queue) {
576         if (filep->fd_table == __TD_FDT(td)) 
577             break;
578     }
579
580     if (filep == NULL)
581         return EINVAL;
582
583     sp = sc->api_sp;
584
585     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
586
587     if (--filep->fd_refcnt == 0) {
588         rm_free_unused_clients(sp, nv, __TD_FDT(td));
589         STAILQ_REMOVE(&sc->filep_queue, filep, nvidia_filep, queue);
590         free(filep, M_NVIDIA);
591     }
592
593     if (--sc->refcnt == 0) {
594         rm_disable_adapter(sp, nv);
595         rm_shutdown_adapter(sp, nv);
596
597         while ((et = STAILQ_FIRST(&sc->event_queue))) {
598             STAILQ_REMOVE(&sc->event_queue, et, nvidia_event, queue);
599             free(et, M_NVIDIA);
600         }
601
602         NV_UMA_ZONE_FREE_STACK(sc->timer_sp);
603         NV_UMA_ZONE_FREE_STACK(sc->isr_sp);
604         NV_UMA_ZONE_FREE_STACK(sc->pci_cfgchk_sp);
605         NV_UMA_ZONE_FREE_STACK(sc->api_sp);
606
607         nv->flags &= ~NV_FLAG_OPEN;
608     }
609
610     return 0;
611 }
612
613
614 int nvidia_modevent(
615     module_t mod,
616     int what,
617     void *arg
618 )
619 {
620     nv_state_t *nv;
621     struct nvidia_softc *sc;
622     nv_stack_t *sp;
623
624     switch (what) {
625         case MOD_LOAD:
626             /*
627              * The module load event. Our KLD has just been loaded and is
628              * ready to initialize. We setup the core resource manager in
629              * this routine, further initialization takes place at attach
630              * time.
631              */
632             sc = &nvidia_ctl_sc;
633
634             nvidia_stack_t_zone = uma_zcreate("nv_stack_t", sizeof(nv_stack_t),
635                     NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
636             if (nvidia_stack_t_zone == NULL)
637                 return ENOMEM;
638
639             NV_UMA_ZONE_ALLOC_STACK(sp);
640             if (sp == NULL) {
641                 uma_zdestroy(nvidia_stack_t_zone);
642                 return ENOMEM;
643             }
644
645             bzero(sc, sizeof(nvidia_softc_t));
646             STAILQ_INIT(&sc->filep_queue);
647
648             if (!rm_init_rm(sp)) {
649                 printf("NVRM: rm_init_rm() failed!\n");
650                 NV_UMA_ZONE_FREE_STACK(sp);
651                 uma_zdestroy(nvidia_stack_t_zone);
652                 return EIO;
653             }
654
655             __nvidia_init_sp = sp;
656
657             mtx_init(&sc->rm_mtx, "ctl.rm_mtx", NULL, MTX_SPIN | MTX_RECURSE);
658             sx_init(&sc->api_sx, "ctl.api_sx");
659
660             nvidia_ctl_state.os_state = sc;
661             sc->nv_state = (void *)&nvidia_ctl_state;
662
663             nvidia_sysctl_init();
664             nvidia_linux_init();
665
666             break;
667
668         case MOD_UNLOAD:
669             /*
670              * Check if the control device is still open and reject the
671              * unload request if it is. This event can occur even when the
672              * module usage count is non-zero!
673              */
674             nv = &nvidia_ctl_state;
675             sc = nv->os_state;
676
677             nv_lock_api(nv);
678
679             if (sc->refcnt != 0) { /* XXX Fix me? (refcnt) */
680                 nv_unlock_api(nv);
681                 return EBUSY;
682             }
683
684             nv_unlock_api(nv);
685
686             mtx_destroy(&sc->rm_mtx);
687             sx_destroy(&sc->api_sx);
688
689             sp = __nvidia_init_sp;
690             rm_shutdown_rm(sp);
691
692             NV_UMA_ZONE_FREE_STACK(sp);
693
694             nvidia_sysctl_exit();
695             nvidia_linux_exit();
696
697             uma_zdestroy(nvidia_stack_t_zone);
698
699             break;
700
701         default:
702             break;
703     }
704
705     return 0;
706 }
707
708
709 #ifdef NV_SUPPORT_OS_AGP
710 S032 nv_os_agp_init(
711     nv_stack_t *sp,
712     nv_state_t *nv,
713     void **base,
714     U032 *limit
715 )
716 {
717     void *bitmap;
718     struct nvidia_softc *sc = nv->os_state;
719     struct agp_info ai;
720
721     U032 mode = 0;
722     U032 fw   = 0;
723     U032 sba  = 0;
724     U032 rate = (8 | 4 | 2 | 1);
725     U032 size = 0;
726
727     sc->agp_dev = agp_find_device();
728     if (!sc->agp_dev) {
729         printf("NVRM: agp_find_device failed, chipset unsupported?\n");
730         return -ENODEV;
731     }
732
733     if (agp_acquire(sc->agp_dev) != 0)
734         return -EBUSY;
735
736     agp_get_info(sc->agp_dev, &ai);
737     mode = ai.ai_mode;
738
739     if (os_set_mem_range(ai.ai_aperture_base, ai.ai_aperture_size,
740                 NV_MEMORY_WRITECOMBINED) != RM_OK) {
741         /*
742          * Failure to set a write-combining range for the AGP aperture is
743          * not necessarily a fatal error condition; we don't know at this
744          * point, however, and abort to prevent performance and stability
745          * problems that may be hard to track down otherwise.
746          */
747         agp_release(sc->agp_dev);
748         return -EIO;
749     }
750
751     rm_read_registry_dword(sp, NULL, "NVreg", "ReqAGPRate", &rate);
752     rm_read_registry_dword(sp, NULL, "NVreg", "EnableAGPFW", &fw);
753     rm_read_registry_dword(sp, NULL, "NVreg", "EnableAGPSBA", &sba);
754
755     if (AGP_MODE_GET_MODE_3(mode))
756         rate = (rate >> 2) & 3;
757     mode = AGP_MODE_SET_RATE(mode, AGP_MODE_GET_RATE(mode) & rate);
758     mode |= 1 /* avoid 0x mode request */;
759
760     if (AGP_MODE_GET_RATE(mode) & 2)
761         mode = AGP_MODE_SET_RATE(mode, AGP_MODE_GET_RATE(mode) & ~1);
762     if (AGP_MODE_GET_RATE(mode) & 4)
763         mode = AGP_MODE_SET_RATE(mode, AGP_MODE_GET_RATE(mode) & ~2);
764
765     mode = AGP_MODE_SET_FW(mode, fw);
766     mode = AGP_MODE_SET_SBA(mode, sba);
767
768     if (agp_enable(sc->agp_dev, mode) != 0) {
769         agp_release(sc->agp_dev);
770         os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
771         return -EIO;
772     }
773
774     size = ai.ai_aperture_size / RM_PAGE_SIZE / 8;
775
776     if (os_alloc_mem((void **)&bitmap, size) != RM_OK) {
777         agp_release(sc->agp_dev);
778         os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
779         return -EIO;
780     }
781
782     os_mem_set(bitmap, 0xff, size);
783
784     if (rm_set_agp_bitmap(sp, nv, bitmap) != RM_OK) {
785         agp_release(sc->agp_dev);
786         os_free_mem(bitmap);
787         os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
788         return -EIO;
789     }
790
791     *base   = (void *) ai.ai_aperture_base;
792     *limit  = (U032)   ai.ai_aperture_size - 1;
793
794     return 0;
795 }
796
797 S032 nv_os_agp_teardown(
798     nv_stack_t *sp,
799     nv_state_t *nv
800 )
801 {
802     struct nvidia_softc *sc = nv->os_state;
803     void *bitmap;
804
805     if (agp_release(sc->agp_dev) != 0)
806         return -EBUSY;
807
808     rm_clear_agp_bitmap(sp, nv, &bitmap);
809     os_free_mem(bitmap);
810
811     os_unset_mem_range(nv->agp.address, nv->agp.size);
812
813     return 0;
814 }
815 #endif /* NV_SUPPORT_OS_AGP */
816
817 RM_STATUS NV_API_CALL nv_agp_init(
818     nv_state_t *nv,
819     void **base,
820     void *limit,
821     U032 config
822 )
823 {
824     RM_STATUS status = RM_ERROR;
825     nv_stack_t *sp;
826
827     if (NV_AGP_ENABLED(nv))
828         return RM_ERR_STATE_IN_USE;
829
830     if (config == NVOS_AGP_CONFIG_DISABLE_AGP) {
831         /*
832          * Match the behavior on Linux, don't consider the attempt
833          * to initialize AGP as 'disabled' an error.
834          */
835         nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
836         nv->agp_status = NV_AGP_STATUS_DISABLED;
837         return RM_OK;
838     }
839
840     NV_UMA_ZONE_ALLOC_STACK(sp);
841     if (sp == NULL)
842         return RM_ERR_NO_FREE_MEM;
843
844 #ifdef NV_SUPPORT_OS_AGP
845     if ((config & NVOS_AGP_CONFIG_OSAGP) != 0) {
846         if (nv_os_agp_init(sp, nv, base, limit) == 0) {
847             /*
848              * If the operating system AGP GART driver successfully
849              * configured its backend, apply chipset overrides.
850              */
851             rm_update_agp_config(sp, nv);
852             NV_UMA_ZONE_FREE_STACK(sp);
853
854             nv->agp_config = NVOS_AGP_CONFIG_OSAGP;
855             nv->agp_status = NV_AGP_STATUS_ENABLED;
856
857             return RM_OK;
858         }
859     }
860 #endif /* NV_SUPPORT_OS_AGP */
861
862     if ((config & NVOS_AGP_CONFIG_NVAGP) == 0) {
863         status = RM_ERR_NOT_SUPPORTED;
864         goto failed;
865     }
866
867     if (devclass_get_softc(devclass_find("agp"), 0) != NULL) {
868         /*
869          * Make sure we don't try to use the internal GART driver when
870          * the OS AGPGART driver (agp.ko) is attached. While that may
871          * be perfectly fine on most systems, but is known to break on
872          * some.
873          * -------------------------------------------------------------
874          * DON'T REDISTRIBUTE THE DRIVER WITH THIS SANITY CHECK REMOVED!
875          * -------------------------------------------------------------
876          */
877         printf("NVRM: detected agp.ko, aborting NVIDIA AGP setup!\n");
878         goto failed;
879     }
880
881     status = rm_init_agp(sp, nv);
882     if (status == RM_OK) {
883         NV_UMA_ZONE_FREE_STACK(sp);
884
885         nv->agp_config = NVOS_AGP_CONFIG_NVAGP;
886         nv->agp_status = NV_AGP_STATUS_ENABLED;
887
888         return status;
889     }
890
891 failed:
892     NV_UMA_ZONE_FREE_STACK(sp);
893
894     nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
895     nv->agp_status = NV_AGP_STATUS_FAILED;
896
897     return status;
898 }
899
900 RM_STATUS NV_API_CALL nv_agp_teardown(nv_state_t *nv)
901 {
902     RM_STATUS status = RM_ERR_NOT_SUPPORTED;
903     nv_stack_t *sp;
904
905     if (!NV_AGP_ENABLED(nv))
906         return status;
907
908     NV_UMA_ZONE_ALLOC_STACK(sp);
909     if (sp == NULL)
910         return RM_ERR_NO_FREE_MEM;
911
912 #ifdef NV_SUPPORT_OS_AGP
913     if (NV_OSAGP_ENABLED(nv))
914         status = (nv_os_agp_teardown(sp, nv) == 0)
915             ? RM_OK : RM_ERROR;
916 #endif
917     if (NV_NVAGP_ENABLED(nv))
918         status = rm_teardown_agp(sp, nv);
919
920     NV_UMA_ZONE_FREE_STACK(sp);
921
922     nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
923     nv->agp_status = NV_AGP_STATUS_DISABLED;
924
925     return status;
926 }
927
928 S032 NV_API_CALL nv_no_incoherent_mappings(void)
929 {
930 #if !defined(NVCPU_X86_64) && !defined(NV_SUPPORT_OS_AGP)
931     return 1;
932 #else
933     /*
934      * XXX We can't modify FreeBSD/amd64's cached direct mapping
935      * and are thus can't provide coherent mappings. The driver
936      * will attempt to work around this problem, but AGP support
937      * may be unavailable on some newer systems.
938      *
939      * The FreeBSD AGP GART driver also doesn't currently update
940      * the kernel mappings of system memory mapped into the AGP
941      * aperture.
942      */
943     return 0;
944 #endif
945 }
946
947 void NV_API_CALL nv_lock_rm(nv_state_t *nv)
948 {
949     /*
950      * With SMPng, the "giant" kernel lock is gone. That means that we're
951      * in a more complex enviroment locking-wise, but since the necessary
952      * locking primitives are available to us, we can handle it.
953      *
954      * With mtx_lock_spin we acquire a spin mutex and locally disable all
955      * interrupts on the current processor.
956      */
957     struct nvidia_softc *sc = nv->os_state;
958     mtx_lock_spin(&sc->rm_mtx);
959 }
960
961 void NV_API_CALL nv_unlock_rm(nv_state_t *nv)
962 {
963     struct nvidia_softc *sc = nv->os_state;
964     mtx_unlock_spin(&sc->rm_mtx);
965 }
966
967 void nv_lock_api(nv_state_t *nv)
968 {
969     struct nvidia_softc *sc = nv->os_state;
970     sx_xlock(&sc->api_sx);
971 }
972
973 void nv_unlock_api(nv_state_t *nv)
974 {
975     struct nvidia_softc *sc = nv->os_state;
976     sx_xunlock(&sc->api_sx);
977 }
978
979
980 void NV_API_CALL nv_post_event(
981     nv_state_t *nv,
982     nv_event_t *event,
983     U032 hObject,
984     U032 index
985 )
986 {
987     struct nvidia_softc *sc;
988     struct nvidia_event *et; 
989
990     et = malloc(sizeof(nvidia_event_t), M_NVIDIA, M_NOWAIT | M_ZERO);
991     if (et == NULL)
992         return;
993
994     et->event = *event;
995     et->event.hObject = hObject;
996     et->event.index = index;
997
998     nv_lock_rm(nv);
999
1000     sc = nv->os_state;
1001     STAILQ_INSERT_TAIL(&sc->event_queue, et, queue);
1002
1003     nv_unlock_rm(nv);
1004
1005     selwakeup(&sc->rsel);
1006 }
1007
1008 S032 NV_API_CALL nv_get_event(
1009     nv_state_t *nv,
1010     void *file,
1011     nv_event_t *event,
1012     U032 *pending
1013 )
1014 {
1015     struct nvidia_softc *sc = nv->os_state;
1016     struct nvidia_event *et, *_et;
1017
1018     nv_lock_rm(nv);
1019
1020     STAILQ_FOREACH(et, &sc->event_queue, queue) {
1021         if (et->event.file == file)
1022             break;
1023     }
1024
1025     if (et != NULL) {
1026         *event = et->event;
1027
1028         STAILQ_REMOVE(&sc->event_queue, et, nvidia_event, queue);
1029
1030         STAILQ_FOREACH(_et, &sc->event_queue, queue) {
1031             if (_et->event.file == file)
1032                 break;
1033         }
1034
1035         *pending = (_et != NULL);
1036
1037         nv_unlock_rm(nv);
1038
1039         /* will attempt to acquire a blockable sleep lock */
1040         free(et, M_NVIDIA);
1041
1042         return RM_OK;
1043     }
1044
1045     nv_unlock_rm(nv);
1046     return RM_ERROR; /* RM polling? */
1047 }
1048
1049 void* NV_API_CALL nv_alloc_kernel_mapping(
1050     nv_state_t *nv,
1051     NvU64 address,
1052     U032 size,
1053     void **private
1054 )
1055 {
1056     struct nvidia_alloc *at;
1057     struct nvidia_softc *sc = nv->os_state;
1058     vm_offset_t offset, linear;
1059
1060     offset = (vm_offset_t) address & PAGE_MASK;
1061     address &= ~PAGE_MASK;
1062
1063     SLIST_FOREACH(at, &sc->alloc_list, list) {
1064         linear = at->address;
1065         do {
1066             if (vtophys(linear) == (vm_offset_t) address)
1067                 return (void *)(linear + offset);
1068             linear += PAGE_SIZE;
1069         } while (linear < (at->address + at->size));
1070     }
1071
1072     return NULL;
1073 }
1074
1075 S032 NV_API_CALL nv_free_kernel_mapping(
1076     nv_state_t *nv,
1077     void *address,
1078     void *private
1079 )
1080 {
1081     /* There's nothing to be done here. */
1082     return RM_OK;
1083 }
1084
1085 S032 nv_alloc_contig_pages(
1086     nv_state_t *nv,
1087     U032 count,
1088     U032 cache_type,
1089     NvU64 *pte_array,
1090     void **private
1091 )
1092 {
1093     struct nvidia_alloc *at;
1094     struct nvidia_softc *sc = nv->os_state;
1095     void *address;
1096     U032 size = count * PAGE_SIZE;
1097     int status;
1098
1099     if (os_alloc_contig_pages(&address, size) != RM_OK)
1100         return -ENOMEM;
1101
1102     at = malloc(sizeof(struct nvidia_alloc), M_NVIDIA, M_WAITOK | M_ZERO);
1103     if (!at) {
1104         os_free_contig_pages(address, size);
1105         return -ENOMEM;
1106     }
1107
1108     if (cache_type != NV_MEMORY_CACHED) {
1109         status = pmap_change_attr((vm_offset_t)address, size, PAT_UNCACHEABLE);
1110         if (status != 0) {
1111             free(at, M_NVIDIA);
1112             os_free_contig_pages(address, size);
1113             return status;
1114         }
1115     }
1116
1117     at->alloc_type_contiguous = 1;
1118
1119     at->cache_type = cache_type;
1120     at->size = size;
1121     at->address = (vm_offset_t)address;
1122     at->pte_array = pte_array;
1123
1124     pte_array[0] = vtophys(at->address);
1125
1126     *private = at;
1127     SLIST_INSERT_HEAD(&sc->alloc_list, at, list);
1128
1129     return 0;
1130 }
1131
1132 S032 nv_free_contig_pages(
1133     nv_state_t *nv,
1134     void *private
1135 )
1136 {
1137     struct nvidia_alloc *at = private;
1138     struct nvidia_softc *sc = nv->os_state;
1139
1140     SLIST_REMOVE(&sc->alloc_list, at, nvidia_alloc, list);
1141
1142     if (at->cache_type != NV_MEMORY_CACHED)
1143         pmap_change_attr(at->address, at->size, PAT_WRITE_BACK);
1144
1145     os_free_contig_pages((void *)at->address, at->size);
1146     free(at, M_NVIDIA);
1147
1148     return 0;
1149 }
1150
1151 S032 nv_alloc_system_pages(
1152     nv_state_t  *nv,
1153     U032 count,
1154     U032 cache_type,
1155     NvU64 *pte_array,
1156     void **private
1157 )
1158 {
1159     struct nvidia_alloc *at;
1160     struct nvidia_softc *sc = nv->os_state;
1161     void *address;
1162     u_int32_t i, size;
1163     int status;
1164
1165     size = count * PAGE_SIZE;
1166     at = malloc(sizeof(struct nvidia_alloc), M_NVIDIA, M_WAITOK | M_ZERO);
1167     if (!at) {
1168         return -ENOMEM;
1169     }
1170
1171     address = malloc(size, M_NVIDIA, M_WAITOK | M_ZERO);
1172     if (!address) {
1173         free(at, M_NVIDIA);
1174         return -ENOMEM;
1175     }
1176
1177     if (cache_type != NV_MEMORY_CACHED) {
1178         status = pmap_change_attr((vm_offset_t)address, size, PAT_UNCACHEABLE);
1179         if (status != 0) {
1180             free(at, M_NVIDIA);
1181             free(address, M_NVIDIA);
1182             return status;
1183         }
1184     }
1185
1186     at->alloc_type_contiguous = 0;
1187
1188     at->cache_type = cache_type;
1189     at->size = size;
1190     at->address = (vm_offset_t)address;
1191     at->pte_array = pte_array;
1192
1193     for (i = 0; i < count; i++) {
1194         pte_array[i] = (NvU64)vtophys(at->address + (i * PAGE_SIZE));
1195         vm_page_lock_queues();
1196         vm_page_wire(PHYS_TO_VM_PAGE(pte_array[i]));
1197         vm_page_unlock_queues();
1198     }
1199
1200     *private = at;
1201     SLIST_INSERT_HEAD(&sc->alloc_list, at, list);
1202
1203     return 0;
1204 }
1205
1206 S032 nv_free_system_pages(
1207     nv_state_t *nv,
1208     void *private
1209 )
1210 {
1211     struct nvidia_alloc *at = private;
1212     struct nvidia_softc *sc = nv->os_state;
1213     u_int32_t i, count;
1214
1215     count = at->size / PAGE_SIZE;
1216     SLIST_REMOVE(&sc->alloc_list, at, nvidia_alloc, list);
1217
1218     for (i = 0; i < count; i++) {
1219         vm_page_lock_queues();
1220         vm_page_unwire(PHYS_TO_VM_PAGE(at->pte_array[i]), 0);
1221         vm_page_unlock_queues();
1222     }
1223
1224     if (at->cache_type != NV_MEMORY_CACHED)
1225         pmap_change_attr(at->address, at->size, PAT_WRITE_BACK);
1226
1227     free((void *)at->address, M_NVIDIA);
1228     free(at, M_NVIDIA);
1229
1230     return 0;
1231 }
1232
1233 #ifdef NV_SUPPORT_OS_AGP
1234 S032 nv_alloc_agp_pages(
1235     nv_state_t *nv,
1236     U032 count,
1237     U032 offset,
1238     void **private
1239 )
1240 {
1241     void *handle;
1242     struct nvidia_softc *sc = nv->os_state;
1243
1244     handle = agp_alloc_memory(sc->agp_dev, 0, count << PAGE_SHIFT);
1245     if (!handle) {
1246         /*
1247          * This is very unlikely to happen, the system's memory resources
1248          * would have to be nearly exhausted.
1249          */
1250         return -ENOMEM;
1251     }
1252
1253     if (agp_bind_memory(sc->agp_dev, handle, offset) != 0) {
1254         /*
1255          * This shouldn't happen, we claimed the AGP backend and are thus
1256          * using it exclusively; the resource manager manages AGP offsets
1257          * internally, we wouldn't have been called had we run out of AGP
1258          * aperture space.
1259          */
1260         os_dbg_breakpoint();
1261
1262         agp_free_memory(sc->agp_dev, handle);
1263         return -ENOMEM;
1264     }
1265
1266     *private = handle;
1267     return 0;
1268 }
1269
1270 S032 nv_free_agp_pages(
1271     nv_state_t *nv,
1272     U032 count,
1273     void *private,
1274     U032 *offset
1275 )
1276 {
1277     void *handle = private;
1278     struct nvidia_softc *sc = nv->os_state;
1279     struct agp_memory_info info;
1280
1281     agp_memory_info(sc->agp_dev, handle, &info);
1282     *offset = info.ami_offset;
1283
1284     if (agp_unbind_memory(sc->agp_dev, handle) != 0) {
1285         /*
1286          * This is the only place where previously bound AGP memory would
1287          * be freed. If we fail to unbind this memory now, something very
1288          * wrong must have happened.
1289          */
1290         os_dbg_breakpoint();
1291     }
1292
1293     agp_free_memory(sc->agp_dev, handle);
1294     return 0;
1295 }
1296 #endif /* NV_SUPPORT_OS_AGP */
1297
1298
1299 RM_STATUS NV_API_CALL nv_alloc_pages(
1300     nv_state_t *nv,
1301     U032 count,
1302     U032 alloc_type_agp,
1303     U032 alloc_type_contiguous,
1304     U032 cache_type,
1305     NvU64 *pte_array,
1306     void **private
1307 )
1308 {
1309     U032 offset;
1310     RM_STATUS status = RM_ERR_NO_FREE_MEM;
1311     nv_stack_t *sp = NULL;
1312
1313     if (alloc_type_agp) {
1314         if (!NV_AGP_ENABLED(nv))
1315             return RM_ERR_NOT_SUPPORTED;
1316
1317         NV_UMA_ZONE_ALLOC_STACK(sp);
1318         if (sp == NULL)
1319             return RM_ERR_NO_FREE_MEM;
1320
1321 #ifdef NV_SUPPORT_OS_AGP
1322         if (NV_OSAGP_ENABLED(nv)) {
1323             status = rm_alloc_agp_bitmap(sp, nv, count, &offset);
1324             if (status != RM_OK)
1325                 goto failed;
1326
1327             if (nv_alloc_agp_pages(nv, count, (offset << PAGE_SHIFT),
1328                     private) != 0) {
1329                 rm_free_agp_bitmap(sp, nv, count, offset);
1330                 goto failed;
1331             }
1332
1333             NV_UMA_ZONE_FREE_STACK(sp);
1334
1335             pte_array[0] = (nv->agp.address + (offset << PAGE_SHIFT));
1336             return RM_OK;
1337         }
1338 #endif /* NV_SUPPORT_OS_AGP */
1339
1340         if (NV_NVAGP_ENABLED(nv)) {
1341             status = rm_alloc_agp_pages(sp, nv, count, private, &offset);
1342             if (status != RM_OK)
1343                 goto failed;
1344
1345             NV_UMA_ZONE_FREE_STACK(sp);
1346
1347             pte_array[0] = (nv->agp.address + (offset << PAGE_SHIFT));
1348             return RM_OK;
1349         }
1350     } else {
1351         /* XXX Fix me! (PAT) */
1352         if (cache_type == NV_MEMORY_WRITECOMBINED) {
1353             status = RM_ERR_NOT_SUPPORTED;
1354             goto failed;
1355         }
1356
1357         if (!alloc_type_contiguous) {
1358             if (nv_alloc_system_pages(nv, count, cache_type, pte_array, private))
1359                 goto failed;
1360         } else {
1361             if (nv_alloc_contig_pages(nv, count, cache_type, pte_array, private))
1362                 goto failed;
1363         }
1364
1365         return RM_OK;
1366     }
1367
1368 failed:
1369     if (sp != NULL)
1370         NV_UMA_ZONE_FREE_STACK(sp);
1371
1372     return status;
1373 }
1374
1375 RM_STATUS NV_API_CALL nv_free_pages(
1376     nv_state_t *nv,
1377     U032 count,
1378     U032 alloc_type_agp,
1379     U032 alloc_type_contiguous,
1380     U032 cache_type,
1381     void *private
1382 )
1383 {
1384     RM_STATUS status = RM_ERROR;
1385     nv_stack_t *sp = NULL;
1386
1387     if (alloc_type_agp) {
1388         if (!NV_AGP_ENABLED(nv))
1389             return RM_ERR_NOT_SUPPORTED;
1390
1391         NV_UMA_ZONE_ALLOC_STACK(sp);
1392         if (sp == NULL)
1393             return RM_ERR_NO_FREE_MEM;
1394
1395 #ifdef NV_SUPPORT_OS_AGP
1396         if (NV_OSAGP_ENABLED(nv)) {
1397             U032 offset;
1398
1399             if (nv_free_agp_pages(nv, count, private, &offset) != 0)
1400                 goto failed;
1401
1402             rm_free_agp_bitmap(sp, nv, count, (offset >> PAGE_SHIFT));
1403             NV_UMA_ZONE_FREE_STACK(sp);
1404
1405             return RM_OK;
1406         }
1407 #endif /* NV_SUPPORT_OS_AGP */
1408
1409         if (NV_NVAGP_ENABLED(nv)) {
1410             if (rm_free_agp_pages(sp, nv, private) != RM_OK)
1411                 goto failed;
1412         }
1413
1414         NV_UMA_ZONE_FREE_STACK(sp);
1415     } else {
1416         if (!alloc_type_contiguous) {
1417             if (nv_free_system_pages(nv, private))
1418                 goto failed;
1419         } else  {
1420             if (nv_free_contig_pages(nv, private))
1421                 goto failed;
1422         }
1423     }
1424
1425     return RM_OK;
1426
1427 failed:
1428     if (sp != NULL)
1429         NV_UMA_ZONE_FREE_STACK(sp);
1430
1431     return status;
1432 }
1433
1434 NvU64 NV_API_CALL nv_dma_to_mmap_token(
1435     nv_state_t *nv,
1436     NvU64 address
1437 )
1438 {
1439     struct nvidia_alloc *at;
1440     struct nvidia_softc *sc = nv->os_state;
1441     vm_offset_t offset, linear;
1442     uint32_t i;
1443
1444     offset = (vm_offset_t)address & PAGE_MASK;
1445     address &= ~PAGE_MASK;
1446
1447     /*
1448      * XXX FreeBSD doesn't currently allow the use of physical
1449      * addresses as mmap(2) tokens, a linear address range
1450      * derived from the allocation's contiguous kernel mapping
1451      * is used, instead.
1452      */
1453     SLIST_FOREACH(at, &sc->alloc_list, list) {
1454         for (i = 0; i < (at->size / PAGE_SIZE); i++) {
1455             if ((!at->alloc_type_contiguous &&
1456                         (address == (NvU64)(NvUPtr)at->pte_array[i]))
1457                   || (address == (NvU64)(NvUPtr)at->pte_array[0] + (i * PAGE_SIZE))) {
1458                 linear = at->address + (i * PAGE_SIZE);
1459                 return NV_VM_TO_MMAP_OFFSET(linear + offset);
1460             }
1461         }
1462     }
1463
1464     return 0;
1465 }
1466
1467
1468 NvU64 NV_API_CALL nv_get_kern_phys_address(NvU64 address)
1469 {
1470     vm_offset_t va = (vm_offset_t) address;
1471
1472 #if defined(NVCPU_X86_64)
1473     if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS)
1474         return DMAP_TO_PHYS(va);
1475 #endif
1476
1477     if (va < VM_MIN_KERNEL_ADDRESS) {
1478         os_dbg_breakpoint();
1479         return 0;
1480     }
1481
1482     return vtophys(va);
1483 }
1484
1485 NvU64 NV_API_CALL nv_get_user_phys_address(NvU64 address)
1486 {
1487     struct vmspace *vm;
1488     vm_offset_t va = (vm_offset_t) address;
1489
1490     if (va >= VM_MIN_KERNEL_ADDRESS) {
1491         os_dbg_breakpoint();
1492         return 0;
1493     }
1494
1495     /* if (vm_fault_quick((caddr_t) va, VM_PROT_WRITE))
1496         return 0; */
1497
1498     vm = curproc->p_vmspace;
1499     return pmap_extract(vmspace_pmap(vm), va);
1500 }
1501
1502
1503 int nvidia_mmap_dev(
1504     struct nvidia_softc *sc,
1505     vm_offset_t offset,
1506     vm_offset_t *physical
1507 )
1508 {
1509     struct nvidia_alloc *at;
1510     nv_state_t *nv = sc->nv_state;
1511     nv_stack_t *sp;
1512
1513     sp = sc->api_sp;
1514
1515     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, TRUE);
1516
1517     /*
1518      * Offsets that fall into the frame buffer, registry or AGP
1519      * apertures are physical addresses and mapped into userspace
1520      * directly.
1521      */
1522     if (IS_FB_OFFSET(nv, offset, PAGE_SIZE) ||
1523             IS_BC_OFFSET(nv, offset, PAGE_SIZE)) {
1524         *physical = offset;
1525         return 0;
1526     }
1527
1528     if (IS_REG_OFFSET(nv, offset, PAGE_SIZE)) {
1529         *physical = offset;
1530         return 0;
1531     }
1532
1533     if (IS_AGP_OFFSET(nv, offset, PAGE_SIZE)) {
1534         *physical = offset;
1535         return 0;
1536     }
1537
1538     offset = NV_MMAP_TO_VM_OFFSET(offset);
1539
1540     SLIST_FOREACH(at, &sc->alloc_list, list) {
1541         if (offset >= at->address &&
1542                 offset < at->address + at->size) {
1543             *physical = vtophys(offset);
1544             return 0;
1545         }
1546     }
1547
1548     return -1;
1549 }
1550
1551 void nvidia_rc_timer(void *data)
1552 {
1553     nv_state_t *nv = data;
1554     struct nvidia_softc *sc = nv->os_state;
1555     nv_stack_t *sp;
1556
1557     sp = sc->timer_sp;
1558
1559     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, TRUE, TRUE, FALSE);
1560
1561     /*
1562      * We need this timer to trigger again one second from
1563      * now, reset the timeout.
1564      */
1565     rm_run_rc_callback(sp, nv);
1566
1567     sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
1568 }
1569
1570 int NV_API_CALL nv_start_rc_timer(
1571     nv_state_t *nv
1572 )
1573 {
1574     struct nvidia_softc *sc = nv->os_state;
1575
1576     if (nv->rc_timer_enabled != 0)
1577         return -EIO;
1578
1579     sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
1580     nv->rc_timer_enabled = 1;
1581
1582     return 0;
1583 }
1584
1585 int NV_API_CALL nv_stop_rc_timer(
1586     nv_state_t *nv
1587 )
1588 {
1589     struct nvidia_softc *sc = nv->os_state;
1590
1591     if (nv->rc_timer_enabled == 0)
1592         return -EIO;
1593
1594     untimeout(nvidia_rc_timer, (void *) nv, sc->timer_ch);
1595     nv->rc_timer_enabled = 0;
1596
1597     return 0;
1598 }
1599
1600 void NV_API_CALL nv_set_dma_address_size(
1601     nv_state_t *nv,
1602     U032 phys_addr_bits
1603 )
1604 {
1605 }
1606
1607 void* NV_API_CALL nv_get_adapter_state(
1608     U016 bus,
1609     U016 slot
1610 )
1611 {
1612     unsigned int i;
1613     struct nvidia_softc *sc;
1614     nv_state_t *nv;
1615
1616     for (i = 0; i < NV_MAX_DEVICES; i++) {
1617         sc = devclass_get_softc(nvidia_devclass, i);
1618         if (!sc)
1619             continue;
1620         nv = sc->nv_state;
1621
1622         if (nv->bus == bus && nv->slot == slot)
1623             return (void *) nv;
1624     }
1625
1626     if (bus == 255 && slot == 255) {
1627         nv = &nvidia_ctl_state;
1628         return (void *) nv;
1629     }
1630
1631     return NULL;
1632 }
1633
1634 void NV_API_CALL nv_verify_pci_config(
1635     nv_state_t *nv,
1636     BOOL check_the_bars
1637 )
1638 {
1639     nv_stack_t *sp;
1640     struct nvidia_softc *sc = nv->os_state;
1641
1642     sp = sc->pci_cfgchk_sp;
1643
1644     NV_PCI_CHECK_CONFIG_SPACE(sp, nv, check_the_bars, FALSE, FALSE);
1645 }
1646
1647 void NV_API_CALL nv_acpi_methods_init(U032 *handlesPresent)
1648 {
1649     *handlesPresent = 0;
1650 }
1651
1652 void NV_API_CALL nv_acpi_methods_uninit(void)
1653 {
1654     return;
1655 }
1656
1657 RM_STATUS NV_API_CALL nv_acpi_method(
1658     U032 acpi_method,
1659     U032 function,
1660     U032 subFunction,
1661     void *inParams,
1662     U016 inParamSize,
1663     U032 *outStatus,
1664     void *outData,
1665     U016 *outDataSize
1666 )
1667 {
1668     return RM_ERR_NOT_SUPPORTED;
1669 }