Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / huron / src / res_piu_pcie.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: res_piu_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#pragma ident "@(#)res_piu_pcie.c 1.6 07/06/07 SMI"
51
52#include <stdarg.h>
53
54#include <sys/htypes.h>
55#include <hypervisor.h>
56#include <traps.h>
57#include <sun4v/asi.h>
58#include <sun4v/errs_defs.h>
59#include <vdev_ops.h>
60#include <vdev_intr.h>
61#include <config.h>
62#include <ncs.h>
63#include <mmu.h>
64#include <cyclic.h>
65#include <vcpu.h>
66#include <strand.h>
67#include <guest.h>
68#include <segments.h>
69#include <memory.h>
70#include <pcie.h>
71#include <support.h>
72#include <md.h>
73#include <abort.h>
74#include <proto.h>
75#include <piu.h>
76#include <fpga.h>
77
78#ifdef CONFIG_PCIE
79
80#ifdef CONFIG_PIU
81extern const struct piu_cookie piu_dev[];
82void c_piu_leaf_soft_reset(const struct piu_cookie *, int root);
83#endif
84
85void plat_config_pcie_bypass(pcie_device_t *pciep);
86static void config_pcie_bypass(guest_t *guestp, int bus_id);
87static void setup_bypass_mappings(int bus_id, uint64_t base_pa, uint64_t size);
88static void clear_pcie_bypass(int bus_id);
89
90/*
91 * (re)-configuration code to handle HV PIU PCI-E resources
92 */
93
94#define MAX_RESETS 10
95
96void
97config_platform_pcie()
98{
99 DBG(c_printf("config_piu()\n"));
100}
101
102void
103reset_platform_pcie_busses(guest_t *guestp, pcie_device_t *pciep)
104{
105 extern const struct piu_cookie piu_dev[];
106 int i;
107
108 /* reset attached devices like the PCI busses */
109 pciep = config.pcie_busses;
110 for (i = 0; i < NUM_PCIE_BUSSES; i++) {
111
112 DBGBR(c_printf("pcie 0x%x assigned to guest 0x%x\n",
113 &pciep[i], pciep[i].guestp));
114
115 /* if bus is assigned to this guest, soft reset the bus */
116 if (pciep[i].guestp == guestp) {
117 DBGBR(c_printf("Soft Reset PCI leaf 0x%x cookie 0x%x\n",
118 i, piu_dev[i].pcie));
119
120#if 0
121 /*
122 * we dont care if this works really - if it fails
123 * the bus is likely dead. The reset on guest restart
124 * will likely set it up to function again ...
125 */
126 (void) pcie_bus_reset(i);
127#endif
128
129 /*
130 * regardless of the bus reset we shutdown PIU's
131 * IOMMU and interrupt logic for this bus
132 */
133 c_piu_leaf_soft_reset(
134 (struct piu_cookie *)&piu_dev[i], i);
135 }
136 }
137}
138
139#ifdef CONFIG_IOBYPASS
140
141/*
142 * For a guest which is allowed direct access to the I/O bridges
143 * this sets up the segments for the I/O physical addresses.
144 */
145
146#define BASE_1 0x8800000000
147#define LIMIT_1 0x8900000000
148#define BASE_2 0xc000000000
149#define LIMIT_2 0xff00000000
150
151#define ASSIGN_PIU_SEGMENTS(_guestp) \
152 assign_ra2pa_segments(_guestp, BASE_1, \
153 LIMIT_1 - BASE_1, 0, IO_SEGMENT); \
154 assign_ra2pa_segments(_guestp, BASE_2, \
155 LIMIT_2 - BASE_2, 0, IO_SEGMENT); \
156 assign_ra2pa_segments(guestp, FPGA_UART_BASE, \
157 FPGA_UART_LIMIT - FPGA_UART_BASE, 0, IO_SEGMENT);
158
159#define UNASSIGN_PIU_SEGMENTS(_guestp) \
160 assign_ra2pa_segments(_guestp, BASE_1, \
161 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT); \
162 assign_ra2pa_segments(_guestp, BASE_2, \
163 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT); \
164 assign_ra2pa_segments(guestp, FPGA_UART_BASE, \
165 FPGA_UART_LIMIT - FPGA_UART_BASE, 0, INVALID_SEGMENT);
166#else
167
168#define PIU_BASE (0xc810000000)
169#define PIU_LIMIT (0xd000000000)
170
171#define ASSIGN_PIU_SEGMENTS(_guestp) \
172 assign_ra2pa_segments(_guestp, PIU_BASE, \
173 PIU_LIMIT - PIU_BASE, 0, IO_SEGMENT); \
174 assign_ra2pa_segments(guestp, FPGA_UART_BASE, \
175 FPGA_UART_LIMIT - FPGA_UART_BASE, 0, IO_SEGMENT);
176
177#define UNASSIGN_PIU_SEGMENTS(_guestp) \
178 assign_ra2pa_segments(_guestp, PIU_BASE, \
179 INVALID_SEGMENT_SIZE, 0, INVALID_SEGMENT); \
180 assign_ra2pa_segments(guestp, FPGA_UART_BASE, \
181 FPGA_UART_LIMIT - FPGA_UART_BASE, 0, INVALID_SEGMENT);
182
183#endif /* CONFIG_IOBYPASS */
184
185void
186config_a_guest_pcie_bus(pcie_device_t *pciep)
187{
188 guest_t *guestp;
189 int id, vinobase, x;
190 uint8_t devid;
191
192 guestp = pciep->guestp;
193 id = pciep->id;
194
195 ASSERT(guestp != NULL);
196
197 devid = (pciep->cfg_handle) >> DEVCFGPA_SHIFT;
198 vinobase = pciep->cfg_handle;
199
200 plat_config_pcie_bypass(pciep);
201
202 switch (id) {
203 case (0):
204 guestp->dev2inst[devid] = DEVOPS_PIU(0);
205 ASSIGN_PIU_SEGMENTS(guestp);
206 DBGBR(c_printf("\tNOTICE pcie LEAF 0x%x " \
207 "configured for guest 0x%x\n", id,
208 guestp->guestid));
209 break;
210 default:
211 DBGBR(c_printf("\tWARNING pcie 0x%x not "
212 "supported for guest 0x%x\n", id, guestp->guestid));
213 /* should probably panic here */
214 break;
215 }
216
217 for (x = 0; x < NINOSPERDEV; x++) {
218 guestp->vino2inst.vino[vinobase + x] =
219 config_pcie_vinos.vino[id][x];
220 }
221}
222
223void
224unconfig_a_guest_pcie_bus(pcie_device_t *pciep)
225{
226 guest_t *guestp;
227 int id, vinobase, x;
228 uint8_t devid;
229
230 guestp = pciep->guestp;
231 id = pciep->id;
232
233 ASSERT(guestp != NULL);
234
235 devid = (pciep->cfg_handle) >> DEVCFGPA_SHIFT;
236 vinobase = pciep->cfg_handle;
237
238 guestp->dev2inst[devid] = DEVOPS_RESERVED;
239 for (x = 0; x < NINOSPERDEV; x++) {
240 guestp->vino2inst.vino[vinobase + x] = DEVOPS_RESERVED;
241 }
242
243 /*
244 * We clear out the PCI I/O address segments by setting their size
245 * to INVALID_SEGMENT_SIZE and flags to INVALID_SEGMENT.
246 */
247 switch (id) {
248 case (0):
249 UNASSIGN_PIU_SEGMENTS(guestp);
250 break;
251 default:
252 break;
253 }
254}
255
256#define CFGWR(_offset, _size, _val) \
257 do { \
258 if (!pci_config_put(firep, (_offset), _size, _val)) { \
259 DBGBR(c_printf("CFGWR fail "#_offset \
260 " ("#_size") <- "#_val"\n")); \
261 return (false); \
262 } \
263 } while (0)
264
265
266static void config_piu_pcie_bus(int busnum);
267
268/*
269 * This function does an initial test of the PCI-E links attached to
270 * PIU - primarily to determine if we have any PLX 8532 AA switches
271 * directly attached ... if so, we need to determine which ports are
272 * live so that we can guarantee a re-train in the event of a reset
273 */
274void
275config_pcie()
276{
277
278}
279
280/*
281 * This function examines the specified PCI-E bus on PIU, and looks
282 * for PLX 8532 AA switches ... and determines which downstream ports on
283 * those switches are live.
284 */
285
286void
287config_piu_pcie_bus(int busnum)
288{
289 uint64_t res;
290 piu_dev_t *piup;
291
292 ASSERT(busnum == 0);
293
294 piup = (piu_dev_t *)&piu_dev[busnum];
295
296 /* Becomes true after bus is used, false after it is reset */
297 piup->needs_warm_reset = false;
298 piup->blacklist = false;
299
300 DBGBR(c_printf("Probing PIU bus %d\n", busnum));
301
302 /*
303 * If the link is down, we don't do anything
304 * since it may mean there is no HW on the bus.
305 */
306
307 /*
308 * Just bail if nothing connected to the bus
309 * We indicate a failure on the bus in this case to ensure
310 * that we mark the bus to be ignored. Even though the link
311 * status is checked on each config write, we try to prevent the
312 * case where a link is down here and comes up later ... without
313 * the bus being properly reset. By returning a failure here we hope
314 * that the HV marks the bus as dead and prevents further
315 * guest accesses.
316 */
317 if (!is_piu_port_link_up(piup))
318 return;
319
320 /*
321 * If we are dealing with something other than
322 * a PLX or bridge (network card, for example)
323 * we simply toggle the link down and up.
324 * Otherwise we have to do the full secondary
325 * reset technique
326 */
327
328 /*
329 * We look for a bridge under PIU.
330 * If the read fails, we have a problem ... abort for now, but
331 * need to handle this as simply the bus being inactive.
332 * We may need a PIU reset to resolve this - i.e. power cycle.
333 */
334
335 if (!pci_config_get(piup, UPST_CFG_BASE + CFG_CLASS_CODE, 4, &res)) {
336 DBGBR(c_printf("Bridge read failed ... abandoning bus\n"));
337 return;
338 }
339
340 DBGBR(c_printf("Bridge class code 0x%x\n", res));
341
342 /*
343 * If the device class code indicates there is no bridge, then we
344 * simply stop here since we're not going to be doing a
345 * secondary reset.
346 */
347
348 if ((res>>8) != BRIDGE_CLASS_CODE) {
349 DBGBR(c_printf("Not a bridge ..."));
350 return;
351 }
352
353 /*
354 * We discovered a bridge, but is it a PLX ? indicating
355 * ... if this read fails something bad
356 * has happened given that we already read from the device.
357 * In this case we abandon the bus !
358 */
359
360 if (!pci_config_get(piup, UPST_CFG_BASE + 0, 4, &res)) {
361 DBGBR(c_printf("Bridge vendor ID read failed !!\n"));
362 return;
363 }
364
365 DBGBR(c_printf("1st bridge vendorid = 0x%x\n", res));
366 DBGBR(c_printf("Done probing bus 0x%x\n", busnum));
367}
368
369/*
370 * This function resets a given PIU leaf
371 *
372 * (It should be based on resetting a given pci-e resource).
373 *
374 * Inputs:
375 *
376 * bus - root complex (0 = leaf A)
377 *
378 * Returns true on success, false on failure.
379 * Caller should mark bus unusable after failure.
380 */
381bool_t
382pcie_bus_reset(int busnum)
383{
384 uint64_t brcode;
385 piu_dev_t *piup;
386
387 piup = (piu_dev_t *)&piu_dev[busnum];
388
389 /*
390 * If the bus just came out of a power on cycle
391 * then we don't need to reset it again here.
392 */
393 if (!piup->needs_warm_reset) {
394 piup->needs_warm_reset = true;
395 DBGBR(c_printf("PCI-E warm reset not required\r\n"));
396 return (true);
397 }
398
399 if (piup->blacklist) {
400 DBGBR(c_printf("PCI-E bus 0x%x blacklisted \r\n", busnum));
401 return (false);
402 }
403
404 DBGBR(c_printf("Resetting bus %d (piup=0x%x)\n",
405 busnum, (uint64_t)piup));
406
407 /*
408 * If the link is down, we don't do anything
409 * since it may mean there is no HW on the bus.
410 */
411 /*
412 * Just bail if nothing connected to the bus
413 * We indicate a failure on the bus in this case to ensure
414 * that we mark the bus to be ignored. Even though the link
415 * status is checked on each config write, we try to prevent the
416 * case where a link is down here and comes up later ... without
417 * the bus being properly reset. By returning a failure here we hope
418 * that the HV marks the bus as dead and prevents further
419 * guest accesses.
420 */
421 if (!is_piu_port_link_up(piup)) {
422 DBGBR(c_printf("PCI-E bus 0x%x link down \r\n", busnum));
423 goto fail;
424 }
425
426 DBGBR(c_printf("PCI-E bus 0x%x link is up \r\n", busnum));
427
428
429 /*
430 * If we are dealing with something other than
431 * a bridge (network card, for example)
432 * we simply toggle the link down and up.
433 * Otherwise we have to do the full secondary
434 * reset technique
435 */
436
437 /*
438 * We look for a bridge under PIU.
439 * If the read fails, we have a problem ... abort for now, but
440 * need to handle this as simply the bus being inactive.
441 * We may need a fire reset to resolve this - i.e. power cycle.
442 */
443
444 if (!pci_config_get(piup, UPST_CFG_BASE + CFG_CLASS_CODE,
445 4, &brcode)) {
446 DBGBR(c_printf("Bridge read failed ... abandoning bus\n"));
447 goto fail;
448 }
449
450 DBGBR(c_printf("Bridge class code 0x%x\n", brcode));
451
452 /*
453 * If the device class code indicates there is no bridge, then we
454 * simply reset the link by toggling it
455 */
456
457 if ((brcode>>8) != BRIDGE_CLASS_CODE) {
458 DBGBR(c_printf("Not a bridge ..."));
459 DBGBR(c_printf("...toggle link\n"));
460
461 if (!piu_link_down(piup))
462 goto fail;
463
464 piu_reset_onboard_devices();
465
466 if (!piu_link_up(piup))
467 goto fail;
468 }
469
470 return (true);
471
472fail:
473 piup->blacklist = true;
474 c_hvabort(-1);
475 return (false);
476}
477
478void
479piu_reset_onboard_devices(void)
480{
481#ifdef CONFIG_FPGA
482 volatile uint16_t *fpga_device_id = (uint16_t *)FPGA_DEVICE_ID;
483 volatile uint8_t *fpga_reset_control =
484 (uint8_t *)FPGA_LDOM_RESET_CONTROL;
485 volatile uint8_t *fpga_slot_reset_control =
486 (uint8_t *)FPGA_LDOM_SLOT_RESET_CONTROL;
487 volatile uint8_t *fpga_device_present =
488 (uint8_t *)FPGA_DEVICE_PRESENT;
489 volatile uint16_t fpga_major_version;
490 volatile uint8_t fpga_devices;
491
492 /*
493 * GPIO reset support
494 * If FPGA has GPIO reset support(checked with major revision
495 * ID), then twiddle the reset pins for the onboard devices
496 * and pcie slots. Hold reset for 200 msec, then wait for
497 * 1 second.
498 */
499 fpga_major_version = (*fpga_device_id >> FPGA_ID_MAJOR_ID_SHIFT)
500 & FPGA_ID_MAJOR_ID_MASK;
501 if (fpga_major_version >= FPGA_MIN_MAJOR_ID_RESET_SUPPORT) {
502 DBGBR(c_printf("link toggled down\n"));
503 fpga_devices = *fpga_device_present;
504 *fpga_reset_control = FPGA_LDOM_RESET_CONTROL_MASK;
505 *fpga_slot_reset_control = fpga_devices;
506 c_usleep(200000); /* 200ms */
507 *fpga_reset_control = 0;
508 *fpga_slot_reset_control = 0;
509 c_usleep(1000000); /* 1sec */
510
511 DBGBR(c_printf("PCI-E bus has devices " \
512 "present at slots 0x%x\r\n", fpga_devices));
513 }
514#endif /* CONFIG_FPGA */
515}
516
517void
518init_pcie_buses(void)
519{
520 DBGPE(c_printf("initializing pcie buses\n"));
521}
522
523static void
524setup_bypass_mappings(int bus_id, uint64_t bypass_pa, uint64_t size)
525{
526 extern const uint64_t piu_iotsb1;
527
528 piu_dev_t *piup;
529 uint64_t *ttep;
530 uint64_t nttes;
531 int i;
532
533 ASSERT(bus_id == 0);
534 piup = (piu_dev_t *)&(piu_dev[bus_id]);
535
536 nttes = size >> IOTSB1_PAGESHIFT;
537
538 DBGPE(c_printf("PA 0x%x size 0x%x shift 0x%x nttes 0x%x max 0x%x\n",
539 bypass_pa, size, IOTSB1_PAGESHIFT, nttes, IOTSB1_TSB_SIZE));
540
541 ASSERT(nttes <= IOMMU_SIZE(IOTSB1_TSB_SIZE));
542
543 ttep = piup->iotsb1;
544
545 /*
546 * Set up a 4MB mapping for each page in the guests address space
547 */
548 for (i = 0; i < nttes; i++) {
549 *ttep++ = PIU_IOTTE(bypass_pa + (i << IOTSB1_PAGESHIFT));
550 }
551}
552
553static void
554clear_pcie_bypass(int bus_id)
555{
556 piu_dev_t *piup;
557
558 /*
559 * Invalidate all entries in the large page IOSTB
560 */
561 ASSERT(bus_id == 0);
562 piup = (piu_dev_t *)&(piu_dev[bus_id]);
563 c_bzero(piup->iotsb1, IOTSB1_SIZE);
564}
565
566static void
567config_pcie_bypass(guest_t *guestp, int bus_id)
568{
569 uint64_t segment_idx;
570 uint64_t bypass_pa;
571 uint64_t bypass_size;
572
573 DBGPE(c_printf("initializing pcie IO TSB1 RA 0x%x limit 0x%x\n",
574 guestp->real_base, guestp->real_limit));
575 DBGPE(c_printf("initializing pcie IO TSB1 PA 0x%x len 0x%x\n",
576 guestp->real_base + guestp->mem_offset,
577 guestp->real_limit - guestp->real_base));
578
579 segment_idx = guestp->real_base >> RA2PA_SHIFT;
580 ASSERT((guestp->ra2pa_segment[segment_idx].flags &
581 MEM_SEGMENT) == MEM_SEGMENT);
582
583 /*
584 * Get the base PA of the guests memory segment. The
585 * size of the bypass address space allocated is the
586 * total real memory allocated to the guest. As with HWTW,
587 * this will break if the guests memory has holes.
588 *
589 * Also, do we really need to OR in PIU_IOMMU_BYPASS_BASE,
590 * this will be masked out of the PA used in the IOTSB.
591 */
592 bypass_pa = (guestp->ra2pa_segment[segment_idx].base +
593 guestp->ra2pa_segment[segment_idx].offset) |
594 PIU_IOMMU_BYPASS_BASE;
595 bypass_size = guestp->real_limit - guestp->real_base;
596
597 DBGPE(c_printf("PCI Bypass Address 0x%x size 0x%x\n",
598 bypass_pa, bypass_size));
599
600 /*
601 * bypass_pa must be aligned on the TSB page size
602 */
603 if (bypass_pa & IOTSB1_PAGE_MASK) {
604 DBGPE(c_printf("Misaligned Guest PCI Bypass Address 0x%llx \n",
605 bypass_pa));
606 c_hvabort(-1);
607 }
608
609 /*
610 * bypass_size must be a multiple of the TSB page size
611 */
612 if (bypass_size & IOTSB1_PAGE_MASK) {
613 DBGPE(c_printf("Invalid Guest PCI Bypass Size 0x%llx \n",
614 bypass_pa));
615 c_hvabort(-1);
616 }
617
618 DBGPE(c_printf("Create IO TSB1 mappings\n"));
619
620 setup_bypass_mappings(bus_id, bypass_pa, bypass_size);
621}
622
623/*
624 * N2 PIU does not have functionality equivalent to N1 Fire Bypass Mode
625 * but some drivers rely on this so we need to provide a similar
626 * feature for PIU. What we do is allocate a second IOTSB which maps
627 * all of the guests memory using 4MB pages. This imposes the constraint
628 * that the guests address space is 4MB aligned and a multiple of 4MB.
629 *
630 * It would be better to just make the second IOTSB available to the
631 * guest for it to create large page mappings itself.
632 */
633void
634plat_config_pcie_bypass(pcie_device_t *pciep)
635{
636 int id;
637
638 id = pciep->id;
639 ASSERT(id == 0);
640
641 if (pciep->allow_bypass) {
642 DBGPE(c_printf("PCI-E Bypass Mode allowed for guest 0x%x\n",
643 pciep->guestp->guestid));
644 config_pcie_bypass(pciep->guestp, id);
645 } else {
646 DBGPE(c_printf("PCI-E Bypass not allowed for guest 0x%x\n",
647 pciep->guestp->guestid));
648 DBGPE(c_printf("invalidating pcie IOTSB1\n"));
649 clear_pcie_bypass(id);
650 }
651}
652
653#endif /* CONFIG_PIU */