ppc64: Don't set Kp bit on SLB
[openbios/afaerber.git] / drivers / pci.c
blobf8c6414978cb3c1324ca65571bee2355c4c88b36
1 /*
2 * OpenBIOS pci driver
4 * This driver is compliant to the
5 * PCI bus binding to IEEE 1275-1994 Rev 2.1
7 * (C) 2004 Stefan Reinauer <stepan@openbios.org>
8 * (C) 2005 Ed Schouten <ed@fxq.nl>
10 * Some parts from OpenHackWare-0.4, Copyright (c) 2004-2005 Jocelyn Mayer
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2
18 #include "config.h"
19 #include "libopenbios/bindings.h"
20 #include "kernel/kernel.h"
21 #include "drivers/pci.h"
22 #include "libc/byteorder.h"
23 #include "libc/vsprintf.h"
25 #include "drivers/drivers.h"
26 #include "drivers/vga.h"
27 #include "timer.h"
28 #include "pci.h"
29 #include "pci_database.h"
30 #ifdef CONFIG_DRIVER_MACIO
31 #include "cuda.h"
32 #include "macio.h"
33 #endif
35 #if defined (CONFIG_DEBUG_PCI)
36 # define PCI_DPRINTF(format, ...) printk(format, ## __VA_ARGS__)
37 #else
38 # define PCI_DPRINTF(format, ...) do { } while (0)
39 #endif
41 #define set_bool_property(ph, name) set_property(ph, name, NULL, 0);
43 /* DECLARE data structures for the nodes. */
45 DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) );
46 DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) );
48 const pci_arch_t *arch;
50 #define IS_NOT_RELOCATABLE 0x80000000
51 #define IS_PREFETCHABLE 0x40000000
52 #define IS_ALIASED 0x20000000
54 enum {
55 CONFIGURATION_SPACE = 0,
56 IO_SPACE = 1,
57 MEMORY_SPACE_32 = 2,
58 MEMORY_SPACE_64 = 3,
61 static int encode_int32_cells(int num_cells, u32 *prop, ucell val)
63 int i = 0;
65 /* hi ... lo */
66 for (i=0; i < num_cells; ++i) {
67 prop[num_cells - i - 1] = val;
68 val >>= 16;
69 val >>= 16;
72 return num_cells;
75 static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code,
76 pci_addr dev, uint8_t reg, uint64_t addr)
79 /* phys.hi */
81 phys[0] = flags | (space_code << 24) | dev | reg;
83 /* phys.mid */
85 phys[1] = addr >> 32;
87 /* phys.lo */
89 phys[2] = addr;
91 return 3;
94 static inline int pci_encode_size(u32 *prop, uint64_t size)
96 return encode_int32_cells(2, prop, size);
99 static int host_address_cells(void)
101 return get_int_property(find_dev("/"), "#address-cells", NULL);
104 static int host_encode_phys_addr(u32 *prop, ucell addr)
106 return encode_int32_cells(host_address_cells(), prop, addr);
109 static int host_size_cells(void)
111 return get_int_property(find_dev("/"), "#size-cells", NULL);
115 static int parent_address_cells(void)
117 phandle_t parent_ph = ih_to_phandle(my_parent());
118 return get_int_property(parent_ph, "#address-cells", NULL);
121 static int parent_size_cells(void)
123 phandle_t parent_ph = ih_to_phandle(my_parent());
124 return get_int_property(parent_ph, "#size-cells", NULL);
128 #if defined(CONFIG_DEBUG_PCI)
129 static void dump_reg_property(const char* description, int nreg, u32 *reg)
131 int i;
132 printk("%s reg", description);
133 for (i=0; i < nreg; ++i) {
134 printk(" %08X", reg[i]);
136 printk("\n");
138 #endif
140 static void
141 ob_pci_open(int *idx)
143 int ret=1;
144 RET ( -ret );
147 static void
148 ob_pci_close(int *idx)
152 static void
153 ob_pci_initialize(int *idx)
157 /* ( str len -- phys.lo phys.mid phys.hi ) */
159 static void
160 ob_pci_decode_unit(int *idx)
162 ucell hi, mid, lo;
163 const char *arg = pop_fstr_copy();
164 int dev, fn, reg, ss, n, p, t;
165 int bus = 0; /* no information */
166 char *ptr;
168 PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx);
170 fn = 0;
171 reg = 0;
172 n = 0;
173 p = 0;
174 t = 0;
176 ptr = (char*)arg;
177 if (*ptr == 'n') {
178 n = IS_NOT_RELOCATABLE;
179 ptr++;
181 if (*ptr == 'i') {
182 ss = IO_SPACE;
183 ptr++;
184 if (*ptr == 't') {
185 t = IS_ALIASED;
186 ptr++;
189 /* DD,F,RR,NNNNNNNN */
191 dev = strtol(ptr, &ptr, 16);
192 ptr++;
193 fn = strtol(ptr, &ptr, 16);
194 ptr++;
195 reg = strtol(ptr, &ptr, 16);
196 ptr++;
197 lo = strtol(ptr, &ptr, 16);
198 mid = 0;
200 } else if (*ptr == 'm') {
201 ss = MEMORY_SPACE_32;
202 ptr++;
203 if (*ptr == 't') {
204 t = IS_ALIASED;
205 ptr++;
207 if (*ptr == 'p') {
208 p = IS_PREFETCHABLE;
209 ptr++;
212 /* DD,F,RR,NNNNNNNN */
214 dev = strtol(ptr, &ptr, 16);
215 ptr++;
216 fn = strtol(ptr, &ptr, 16);
217 ptr++;
218 reg = strtol(ptr, &ptr, 16);
219 ptr++;
220 lo = strtol(ptr, &ptr, 16);
221 mid = 0;
223 } else if (*ptr == 'x') {
224 unsigned long long addr64;
225 ss = MEMORY_SPACE_64;
226 ptr++;
227 if (*ptr == 'p') {
228 p = IS_PREFETCHABLE;
229 ptr++;
232 /* DD,F,RR,NNNNNNNNNNNNNNNN */
234 dev = strtol(ptr, &ptr, 16);
235 ptr++;
236 fn = strtol(ptr, &ptr, 16);
237 ptr++;
238 reg = strtol(ptr, &ptr, 16);
239 ptr++;
240 addr64 = strtoll(ptr, &ptr, 16);
241 lo = (ucell)addr64;
242 mid = addr64 >> 32;
244 } else {
245 ss = CONFIGURATION_SPACE;
246 /* "DD" or "DD,FF" */
247 dev = strtol(ptr, &ptr, 16);
248 if (*ptr == ',') {
249 ptr++;
250 fn = strtol(ptr, NULL, 16);
252 lo = 0;
253 mid = 0;
255 free((char*)arg);
257 hi = n | p | t | (ss << 24) | (bus << 16) | (dev << 11) | (fn << 8) | reg;
259 PUSH(lo);
260 PUSH(mid);
261 PUSH(hi);
263 PCI_DPRINTF("ob_pci_decode_unit idx=%p addr="
264 FMT_ucellx " " FMT_ucellx " " FMT_ucellx "\n",
265 idx, lo, mid, hi);
268 /* ( phys.lo phy.mid phys.hi -- str len ) */
270 static void
271 ob_pci_encode_unit(int *idx)
273 char buf[28];
274 cell hi = POP();
275 cell mid = POP();
276 cell lo = POP();
277 int n, p, t, ss, dev, fn, reg;
279 n = hi & IS_NOT_RELOCATABLE;
280 p = hi & IS_PREFETCHABLE;
281 t = hi & IS_ALIASED;
282 ss = (hi >> 24) & 0x03;
284 dev = (hi >> 11) & 0x1F;
285 fn = (hi >> 8) & 0x07;
286 reg = hi & 0xFF;
288 switch(ss) {
289 case CONFIGURATION_SPACE:
291 if (fn == 0) /* DD */
292 snprintf(buf, sizeof(buf), "%x", dev);
293 else /* DD,F */
294 snprintf(buf, sizeof(buf), "%x,%x", dev, fn);
295 break;
297 case IO_SPACE:
299 /* [n]i[t]DD,F,RR,NNNNNNNN */
300 snprintf(buf, sizeof(buf), "%si%s%x,%x,%x," FMT_ucellx,
301 n ? "n" : "", /* relocatable */
302 t ? "t" : "", /* aliased */
303 dev, fn, reg, t ? lo & 0x03FF : lo);
304 break;
306 case MEMORY_SPACE_32:
308 /* [n]m[t][p]DD,F,RR,NNNNNNNN */
309 snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x," FMT_ucellx,
310 n ? "n" : "", /* relocatable */
311 t ? "t" : "", /* aliased */
312 p ? "p" : "", /* prefetchable */
313 dev, fn, reg, lo );
314 break;
316 case MEMORY_SPACE_64:
318 /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */
319 snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx",
320 n ? "n" : "", /* relocatable */
321 p ? "p" : "", /* prefetchable */
322 dev, fn, reg, ((long long)mid << 32) | (long long)lo);
323 break;
325 push_str(buf);
327 PCI_DPRINTF("ob_pci_encode_unit space=%d dev=%d fn=%d buf=%s\n",
328 ss, dev, fn, buf);
331 NODE_METHODS(ob_pci_bus_node) = {
332 { NULL, ob_pci_initialize },
333 { "open", ob_pci_open },
334 { "close", ob_pci_close },
335 { "decode-unit", ob_pci_decode_unit },
336 { "encode-unit", ob_pci_encode_unit },
339 NODE_METHODS(ob_pci_simple_node) = {
340 { NULL, ob_pci_initialize },
341 { "open", ob_pci_open },
342 { "close", ob_pci_close },
345 static void pci_set_bus_range(const pci_config_t *config)
347 phandle_t dev = find_dev(config->path);
348 u32 props[2];
350 props[0] = config->secondary_bus;
351 props[1] = config->subordinate_bus;
353 PCI_DPRINTF("setting bus range for %s PCI device, "
354 "package handle " FMT_ucellx " "
355 "bus primary=%d secondary=%d subordinate=%d\n",
356 config->path,
357 dev,
358 config->primary_bus,
359 config->secondary_bus,
360 config->subordinate_bus);
363 set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
366 static void pci_host_set_interrupt_map(const pci_config_t *config)
368 /* XXX We currently have a hook in the MPIC init code to fill in its handle.
369 * If you want to have interrupt maps for your PCI host bus, add your
370 * architecture to the #if and make your bridge detect code fill in its
371 * handle too.
373 * It would be great if someone clever could come up with a more universal
374 * mechanism here.
376 #if defined(CONFIG_PPC)
377 phandle_t dev = get_cur_dev();
378 u32 props[7 * 4];
379 int i;
381 #if defined(CONFIG_PPC)
382 /* Oldworld macs do interrupt maps differently */
383 if(!is_newworld())
384 return;
385 #endif
387 for (i = 0; i < (7*4); i+=7) {
388 props[i+PCI_INT_MAP_PCI0] = 0;
389 props[i+PCI_INT_MAP_PCI1] = 0;
390 props[i+PCI_INT_MAP_PCI2] = 0;
391 props[i+PCI_INT_MAP_PCI_INT] = (i / 7) + 1; // starts at PINA=1
392 props[i+PCI_INT_MAP_PIC_HANDLE] = 0; // gets patched in later
393 props[i+PCI_INT_MAP_PIC_INT] = arch->irqs[i / 7];
394 props[i+PCI_INT_MAP_PIC_POL] = 3;
396 set_property(dev, "interrupt-map", (char *)props, 7 * 4 * sizeof(props[0]));
398 props[PCI_INT_MAP_PCI0] = 0;
399 props[PCI_INT_MAP_PCI1] = 0;
400 props[PCI_INT_MAP_PCI2] = 0;
401 props[PCI_INT_MAP_PCI_INT] = 0x7;
403 set_property(dev, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
404 #endif
407 static void pci_host_set_reg(phandle_t phandle)
409 phandle_t dev = phandle;
411 /* at most 2 integers for address and size */
412 u32 props[4];
413 int ncells = 0;
415 ncells += encode_int32_cells(host_address_cells(), props + ncells,
416 arch->cfg_base);
418 ncells += encode_int32_cells(host_size_cells(), props + ncells,
419 arch->cfg_len);
421 set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
423 #if defined(CONFIG_DEBUG_PCI)
424 dump_reg_property("pci_host_set_reg", 4, props);
425 #endif
428 /* child-phys : parent-phys : size */
429 /* 3 cells for PCI : 2 cells for 64bit parent : 2 cells for PCI */
431 static void pci_host_set_ranges(const pci_config_t *config)
433 phandle_t dev = get_cur_dev();
434 u32 props[32];
435 int ncells;
437 ncells = 0;
438 /* first encode PCI configuration space */
440 ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
441 config->dev, 0, 0);
442 ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr);
443 ncells += pci_encode_size(props + ncells, arch->cfg_len);
446 if (arch->io_base) {
447 ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
448 config->dev, 0, 0);
449 ncells += host_encode_phys_addr(props + ncells, arch->io_base);
450 ncells += pci_encode_size(props + ncells, arch->io_len);
452 if (arch->rbase) {
453 ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
454 config->dev, 0, 0);
455 ncells += host_encode_phys_addr(props + ncells, arch->rbase);
456 ncells += pci_encode_size(props + ncells, arch->rlen);
458 if (arch->host_mem_base) {
459 ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
460 config->dev, 0, arch->pci_mem_base);
461 ncells += host_encode_phys_addr(props + ncells, arch->host_mem_base);
462 ncells += pci_encode_size(props + ncells, arch->mem_len);
464 set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
467 static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
469 #ifdef CONFIG_SPARC64
470 return arch->cfg_data + (unsigned long)ba;
471 #else
472 return (unsigned long)ba;
473 #endif
476 int host_config_cb(const pci_config_t *config)
478 //XXX this overrides "reg" property
479 pci_host_set_reg(get_cur_dev());
480 pci_host_set_ranges(config);
481 pci_host_set_interrupt_map(config);
483 return 0;
486 static int sabre_configure(phandle_t dev)
488 uint32_t props[28];
490 props[0] = 0xc0000000;
491 props[1] = 0x20000000;
492 set_property(dev, "virtual-dma", (char *)props, 2 * sizeof(props[0]));
493 props[0] = 1;
494 set_property(dev, "#virtual-dma-size-cells", (char *)props,
495 sizeof(props[0]));
496 set_property(dev, "#virtual-dma-addr-cells", (char *)props,
497 sizeof(props[0]));
498 props[0] = 0x000007f0;
499 props[1] = 0x000007ee;
500 props[2] = 0x000007ef;
501 props[3] = 0x000007e5;
502 set_property(dev, "interrupts", (char *)props, 4 * sizeof(props[0]));
503 props[0] = 0x0000001f;
504 set_property(dev, "upa-portid", (char *)props, 1 * sizeof(props[0]));
505 return 0;
508 int sabre_config_cb(const pci_config_t *config)
510 host_config_cb(config);
512 return sabre_configure(get_cur_dev());
515 int bridge_config_cb(const pci_config_t *config)
517 phandle_t aliases;
519 aliases = find_dev("/aliases");
520 set_property(aliases, "bridge", config->path, strlen(config->path) + 1);
522 return 0;
525 int ide_config_cb2 (const pci_config_t *config)
527 ob_ide_init(config->path,
528 config->assigned[0] & ~0x0000000F,
529 config->assigned[1] & ~0x0000000F,
530 config->assigned[2] & ~0x0000000F,
531 config->assigned[3] & ~0x0000000F);
532 return 0;
535 int eth_config_cb (const pci_config_t *config)
537 phandle_t ph = get_cur_dev();
539 set_property(ph, "network-type", "ethernet", 9);
540 set_property(ph, "removable", "network", 8);
541 set_property(ph, "category", "net", 4);
543 return 0;
546 static inline void pci_decode_pci_addr(pci_addr addr, int *flags,
547 int *space_code, uint32_t *mask)
549 *flags = 0;
551 if (addr & 0x01) {
552 *space_code = IO_SPACE;
553 *mask = 0x00000001;
554 } else {
555 if (addr & 0x04) {
556 *space_code = MEMORY_SPACE_64;
557 *flags |= IS_NOT_RELOCATABLE; /* XXX: why not relocatable? */
558 } else {
559 *space_code = MEMORY_SPACE_32;
562 if (addr & 0x08) {
563 *flags |= IS_PREFETCHABLE;
566 *mask = 0x0000000F;
571 * "Designing PCI Cards and Drivers for Power Macintosh Computers", p. 454
573 * "AAPL,address" provides an array of 32-bit logical addresses
574 * Nth entry corresponding to Nth "assigned-address" base address entry.
577 static void pci_set_AAPL_address(const pci_config_t *config)
579 phandle_t dev = get_cur_dev();
580 cell props[7];
581 int ncells, i;
583 ncells = 0;
584 for (i = 0; i < 6; i++) {
585 if (!config->assigned[i] || !config->sizes[i])
586 continue;
587 props[ncells++] = config->assigned[i] & ~0x0000000F;
589 if (ncells)
590 set_property(dev, "AAPL,address", (char *)props,
591 ncells * sizeof(cell));
594 static void pci_set_assigned_addresses(phandle_t phandle,
595 const pci_config_t *config, int num_bars)
597 phandle_t dev = phandle;
598 u32 props[32];
599 int ncells;
600 int i;
601 uint32_t mask;
602 int flags, space_code;
604 ncells = 0;
605 for (i = 0; i < num_bars; i++) {
606 /* consider only bars with non-zero region size */
607 if (!config->sizes[i])
608 continue;
609 pci_decode_pci_addr(config->assigned[i],
610 &flags, &space_code, &mask);
612 ncells += pci_encode_phys_addr(props + ncells,
613 flags, space_code, config->dev,
614 PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
615 config->assigned[i] & ~mask);
617 props[ncells++] = 0x00000000;
618 props[ncells++] = config->sizes[i];
620 if (ncells)
621 set_property(dev, "assigned-addresses", (char *)props,
622 ncells * sizeof(props[0]));
625 /* call after writing "reg" property to update config->path */
626 static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config)
628 /* since "name" and "reg" are now assigned
629 we need to reload current node name */
631 PUSH(phandle);
632 fword("get-package-path");
633 char *new_path = pop_fstr_copy();
634 if (new_path) {
635 if (0 != strcmp(config->path, new_path)) {
636 PCI_DPRINTF("\n=== CHANGED === package path old=%s new=%s\n",
637 config->path, new_path);
638 strncpy(config->path, new_path, sizeof(config->path));
639 config->path[sizeof(config->path)-1] = '\0';
641 free(new_path);
642 } else {
643 PCI_DPRINTF("\n=== package path old=%s new=NULL\n", config->path);
647 static void pci_set_reg(phandle_t phandle,
648 pci_config_t *config, int num_bars)
650 phandle_t dev = phandle;
651 u32 props[38];
652 int ncells;
653 int i;
654 uint32_t mask;
655 int space_code, flags;
657 ncells = 0;
659 /* first (addr, size) pair is the beginning of configuration address space */
660 ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
661 config->dev, 0, 0);
663 ncells += pci_encode_size(props + ncells, 0);
665 for (i = 0; i < num_bars; i++) {
666 /* consider only bars with non-zero region size */
667 if (!config->sizes[i])
668 continue;
670 pci_decode_pci_addr(config->regions[i],
671 &flags, &space_code, &mask);
673 ncells += pci_encode_phys_addr(props + ncells,
674 flags, space_code, config->dev,
675 PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
676 config->regions[i] & ~mask);
678 /* set size */
679 ncells += pci_encode_size(props + ncells, config->sizes[i]);
682 set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
683 ob_pci_reload_device_path(dev, config);
685 #if defined(CONFIG_DEBUG_PCI)
686 dump_reg_property("pci_set_reg", ncells, props);
687 #endif
691 static void pci_set_ranges(const pci_config_t *config)
693 phandle_t dev = get_cur_dev();
694 u32 props[32];
695 int ncells;
696 int i;
697 uint32_t mask;
698 int flags;
699 int space_code;
701 ncells = 0;
702 for (i = 0; i < 6; i++) {
703 if (!config->assigned[i] || !config->sizes[i])
704 continue;
706 /* child address */
708 props[ncells++] = 0x00000000;
710 /* parent address */
712 pci_decode_pci_addr(config->assigned[i],
713 &flags, &space_code, &mask);
714 ncells += pci_encode_phys_addr(props + ncells, flags, space_code,
715 config->dev, 0x10 + i * 4,
716 config->assigned[i] & ~mask);
718 /* size */
720 props[ncells++] = config->sizes[i];
722 set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
725 int macio_heathrow_config_cb (const pci_config_t *config)
727 pci_set_ranges(config);
729 #ifdef CONFIG_DRIVER_MACIO
730 ob_macio_heathrow_init(config->path, config->assigned[0] & ~0x0000000F);
731 #endif
732 return 0;
735 int macio_keylargo_config_cb (const pci_config_t *config)
737 pci_set_ranges(config);
739 #ifdef CONFIG_DRIVER_MACIO
740 ob_macio_keylargo_init(config->path, config->assigned[0] & ~0x0000000F);
741 #endif
742 return 0;
745 int vga_config_cb (const pci_config_t *config)
747 if (config->assigned[0] != 0x00000000)
748 vga_vbe_init(config->path,
749 pci_bus_addr_to_host_addr(config->assigned[0] & ~0x0000000F),
750 config->sizes[0],
751 pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F),
752 config->sizes[1]);
753 return 0;
756 int ebus_config_cb(const pci_config_t *config)
758 #ifdef CONFIG_DRIVER_EBUS
759 #ifdef CONFIG_DRIVER_FLOPPY
760 ob_floppy_init(config->path, "fdthree", 0x3f0ULL, 0);
761 #endif
762 #ifdef CONFIG_DRIVER_PC_SERIAL
763 ob_pc_serial_init(config->path, "su", arch->io_base, 0x3f8ULL, 0);
764 #endif
765 #ifdef CONFIG_DRIVER_PC_KBD
766 ob_pc_kbd_init(config->path, "kb_ps2", arch->io_base, 0x60ULL, 0);
767 #endif
768 #endif
769 return 0;
772 static void ob_pci_add_properties(phandle_t phandle,
773 pci_addr addr, const pci_dev_t *pci_dev,
774 const pci_config_t *config, int num_bars)
776 /* cannot use get_cur_dev() path resolution since "name" and "reg"
777 properties are being changed */
778 phandle_t dev=phandle;
779 int status,id;
780 uint16_t vendor_id, device_id;
781 uint8_t rev;
782 uint32_t class_code;
784 vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
785 device_id = pci_config_read16(addr, PCI_DEVICE_ID);
786 rev = pci_config_read8(addr, PCI_REVISION_ID);
787 class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
789 if (pci_dev) {
790 /**/
791 if (pci_dev->name) {
792 push_str(pci_dev->name);
793 fword("encode-string");
794 push_str("name");
795 fword("property");
796 } else {
797 char path[256];
798 snprintf(path, sizeof(path),
799 "pci%x,%x", vendor_id, device_id);
800 push_str(path);
801 fword("encode-string");
802 push_str("name");
803 fword("property");
805 } else {
806 PCI_DPRINTF("*** missing pci_dev\n");
809 /* create properties as described in 2.5 */
811 set_int_property(dev, "vendor-id", vendor_id);
812 set_int_property(dev, "device-id", device_id);
813 set_int_property(dev, "revision-id", rev);
814 set_int_property(dev, "class-code", class_code << 8);
816 if (config->irq_pin) {
817 OLDWORLD(set_int_property(dev, "AAPL,interrupts",
818 config->irq_line));
819 set_int_property(dev, "interrupts", config->irq_pin);
822 set_int_property(dev, "min-grant", pci_config_read8(addr, PCI_MIN_GNT));
823 set_int_property(dev, "max-latency", pci_config_read8(addr, PCI_MAX_LAT));
825 status=pci_config_read16(addr, PCI_STATUS);
827 set_int_property(dev, "devsel-speed",
828 (status&PCI_STATUS_DEVSEL_MASK)>>10);
830 if(status&PCI_STATUS_FAST_BACK)
831 set_bool_property(dev, "fast-back-to-back");
832 if(status&PCI_STATUS_66MHZ)
833 set_bool_property(dev, "66mhz-capable");
834 if(status&PCI_STATUS_UDF)
835 set_bool_property(dev, "udf-supported");
837 id=pci_config_read16(addr, PCI_SUBSYSTEM_VENDOR_ID);
838 if(id)
839 set_int_property(dev, "subsystem-vendor-id", id);
840 id=pci_config_read16(addr, PCI_SUBSYSTEM_ID);
841 if(id)
842 set_int_property(dev, "subsystem-id", id);
844 set_int_property(dev, "cache-line-size",
845 pci_config_read16(addr, PCI_CACHE_LINE_SIZE));
847 if (pci_dev) {
848 if (pci_dev->type) {
849 push_str(pci_dev->type);
850 fword("encode-string");
851 push_str("device_type");
852 fword("property");
854 if (pci_dev->model) {
855 push_str(pci_dev->model);
856 fword("encode-string");
857 push_str("model");
858 fword("property");
860 if (pci_dev->compat)
861 set_property(dev, "compatible",
862 pci_dev->compat, pci_compat_len(pci_dev));
864 if (pci_dev->acells)
865 set_int_property(dev, "#address-cells",
866 pci_dev->acells);
867 if (pci_dev->scells)
868 set_int_property(dev, "#size-cells",
869 pci_dev->scells);
870 if (pci_dev->icells)
871 set_int_property(dev, "#interrupt-cells",
872 pci_dev->icells);
875 pci_set_assigned_addresses(phandle, config, num_bars);
876 OLDWORLD(pci_set_AAPL_address(config));
878 PCI_DPRINTF("\n");
881 #ifdef CONFIG_XBOX
882 static char pci_xbox_blacklisted (int bus, int devnum, int fn)
885 * The Xbox MCPX chipset is a derivative of the nForce 1
886 * chipset. It almost has the same bus layout; some devices
887 * cannot be used, because they have been removed.
891 * Devices 00:00.1 and 00:00.2 used to be memory controllers on
892 * the nForce chipset, but on the Xbox, using them will lockup
893 * the chipset.
895 if ((bus == 0) && (devnum == 0) && ((fn == 1) || (fn == 2)))
896 return 1;
899 * Bus 1 only contains a VGA controller at 01:00.0. When you try
900 * to probe beyond that device, you only get garbage, which
901 * could cause lockups.
903 if ((bus == 1) && ((devnum != 0) || (fn != 0)))
904 return 1;
907 * Bus 2 used to contain the AGP controller, but the Xbox MCPX
908 * doesn't have one. Probing it can cause lockups.
910 if (bus >= 2)
911 return 1;
914 * The device is not blacklisted.
916 return 0;
918 #endif
920 static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config,
921 int reg, int config_addr,
922 uint32_t *p_omask,
923 unsigned long *mem_base,
924 unsigned long *io_base)
926 uint32_t smask, amask, size, reloc, min_align;
927 unsigned long base;
929 config->assigned[reg] = 0x00000000;
930 config->sizes[reg] = 0x00000000;
932 if ((*p_omask & 0x0000000f) == 0x4) {
933 /* 64 bits memory mapping */
934 return;
937 config->regions[reg] = pci_config_read32(addr, config_addr);
939 /* get region size */
941 pci_config_write32(addr, config_addr, 0xffffffff);
942 smask = pci_config_read32(addr, config_addr);
943 if (smask == 0x00000000 || smask == 0xffffffff)
944 return;
946 if (smask & 0x00000001 && reg != 6) {
947 /* I/O space */
948 base = *io_base;
949 min_align = 1 << 7;
950 amask = 0x00000001;
951 } else {
952 /* Memory Space */
953 base = *mem_base;
954 min_align = 1 << 16;
955 amask = 0x0000000F;
956 if (reg == 6) {
957 smask |= 1; /* ROM */
960 *p_omask = smask & amask;
961 smask &= ~amask;
962 size = (~smask) + 1;
963 config->sizes[reg] = size;
964 reloc = base;
965 if (size < min_align)
966 size = min_align;
967 reloc = (reloc + size -1) & ~(size - 1);
968 if (*io_base == base) {
969 *io_base = reloc + size;
970 reloc -= arch->io_base;
971 } else {
972 *mem_base = reloc + size;
974 pci_config_write32(addr, config_addr, reloc | *p_omask);
975 config->assigned[reg] = reloc | *p_omask;
978 static void ob_pci_configure_irq(pci_addr addr, pci_config_t *config)
980 uint8_t irq_pin, irq_line;
982 irq_pin = pci_config_read8(addr, PCI_INTERRUPT_PIN);
983 if (irq_pin) {
984 config->irq_pin = irq_pin;
985 irq_pin = (((config->dev >> 11) & 0x1F) + irq_pin - 1) & 3;
986 irq_line = arch->irqs[irq_pin];
987 pci_config_write8(addr, PCI_INTERRUPT_LINE, irq_line);
988 config->irq_line = irq_line;
989 } else
990 config->irq_line = -1;
993 static void
994 ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
995 unsigned long *mem_base, unsigned long *io_base)
998 uint32_t omask;
999 uint16_t cmd;
1000 int reg;
1001 pci_addr config_addr;
1003 ob_pci_configure_irq(addr, config);
1005 omask = 0x00000000;
1006 for (reg = 0; reg < num_regs; ++reg) {
1007 config_addr = PCI_BASE_ADDR_0 + reg * 4;
1009 ob_pci_configure_bar(addr, config, reg, config_addr,
1010 &omask, mem_base,
1011 io_base);
1014 if (rom_bar) {
1015 config_addr = rom_bar;
1016 ob_pci_configure_bar(addr, config, reg, config_addr,
1017 &omask, mem_base, io_base);
1019 cmd = pci_config_read16(addr, PCI_COMMAND);
1020 cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1021 pci_config_write16(addr, PCI_COMMAND, cmd);
1024 static void ob_configure_pci_device(const char* parent_path,
1025 int *bus_num, unsigned long *mem_base, unsigned long *io_base,
1026 int bus, int devnum, int fn, int *p_is_multi);
1028 static void ob_scan_pci_bus(int *bus_num, unsigned long *mem_base,
1029 unsigned long *io_base, const char *path,
1030 int bus)
1032 int devnum, fn, is_multi;
1034 PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path);
1036 for (devnum = 0; devnum < 32; devnum++) {
1037 is_multi = 0;
1038 for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
1039 ob_configure_pci_device(path, bus_num, mem_base, io_base,
1040 bus, devnum, fn, &is_multi);
1046 static void ob_configure_pci_bridge(pci_addr addr,
1047 int *bus_num, unsigned long *mem_base,
1048 unsigned long *io_base,
1049 int primary_bus, pci_config_t *config)
1051 config->primary_bus = primary_bus;
1052 pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);
1054 config->secondary_bus = *bus_num;
1055 pci_config_write8(addr, PCI_SECONDARY_BUS, config->secondary_bus);
1057 config->subordinate_bus = 0xff;
1058 pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
1060 PCI_DPRINTF("scanning new pci bus %u under bridge %s\n",
1061 config->secondary_bus, config->path);
1063 /* make pci bridge parent device, prepare for recursion */
1065 ob_scan_pci_bus(bus_num, mem_base, io_base,
1066 config->path, config->secondary_bus);
1068 /* bus scan updates *bus_num to last revealed pci bus number */
1069 config->subordinate_bus = *bus_num;
1070 pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
1072 PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n",
1073 config->path, config->primary_bus, config->secondary_bus,
1074 config->subordinate_bus);
1076 pci_set_bus_range(config);
1079 static int ob_pci_read_identification(int bus, int devnum, int fn,
1080 int *p_vid, int *p_did,
1081 uint8_t *p_class, uint8_t *p_subclass)
1083 int vid, did;
1084 uint32_t ccode;
1085 pci_addr addr;
1087 #ifdef CONFIG_XBOX
1088 if (pci_xbox_blacklisted (bus, devnum, fn))
1089 return;
1090 #endif
1091 addr = PCI_ADDR(bus, devnum, fn);
1092 vid = pci_config_read16(addr, PCI_VENDOR_ID);
1093 did = pci_config_read16(addr, PCI_DEVICE_ID);
1095 if (vid==0xffff || vid==0) {
1096 return 0;
1099 if (p_vid) {
1100 *p_vid = vid;
1103 if (p_did) {
1104 *p_did = did;
1107 ccode = pci_config_read16(addr, PCI_CLASS_DEVICE);
1109 if (p_class) {
1110 *p_class = ccode >> 8;
1113 if (p_subclass) {
1114 *p_subclass = ccode;
1117 return 1;
1120 static void ob_configure_pci_device(const char* parent_path,
1121 int *bus_num, unsigned long *mem_base, unsigned long *io_base,
1122 int bus, int devnum, int fn, int *p_is_multi)
1124 int vid, did;
1125 unsigned int htype;
1126 pci_addr addr;
1127 pci_config_t config = {};
1128 const pci_dev_t *pci_dev;
1129 uint8_t class, subclass, iface;
1130 int num_bars, rom_bar;
1132 phandle_t phandle = 0;
1133 int is_host_bridge = 0;
1135 if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) {
1136 return;
1139 addr = PCI_ADDR(bus, devnum, fn);
1140 iface = pci_config_read8(addr, PCI_CLASS_PROG);
1142 pci_dev = pci_find_device(class, subclass, iface,
1143 vid, did);
1145 PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn,
1146 vid, did);
1148 htype = pci_config_read8(addr, PCI_HEADER_TYPE);
1150 if (fn == 0) {
1151 if (p_is_multi) {
1152 *p_is_multi = htype & 0x80;
1156 /* stop adding host bridge accessible from it's primary bus
1157 PCI host bridge is to be added by host code
1159 if (class == PCI_BASE_CLASS_BRIDGE &&
1160 subclass == PCI_SUBCLASS_BRIDGE_HOST) {
1161 is_host_bridge = 1;
1164 if (is_host_bridge) {
1165 /* reuse device tree node */
1166 PCI_DPRINTF("host bridge found - ");
1167 snprintf(config.path, sizeof(config.path),
1168 "%s", parent_path);
1169 } else if (pci_dev == NULL || pci_dev->name == NULL) {
1170 snprintf(config.path, sizeof(config.path),
1171 "%s/pci%x,%x", parent_path, vid, did);
1173 else {
1174 snprintf(config.path, sizeof(config.path),
1175 "%s/%s", parent_path, pci_dev->name);
1178 PCI_DPRINTF("%s - ", config.path);
1180 config.dev = addr & 0x00FFFFFF;
1182 switch (class) {
1183 case PCI_BASE_CLASS_BRIDGE:
1184 if (subclass != PCI_SUBCLASS_BRIDGE_HOST) {
1185 REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle);
1187 break;
1188 default:
1189 REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle);
1190 break;
1193 if (is_host_bridge) {
1194 phandle = find_dev(config.path);
1196 if (get_property(phandle, "vendor-id", NULL)) {
1197 PCI_DPRINTF("host bridge already configured\n");
1198 return;
1202 activate_dev(phandle);
1204 if (htype & PCI_HEADER_TYPE_BRIDGE) {
1205 num_bars = 2;
1206 rom_bar = PCI_ROM_ADDRESS1;
1207 } else {
1208 num_bars = 6;
1209 rom_bar = PCI_ROM_ADDRESS;
1212 ob_pci_configure(addr, &config, num_bars, rom_bar,
1213 mem_base, io_base);
1215 ob_pci_add_properties(phandle, addr, pci_dev, &config, num_bars);
1217 if (!is_host_bridge) {
1218 pci_set_reg(phandle, &config, num_bars);
1221 /* call device-specific configuration callback */
1222 if (pci_dev && pci_dev->config_cb) {
1223 //activate_device(config.path);
1224 pci_dev->config_cb(&config);
1227 /* device is configured so we may move it out of scope */
1228 device_end();
1230 /* scan bus behind bridge device */
1231 //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) {
1232 if ( class == PCI_BASE_CLASS_BRIDGE &&
1233 ( subclass == PCI_SUBCLASS_BRIDGE_PCI ||
1234 subclass == PCI_SUBCLASS_BRIDGE_HOST ) ) {
1236 if (subclass == PCI_SUBCLASS_BRIDGE_PCI) {
1237 /* reserve next pci bus number for this PCI bridge */
1238 ++(*bus_num);
1241 ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config);
1245 int ob_pci_init(void)
1247 int bus, devnum, fn;
1248 uint8_t class, subclass;
1249 unsigned long mem_base, io_base;
1251 pci_config_t config = {}; /* host bridge */
1252 phandle_t phandle_host;
1254 PCI_DPRINTF("Initializing PCI host bridge...\n");
1256 activate_device("/");
1258 /* Find all PCI bridges */
1260 mem_base = arch->pci_mem_base;
1261 /* I/O ports under 0x400 are used by devices mapped at fixed
1262 location. */
1263 io_base = arch->io_base + 0x400;
1265 bus = 0;
1267 for (devnum = 0; devnum < 32; devnum++) {
1268 /* scan only fn 0 */
1269 fn = 0;
1271 if (!ob_pci_read_identification(bus, devnum, fn,
1272 0, 0, &class, &subclass)) {
1273 continue;
1276 if (class != PCI_BASE_CLASS_BRIDGE || subclass != PCI_SUBCLASS_BRIDGE_HOST) {
1277 continue;
1280 /* create root node for host PCI bridge */
1282 /* configure */
1283 snprintf(config.path, sizeof(config.path), "/pci");
1285 REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host);
1287 pci_host_set_reg(phandle_host);
1289 /* update device path after changing "reg" property */
1290 ob_pci_reload_device_path(phandle_host, &config);
1292 ob_configure_pci_device(config.path, &bus, &mem_base, &io_base,
1293 bus, devnum, fn, 0);
1295 /* we expect single host PCI bridge
1296 but this may be machine-specific */
1297 break;
1301 device_end();
1303 return 0;