1 /* This file is part of the program psim.
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "device_table.h"
43 PHB implements a model of the PCI-host bridge described in the PPCP
46 For bridge devices, Open Firmware specifies that the <<ranges>>
47 property be used to specify the mapping of address spaces between a
48 bridges parent and child busses. This PHB model configures itsself
49 according to the information specified in its ranges property. The
50 <<ranges>> property is described in detail in the Open Firmware
53 For DMA transfers, any access to a PCI address space which falls
54 outside of the mapped memory space is assumed to be a transfer
55 intended for the parent bus.
61 ranges = <my-phys-addr> <parent-phys-addr> <my-size> ... (required)
63 Define a number of mappings from the parent bus to one of this
64 devices PCI busses. The exact format of the <<parent-phys-addr>>
65 is parent bus dependant. The format of <<my-phys-addr>> is
66 described in the Open Firmware PCI bindings document (note that the
67 address must be non-relocatable).
70 #address-cells = 3 (required)
72 Number of cells used by an Open Firmware PCI address. This
73 property must be defined before specifying the <<ranges>> property.
76 #size-cells = 2 (required)
78 Number of cells used by an Open Firmware PCI size. This property
79 must be defined before specifying the <<ranges>> property.
91 Since device tree entries that are specified on the command line
92 are added before most of the device tree has been built it is often
93 necessary to explictly add certain device properties and thus
94 ensure they are already present in the device tree. For the
95 <<phb>> one such property is parent busses <<#address-cells>>.
97 | -o '/#address-cells 1' \
100 Create the PHB remembering to include the cell size properties:
102 | -o '/phb@0x80000000/#address-cells 3' \
103 | -o '/phb@0x80000000/#size-cells 2' \
106 Specify that the memory address range <<0x80000000>> to
107 <<0x8fffffff>> should map directly onto the PCI memory address
108 space while the processor address range <<0xc0000000>> to
109 <<0xc000ffff>> should map onto the PCI I/O address range starting
112 | -o '/phb@0x80000000/ranges \
113 | nm0,0,0,80000000 0x80000000 0x10000000 \
114 | ni0,0,0,0 0xc0000000 0x10000' \
117 Insert a 4k <<nvram>> into slot zero of the PCI bus. Have it
118 directly accessible in both the I/O (address <<0x100>>) and memory
119 (address 0x80001000) spaces:
121 | -o '/phb@0x80000000/nvram@0/assigned-addresses \
122 | nm0,0,10,80001000 4096 \
124 | -o '/phb@0x80000000/nvram@0/reg \
127 | -o '/phb@0x80000000/nvram@0/alternate-reg \
131 The <<assigned-address>> property corresponding to what (if it were
132 implemented) be found in the config base registers while the
133 <<reg>> and <<alternative-reg>> properties indicating the location
134 of registers within each address space.
136 Of the possible addresses, only the non-relocatable versions are
137 used when attaching the device to the bus.
143 The implementation of the PCI configuration space is left as an
144 exercise for the reader. Such a restriction should only impact on
145 systems wanting to dynamically configure devices on the PCI bus.
147 The <<CHRP>> document specfies additional (optional) functionality
148 of the primary PHB. The implementation of such functionality is
149 left as an exercise for the reader.
151 The Open Firmware PCI bus bindings document (rev 1.6 and 2.0) is
152 unclear on the value of the "ss" bits for a 64bit memory address.
153 The correct value, as used by this module, is 0b11.
155 The Open Firmware PCI bus bindings document (rev 1.6) suggests that
156 the register field of non-relocatable PCI address should be zero.
157 Unfortunatly, PCI addresses specified in the <<assigned-addresses>>
158 property must be both non-relocatable and have non-zero register
161 The unit-decode method is not inserting a bus number into any
162 address that it decodes. Instead the bus-number is left as zero.
164 Support for aliased memory and I/O addresses is left as an exercise
167 Support for interrupt-ack and special cycles are left as an
168 exercise for the reader. One issue to consider when attempting
169 this exercise is how to specify the address of the int-ack and
170 special cycle register. Hint: <</8259-interrupt-ackowledge>> is
173 Children of this node can only use the client callback interface
174 when attaching themselves to the <<phb>>.
180 http://playground.sun.com/1275/home.html#OFDbusPCI
186 typedef struct _phb_space
{
190 unsigned_word parent_base
;
192 unsigned_word my_base
;
198 typedef struct _hw_phb_device
{
199 phb_space space
[nr_hw_phb_spaces
];
204 hw_phb_decode_name(hw_phb_decode level
)
207 case hw_phb_normal_decode
: return "normal";
208 case hw_phb_subtractive_decode
: return "subtractive";
209 case hw_phb_master_abort_decode
: return "master-abort";
210 default: return "invalid decode";
216 hw_phb_init_address(device
*me
)
218 hw_phb_device
*phb
= device_data(me
);
220 /* check some basic properties */
221 if (device_nr_address_cells(me
) != 3)
222 device_error(me
, "incorrect #address-cells");
223 if (device_nr_size_cells(me
) != 2)
224 device_error(me
, "incorrect #size-cells");
226 /* (re) initialize each PCI space */
228 hw_phb_spaces space_nr
;
229 for (space_nr
= 0; space_nr
< nr_hw_phb_spaces
; space_nr
++) {
230 phb_space
*pci_space
= &phb
->space
[space_nr
];
231 core_init(pci_space
->map
);
236 /* decode each of the ranges properties entering the information
237 into the space table */
239 range_property_spec range
;
242 for (ranges_entry
= 0;
243 device_find_range_array_property(me
, "ranges", ranges_entry
,
247 unsigned_word my_attach_address
;
248 int parent_attach_space
;
249 unsigned_word parent_attach_address
;
251 phb_space
*pci_space
;
252 /* convert the addresses into something meaningful */
253 device_address_to_attach_address(me
, &range
.child_address
,
257 device_address_to_attach_address(device_parent(me
),
258 &range
.parent_address
,
259 &parent_attach_space
,
260 &parent_attach_address
,
262 device_size_to_attach_size(me
, &range
.size
, &size
, me
);
263 if (my_attach_space
< 0 || my_attach_space
>= nr_hw_phb_spaces
)
264 device_error(me
, "ranges property contains an invalid address space");
265 pci_space
= &phb
->space
[my_attach_space
];
266 if (pci_space
->size
!= 0)
267 device_error(me
, "ranges property contains duplicate mappings for %s address space",
269 pci_space
->parent_base
= parent_attach_address
;
270 pci_space
->parent_space
= parent_attach_space
;
271 pci_space
->my_base
= my_attach_address
;
272 pci_space
->my_space
= my_attach_space
;
273 pci_space
->size
= size
;
274 device_attach_address(device_parent(me
),
276 parent_attach_space
, parent_attach_address
, size
,
277 access_read_write_exec
,
279 DTRACE(phb
, ("map %d:0x%lx to %s:0x%lx (0x%lx bytes)\n",
280 (int)parent_attach_space
,
281 (unsigned long)parent_attach_address
,
283 (unsigned long)my_attach_address
,
284 (unsigned long)size
));
287 if (ranges_entry
== 0) {
288 device_error(me
, "Missing or empty ranges property");
296 hw_phb_attach_address(device
*me
,
302 device
*client
) /*callback/default*/
304 hw_phb_device
*phb
= device_data(me
);
305 phb_space
*pci_space
;
307 if (space
< 0 || space
>= nr_hw_phb_spaces
)
308 device_error(me
, "attach space (%d) specified by %s invalid",
309 space
, device_path(client
));
310 pci_space
= &phb
->space
[space
];
311 if (addr
+ nr_bytes
> pci_space
->my_base
+ pci_space
->size
312 || addr
< pci_space
->my_base
)
313 device_error(me
, "attach addr (0x%lx) specified by %s outside of bus address range",
314 (unsigned long)addr
, device_path(client
));
315 if (type
!= hw_phb_normal_decode
316 && type
!= hw_phb_subtractive_decode
)
317 device_error(me
, "attach type (%d) specified by %s invalid",
318 type
, device_path(client
));
319 /* attach it to the relevent bus */
320 DTRACE(phb
, ("attach %s - %s %s:0x%lx (0x%lx bytes)\n",
322 hw_phb_decode_name(type
),
325 (unsigned long)nr_bytes
));
326 core_attach(pci_space
->map
,
336 /* Extract/set various fields from a PCI unit address.
338 Note: only the least significant 32 bits of each cell is used.
340 Note: for PPC MSB is 0 while for PCI it is 31. */
343 /* relocatable bit n */
346 extract_n(const device_unit
*address
)
348 return EXTRACTED32(address
->cells
[0], 0, 0);
352 set_n(device_unit
*address
)
354 BLIT32(address
->cells
[0], 0, 1);
358 /* prefetchable bit p */
361 extract_p(const device_unit
*address
)
363 ASSERT(address
->nr_cells
== 3);
364 return EXTRACTED32(address
->cells
[0], 1, 1);
368 set_p(device_unit
*address
)
370 BLIT32(address
->cells
[0], 1, 1);
377 extract_t(const device_unit
*address
)
379 ASSERT(address
->nr_cells
== 3);
380 return EXTRACTED32(address
->cells
[0], 2, 2);
384 set_t(device_unit
*address
)
386 BLIT32(address
->cells
[0], 2, 1);
395 ss_32bit_memory_code
= 2,
396 ss_64bit_memory_code
= 3,
400 extract_ss(const device_unit
*address
)
402 ASSERT(address
->nr_cells
== 3);
403 return EXTRACTED32(address
->cells
[0], 6, 7);
407 set_ss(device_unit
*address
, ss_type val
)
409 MBLIT32(address
->cells
[0], 6, 7, val
);
413 /* bus number bbbbbbbb */
417 extract_bbbbbbbb(const device_unit
*address
)
419 ASSERT(address
->nr_cells
== 3);
420 return EXTRACTED32(address
->cells
[0], 8, 15);
426 set_bbbbbbbb(device_unit
*address
, unsigned val
)
428 MBLIT32(address
->cells
[0], 8, 15, val
);
433 /* device number ddddd */
436 extract_ddddd(const device_unit
*address
)
438 ASSERT(address
->nr_cells
== 3);
439 return EXTRACTED32(address
->cells
[0], 16, 20);
443 set_ddddd(device_unit
*address
, unsigned val
)
445 MBLIT32(address
->cells
[0], 16, 20, val
);
449 /* function number fff */
452 extract_fff(const device_unit
*address
)
454 ASSERT(address
->nr_cells
== 3);
455 return EXTRACTED32(address
->cells
[0], 21, 23);
459 set_fff(device_unit
*address
, unsigned val
)
461 MBLIT32(address
->cells
[0], 21, 23, val
);
465 /* register number rrrrrrrr */
468 extract_rrrrrrrr(const device_unit
*address
)
470 ASSERT(address
->nr_cells
== 3);
471 return EXTRACTED32(address
->cells
[0], 24, 31);
475 set_rrrrrrrr(device_unit
*address
, unsigned val
)
477 MBLIT32(address
->cells
[0], 24, 31, val
);
481 /* MSW of 64bit address hh..hh */
484 extract_hh_hh(const device_unit
*address
)
486 ASSERT(address
->nr_cells
== 3);
487 return address
->cells
[1];
491 set_hh_hh(device_unit
*address
, unsigned val
)
493 address
->cells
[2] = val
;
497 /* LSW of 64bit address ll..ll */
500 extract_ll_ll(const device_unit
*address
)
502 ASSERT(address
->nr_cells
== 3);
503 return address
->cells
[2];
507 set_ll_ll(device_unit
*address
, unsigned val
)
509 address
->cells
[2] = val
;
513 /* Convert PCI textual bus address into a device unit */
516 hw_phb_unit_decode(device
*me
,
518 device_unit
*address
)
521 const char *chp
= unit
;
524 if (device_nr_address_cells(me
) != 3)
525 device_error(me
, "PCI bus should have #address-cells == 3");
526 memset(address
, 0, sizeof(*address
));
531 address
->nr_cells
= 3;
533 if (isxdigit(*chp
)) {
534 set_ss(address
, ss_config_code
);
538 /* non-relocatable? */
546 set_ss(address
, ss_io_code
);
549 else if (*chp
== 'm') {
550 set_ss(address
, ss_32bit_memory_code
);
553 else if (*chp
== 'x') {
554 set_ss(address
, ss_64bit_memory_code
);
558 device_error(me
, "Problem parsing PCI address %s", unit
);
562 if (extract_ss(address
) == ss_64bit_memory_code
)
563 device_error(me
, "Invalid alias bit in PCI address %s", unit
);
570 if (extract_ss(address
) != ss_32bit_memory_code
)
571 device_error(me
, "Invalid prefetchable bit (p) in PCI address %s",
581 device_error(me
, "Missing device number in PCI address %s", unit
);
582 val
= strtoul(chp
, &end
, 16);
584 device_error(me
, "Problem parsing device number in PCI address %s", unit
);
585 if ((val
& 0x1f) != val
)
586 device_error(me
, "Device number (0x%lx) out of range (0..0x1f) in PCI address %s",
588 set_ddddd(address
, val
);
591 /* For config space, the F is optional */
592 if (extract_ss(address
) == ss_config_code
593 && (isspace(*chp
) || *chp
== '\0'))
596 /* function number F */
598 device_error(me
, "Missing function number in PCI address %s", unit
);
600 val
= strtoul(chp
, &end
, 10);
602 device_error(me
, "Problem parsing function number in PCI address %s",
604 if ((val
& 7) != val
)
605 device_error(me
, "Function number (%ld) out of range (0..7) in PCI address %s",
607 set_fff(address
, val
);
610 /* for config space, must be end */
611 if (extract_ss(address
) == ss_config_code
) {
612 if (!isspace(*chp
) && *chp
!= '\0')
613 device_error(me
, "Problem parsing PCI config address %s",
618 /* register number RR */
620 device_error(me
, "Missing register number in PCI address %s", unit
);
622 val
= strtoul(chp
, &end
, 16);
624 device_error(me
, "Problem parsing register number in PCI address %s",
626 switch (extract_ss(address
)) {
629 if (extract_n(address
) && val
!= 0)
630 device_error(me
, "non-relocatable I/O register must be zero in PCI address %s", unit
);
631 else if (!extract_n(address
)
632 && val
!= 0x10 && val
!= 0x14 && val
!= 0x18
633 && val
!= 0x1c && val
!= 0x20 && val
!= 0x24)
634 device_error(me
, "I/O register invalid in PCI address %s", unit
);
637 case ss_32bit_memory_code
:
639 if (extract_n(address
) && val
!= 0)
640 device_error(me
, "non-relocatable memory register must be zero in PCI address %s", unit
);
641 else if (!extract_n(address
)
642 && val
!= 0x10 && val
!= 0x14 && val
!= 0x18
643 && val
!= 0x1c && val
!= 0x20 && val
!= 0x24 && val
!= 0x30)
644 device_error(me
, "I/O register (0x%lx) invalid in PCI address %s",
648 case ss_64bit_memory_code
:
649 if (extract_n(address
) && val
!= 0)
650 device_error(me
, "non-relocatable 32bit memory register must be zero in PCI address %s", unit
);
651 else if (!extract_n(address
)
652 && val
!= 0x10 && val
!= 0x18 && val
!= 0x20)
653 device_error(me
, "Register number (0x%lx) invalid in 64bit PCI address %s",
656 device_error(me
, "internal error");
658 if ((val
& 0xff) != val
)
659 device_error(me
, "Register number (0x%lx) out of range (0..0xff) in PCI address %s",
661 set_rrrrrrrr(address
, val
);
666 device_error(me
, "Missing address in PCI address %s", unit
);
668 switch (extract_ss(address
)) {
670 case ss_32bit_memory_code
:
671 val
= strtoul(chp
, &end
, 16);
673 device_error(me
, "Problem parsing address in PCI address %s", unit
);
674 switch (extract_ss(address
)) {
676 if (extract_n(address
) && extract_t(address
)
677 && (val
& 1024) != val
)
678 device_error(me
, "10bit aliased non-relocatable address (0x%lx) out of range in PCI address %s",
680 if (!extract_n(address
) && extract_t(address
)
681 && (val
& 0xffff) != val
)
682 device_error(me
, "64k relocatable address (0x%lx) out of range in PCI address %s",
685 case ss_32bit_memory_code
:
686 if (extract_t(address
) && (val
& 0xfffff) != val
)
687 device_error(me
, "1mb memory address (0x%lx) out of range in PCI address %s",
689 if (!extract_t(address
) && (val
& 0xffffffff) != val
)
690 device_error(me
, "32bit memory address (0x%lx) out of range in PCI address %s",
693 case ss_64bit_memory_code
:
695 device_error(me
, "internal error");
697 set_ll_ll(address
, val
);
700 case ss_64bit_memory_code
:
701 device_error(me
, "64bit addresses unimplemented");
702 set_hh_hh(address
, val
);
703 set_ll_ll(address
, val
);
706 device_error(me
, "internal error");
711 if (!isspace(*chp
) && *chp
!= '\0')
712 device_error(me
, "Problem parsing PCI address %s", unit
);
718 /* Convert PCI device unit into its corresponding textual
722 hw_phb_unit_encode(device
*me
,
723 const device_unit
*unit_address
,
727 if (unit_address
->nr_cells
!= 3)
728 device_error(me
, "Incorrect number of cells in PCI unit address");
729 if (device_nr_address_cells(me
) != 3)
730 device_error(me
, "PCI bus should have #address-cells == 3");
731 if (extract_ss(unit_address
) == ss_config_code
732 && extract_fff(unit_address
) == 0
733 && extract_rrrrrrrr(unit_address
) == 0
734 && extract_hh_hh(unit_address
) == 0
735 && extract_ll_ll(unit_address
) == 0) {
736 /* DD - Configuration Space address */
738 extract_ddddd(unit_address
));
740 else if (extract_ss(unit_address
) == ss_config_code
741 && extract_fff(unit_address
) != 0
742 && extract_rrrrrrrr(unit_address
) == 0
743 && extract_hh_hh(unit_address
) == 0
744 && extract_ll_ll(unit_address
) == 0) {
745 /* DD,F - Configuration Space */
746 sprintf(buf
, "%x,%d",
747 extract_ddddd(unit_address
),
748 extract_fff(unit_address
));
750 else if (extract_ss(unit_address
) == ss_io_code
751 && extract_hh_hh(unit_address
) == 0) {
752 /* [n]i[t]DD,F,RR,NNNNNNNN - 32bit I/O space */
753 sprintf(buf
, "%si%s%x,%d,%x,%x",
754 extract_n(unit_address
) ? "n" : "",
755 extract_t(unit_address
) ? "t" : "",
756 extract_ddddd(unit_address
),
757 extract_fff(unit_address
),
758 extract_rrrrrrrr(unit_address
),
759 extract_ll_ll(unit_address
));
761 else if (extract_ss(unit_address
) == ss_32bit_memory_code
762 && extract_hh_hh(unit_address
) == 0) {
763 /* [n]m[t][p]DD,F,RR,NNNNNNNN - 32bit memory space */
764 sprintf(buf
, "%sm%s%s%x,%d,%x,%x",
765 extract_n(unit_address
) ? "n" : "",
766 extract_t(unit_address
) ? "t" : "",
767 extract_p(unit_address
) ? "p" : "",
768 extract_ddddd(unit_address
),
769 extract_fff(unit_address
),
770 extract_rrrrrrrr(unit_address
),
771 extract_ll_ll(unit_address
));
773 else if (extract_ss(unit_address
) == ss_32bit_memory_code
) {
774 /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN - 64bit memory space */
775 sprintf(buf
, "%sx%s%x,%d,%x,%x%08x",
776 extract_n(unit_address
) ? "n" : "",
777 extract_p(unit_address
) ? "p" : "",
778 extract_ddddd(unit_address
),
779 extract_fff(unit_address
),
780 extract_rrrrrrrr(unit_address
),
781 extract_hh_hh(unit_address
),
782 extract_ll_ll(unit_address
));
785 device_error(me
, "Invalid PCI unit address 0x%08lx 0x%08lx 0x%08lx",
786 (unsigned long)unit_address
->cells
[0],
787 (unsigned long)unit_address
->cells
[1],
788 (unsigned long)unit_address
->cells
[2]);
790 if (strlen(buf
) > sizeof_buf
)
791 error("buffer overflow");
797 hw_phb_address_to_attach_address(device
*me
,
798 const device_unit
*address
,
800 unsigned_word
*attach_address
,
803 if (address
->nr_cells
!= 3)
804 device_error(me
, "attach address has incorrect number of cells");
805 if (address
->cells
[1] != 0)
806 device_error(me
, "64bit attach address unsupported");
808 /* directly decode the address/space */
809 *attach_address
= address
->cells
[2];
810 switch (extract_ss(address
)) {
812 *attach_space
= hw_phb_config_space
;
815 *attach_space
= hw_phb_io_space
;
817 case ss_32bit_memory_code
:
818 case ss_64bit_memory_code
:
819 *attach_space
= hw_phb_memory_space
;
823 /* if non-relocatable finished */
824 if (extract_n(address
))
827 /* make memory and I/O addresses absolute */
828 if (*attach_space
== hw_phb_io_space
829 || *attach_space
== hw_phb_memory_space
) {
831 reg_property_spec assigned
;
832 if (extract_ss(address
) == ss_64bit_memory_code
)
833 device_error(me
, "64bit memory address not unsuported");
835 device_find_reg_array_property(client
, "assigned-addresses", reg_nr
,
838 if (!extract_n(&assigned
.address
)
839 || extract_rrrrrrrr(&assigned
.address
) == 0)
840 device_error(me
, "client %s has invalid assigned-address property",
841 device_path(client
));
842 if (extract_rrrrrrrr(address
) == extract_rrrrrrrr(&assigned
.address
)) {
843 /* corresponding base register */
844 if (extract_ss(address
) != extract_ss(&assigned
.address
))
845 device_error(me
, "client %s has conflicting types for base register 0x%lx",
847 (unsigned long)extract_rrrrrrrr(address
));
848 *attach_address
+= assigned
.address
.cells
[2];
852 device_error(me
, "client %s missing base address register 0x%lx in assigned-addresses property",
854 (unsigned long)extract_rrrrrrrr(address
));
862 hw_phb_size_to_attach_size(device
*me
,
863 const device_unit
*size
,
867 if (size
->nr_cells
!= 2)
868 device_error(me
, "size has incorrect number of cells");
869 if (size
->cells
[0] != 0)
870 device_error(me
, "64bit size unsupported");
871 *nr_bytes
= size
->cells
[1];
872 return size
->cells
[1];
876 static const phb_space
*
877 find_phb_space(hw_phb_device
*phb
,
882 /* find the space that matches the address */
883 for (space
= 0; space
< nr_hw_phb_spaces
; space
++) {
884 phb_space
*pci_space
= &phb
->space
[space
];
885 if (addr
>= pci_space
->parent_base
886 && (addr
+ nr_bytes
) <= (pci_space
->parent_base
+ pci_space
->size
)) {
895 map_phb_addr(const phb_space
*space
,
898 return addr
- space
->parent_base
+ space
->my_base
;
904 hw_phb_io_read_buffer(device
*me
,
912 hw_phb_device
*phb
= (hw_phb_device
*)device_data(me
);
913 const phb_space
*pci_space
= find_phb_space(phb
, addr
, nr_bytes
);
914 unsigned_word bus_addr
;
915 if (pci_space
== NULL
)
917 bus_addr
= map_phb_addr(pci_space
, addr
);
918 DTRACE(phb
, ("io read - %d:0x%lx -> %s:0x%lx (%u bytes)\n",
919 space
, (unsigned long)addr
, pci_space
->name
, (unsigned long)bus_addr
,
921 return core_map_read_buffer(pci_space
->readable
,
922 dest
, bus_addr
, nr_bytes
);
927 hw_phb_io_write_buffer(device
*me
,
935 hw_phb_device
*phb
= (hw_phb_device
*)device_data(me
);
936 const phb_space
*pci_space
= find_phb_space(phb
, addr
, nr_bytes
);
937 unsigned_word bus_addr
;
938 if (pci_space
== NULL
)
940 bus_addr
= map_phb_addr(pci_space
, addr
);
941 DTRACE(phb
, ("io write - %d:0x%lx -> %s:0x%lx (%u bytes)\n",
942 space
, (unsigned long)addr
, pci_space
->name
, (unsigned long)bus_addr
,
944 return core_map_write_buffer(pci_space
->writeable
, source
,
950 hw_phb_dma_read_buffer(device
*me
,
956 hw_phb_device
*phb
= (hw_phb_device
*)device_data(me
);
957 const phb_space
*pci_space
;
959 if (space
!= hw_phb_memory_space
)
960 device_error(me
, "invalid dma address space %d", space
);
961 pci_space
= &phb
->space
[space
];
962 /* check out the address */
963 if ((addr
>= pci_space
->my_base
964 && addr
<= pci_space
->my_base
+ pci_space
->size
)
965 || (addr
+ nr_bytes
>= pci_space
->my_base
966 && addr
+ nr_bytes
<= pci_space
->my_base
+ pci_space
->size
))
967 device_error(me
, "Do not support DMA into own bus");
969 DTRACE(phb
, ("dma read - %s:0x%lx (%d bytes)\n",
970 pci_space
->name
, (unsigned long)addr
, nr_bytes
));
971 return device_dma_read_buffer(device_parent(me
),
972 dest
, pci_space
->parent_space
,
978 hw_phb_dma_write_buffer(device
*me
,
983 int violate_read_only_section
)
985 hw_phb_device
*phb
= (hw_phb_device
*)device_data(me
);
986 const phb_space
*pci_space
;
988 if (space
!= hw_phb_memory_space
)
989 device_error(me
, "invalid dma address space %d", space
);
990 pci_space
= &phb
->space
[space
];
991 /* check out the address */
992 if ((addr
>= pci_space
->my_base
993 && addr
<= pci_space
->my_base
+ pci_space
->size
)
994 || (addr
+ nr_bytes
>= pci_space
->my_base
995 && addr
+ nr_bytes
<= pci_space
->my_base
+ pci_space
->size
))
996 device_error(me
, "Do not support DMA into own bus");
998 DTRACE(phb
, ("dma write - %s:0x%lx (%d bytes)\n",
999 pci_space
->name
, (unsigned long)addr
, nr_bytes
));
1000 return device_dma_write_buffer(device_parent(me
),
1001 source
, pci_space
->parent_space
,
1003 violate_read_only_section
);
1007 static device_callbacks
const hw_phb_callbacks
= {
1008 { hw_phb_init_address
, },
1009 { hw_phb_attach_address
, },
1010 { hw_phb_io_read_buffer
, hw_phb_io_write_buffer
},
1011 { hw_phb_dma_read_buffer
, hw_phb_dma_write_buffer
},
1012 { NULL
, }, /* interrupt */
1013 { hw_phb_unit_decode
,
1015 hw_phb_address_to_attach_address
,
1016 hw_phb_size_to_attach_size
}
1021 hw_phb_create(const char *name
,
1022 const device_unit
*unit_address
,
1025 /* create the descriptor */
1026 hw_phb_device
*phb
= ZALLOC(hw_phb_device
);
1028 /* create the core maps now */
1029 hw_phb_spaces space_nr
;
1030 for (space_nr
= 0; space_nr
< nr_hw_phb_spaces
; space_nr
++) {
1031 phb_space
*pci_space
= &phb
->space
[space_nr
];
1032 pci_space
->map
= core_create();
1033 pci_space
->readable
= core_readable(pci_space
->map
);
1034 pci_space
->writeable
= core_writeable(pci_space
->map
);
1036 case hw_phb_memory_space
:
1037 pci_space
->name
= "memory";
1039 case hw_phb_io_space
:
1040 pci_space
->name
= "I/O";
1042 case hw_phb_config_space
:
1043 pci_space
->name
= "config";
1045 case hw_phb_special_space
:
1046 pci_space
->name
= "special";
1049 error ("internal error");
1058 const device_descriptor hw_phb_device_descriptor
[] = {
1059 { "phb", hw_phb_create
, &hw_phb_callbacks
},
1060 { "pci", NULL
, &hw_phb_callbacks
},
1064 #endif /* _HW_PHB_ */