1/** @file
2*  Differentiated System Description Table Fields (DSDT).
3*
4*  Copyright (c) 2020, Linaro Ltd. All rights reserved.
5*
6*  SPDX-License-Identifier: BSD-2-Clause-Patent
7**/
8
9#include <configs/qemu-sbsa.h>
10
11#define LINK_DEVICE(Uid, LinkName, Irq)                                        \
12        Device (LinkName) {                                                    \
13            Name (_HID, EISAID("PNP0C0F"))                                     \
14            Name (_UID, Uid)                                                   \
15            Name (_PRS, ResourceTemplate() {                                   \
16                Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { Irq } \
17            })                                                                 \
18            Method (_STA) {                                                    \
19              Return (0xF)                                                     \
20            }                                                                  \
21            Method (_CRS, 0) { Return (_PRS) }                                 \
22            Method (_SRS, 1) { }                                               \
23            Method (_DIS) { }                                                  \
24        }
25
26#define PRT_ENTRY(Address, Pin, Link)                                          \
27        Package (4) {                                                          \
28            Address, Pin, Link, Zero                                           \
29          }
30
31DefinitionBlock ("Dsdt.aml", "DSDT", 2, "U-Boot", "SBSAQEMU", 2) {
32  Scope (_SB) {
33    // UART PL011
34    Device (COM0) {
35      Name (_HID, "ARMH0011")
36      Name (_UID, Zero)
37      Name (_CRS, ResourceTemplate () {
38        Memory32Fixed (ReadWrite,
39                       SBSA_UART_BASE_ADDR,
40                       SBSA_UART_LENGTH)
41        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 33 }
42      })
43      Method (_STA) {
44        Return (0xF)
45      }
46    }
47
48    // AHCI Host Controller
49    Device (AHC0) {
50      Name (_HID, "LNRO001E")
51      Name (_CLS, Package (3) {
52        0x01,
53        0x06,
54        0x01,
55      })
56      Name (_CCA, 1)
57      Name (_CRS, ResourceTemplate() {
58        Memory32Fixed (ReadWrite,
59                       SBSA_AHCI_BASE_ADDR,
60                       SBSA_AHCI_LENGTH)
61        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 42 }
62      })
63      Method (_STA) {
64        Return (0xF)
65      }
66    }
67
68
69    // USB XHCI Host Controller
70    Device (USB0) {
71        Name (_HID, "PNP0D10")      // _HID: Hardware ID
72        Name (_UID, 0x00)            // _UID: Unique ID
73        Name (_CCA, 0x01)            // _CCA: Cache Coherency Attribute
74        Name (XHCI, 0xF)            // will be set using AcpiLib
75        Method (_STA) {
76          Return (XHCI)
77        }
78        Name (_CRS, ResourceTemplate() {
79            Memory32Fixed (ReadWrite,
80                           SBSA_XHCI_BASE_ADDR,
81                           SBSA_XHCI_LENGTH)
82            Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 43 }
83        })
84
85        // Root Hub
86        Device (RHUB) {
87            Name (_ADR, 0x00000000)  // Address of Root Hub should be 0 as per ACPI 5.0 spec
88            Method (_STA) {
89              Return (0xF)
90            }
91
92            // Ports connected to Root Hub
93            Device (HUB1) {
94                Name (_ADR, 0x00000001)
95                Name (_UPC, Package() {
96                    0x00,       // Port is NOT connectable
97                    0xFF,       // Don't care
98                    0x00000000, // Reserved 0 must be zero
99                    0x00000000  // Reserved 1 must be zero
100                })
101                Method (_STA) {
102                  Return (0xF)
103                }
104
105                Device (PRT1) {
106                    Name (_ADR, 0x00000001)
107                    Name (_UPC, Package() {
108                        0xFF,        // Port is connectable
109                        0x00,        // Port connector is A
110                        0x00000000,
111                        0x00000000
112                    })
113                    Name (_PLD, Package() {
114                        Buffer(0x10) {
115                            0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116                            0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
117                        }
118                    })
119                    Method (_STA) {
120                      Return (0xF)
121                    }
122                } // USB0_RHUB_HUB1_PRT1
123                Device (PRT2) {
124                    Name (_ADR, 0x00000002)
125                    Name (_UPC, Package() {
126                        0xFF,        // Port is connectable
127                        0x00,        // Port connector is A
128                        0x00000000,
129                        0x00000000
130                    })
131                    Name (_PLD, Package() {
132                        Buffer(0x10) {
133                            0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134                            0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
135                        }
136                    })
137                    Method (_STA) {
138                      Return (0xF)
139                    }
140                } // USB0_RHUB_HUB1_PRT2
141
142                Device (PRT3) {
143                    Name (_ADR, 0x00000003)
144                    Name (_UPC, Package() {
145                        0xFF,        // Port is connectable
146                        0x09,        // Type C connector - USB2 and SS with Switch
147                        0x00000000,
148                        0x00000000
149                    })
150                    Name (_PLD, Package() {
151                        Buffer (0x10) {
152                            0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153                            0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
154                        }
155                    })
156                    Method (_STA) {
157                      Return (0xF)
158                    }
159                } // USB0_RHUB_HUB1_PRT3
160
161                Device (PRT4) {
162                    Name (_ADR, 0x00000004)
163                    Name (_UPC, Package() {
164                        0xFF,        // Port is connectable
165                        0x09,        // Type C connector - USB2 and SS with Switch
166                        0x00000000,
167                        0x00000000
168                    })
169                    Name (_PLD, Package() {
170                        Buffer (0x10){
171                            0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172                            0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
173                        }
174                    })
175                    Method (_STA) {
176                      Return (0xF)
177                    }
178                } // USB0_RHUB_HUB1_PRT4
179            } // USB0_RHUB_HUB1
180        } // USB0_RHUB
181    } // USB0
182
183    Device (PCI0)
184    {
185      Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge
186      Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge
187      Name (_SEG, Zero) // PCI Segment Group number
188      Name (_BBN, Zero) // PCI Base Bus Number
189      Name (_UID, "PCI0")
190      Name (_CCA, One)    // Initially mark the PCI coherent (for JunoR1)
191
192      Method (_STA) {
193        Return (0xF)
194      }
195
196      Method (_CBA, 0, NotSerialized) {
197          return (SBSA_PCIE_ECAM_BASE_ADDR)
198      }
199
200      LINK_DEVICE(0, GSI0, 0x23)
201      LINK_DEVICE(1, GSI1, 0x24)
202      LINK_DEVICE(2, GSI2, 0x25)
203      LINK_DEVICE(3, GSI3, 0x26)
204
205      Name (_PRT, Package ()  // _PRT: PCI Routing Table
206      {
207        PRT_ENTRY(0x0000FFFF, 0, GSI0),
208        PRT_ENTRY(0x0000FFFF, 0, GSI1),
209        PRT_ENTRY(0x0000FFFF, 0, GSI2),
210        PRT_ENTRY(0x0000FFFF, 0, GSI3),
211
212        PRT_ENTRY(0x0001FFFF, 0, GSI1),
213        PRT_ENTRY(0x0001FFFF, 1, GSI2),
214        PRT_ENTRY(0x0001FFFF, 2, GSI3),
215        PRT_ENTRY(0x0001FFFF, 3, GSI0),
216
217        PRT_ENTRY(0x0002FFFF, 0, GSI2),
218        PRT_ENTRY(0x0002FFFF, 1, GSI3),
219        PRT_ENTRY(0x0002FFFF, 2, GSI0),
220        PRT_ENTRY(0x0002FFFF, 3, GSI1),
221
222        PRT_ENTRY(0x0003FFFF, 0, GSI3),
223        PRT_ENTRY(0x0003FFFF, 1, GSI0),
224        PRT_ENTRY(0x0003FFFF, 2, GSI1),
225        PRT_ENTRY(0x0003FFFF, 3, GSI2),
226
227        PRT_ENTRY(0x0004FFFF, 0, GSI0),
228        PRT_ENTRY(0x0004FFFF, 1, GSI1),
229        PRT_ENTRY(0x0004FFFF, 2, GSI2),
230        PRT_ENTRY(0x0004FFFF, 3, GSI3),
231
232        PRT_ENTRY(0x0005FFFF, 0, GSI1),
233        PRT_ENTRY(0x0005FFFF, 1, GSI2),
234        PRT_ENTRY(0x0005FFFF, 2, GSI3),
235        PRT_ENTRY(0x0005FFFF, 3, GSI0),
236
237        PRT_ENTRY(0x0006FFFF, 0, GSI2),
238        PRT_ENTRY(0x0006FFFF, 1, GSI3),
239        PRT_ENTRY(0x0006FFFF, 2, GSI0),
240        PRT_ENTRY(0x0006FFFF, 3, GSI1),
241
242        PRT_ENTRY(0x0007FFFF, 0, GSI3),
243        PRT_ENTRY(0x0007FFFF, 1, GSI0),
244        PRT_ENTRY(0x0007FFFF, 2, GSI1),
245        PRT_ENTRY(0x0007FFFF, 3, GSI2),
246
247        PRT_ENTRY(0x0008FFFF, 0, GSI0),
248        PRT_ENTRY(0x0008FFFF, 1, GSI1),
249        PRT_ENTRY(0x0008FFFF, 2, GSI2),
250        PRT_ENTRY(0x0008FFFF, 3, GSI3),
251
252        PRT_ENTRY(0x0009FFFF, 0, GSI1),
253        PRT_ENTRY(0x0009FFFF, 1, GSI2),
254        PRT_ENTRY(0x0009FFFF, 2, GSI3),
255        PRT_ENTRY(0x0009FFFF, 3, GSI0),
256
257        PRT_ENTRY(0x000AFFFF, 0, GSI2),
258        PRT_ENTRY(0x000AFFFF, 1, GSI3),
259        PRT_ENTRY(0x000AFFFF, 2, GSI0),
260        PRT_ENTRY(0x000AFFFF, 3, GSI1),
261
262        PRT_ENTRY(0x000BFFFF, 0, GSI3),
263        PRT_ENTRY(0x000BFFFF, 1, GSI0),
264        PRT_ENTRY(0x000BFFFF, 2, GSI1),
265        PRT_ENTRY(0x000BFFFF, 3, GSI2),
266
267        PRT_ENTRY(0x000CFFFF, 0, GSI0),
268        PRT_ENTRY(0x000CFFFF, 1, GSI1),
269        PRT_ENTRY(0x000CFFFF, 2, GSI2),
270        PRT_ENTRY(0x000CFFFF, 3, GSI3),
271
272        PRT_ENTRY(0x000DFFFF, 0, GSI1),
273        PRT_ENTRY(0x000DFFFF, 1, GSI2),
274        PRT_ENTRY(0x000DFFFF, 2, GSI3),
275        PRT_ENTRY(0x000DFFFF, 3, GSI0),
276
277        PRT_ENTRY(0x000EFFFF, 0, GSI2),
278        PRT_ENTRY(0x000EFFFF, 1, GSI3),
279        PRT_ENTRY(0x000EFFFF, 2, GSI0),
280        PRT_ENTRY(0x000EFFFF, 3, GSI1),
281
282        PRT_ENTRY(0x000FFFFF, 0, GSI3),
283        PRT_ENTRY(0x000FFFFF, 1, GSI0),
284        PRT_ENTRY(0x000FFFFF, 2, GSI1),
285        PRT_ENTRY(0x000FFFFF, 3, GSI2),
286
287        PRT_ENTRY(0x0010FFFF, 0, GSI0),
288        PRT_ENTRY(0x0010FFFF, 1, GSI1),
289        PRT_ENTRY(0x0010FFFF, 2, GSI2),
290        PRT_ENTRY(0x0010FFFF, 3, GSI3),
291
292        PRT_ENTRY(0x0011FFFF, 0, GSI1),
293        PRT_ENTRY(0x0011FFFF, 1, GSI2),
294        PRT_ENTRY(0x0011FFFF, 2, GSI3),
295        PRT_ENTRY(0x0011FFFF, 3, GSI0),
296
297        PRT_ENTRY(0x0012FFFF, 0, GSI2),
298        PRT_ENTRY(0x0012FFFF, 1, GSI3),
299        PRT_ENTRY(0x0012FFFF, 2, GSI0),
300        PRT_ENTRY(0x0012FFFF, 3, GSI1),
301
302        PRT_ENTRY(0x0013FFFF, 0, GSI3),
303        PRT_ENTRY(0x0013FFFF, 1, GSI0),
304        PRT_ENTRY(0x0013FFFF, 2, GSI1),
305        PRT_ENTRY(0x0013FFFF, 3, GSI2),
306
307        PRT_ENTRY(0x0014FFFF, 0, GSI0),
308        PRT_ENTRY(0x0014FFFF, 1, GSI1),
309        PRT_ENTRY(0x0014FFFF, 2, GSI2),
310        PRT_ENTRY(0x0014FFFF, 3, GSI3),
311
312        PRT_ENTRY(0x0015FFFF, 0, GSI1),
313        PRT_ENTRY(0x0015FFFF, 1, GSI2),
314        PRT_ENTRY(0x0015FFFF, 2, GSI3),
315        PRT_ENTRY(0x0015FFFF, 3, GSI0),
316
317        PRT_ENTRY(0x0016FFFF, 0, GSI2),
318        PRT_ENTRY(0x0016FFFF, 1, GSI3),
319        PRT_ENTRY(0x0016FFFF, 2, GSI0),
320        PRT_ENTRY(0x0016FFFF, 3, GSI1),
321
322        PRT_ENTRY(0x0017FFFF, 0, GSI3),
323        PRT_ENTRY(0x0017FFFF, 1, GSI0),
324        PRT_ENTRY(0x0017FFFF, 2, GSI1),
325        PRT_ENTRY(0x0017FFFF, 3, GSI2),
326
327        PRT_ENTRY(0x0018FFFF, 0, GSI0),
328        PRT_ENTRY(0x0018FFFF, 1, GSI1),
329        PRT_ENTRY(0x0018FFFF, 2, GSI2),
330        PRT_ENTRY(0x0018FFFF, 3, GSI3),
331
332        PRT_ENTRY(0x0019FFFF, 0, GSI1),
333        PRT_ENTRY(0x0019FFFF, 1, GSI2),
334        PRT_ENTRY(0x0019FFFF, 2, GSI3),
335        PRT_ENTRY(0x0019FFFF, 3, GSI0),
336
337        PRT_ENTRY(0x001AFFFF, 0, GSI2),
338        PRT_ENTRY(0x001AFFFF, 1, GSI3),
339        PRT_ENTRY(0x001AFFFF, 2, GSI0),
340        PRT_ENTRY(0x001AFFFF, 3, GSI1),
341
342        PRT_ENTRY(0x001BFFFF, 0, GSI3),
343        PRT_ENTRY(0x001BFFFF, 1, GSI0),
344        PRT_ENTRY(0x001BFFFF, 2, GSI1),
345        PRT_ENTRY(0x001BFFFF, 3, GSI2),
346
347        PRT_ENTRY(0x001CFFFF, 0, GSI0),
348        PRT_ENTRY(0x001CFFFF, 1, GSI1),
349        PRT_ENTRY(0x001CFFFF, 2, GSI2),
350        PRT_ENTRY(0x001CFFFF, 3, GSI3),
351
352        PRT_ENTRY(0x001DFFFF, 0, GSI1),
353        PRT_ENTRY(0x001DFFFF, 1, GSI2),
354        PRT_ENTRY(0x001DFFFF, 2, GSI3),
355        PRT_ENTRY(0x001DFFFF, 3, GSI0),
356
357        PRT_ENTRY(0x001EFFFF, 0, GSI2),
358        PRT_ENTRY(0x001EFFFF, 1, GSI3),
359        PRT_ENTRY(0x001EFFFF, 2, GSI0),
360        PRT_ENTRY(0x001EFFFF, 3, GSI1),
361
362        PRT_ENTRY(0x001FFFFF, 0, GSI3),
363        PRT_ENTRY(0x001FFFFF, 1, GSI0),
364        PRT_ENTRY(0x001FFFFF, 2, GSI1),
365        PRT_ENTRY(0x001FFFFF, 3, GSI2),
366      })
367
368      // Root complex resources
369      Name (_CRS, ResourceTemplate () {
370        WordBusNumber ( // Bus numbers assigned to this root
371        ResourceProducer,
372        MinFixed, MaxFixed, PosDecode,
373        0,   // AddressGranularity
374        0,   // AddressMinimum - Minimum Bus Number
375        0xff,// AddressMaximum - Maximum Bus Number
376        0,   // AddressTranslation - Set to 0
377        256  // RangeLength - Number of Busses
378        )
379
380        // IO to mmio window
381        QWordIO (
382          ResourceProducer, MinFixed,
383          MaxFixed, PosDecode,
384          EntireRange,
385          0x00000000,                              // Granularity
386          0x0000,                                  // Min Base Address
387          0xffff,                                  // Max Base Address
388          SBSA_PIO_BASE_ADDR,                      // Translate
389          SBSA_PIO_LENGTH                          // Length
390        )
391
392        DWordMemory ( // 32-bit BAR Windows
393          ResourceProducer, PosDecode,
394          MinFixed, MaxFixed,
395          Cacheable, ReadWrite,
396          0x00000000,                              // Granularity
397          SBSA_PCIE_MMIO_BASE_ADDR,                // Min Base Address
398          SBSA_PCIE_MMIO_END,                      // Max Base Address
399          0,                                       // Translate
400          SBSA_PCIE_MMIO_LENGTH                    // Length
401          )
402
403        QWordMemory ( // 64-bit BAR Windows
404          ResourceProducer, PosDecode,
405          MinFixed, MaxFixed,
406          Cacheable, ReadWrite,
407          0x00000000,                              // Granularity
408          SBSA_PCIE_MMIO_HIGH_BASE_ADDR,           // Min Base Address
409          SBSA_PCIE_MMIO_HIGH_END,                 // Max Base Address
410          0,                                       // Translate
411          SBSA_PCIE_MMIO_HIGH_LENGTH               // Length
412          )
413      }) // Name(_CRS)
414
415      Device (RES0)
416      {
417        Name (_HID, "PNP0C02" /* PNP Motherboard Resources */)  // _HID: Hardware ID
418        Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
419        {
420           QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
421           0x0000000000000000,                       // Granularity
422           SBSA_PCIE_ECAM_BASE_ADDR,                 // Range Minimum
423           SBSA_PCIE_ECAM_END,                       // Range Maximum
424           0x0000000000000000,                       // Translation Offset
425           SBSA_PCIE_ECAM_LENGTH,                    // Length
426           ,, , AddressRangeMemory, TypeStatic)
427        })
428        Method (_STA) {
429          Return (0xF)
430        }
431      }
432
433      // OS Control Handoff
434      Name (SUPP, Zero) // PCI _OSC Support Field value
435      Name (CTRL, Zero) // PCI _OSC Control Field value
436
437      /*
438       * See [1] 6.2.10, [2] 4.5
439       */
440      Method (_OSC,4) {
441        // Check for proper UUID
442        If (Arg0 == ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")) {
443          // Create DWord-adressable fields from the Capabilities Buffer
444          CreateDWordField (Arg3,0,CDW1)
445          CreateDWordField (Arg3,4,CDW2)
446          CreateDWordField (Arg3,8,CDW3)
447
448          // Save Capabilities DWord2 & 3
449          Store (CDW2,SUPP)
450          Store (CDW3,CTRL)
451
452          // Only allow native hot plug control if OS supports:
453          // * ASPM
454          // * Clock PM
455          // * MSI/MSI-X
456          If ((SUPP & 0x16) != 0x16) {
457            CTRL &= 0x1E // Mask bit 0 (and undefined bits)
458          }
459
460          // Always allow native PME, AER (no dependencies)
461
462          // Never allow SHPC (no SHPC controller in this system)
463          CTRL &= 0x1D
464
465          If (Arg1 != One) {         // Unknown revision
466            CDW1 |= 0x08
467          }
468
469          If (CDW3 != CTRL) {        // Capabilities bits were masked
470            CDW1 |= 0x10
471          }
472
473          // Update DWORD3 in the buffer
474          Store (CTRL,CDW3)
475          Return (Arg3)
476        } Else {
477          CDW1 |= 4 // Unrecognized UUID
478          Return (Arg3)
479        }
480      } // End _OSC
481    }
482  } // Scope (_SB)
483}
484