2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (C) 2010 Nathan Whitehorn
5 * Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/module.h>
33 #include <sys/malloc.h>
35 #include <sys/clock.h>
38 #include <sys/mutex.h>
39 #include <sys/resource.h>
45 #include <machine/bus.h>
46 #include <machine/platform.h>
47 #include <machine/resource.h>
50 #include "ps3-hvcall.h"
54 static void ps3bus_identify(driver_t
*, device_t
);
55 static int ps3bus_probe(device_t
);
56 static int ps3bus_attach(device_t
);
57 static int ps3bus_print_child(device_t dev
, device_t child
);
58 static int ps3bus_read_ivar(device_t bus
, device_t child
, int which
,
60 static struct rman
*ps3bus_get_rman(device_t bus
, int type
, u_int flags
);
61 static struct resource
*ps3bus_alloc_resource(device_t bus
, device_t child
,
62 int type
, int *rid
, rman_res_t start
, rman_res_t end
,
63 rman_res_t count
, u_int flags
);
64 static int ps3bus_map_resource(device_t bus
, device_t child
,
65 struct resource
*r
, struct resource_map_request
*argsp
,
66 struct resource_map
*map
);
67 static int ps3bus_unmap_resource(device_t bus
, device_t child
,
68 struct resource
*r
, struct resource_map
*map
);
69 static bus_dma_tag_t
ps3bus_get_dma_tag(device_t dev
, device_t child
);
70 static int ps3_iommu_map(device_t dev
, bus_dma_segment_t
*segs
, int *nsegs
,
71 bus_addr_t min
, bus_addr_t max
, bus_size_t alignment
,
72 bus_addr_t boundary
, void *cookie
);
73 static int ps3_iommu_unmap(device_t dev
, bus_dma_segment_t
*segs
,
74 int nsegs
, void *cookie
);
75 static int ps3_gettime(device_t dev
, struct timespec
*ts
);
76 static int ps3_settime(device_t dev
, struct timespec
*ts
);
78 struct ps3bus_devinfo
{
86 struct resource_list resources
;
87 bus_dma_tag_t dma_tag
;
90 bus_addr_t dma_base
[4];
93 static MALLOC_DEFINE(M_PS3BUS
, "ps3bus", "PS3 system bus device information");
95 enum ps3bus_irq_type
{
101 enum ps3bus_reg_type
{
106 static device_method_t ps3bus_methods
[] = {
107 /* Device interface */
108 DEVMETHOD(device_identify
, ps3bus_identify
),
109 DEVMETHOD(device_probe
, ps3bus_probe
),
110 DEVMETHOD(device_attach
, ps3bus_attach
),
113 DEVMETHOD(bus_add_child
, bus_generic_add_child
),
114 DEVMETHOD(bus_get_dma_tag
, ps3bus_get_dma_tag
),
115 DEVMETHOD(bus_print_child
, ps3bus_print_child
),
116 DEVMETHOD(bus_read_ivar
, ps3bus_read_ivar
),
117 DEVMETHOD(bus_get_rman
, ps3bus_get_rman
),
118 DEVMETHOD(bus_alloc_resource
, ps3bus_alloc_resource
),
119 DEVMETHOD(bus_adjust_resource
, bus_generic_rman_adjust_resource
),
120 DEVMETHOD(bus_activate_resource
, bus_generic_rman_activate_resource
),
121 DEVMETHOD(bus_deactivate_resource
, bus_generic_rman_deactivate_resource
),
122 DEVMETHOD(bus_map_resource
, ps3bus_map_resource
),
123 DEVMETHOD(bus_unmap_resource
, ps3bus_unmap_resource
),
124 DEVMETHOD(bus_release_resource
, bus_generic_rman_release_resource
),
125 DEVMETHOD(bus_setup_intr
, bus_generic_setup_intr
),
126 DEVMETHOD(bus_teardown_intr
, bus_generic_teardown_intr
),
128 /* IOMMU interface */
129 DEVMETHOD(iommu_map
, ps3_iommu_map
),
130 DEVMETHOD(iommu_unmap
, ps3_iommu_unmap
),
132 /* Clock interface */
133 DEVMETHOD(clock_gettime
, ps3_gettime
),
134 DEVMETHOD(clock_settime
, ps3_settime
),
139 struct ps3bus_softc
{
140 struct rman sc_mem_rman
;
141 struct rman sc_intr_rman
;
142 struct mem_region
*regions
;
146 static driver_t ps3bus_driver
= {
149 sizeof(struct ps3bus_softc
)
152 DRIVER_MODULE(ps3bus
, nexus
, ps3bus_driver
, 0, 0);
155 ps3bus_identify(driver_t
*driver
, device_t parent
)
157 if (strcmp(installed_platform(), "ps3") != 0)
160 if (device_find_child(parent
, "ps3bus", -1) == NULL
)
161 BUS_ADD_CHILD(parent
, 0, "ps3bus", 0);
165 ps3bus_probe(device_t dev
)
167 /* Do not attach to any OF nodes that may be present */
169 device_set_desc(dev
, "Playstation 3 System Bus");
171 return (BUS_PROBE_NOWILDCARD
);
175 ps3bus_resources_init(struct rman
*rm
, int bus_index
, int dev_index
,
176 struct ps3bus_devinfo
*dinfo
)
178 uint64_t irq_type
, irq
, outlet
;
179 uint64_t reg_type
, paddr
, len
;
184 resource_list_init(&dinfo
->resources
);
186 lv1_get_logical_ppe_id(&ppe
);
187 thread
= 32 - fls(mfctrl());
189 /* Scan for interrupts */
190 for (i
= 0; i
< 10; i
++) {
191 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
192 (lv1_repository_string("bus") >> 32) | bus_index
,
193 lv1_repository_string("dev") | dev_index
,
194 lv1_repository_string("intr") | i
, 0, &irq_type
, &irq
);
201 lv1_construct_event_receive_port(&outlet
);
202 lv1_connect_irq_plug_ext(ppe
, thread
, outlet
, outlet
,
204 lv1_connect_interrupt_event_receive_port(dinfo
->bus
,
205 dinfo
->dev
, outlet
, irq
);
209 lv1_construct_io_irq_outlet(irq
, &outlet
);
210 lv1_connect_irq_plug_ext(ppe
, thread
, outlet
, outlet
,
214 printf("Unknown IRQ type %ld for device %d.%d\n",
215 irq_type
, dinfo
->bus
, dinfo
->dev
);
219 resource_list_add(&dinfo
->resources
, SYS_RES_IRQ
, i
,
223 /* Scan for registers */
224 for (i
= 0; i
< 10; i
++) {
225 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
226 (lv1_repository_string("bus") >> 32) | bus_index
,
227 lv1_repository_string("dev") | dev_index
,
228 lv1_repository_string("reg") | i
,
229 lv1_repository_string("type"), ®_type
, &junk
);
234 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
235 (lv1_repository_string("bus") >> 32) | bus_index
,
236 lv1_repository_string("dev") | dev_index
,
237 lv1_repository_string("reg") | i
,
238 lv1_repository_string("data"), &paddr
, &len
);
240 result
= lv1_map_device_mmio_region(dinfo
->bus
, dinfo
->dev
,
241 paddr
, len
, 12 /* log_2(4 KB) */, &paddr
);
244 printf("Mapping registers failed for device "
245 "%d.%d (%ld.%ld): %d\n", dinfo
->bus
, dinfo
->dev
,
246 dinfo
->bustype
, dinfo
->devtype
, result
);
250 rman_manage_region(rm
, paddr
, paddr
+ len
- 1);
251 resource_list_add(&dinfo
->resources
, SYS_RES_MEMORY
, i
,
252 paddr
, paddr
+ len
, len
);
257 ps3bus_resources_init_by_type(struct rman
*rm
, int bus_index
, int dev_index
,
258 uint64_t irq_type
, uint64_t reg_type
, struct ps3bus_devinfo
*dinfo
)
260 uint64_t _irq_type
, irq
, outlet
;
261 uint64_t _reg_type
, paddr
, len
;
266 resource_list_init(&dinfo
->resources
);
268 lv1_get_logical_ppe_id(&ppe
);
269 thread
= 32 - fls(mfctrl());
271 /* Scan for interrupts */
272 for (i
= 0; i
< 10; i
++) {
273 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
274 (lv1_repository_string("bus") >> 32) | bus_index
,
275 lv1_repository_string("dev") | dev_index
,
276 lv1_repository_string("intr") | i
, 0, &_irq_type
, &irq
);
281 if (_irq_type
!= irq_type
)
284 lv1_construct_io_irq_outlet(irq
, &outlet
);
285 lv1_connect_irq_plug_ext(ppe
, thread
, outlet
, outlet
,
287 resource_list_add(&dinfo
->resources
, SYS_RES_IRQ
, i
,
291 /* Scan for registers */
292 for (i
= 0; i
< 10; i
++) {
293 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
294 (lv1_repository_string("bus") >> 32) | bus_index
,
295 lv1_repository_string("dev") | dev_index
,
296 lv1_repository_string("reg") | i
,
297 lv1_repository_string("type"), &_reg_type
, &junk
);
302 if (_reg_type
!= reg_type
)
305 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
306 (lv1_repository_string("bus") >> 32) | bus_index
,
307 lv1_repository_string("dev") | dev_index
,
308 lv1_repository_string("reg") | i
,
309 lv1_repository_string("data"), &paddr
, &len
);
311 result
= lv1_map_device_mmio_region(dinfo
->bus
, dinfo
->dev
,
312 paddr
, len
, 12 /* log_2(4 KB) */, &paddr
);
315 printf("Mapping registers failed for device "
316 "%d.%d (%ld.%ld): %d\n", dinfo
->bus
, dinfo
->dev
,
317 dinfo
->bustype
, dinfo
->devtype
, result
);
321 rman_manage_region(rm
, paddr
, paddr
+ len
- 1);
322 resource_list_add(&dinfo
->resources
, SYS_RES_MEMORY
, i
,
323 paddr
, paddr
+ len
, len
);
328 ps3bus_attach(device_t self
)
330 struct ps3bus_softc
*sc
;
331 struct ps3bus_devinfo
*dinfo
;
332 int bus_index
, dev_index
, result
;
333 uint64_t bustype
, bus
, devs
;
334 uint64_t dev
, devtype
;
338 sc
= device_get_softc(self
);
339 sc
->sc_mem_rman
.rm_type
= RMAN_ARRAY
;
340 sc
->sc_mem_rman
.rm_descr
= "PS3Bus Memory Mapped I/O";
341 sc
->sc_intr_rman
.rm_type
= RMAN_ARRAY
;
342 sc
->sc_intr_rman
.rm_descr
= "PS3Bus Interrupts";
343 rman_init(&sc
->sc_mem_rman
);
344 rman_init(&sc
->sc_intr_rman
);
345 rman_manage_region(&sc
->sc_intr_rman
, 0, ~0);
347 /* Get memory regions for DMA */
348 mem_regions(&sc
->regions
, &sc
->rcount
, NULL
, NULL
);
351 * Probe all the PS3's buses.
354 for (bus_index
= 0; bus_index
< 5; bus_index
++) {
355 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
356 (lv1_repository_string("bus") >> 32) | bus_index
,
357 lv1_repository_string("type"), 0, 0, &bustype
, &junk
);
362 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
363 (lv1_repository_string("bus") >> 32) | bus_index
,
364 lv1_repository_string("id"), 0, 0, &bus
, &junk
);
369 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
370 (lv1_repository_string("bus") >> 32) | bus_index
,
371 lv1_repository_string("num_dev"), 0, 0, &devs
, &junk
);
373 for (dev_index
= 0; dev_index
< devs
; dev_index
++) {
374 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
375 (lv1_repository_string("bus") >> 32) | bus_index
,
376 lv1_repository_string("dev") | dev_index
,
377 lv1_repository_string("type"), 0, &devtype
, &junk
);
382 result
= lv1_get_repository_node_value(PS3_LPAR_ID_PME
,
383 (lv1_repository_string("bus") >> 32) | bus_index
,
384 lv1_repository_string("dev") | dev_index
,
385 lv1_repository_string("id"), 0, &dev
, &junk
);
391 case PS3_DEVTYPE_USB
:
392 /* USB device has OHCI and EHCI USB host controllers */
394 lv1_open_device(bus
, dev
, 0);
396 /* OHCI host controller */
398 dinfo
= malloc(sizeof(*dinfo
), M_PS3BUS
,
403 dinfo
->bustype
= bustype
;
404 dinfo
->devtype
= devtype
;
405 dinfo
->busidx
= bus_index
;
406 dinfo
->devidx
= dev_index
;
408 ps3bus_resources_init_by_type(&sc
->sc_mem_rman
, bus_index
,
409 dev_index
, OHCI_IRQ
, OHCI_REG
, dinfo
);
411 cdev
= device_add_child(self
, "ohci", DEVICE_UNIT_ANY
);
414 "device_add_child failed\n");
415 free(dinfo
, M_PS3BUS
);
419 mtx_init(&dinfo
->iommu_mtx
, "iommu", NULL
, MTX_DEF
);
420 device_set_ivars(cdev
, dinfo
);
422 /* EHCI host controller */
424 dinfo
= malloc(sizeof(*dinfo
), M_PS3BUS
,
429 dinfo
->bustype
= bustype
;
430 dinfo
->devtype
= devtype
;
431 dinfo
->busidx
= bus_index
;
432 dinfo
->devidx
= dev_index
;
434 ps3bus_resources_init_by_type(&sc
->sc_mem_rman
, bus_index
,
435 dev_index
, EHCI_IRQ
, EHCI_REG
, dinfo
);
437 cdev
= device_add_child(self
, "ehci", DEVICE_UNIT_ANY
);
440 "device_add_child failed\n");
441 free(dinfo
, M_PS3BUS
);
445 mtx_init(&dinfo
->iommu_mtx
, "iommu", NULL
, MTX_DEF
);
446 device_set_ivars(cdev
, dinfo
);
449 dinfo
= malloc(sizeof(*dinfo
), M_PS3BUS
,
454 dinfo
->bustype
= bustype
;
455 dinfo
->devtype
= devtype
;
456 dinfo
->busidx
= bus_index
;
457 dinfo
->devidx
= dev_index
;
459 if (dinfo
->bustype
== PS3_BUSTYPE_SYSBUS
||
460 dinfo
->bustype
== PS3_BUSTYPE_STORAGE
)
461 lv1_open_device(bus
, dev
, 0);
463 ps3bus_resources_init(&sc
->sc_mem_rman
, bus_index
,
466 cdev
= device_add_child(self
, NULL
, DEVICE_UNIT_ANY
);
469 "device_add_child failed\n");
470 free(dinfo
, M_PS3BUS
);
474 mtx_init(&dinfo
->iommu_mtx
, "iommu", NULL
, MTX_DEF
);
475 device_set_ivars(cdev
, dinfo
);
480 clock_register(self
, 1000);
482 bus_attach_children(self
);
487 ps3bus_print_child(device_t dev
, device_t child
)
489 struct ps3bus_devinfo
*dinfo
= device_get_ivars(child
);
492 retval
+= bus_print_child_header(dev
, child
);
493 retval
+= resource_list_print_type(&dinfo
->resources
, "mem",
494 SYS_RES_MEMORY
, "%#jx");
495 retval
+= resource_list_print_type(&dinfo
->resources
, "irq",
498 retval
+= bus_print_child_footer(dev
, child
);
504 ps3bus_read_ivar(device_t bus
, device_t child
, int which
, uintptr_t *result
)
506 struct ps3bus_devinfo
*dinfo
= device_get_ivars(child
);
509 case PS3BUS_IVAR_BUS
:
510 *result
= dinfo
->bus
;
512 case PS3BUS_IVAR_DEVICE
:
513 *result
= dinfo
->dev
;
515 case PS3BUS_IVAR_BUSTYPE
:
516 *result
= dinfo
->bustype
;
518 case PS3BUS_IVAR_DEVTYPE
:
519 *result
= dinfo
->devtype
;
521 case PS3BUS_IVAR_BUSIDX
:
522 *result
= dinfo
->busidx
;
524 case PS3BUS_IVAR_DEVIDX
:
525 *result
= dinfo
->devidx
;
535 ps3bus_get_rman(device_t bus
, int type
, u_int flags
)
537 struct ps3bus_softc
*sc
;
539 sc
= device_get_softc(bus
);
542 return (&sc
->sc_mem_rman
);
544 return (&sc
->sc_intr_rman
);
550 static struct resource
*
551 ps3bus_alloc_resource(device_t bus
, device_t child
, int type
, int *rid
,
552 rman_res_t start
, rman_res_t end
, rman_res_t count
, u_int flags
)
554 struct ps3bus_devinfo
*dinfo
;
555 rman_res_t adjstart
, adjend
, adjcount
;
556 struct resource_list_entry
*rle
;
558 dinfo
= device_get_ivars(child
);
562 rle
= resource_list_find(&dinfo
->resources
, SYS_RES_MEMORY
,
565 device_printf(bus
, "no rle for %s memory %d\n",
566 device_get_nameunit(child
), *rid
);
570 if (start
< rle
->start
)
571 adjstart
= rle
->start
;
572 else if (start
> rle
->end
)
577 if (end
< rle
->start
)
579 else if (end
> rle
->end
)
584 adjcount
= adjend
- adjstart
;
587 rle
= resource_list_find(&dinfo
->resources
, SYS_RES_IRQ
,
589 adjstart
= rle
->start
;
590 adjcount
= ulmax(count
, rle
->count
);
591 adjend
= ulmax(rle
->end
, rle
->start
+ adjcount
- 1);
594 device_printf(bus
, "unknown resource request from %s\n",
595 device_get_nameunit(child
));
599 return (bus_generic_rman_alloc_resource(bus
, child
, type
, rid
, adjstart
,
600 adjend
, adjcount
, flags
));
604 ps3bus_map_resource(device_t bus
, device_t child
, struct resource
*r
,
605 struct resource_map_request
*argsp
, struct resource_map
*map
)
607 struct resource_map_request args
;
608 rman_res_t length
, start
;
611 /* Resources must be active to be mapped. */
612 if (!(rman_get_flags(r
) & RF_ACTIVE
))
615 /* Mappings are only supported on memory resources. */
616 switch (rman_get_type(r
)) {
623 resource_init_map_request(&args
);
624 error
= resource_validate_map_request(r
, argsp
, &args
, &start
, &length
);
629 printf("ps3 mapdev: start %jx, len %jd\n", start
, length
);
631 map
->r_vaddr
= pmap_mapdev_attr(start
, length
, args
.memattr
);
632 if (map
->r_vaddr
== NULL
)
634 map
->r_bustag
= &bs_be_tag
;
635 map
->r_bushandle
= (vm_offset_t
)map
->r_vaddr
;
636 map
->r_size
= length
;
641 ps3bus_unmap_resource(device_t bus
, device_t child
, struct resource
*r
,
642 struct resource_map
*map
)
645 switch (rman_get_type(r
)) {
647 pmap_unmapdev(map
->r_vaddr
, map
->r_size
);
655 ps3bus_get_dma_tag(device_t dev
, device_t child
)
657 struct ps3bus_devinfo
*dinfo
= device_get_ivars(child
);
658 struct ps3bus_softc
*sc
= device_get_softc(dev
);
659 int i
, err
, flags
, pagesize
;
661 if (dinfo
->bustype
!= PS3_BUSTYPE_SYSBUS
&&
662 dinfo
->bustype
!= PS3_BUSTYPE_STORAGE
)
663 return (bus_get_dma_tag(dev
));
665 mtx_lock(&dinfo
->iommu_mtx
);
666 if (dinfo
->dma_tag
!= NULL
) {
667 mtx_unlock(&dinfo
->iommu_mtx
);
668 return (dinfo
->dma_tag
);
671 flags
= 0; /* 32-bit mode */
672 if (dinfo
->bustype
== PS3_BUSTYPE_SYSBUS
&&
673 dinfo
->devtype
== PS3_DEVTYPE_USB
)
674 flags
= 2; /* 8-bit mode */
676 pagesize
= 24; /* log_2(16 MB) */
677 if (dinfo
->bustype
== PS3_BUSTYPE_STORAGE
)
678 pagesize
= 12; /* 4 KB */
680 for (i
= 0; i
< sc
->rcount
; i
++) {
681 err
= lv1_allocate_device_dma_region(dinfo
->bus
, dinfo
->dev
,
682 sc
->regions
[i
].mr_size
, pagesize
, flags
,
683 &dinfo
->dma_base
[i
]);
686 "could not allocate DMA region %d: %d\n", i
, err
);
690 err
= lv1_map_device_dma_region(dinfo
->bus
, dinfo
->dev
,
691 sc
->regions
[i
].mr_start
, dinfo
->dma_base
[i
],
692 sc
->regions
[i
].mr_size
,
693 0xf800000000000800UL
/* Cell Handbook Figure 7.3.4.1 */);
696 "could not map DMA region %d: %d\n", i
, err
);
701 err
= bus_dma_tag_create(bus_get_dma_tag(dev
),
702 1, 0, BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
703 NULL
, NULL
, BUS_SPACE_MAXSIZE
, 0, BUS_SPACE_MAXSIZE
,
704 0, NULL
, NULL
, &dinfo
->dma_tag
);
707 * Note: storage devices have IOMMU mappings set up by the hypervisor,
708 * but use physical, non-translated addresses. The above IOMMU
709 * initialization is necessary for the hypervisor to be able to set up
710 * the mappings, but actual DMA mappings should not use the IOMMU
713 if (dinfo
->bustype
!= PS3_BUSTYPE_STORAGE
)
714 bus_dma_tag_set_iommu(dinfo
->dma_tag
, dev
, dinfo
);
717 mtx_unlock(&dinfo
->iommu_mtx
);
722 return (dinfo
->dma_tag
);
726 ps3_iommu_map(device_t dev
, bus_dma_segment_t
*segs
, int *nsegs
,
727 bus_addr_t min
, bus_addr_t max
, bus_size_t alignment
, bus_addr_t boundary
,
730 struct ps3bus_devinfo
*dinfo
= cookie
;
731 struct ps3bus_softc
*sc
= device_get_softc(dev
);
734 for (i
= 0; i
< *nsegs
; i
++) {
735 for (j
= 0; j
< sc
->rcount
; j
++) {
736 if (segs
[i
].ds_addr
>= sc
->regions
[j
].mr_start
&&
737 segs
[i
].ds_addr
< sc
->regions
[j
].mr_start
+
738 sc
->regions
[j
].mr_size
)
741 KASSERT(j
< sc
->rcount
,
742 ("Trying to map address %#lx not in physical memory",
745 segs
[i
].ds_addr
= dinfo
->dma_base
[j
] +
746 (segs
[i
].ds_addr
- sc
->regions
[j
].mr_start
);
753 ps3_iommu_unmap(device_t dev
, bus_dma_segment_t
*segs
, int nsegs
, void *cookie
)
759 #define Y2K 946684800
762 ps3_gettime(device_t dev
, struct timespec
*ts
)
767 result
= lv1_get_rtc(&rtc
, &tb
);
771 ts
->tv_sec
= rtc
+ Y2K
;
777 ps3_settime(device_t dev
, struct timespec
*ts
)