Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / ontario / src / res_fire_pcie.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: res_fire_pcie.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
47 */
48
49/*
50 * (re)-configuration code to handle HV Fire PCI-E resources
51 */
52
53#pragma ident "@(#)res_fire_pcie.c 1.5 07/06/07 SMI"
54
55#include <stdarg.h>
56#include <sys/htypes.h>
57#include <hypervisor.h>
58#include <traps.h>
59#include <cache.h>
60#include <mmu.h>
61#include <sun4v/asi.h>
62#include <sun4v/errs_defs.h>
63#include <cpu_errs_defs.h>
64#include <cpu_errs.h>
65#include <vpci_errs_defs.h>
66#include <vdev_intr.h>
67#include <ncs.h>
68#include <cyclic.h>
69#include <support.h>
70#include <strand.h>
71#include <vcpu.h>
72#include <guest.h>
73#include <pcie.h>
74#include <vdev_ops.h>
75#include <fpga.h>
76#include <ldc.h>
77#include <config.h>
78#include <offsets.h>
79#include <hvctl.h>
80#include <md.h>
81#include <abort.h>
82#include <hypervisor.h>
83#include <proto.h>
84#include <fire.h>
85
86#ifdef CONFIG_PCIE
87
88#define PCIE_LEAF_A FIRE_LEAF(A)
89#define PCIE_LEAF_B FIRE_LEAF(B)
90
91#define MAX_RESETS 10
92
93
94/*
95 * resource processing support
96 */
97void config_a_guest_pcie_bus(pcie_device_t *pciep);
98void unconfig_a_guest_pcie_bus(pcie_device_t *pciep);
99
100void c_fire_leaf_soft_reset(const struct fire_cookie *, int root);
101
102void
103reset_platform_pcie_busses(guest_t *guestp, pcie_device_t *pciep)
104{
105 extern const struct fire_cookie fire_dev[];
106 int i;
107
108 for (i = 0; i < NUM_PCIE_BUSSES; i++) {
109
110 DBG(c_printf("pcie 0x%x assigned to guest 0x%x\n",
111 &pciep[i], pciep[i].guestp));
112
113 /* if bus is assigned to this guest, soft reset the bus */
114 if (pciep[i].guestp == guestp) {
115 DBG(c_printf("Soft Reset PCI leaf 0x%x\n", i));
116
117 /* we dont care if this works really - if it fails */
118 /* the bus is likely dead. The reset on guest restart */
119 /* will likely set it up to function again ... */
120 (void) pcie_bus_reset(i);
121
122 /* regardless of the bus reset we shutdown Fire's */
123 /* IOMMU and interrupt logic for this bus */
124 c_fire_leaf_soft_reset(
125 (struct fire_cookie *)&fire_dev[i], i);
126 }
127 }
128}
129
130
131void
132fire_map_tte(fire_dev_t *firep, uint64_t idx, uint64_t pa)
133{
134 uint64_t *ttep;
135
136 ttep = &firep->iotsb[idx];
137 *ttep = FIRE_IO_TTE(pa);
138}
139
140void
141fire_set_eqbase(fire_dev_t *firep, bool_t bypass)
142{
143 volatile uint64_t *basep;
144 uint64_t addr;
145
146 basep = (uint64_t *)(firep->pcie + FIRE_DLC_IMU_EQS_EQ_BASE_ADDRESS);
147
148 if (bypass)
149 addr = (uint64_t)firep->msieqbase | MSI_EQ_BASE_BYPASS_ADDR;
150 else
151 addr = firep->guest_pci_va_limit;
152
153 DBGEQ(c_printf("Setting eq base 0x%x, addr 0x%x\n", basep, addr));
154
155 *basep = addr;
156
157}
158
159void
160init_fire_msi_eq(int busnum)
161{
162 fire_dev_t *firep;
163 uint64_t max_virtaddr, base_virtaddr;
164 uint64_t offset_tte_idx, nttes;
165 int i;
166
167 DBGEQ(c_printf("Initializing MSI EQ mappings for bus 0x%x\n", busnum));
168
169 ASSERT(busnum >= 0 && busnum < NFIRELEAVES);
170
171 firep = (fire_dev_t *)&(fire_dev[busnum]);
172
173 max_virtaddr = FIRE_DVMA_RANGE_MAX - IOMMU_EQ_RESERVE;
174 base_virtaddr = FIRE_DVMA_RANGE_MAX - IOMMU_SPACE;
175
176 firep->guest_pci_va_limit = max_virtaddr;
177
178 DBGEQ(c_printf("Basevirtaddr 0x%x, max_virtaddr 0x%x, reserve 0x%x\n",
179 base_virtaddr, max_virtaddr, IOMMU_EQ_RESERVE));
180
181 DBGEQ(c_printf("Guest idx max 0x%x\n", IOTSB_INDEX_MAX));
182
183 offset_tte_idx = (max_virtaddr - base_virtaddr) >> IOMMU_PAGESHIFT;
184 nttes = EQ_MAX_SIZE >> IOMMU_PAGESHIFT;
185
186 DBGEQ(c_printf("Offset idx 0x%x, nttes 0x%x\n",
187 offset_tte_idx, nttes));
188
189 ASSERT((offset_tte_idx + nttes) <= FIRE_IOMMU_SIZE(FIRE_TSB_SIZE));
190
191 for (i = 0; i < nttes; i++) {
192 uint64_t pa;
193
194 pa = (uint64_t)firep->msieqbase +
195 ((uint64_t)i << IOMMU_PAGESHIFT);
196
197 fire_map_tte(firep, (uint64_t)(offset_tte_idx + i), pa);
198 }
199}
200
201void
202init_pcie_buses(void)
203{
204 DBGEQ(c_printf("initializing pcie buses\n"));
205 init_fire_msi_eq(PCIE_LEAF_A);
206 init_fire_msi_eq(PCIE_LEAF_B);
207}
208
209void
210plat_config_pcie_bypass(pcie_device_t *pciep)
211{
212 int id;
213 fire_dev_t *firep;
214
215 id = pciep->id;
216 firep = (fire_dev_t *)&fire_dev[id];
217
218 fire_config_bypass(firep, pciep->allow_bypass);
219
220 fire_set_eqbase(firep, pciep->allow_bypass);
221}
222
223#ifdef CONFIG_IOBYPASS
224/*
225 * For a guest which is allowed direct access to the I/O bridges (Tomatillo,
226 * Fire), this sets up the segments for the I/O physical addresses.
227 */
228#define AID_TO_PCIE_LEAF_A_BASE 0x800e000000
229#define AID_TO_PCIE_LEAF_A_LIMIT 0x8010000000
230#define AID_TO_PCIE_LEAF_B_BASE 0xc000000000
231#define AID_TO_PCIE_LEAF_B_LIMIT 0xff00000000
232
233#define ASSIGN_LEAFA_SEGMENTS(_guestp) \
234 assign_ra2pa_segments(_guestp, AID_TO_PCIE_LEAF_A_BASE, \
235 AID_TO_PCIE_LEAF_A_LIMIT - AID_TO_PCIE_LEAF_A_BASE, \
236 0, IO_SEGMENT);
237
238#define ASSIGN_LEAFB_SEGMENTS(_guestp) \
239 assign_ra2pa_segments(_guestp, AID_TO_PCIE_LEAF_B_BASE, \
240 AID_TO_PCIE_LEAF_B_LIMIT - AID_TO_PCIE_LEAF_B_BASE, \
241 0, IO_SEGMENT);
242
243#define UNASSIGN_LEAFA_SEGMENTS(_guestp) \
244 assign_ra2pa_segments(guestp, AID_TO_PCIE_LEAF_A_BASE, \
245 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT);
246
247#define UNASSIGN_LEAFB_SEGMENTS(_guestp) \
248 assign_ra2pa_segments(guestp, AID_TO_PCIE_LEAF_B_BASE, \
249 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT);
250#else
251
252#define FIRE_IOBASE_A 0xe810000000
253#define FIRE_IOLIMIT_A 0xf000000000
254
255#define FIRE_IOBASE_B 0xf010000000
256#define FIRE_IOLIMIT_B 0xf800000000
257
258#define FIRE_EBUS_BASE 0xf820000000
259#define FIRE_EBUS_LIMIT 0xf828000000
260
261#define ASSIGN_LEAFA_SEGMENTS(_guestp) \
262 assign_ra2pa_segments(_guestp, FIRE_IOBASE_A, \
263 FIRE_IOLIMIT_A - FIRE_IOBASE_A, 0, IO_SEGMENT); \
264 assign_ra2pa_segments(_guestp, FIRE_EBUS_BASE, \
265 (FIRE_EBUS_LIMIT - FIRE_EBUS_BASE), 0, IO_SEGMENT);
266
267#define ASSIGN_LEAFB_SEGMENTS(_guestp) \
268 assign_ra2pa_segments(_guestp, FIRE_IOBASE_B, \
269 FIRE_IOLIMIT_B - FIRE_IOBASE_B, 0, IO_SEGMENT);
270
271#define UNASSIGN_LEAFA_SEGMENTS(_guestp) \
272 assign_ra2pa_segments(_guestp, FIRE_IOBASE_A, \
273 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT); \
274 assign_ra2pa_segments(_guestp, FIRE_EBUS_BASE, \
275 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT);
276
277#define UNASSIGN_LEAFB_SEGMENTS(_guestp) \
278 assign_ra2pa_segments(_guestp, FIRE_IOBASE_B, \
279 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT);
280
281#endif /* !CONFIG_IOBYPASS */
282
283void
284config_a_guest_pcie_bus(pcie_device_t *pciep)
285{
286 guest_t *guestp;
287 int id, vinobase, x;
288 uint8_t devid;
289
290 guestp = pciep->guestp;
291 id = pciep->id;
292
293 ASSERT(guestp != NULL);
294
295 devid = (pciep->cfg_handle) >> DEVCFGPA_SHIFT;
296 vinobase = pciep->cfg_handle;
297
298 plat_config_pcie_bypass(pciep);
299
300 switch (id) {
301 case PCIE_LEAF_A:
302 guestp->dev2inst[devid] = DEVOPS_FIRE_A;
303 ASSIGN_LEAFA_SEGMENTS(guestp);
304 DBG(c_printf("\tNOTICE pcie LEAF 0x%x " \
305 "configured for guest 0x%x\n", id,
306 guestp->guestid));
307 break;
308 case PCIE_LEAF_B:
309 guestp->dev2inst[devid] = DEVOPS_FIRE_B;
310 ASSIGN_LEAFB_SEGMENTS(guestp);
311 DBG(c_printf("\tNOTICE pcie LEAF 0x%x " \
312 "configured for guest 0x%x\n", id,
313 guestp->guestid));
314 break;
315 default:
316 DBG(c_printf("\tWARNING pcie 0x%x not "
317 "supported for guest 0x%x\n", id, guestp->guestid));
318 /* should probably panic here */
319 break;
320 }
321
322 for (x = 0; x < NINOSPERDEV; x++) {
323 guestp->vino2inst.vino[vinobase + x] =
324 config_pcie_vinos.vino[id][x];
325 }
326}
327
328void
329unconfig_a_guest_pcie_bus(pcie_device_t *pciep)
330{
331 guest_t *guestp;
332 int id, vinobase, x;
333 uint8_t devid;
334
335 guestp = pciep->guestp;
336 id = pciep->id;
337
338 ASSERT(guestp != NULL);
339
340 devid = (pciep->cfg_handle) >> DEVCFGPA_SHIFT;
341 vinobase = pciep->cfg_handle;
342
343 guestp->dev2inst[devid] = DEVOPS_RESERVED;
344 for (x = 0; x < NINOSPERDEV; x++) {
345 guestp->vino2inst.vino[vinobase + x] = DEVOPS_RESERVED;
346 }
347
348 /*
349 * We clear out the PCI I/O address segments by setting their size
350 * to INVALID_SEGMENT_SIZE and flags to INVALID_SEGMENT.
351 */
352 switch (id) {
353 case (PCIE_LEAF_A):
354 UNASSIGN_LEAFA_SEGMENTS(guestp);
355 break;
356 case (PCIE_LEAF_B):
357 UNASSIGN_LEAFB_SEGMENTS(guestp);
358 break;
359 default:
360 break;
361 }
362}
363
364
365
366#define CFGWR(_offset, _size, _val) \
367 do { \
368 if (!pci_config_put(firep, (_offset), _size, _val)) { \
369 DBGBR(c_printf("CFGWR fail "#_offset \
370 " ("#_size") <- "#_val"\n")); \
371 return (false); \
372 } \
373 } while (0)
374
375static bool_t plx_8532_aa_reset(int busnum);
376static bool_t plx_upstream_port_reset(fire_dev_t *firep);
377static bool_t is_plx_downstream_port_ready(fire_dev_t *firep, int port);
378static bool_t plx_set_elec_idle(int busnum, int port, bool_t on);
379#define NUM_PLX_PORTS 16
380static void plx_port_check(fire_dev_t *firep, int port);
381static void config_fire_pcie_bus(int busnum);
382
383static bool_t ontario_southbridge_reset(fire_dev_t *firep);
384
385
386/*
387 * This function does an initial test of the PCI-E links attached to
388 * Fire - primarily to determine if we have any PLX 8532 AA switches
389 * directly attached ... if so, we need to determine which ports are
390 * live so that we can guarantee a re-train in the event of a reset
391 */
392
393void
394config_platform_pcie()
395{
396 config_fire_pcie_bus(0);
397 config_fire_pcie_bus(1);
398}
399
400
401/*
402 * This function examines the specified PCI-E bus on fire, and looks
403 * for PLX 8532 AA switches ... and determines which downstream ports on
404 * those switches are live.
405 */
406
407void
408config_fire_pcie_bus(int busnum)
409{
410 uint64_t res;
411 fire_dev_t *firep;
412
413 firep = (fire_dev_t *)&fire_dev[busnum];
414
415 /* Becomes true after bus is used, false after it is reset */
416 firep->needs_warm_reset = false;
417 firep->blacklist = false;
418
419 DBGBR(c_printf("Probing Fire bus %d\n", busnum));
420
421 /*
422 * If the link is down, we don't do anything
423 * since it may mean there is no HW on the bus.
424 */
425
426 /*
427 * Just bail if nothing connected to the bus - Erie ?
428 * We indicate a failure on the bus in this case to ensure
429 * that we mark the bus to be ignored. Even though the link
430 * status is checked on each config write, we try to prevent the
431 * case where a link is down here and comes up later ... without
432 * the bus being properly reset. By returning a failure here we hope
433 * that the HV marks the bus as dead and prevents further
434 * guest accesses.
435 */
436 if (!is_fire_port_link_up(firep))
437 return;
438
439 /*
440 * If we are dealing with something other than
441 * a PLX or bridge (network card, for example)
442 * we simply toggle the link down and up.
443 * Otherwise we have to do the full secondary
444 * reset technique
445 */
446
447 /*
448 * We look for a bridge under fire.
449 * If the read fails, we have a problem ... abort for now, but
450 * need to handle this as simply the bus being inactive.
451 * We may need a fire reset to resolve this - i.e. power cycle.
452 */
453
454 if (!pci_config_get(firep, UPST_CFG_BASE + CFG_CLASS_CODE, 4, &res)) {
455 DBGBR(c_printf("Bridge read failed ... abandoning bus\n"));
456 return;
457 }
458
459 DBGBR(c_printf("Bridge class code 0x%x\n", res));
460
461 /*
462 * If the device class code indicates there is no bridge, then we
463 * simply stop here since we're not going to be doing a
464 * secondary reset.
465 */
466
467 if ((res>>8) != BRIDGE_CLASS_CODE) {
468 DBGBR(c_printf("Not a bridge ..."));
469 return;
470 }
471
472 /*
473 * We discovered a bridge, but is it a PLX ? indicating
474 * ... if this read fails something bad
475 * has happened given that we already read from the device.
476 * In this case we abandon the bus !
477 */
478
479 if (!pci_config_get(firep, UPST_CFG_BASE + 0, 4, &res)) {
480 DBGBR(c_printf("Bridge vendor ID read failed !!\n"));
481 return;
482 }
483
484 DBGBR(c_printf("1st bridge vendorid = 0x%x\n", res));
485
486 if (res != PLX_8532_DEV_VEND_ID)
487 return;
488
489 /*
490 * Scan the downstream ports on the PLX parts to "discover"
491 * which ones are live.
492 */
493
494 firep->live_port = 0;
495
496 switch (busnum) {
497 case 0:
498 plx_port_check(firep, 1);
499 plx_port_check(firep, 8);
500 break;
501 case 1:
502 plx_port_check(firep, 1);
503 plx_port_check(firep, 2);
504 plx_port_check(firep, 8);
505 plx_port_check(firep, 9);
506 break;
507 }
508
509 DBGBR(c_printf("Done probing bus 0x%x\n", busnum));
510}
511
512
513void
514plx_port_check(fire_dev_t *firep, int port)
515{
516 if (is_plx_downstream_port_ready(firep, port)) {
517 DBGBR(c_printf("Leaf %d has port %d\n",
518 firep - (fire_dev_t *)&(fire_dev[0]), port));
519 firep->live_port |= 1<<port;
520 }
521}
522
523
524bool_t
525toggle_fire_link(fire_dev_t *firep)
526{
527 DBGBR(c_printf("...toggle link\n"));
528
529 if (!fire_link_down(firep))
530 return (false);
531
532 c_usleep(500000);
533
534 if (!fire_link_up(firep))
535 return (false);
536
537 return (true);
538}
539
540/*
541 * This function resets a given Fire leaf
542 *
543 * (It should be based on rsetting a given pci-e resource).
544 *
545 * Inputs:
546 *
547 * bus - root complex (0 = leaf A, 1 = leaf B)
548 *
549 * Returns true on success, false on failure.
550 * Caller should mark bus unusable after failure.
551 */
552
553
554bool_t
555pcie_bus_reset(int busnum)
556{
557 uint64_t res, brcode;
558 fire_dev_t *firep;
559
560 firep = (fire_dev_t *)&fire_dev[busnum];
561
562 /*
563 * If the bus just came out of a power on cycle
564 * then we don't need to reset it again here.
565 */
566 if (!firep->needs_warm_reset) {
567 firep->needs_warm_reset = true;
568 return (true);
569 }
570
571 if (firep->blacklist)
572 return (false);
573
574 DBGBR(c_printf("Resetting bus %d (firep=0x%x)\n",
575 busnum, (uint64_t)firep));
576
577 /*
578 * If the link is down, we don't do anything
579 * since it may mean there is no HW on the bus.
580 */
581
582 /*
583 * Just bail if nothing connected to the bus - Erie ?
584 * We indicate a failure on the bus in this case to ensure
585 * that we mark the bus to be ignored. Even though the link
586 * status is checked on each config write, we try to prevent the
587 * case where a link is down here and comes up later ... without
588 * the bus being properly reset. By returning a failure here we hope
589 * that the HV marks the bus as dead and prevents further
590 * guest accesses.
591 */
592 if (!is_fire_port_link_up(firep)) {
593 goto fail;
594 }
595
596 /*
597 * If we are dealing with something other than
598 * a bridge (network card, for example)
599 * we simply toggle the link down and up.
600 * Otherwise we have to do the full secondary
601 * reset technique
602 */
603
604 /*
605 * We look for a bridge under fire.
606 * If the read fails, we have a problem ... abort for now, but
607 * need to handle this as simply the bus being inactive.
608 * We may need a fire reset to resolve this - i.e. power cycle.
609 */
610
611 if (!pci_config_get(firep, UPST_CFG_BASE + CFG_CLASS_CODE,
612 4, &brcode)) {
613 DBGBR(c_printf("Bridge read failed ... abandoning bus\n"));
614 goto fail;
615 }
616
617 DBGBR(c_printf("Bridge class code 0x%x\n", brcode));
618
619 /*
620 * If the device class code indicates there is no bridge, then we
621 * simply reset the link by toggling it
622 */
623
624 if ((brcode >> 8) != BRIDGE_CLASS_CODE) {
625 DBGBR(c_printf("Not a bridge ..."));
626 goto link_down_up;
627 }
628
629 /*
630 * We discovered a bridge, determine if it is a
631 * PLX 8532 also on Ontario we need to reset the south bridge.
632 * If the bridge is a PLX 8532 AA part we do a secondary bus reset.
633 * On other bridges and versions of PLX 8532 we just toggle
634 * the fire link.
635 */
636
637 if (!pci_config_get(firep, UPST_CFG_BASE + 0, 4, &res)) {
638 DBGBR(c_printf("Bridge vendor ID read failed !!\n"));
639 goto fail;
640 }
641
642 DBGBR(c_printf("1st bridge vendorid = 0x%x\n", res));
643
644 switch (res) {
645
646 case PLX_8532_DEV_VEND_ID :
647
648 /*
649 * Reset Southbridge if found.
650 */
651 if ((busnum == 1) && firep->live_port & 0x2) {
652 DBGBR(c_printf("Southbridge reset\n"));
653 if (!ontario_southbridge_reset(firep)) {
654 DBGBR(c_printf(
655 "Southbridge reset failed\n"));
656 goto fail;
657 }
658 }
659
660 if ((brcode & 0xff) == 0xaa) {
661 /*
662 * Perform secondary reset.
663 */
664
665 if (!plx_8532_aa_reset(busnum)) {
666 DBGBR(c_printf(
667 "Failed PLX 8532 AA reset\n"));
668 goto fail;
669 }
670 } else {
671 DBGBR(c_printf(
672 "Found 0x%x PLX part toggling fire link.\n",
673 brcode &0xff));
674 if (!toggle_fire_link(firep))
675 goto fail;
676 c_usleep(200000); /* 200ms */
677 }
678 break;
679 default :
680 goto link_down_up;
681 };
682
683 DBGBR(c_printf("Fire port reset\n"));
684
685 return (true);
686
687link_down_up:
688 if (!toggle_fire_link(firep))
689 goto fail;
690
691 return (true);
692fail:
693 firep->blacklist = true;
694 DBGBR(c_printf("Fire Leaf reset FAILED BLACKLISTING\n"));
695 return (false);
696}
697
698
699static bool_t
700plx_8532_aa_reset(int busnum)
701{
702 int reset_count;
703 fire_dev_t *firep;
704 int i;
705 uint64_t res;
706
707 firep = (fire_dev_t *)&fire_dev[busnum];
708
709 /*
710 * We discovered a bridge, but is it a PLX ? indicating
711 * ... if this read fails something bad
712 * has happened given that we already read from the device.
713 * In this case we abandon the bus !
714 */
715
716 DBGBR(c_printf("Resetting with SBR\n"));
717 if (!pci_config_get(firep, UPST_CFG_BASE + 0, 4, &res)) {
718 DBGBR(c_printf("Bridge vendor ID read failed !!\n"));
719 return (false);
720 }
721
722 DBGBR(c_printf("1st bridge vendorid = 0x%x\n", res));
723
724 reset_count = 0;
725
726 DBGBR(c_printf("\tdetect elect idle on station 0\n"));
727 (void) plx_set_elec_idle(busnum, 0, false);
728 DBGBR(c_printf("\tdetect elect idle on station 1\n"));
729 (void) plx_set_elec_idle(busnum, 8, false);
730
731reset_again:;
732
733 c_usleep(500000);
734 DBGBR(c_printf("Attempting PLX upstream reset for bus %d - try %d\n",
735 busnum, reset_count));
736
737 if (!plx_upstream_port_reset(firep))
738 return (false);
739
740 /* wait for everything to settle/retrain */
741 c_usleep(1500000);
742
743 for (i = 0; i < NUM_PLX_PORTS; i++) {
744 if (((firep->live_port >> i) & 1) == 0)
745 continue;
746
747 /* Enter here if port i requires resetting */
748
749 DBGBR(c_printf("Secondary reset for leaf %d port %d\n",
750 busnum, i));
751
752 if (is_plx_downstream_port_ready(firep, i))
753 continue;
754
755 /* Failed - we need another upstream reset */
756
757 if (++reset_count < MAX_RESETS)
758 goto reset_again;
759
760 /* After max resets we'll blacklist the port instead */
761 }
762
763 DBGBR(c_printf("\tdont detect elect idle on station 0\n"));
764 (void) plx_set_elec_idle(busnum, 0, true);
765 DBGBR(c_printf("\tdont detect elect idle on station 1\n"));
766 (void) plx_set_elec_idle(busnum, 8, true);
767
768
769 /* initialize up stream port */
770 CFGWR(UPST_CFG_BASE + CFG_CMD_REG, 2, 0x0);
771 CFGWR(UPST_CFG_BASE + CFG_BAR0, 4, 0x0);
772 CFGWR(UPST_CFG_BASE + CFG_BAR1, 4, 0x0);
773 CFGWR(UPST_CFG_BASE + CFG_PS_BUS, 4, 0x0);
774 CFGWR(UPST_CFG_BASE + CFG_IOBASE_LIM, 2, 0xff);
775 CFGWR(UPST_CFG_BASE + CFG_MEMBASE, 2, 0xffff);
776 CFGWR(UPST_CFG_BASE + CFG_MEMLIM, 2, 0x0);
777 CFGWR(UPST_CFG_BASE + CFG_PFBASE, 2, 0xffff);
778 CFGWR(UPST_CFG_BASE + CFG_PFLIM, 2, 0x0);
779 CFGWR(UPST_CFG_BASE + CFG_PF_UBASE, 4, 0xffffffff);
780 CFGWR(UPST_CFG_BASE + CFG_PF_ULIM, 4, 0x0);
781 CFGWR(UPST_CFG_BASE + CFG_IO_UBASE, 2, 0xffff);
782 CFGWR(UPST_CFG_BASE + CFG_IO_ULIM, 2, 0x0);
783
784 /* Finally clear any accumulated errors */
785 CFGWR(UPST_CFG_BASE + CFG_STAT_CTRL, 4, 0x000f0000);
786
787 return (true);
788}
789
790static bool_t
791plx_upstream_port_reset(fire_dev_t *firep)
792{
793 uint64_t res;
794
795 DBGBR(c_printf("plx_upstream_port_reset\n"));
796 /* If the loads and stores fail - abandon the bus */
797 if (!pci_config_get(firep, UPST_CFG_BASE+CFG_SECONDARY_RESET,
798 4, &res)) {
799 DBGBR(c_printf("SECONDARY_RESET set, read fail\n"));
800 return (false);
801 }
802
803 if (!pci_config_put(firep, UPST_CFG_BASE+CFG_SECONDARY_RESET,
804 4, res | (1LL<<22))) {
805 DBGBR(c_printf("SECONDARY_RESET set, write fail\n"));
806#if 0 /* { FIXME: */
807 return (false);
808#endif /* } */
809 }
810
811 DBGBR(c_printf("\tBus down ... waiting 200ms\n"));
812
813 c_usleep(200000);
814
815 DBGBR(c_printf("\tWakeup bus\n"));
816
817 if (!pci_config_get(firep, UPST_CFG_BASE+CFG_SECONDARY_RESET,
818 4, &res)) {
819 DBGBR(c_printf("SECONDARY_RESET clear, read fail\n"));
820 return (false);
821 }
822
823 DBGBR(c_printf("\tsecondary reset register status 0x%x\n", res));
824
825 if (!pci_config_put(firep, UPST_CFG_BASE+CFG_SECONDARY_RESET,
826 4, res & ~(1LL<<22))) {
827 DBGBR(c_printf("SECONDARY_RESET clear, write fail\n"));
828 return (false);
829 }
830
831 DBGBR(c_printf("\tSecondary reset completed\n"));
832 return (true);
833}
834
835
836static bool_t
837is_plx_downstream_port_ready(fire_dev_t *firep, int port)
838{
839 uint64_t port_cfg_base;
840 uint64_t res;
841
842 port_cfg_base = DNST_CFG_PORT_BASE(port);
843
844 DBGBR(c_printf("is_plx_downstream_port_ready : port %d\n", port));
845
846 /* setup config access to the downstream port */
847 CFGWR(UPST_CFG_BASE + CFG_PS_BUS, 4, UPST_CFG_PS_BUS_VAL);
848
849 DBGBR(c_printf("\tChecking link up ..\n"));
850
851 if (!pci_config_get(firep, port_cfg_base + CFG_VC0_STATUS,
852 4, &res)) {
853 DBGBR(c_printf("VC0 status register read failed\n"));
854 return (false);
855 }
856
857 DBGBR(c_printf("VC0 status = 0x%x\n", res));
858
859 if ((res & CFG_VC0_STATUS_MASK) != 0) {
860 DBGBR(c_printf("\n\nPLX link failed to train\n\n\n"));
861 return (false);
862 }
863
864 return (true);
865}
866
867
868/*
869 * On an Ontario, to reset the Southbridge we have to:
870 * - initiate secondary reset
871 * - program bus to allow Southbridge IO access
872 * - reset southbridge device
873 * - initiate secondary reset (again)
874 */
875static bool_t
876ontario_southbridge_reset(fire_dev_t *firep)
877{
878 uint64_t res;
879
880 /* setup config access */
881 CFGWR(UPST_CFG_BASE + CFG_PS_BUS, 4, UPST_CFG_PS_BUS_VAL);
882
883 /* I/O base and Limit : 0 - 1000 */
884 CFGWR(UPST_CFG_BASE + CFG_IOBASE_LIM, 2, 0x0100);
885
886 /* IO upper base */
887 CFGWR(UPST_CFG_BASE + CFG_IO_UBASE, 4, 0x0);
888
889 /* command register: allow IO access */
890 CFGWR(UPST_CFG_BASE + CFG_CMD_REG, 4, 0x5);
891
892 /* config downstream bus for Southbridge IO access */
893 CFGWR(DNST_CFG_BASE + CFG_PS_BUS, 4, DNST_CFG_PS_BUS_VAL);
894
895 /* I/O base and Limit: 0 - 1000 */
896 CFGWR(DNST_CFG_BASE + CFG_IOBASE_LIM, 2, 0x0100);
897
898 /* IO upper base */
899 CFGWR(DNST_CFG_BASE + CFG_IO_UBASE, 2, 0x0);
900
901 /* command register: allow IO access */
902 CFGWR(DNST_CFG_BASE + CFG_CMD_REG, 2, 0x5);
903
904 /*
905 * Let's check and see if we have an Intel PCI-E -> PCI-X
906 * bridge .. if not, then we have no southbridge either
907 */
908
909 if (!pci_config_get(firep, PE2X_CFG_BASE + 0x0, 4, &res)) {
910 DBGBR(c_printf("Failed reading second bridge vendor id\n"));
911 return (false);
912 }
913
914 /*
915 * If no Intel bridge, then we have no Southbridge to reset.
916 */
917 if (res != INTEL_BRG_DEV_VEND_ID) {
918 DBGBR(c_printf("No Intel bridge - ergo no southbridge\n"));
919 return (true);
920 }
921
922
923 /*
924 * Now we do the south bridge clobber
925 */
926
927 /*
928 * config PCIE->PCIX for Southbridge IO access
929 * setup config access
930 */
931 CFGWR(PE2X_CFG_BASE + CFG_PS_BUS, 4, PE2X_CFG_PS_BUS_VAL);
932
933 /* I/O base and Limit: 0 - 1000 */
934 CFGWR(PE2X_CFG_BASE + CFG_IOBASE_LIM, 2, 0x0100);
935
936 /* IO upper base */
937 CFGWR(PE2X_CFG_BASE + CFG_IO_UBASE, 4, 0x0);
938
939 /* command register: allow IO access */
940 CFGWR(PE2X_CFG_BASE + CFG_CMD_REG, 2, 0x5);
941
942
943 /*
944 * Check the vendor ID of the southbridge
945 */
946
947 if (!pci_config_get(firep, SOUTHBRIDGE_CFG_BASE + 0x0, 4, &res)) {
948 DBGBR(c_printf("Failed reading southbridge vendor ID\n"));
949 return (false);
950 }
951
952 if (res != ALI_SB_DEV_VEND_ID) {
953 DBGBR(c_printf("Success - no southbridge to reset\n"));
954 return (true);
955 }
956
957 DBGBR(c_printf("Resetting southbridge NOW !\n"));
958
959
960 /* Enable IO space access */
961 CFGWR(SOUTHBRIDGE_CFG_BASE + SOUTHBRIDGE_CFG_RESET, 1, 1LL<<7);
962
963#define MB * (1024LL*1024LL) /* used by CFG_SIZE! */
964
965 /* Now we do an IO write to the Southbridge */
966 if (!pci_io_poke(firep, firep->cfg + CFG_SIZE + SOUTHBRIDGE_IO_RESET,
967 1, SOUTHBRIDGE_RESET_VAL, SOUTHBRIDGE_CFG_BASE)) {
968 DBGBR(c_printf("Couldn't poke SB reset\n"));
969 }
970
971 /* Cleanup after ourselves */
972 CFGWR(PE2X_CFG_BASE + CFG_PS_BUS, 4, 0x0);
973 CFGWR(PE2X_CFG_BASE + CFG_IOBASE_LIM, 2, 0xff);
974 CFGWR(PE2X_CFG_BASE + CFG_IO_UBASE, 4, 0xffff);
975 CFGWR(PE2X_CFG_BASE + CFG_CMD_REG, 2, 0x0);
976 CFGWR(DNST_CFG_BASE + CFG_PS_BUS, 4, 0x0);
977 CFGWR(DNST_CFG_BASE + CFG_IOBASE_LIM, 2, 0xff);
978 CFGWR(DNST_CFG_BASE + CFG_IO_UBASE, 2, 0xffff);
979 CFGWR(DNST_CFG_BASE + CFG_CMD_REG, 2, 0x0);
980 CFGWR(UPST_CFG_BASE + CFG_IOBASE_LIM, 2, 0xff);
981 CFGWR(UPST_CFG_BASE + CFG_IO_UBASE, 4, 0xffff);
982 CFGWR(UPST_CFG_BASE + CFG_CMD_REG, 4, 0x0);
983
984 c_usleep(1000000);
985 return (true);
986}
987
988
989/*
990 * This function only works for PLX 8532 AA parts.
991 */
992
993static bool_t
994plx_set_elec_idle(int busnum, int port, bool_t post_reset)
995{
996 uint64_t fire_membase, offset, res;
997 uint64_t port_cfg_offset;
998 fire_dev_t *firep;
999
1000 firep = (fire_dev_t *)&fire_dev[busnum];
1001
1002 fire_membase = busnum ? FIRE_BAR(0xf200ull) : FIRE_BAR(0xea00ull);
1003
1004 offset = port * 4096 + 0x22C; /* electric idle bit offset */
1005
1006 port_cfg_offset = (port == 0) ? UPST_CFG_BASE :
1007 DNST_CFG_PORT_BASE(port);
1008
1009 DBGBR(c_printf("Fire leaf 0x%x membase 0x%x offset 0x%x = 0x%x\n",
1010 busnum, fire_membase, offset, fire_membase +offset));
1011
1012 CFGWR(UPST_CFG_BASE + CFG_PS_BUS, 4, UPST_CFG_PS_BUS_VAL);
1013 CFGWR(UPST_CFG_BASE + CFG_CMD_REG, 2, 2);
1014 CFGWR(UPST_CFG_BASE + CFG_BAR0, 4, 0);
1015 if (!pci_io_peek(firep, fire_membase + offset, 4, &res)) {
1016 DBGBR(c_printf("Couldn't peek elec idle\n"));
1017 }
1018
1019 DBGBR(c_printf("PHY elec idle reg 0x%x\n", res));
1020
1021 if (!post_reset) {
1022 res &= ~0x10LL;
1023 } else {
1024 res |= 0x10LL;
1025 }
1026
1027 DBGBR(c_printf("PHY elec idle reg after op %d 0x%x\n", post_reset,
1028 res));
1029 if (!pci_io_poke(firep, fire_membase + offset,
1030 4, res, port_cfg_offset)) {
1031 DBGBR(c_printf("Couldn't poke elec idle\n"));
1032 }
1033
1034 return (true);
1035}
1036
1037#endif