summaryrefslogtreecommitdiff
path: root/Silicon/Socionext/SynQuacer/Stage2Tables/Stage2Tables.S
blob: 313ef3c56abc27e83c60a472a676075e4d6f3c99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/** @file
  Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>

  This program and the accompanying materials are licensed and made available
  under the terms and conditions of the BSD License which accompanies this
  distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

/*
 * This file contains the assembler code to instantiate a set of stage 2
 * translation tables that make the ECAM space of the Synopsys DesignWare
 * PCIe root complexes appear sane to the OS.
 * - ECAM 'shadows' caused by non TLP filtering root ports are eliminated
 * - MMIO region are mapped with device attributes that supersede write combine
 *   attributes that the OS may attempt to use, and which is not supported by
 *   the SoC.
 */

#define TT_S2_CONT_SHIFT          52
#define TT_S2_AF                  (0x1 << 10)
#define TT_S2_SH_NON_SHAREABLE    (0x0 << 8)
#define TT_S2_AP_RW               (0x3 << 6)
#define TT_S2_MEMATTR_DEVICE_nGRE (0x2 << 2)
#define TT_S2_MEMATTR_MEMORY_WB   (0xf << 2)
#define TT_S2_TABLE               (0x3 << 0)
#define TT_S2_L3_PAGE             (0x1 << 1)
#define TT_S2_VALID               (0x1 << 0)

  .altmacro
  .macro    for, start, count, do, arg2, arg3, arg4
  .if       \count == 1
  \do       \start, \arg2, \arg3, \arg4
  .elseif   \count > 1
  for       \start, %(\count / 2), \do, \arg2, \arg3, \arg4
  for       %(\start + \count / 2), %((\count + 1) / 2), \do, \arg2, \arg3, \arg4
  .endif
  .endm

  .macro    s2_dev_entry, base, shift=30, offset=0, cont=0
  .quad     ((\base << \shift) + \offset) | TT_S2_AF | TT_S2_AP_RW | \
            TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_DEVICE_nGRE | \
            TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT)
  .endm

  .macro    s2_mem_entry, base, shift=30, offset=0, cont=0
  .quad     ((\base << \shift) + \offset) | TT_S2_AF | TT_S2_AP_RW | \
            TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_MEMORY_WB | \
            TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT)
  .endm

  .macro    s2_l3_entry, base, offset=0, cont=0
  .quad     ((\base << 12) + \offset) | TT_S2_AF | TT_S2_AP_RW | \
            TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_MEMORY_WB | \
            TT_S2_L3_PAGE | TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT)
  .endm

  .section  ".rodata", "a", %progbits
  /* level 1 */
  s2_mem_entry  0      /* 0x0000_0000 - 0x3fff_ffff */
  .quad   1f + TT_S2_TABLE /* 0x4000_0000 - 0x7fff_ffff */
  for       2, 246, s2_mem_entry  /* 0x8000_0000 - 0x3d_ffff_ffff */
  for     248,   8, s2_dev_entry  /* PCIe MMIO64 */
  for     256, 768, s2_mem_entry  /* 0x40_0000_0000 - 0xff_ffff_ffff */

  /* level 2 */
1:for     0, 256, s2_mem_entry, 21, 0x40000000, 1

  .quad   2f + TT_S2_TABLE /* 0x6000_0000 -> RC #0 bus 0 */
  for     1, 15, s2_mem_entry, 21, 0x60000000
  for     0, 48, s2_mem_entry, 21, 0x62000000, 1
  for     0, 64, s2_dev_entry, 21, 0x68000000, 1 /* PCIe MMIO32 */

  .quad   3f + TT_S2_TABLE /* 0x7000_0000 -> RC #1 bus 0 */
  for     1, 15, s2_mem_entry, 21, 0x70000000
  for     0, 48, s2_mem_entry, 21, 0x72000000, 1
  for     0, 64, s2_dev_entry, 21, 0x78000000, 1 /* PCIe MMIO32 */

  /* level 3 */
2:for     0,   8, s2_l3_entry, 0x60000000
  for     0,   8, s2_l3_entry, 0x60010000  /* hide device #1 */
  for     0, 496, s2_l3_entry, 0x60010000, 1
3:for     0,   8, s2_l3_entry, 0x70000000
  for     0,   8, s2_l3_entry, 0x70010000  /* hide device #1 */
  for     0, 496, s2_l3_entry, 0x70010000, 1