Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
0007  * Copyright (C) 1999, 2000 by Ralf Baechle
0008  */
0009 #ifndef _ASM_SN_ADDRS_H
0010 #define _ASM_SN_ADDRS_H
0011 
0012 
0013 #ifndef __ASSEMBLY__
0014 #include <linux/smp.h>
0015 #include <linux/types.h>
0016 #endif /* !__ASSEMBLY__ */
0017 
0018 #include <asm/addrspace.h>
0019 #include <asm/sn/kldir.h>
0020 
0021 #if defined(CONFIG_SGI_IP27)
0022 #include <asm/sn/sn0/addrs.h>
0023 #elif defined(CONFIG_SGI_IP35)
0024 #include <asm/sn/sn1/addrs.h>
0025 #endif
0026 
0027 
0028 #ifndef __ASSEMBLY__
0029 
0030 #define UINT64_CAST     (unsigned long)
0031 
0032 #else /* __ASSEMBLY__ */
0033 
0034 #define UINT64_CAST
0035 
0036 #endif /* __ASSEMBLY__ */
0037 
0038 
0039 #define NASID_GET_META(_n)  ((_n) >> NASID_LOCAL_BITS)
0040 #ifdef CONFIG_SGI_IP27
0041 #define NASID_GET_LOCAL(_n) ((_n) & 0xf)
0042 #endif
0043 #define NASID_MAKE(_m, _l)  (((_m) << NASID_LOCAL_BITS) | (_l))
0044 
0045 #define NODE_ADDRSPACE_MASK (NODE_ADDRSPACE_SIZE - 1)
0046 #define TO_NODE_ADDRSPACE(_pa)  (UINT64_CAST (_pa) & NODE_ADDRSPACE_MASK)
0047 
0048 #define CHANGE_ADDR_NASID(_pa, _nasid)  \
0049         ((UINT64_CAST(_pa) & ~NASID_MASK) | \
0050          (UINT64_CAST(_nasid) <<  NASID_SHFT))
0051 
0052 
0053 /*
0054  * The following macros are used to index to the beginning of a specific
0055  * node's address space.
0056  */
0057 
0058 #define NODE_OFFSET(_n)     (UINT64_CAST (_n) << NODE_SIZE_BITS)
0059 
0060 #define NODE_CAC_BASE(_n)   (CAC_BASE   + NODE_OFFSET(_n))
0061 #define NODE_HSPEC_BASE(_n) (HSPEC_BASE + NODE_OFFSET(_n))
0062 #define NODE_IO_BASE(_n)    (IO_BASE    + NODE_OFFSET(_n))
0063 #define NODE_MSPEC_BASE(_n) (MSPEC_BASE + NODE_OFFSET(_n))
0064 #define NODE_UNCAC_BASE(_n) (UNCAC_BASE + NODE_OFFSET(_n))
0065 
0066 #define TO_NODE(_n, _x)     (NODE_OFFSET(_n)     | ((_x)           ))
0067 #define TO_NODE_CAC(_n, _x) (NODE_CAC_BASE(_n)   | ((_x) & TO_PHYS_MASK))
0068 #define TO_NODE_UNCAC(_n, _x)   (NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
0069 #define TO_NODE_MSPEC(_n, _x)   (NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
0070 #define TO_NODE_HSPEC(_n, _x)   (NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
0071 
0072 
0073 #define RAW_NODE_SWIN_BASE(nasid, widget)               \
0074     (NODE_IO_BASE(nasid) + (UINT64_CAST(widget) << SWIN_SIZE_BITS))
0075 
0076 #define WIDGETID_GET(addr)  ((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff))
0077 
0078 /*
0079  * The following definitions pertain to the IO special address
0080  * space.  They define the location of the big and little windows
0081  * of any given node.
0082  */
0083 
0084 #define SWIN_SIZE_BITS      24
0085 #define SWIN_SIZE       (UINT64_CAST 1 << 24)
0086 #define SWIN_SIZEMASK       (SWIN_SIZE - 1)
0087 #define SWIN_WIDGET_MASK    0xF
0088 
0089 /*
0090  * Convert smallwindow address to xtalk address.
0091  *
0092  * 'addr' can be physical or virtual address, but will be converted
0093  * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
0094  */
0095 #define SWIN_WIDGETADDR(addr)   ((addr) & SWIN_SIZEMASK)
0096 #define SWIN_WIDGETNUM(addr)    (((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
0097 /*
0098  * Verify if addr belongs to small window address on node with "nasid"
0099  *
0100  *
0101  * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
0102  * address
0103  *
0104  *
0105  */
0106 #define NODE_SWIN_ADDR(nasid, addr) \
0107         (((addr) >= NODE_SWIN_BASE(nasid, 0))  && \
0108          ((addr) <  (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\
0109          ))
0110 
0111 /*
0112  * The following define the major position-independent aliases used
0113  * in SN.
0114  *  UALIAS -- 256MB in size, reads in the UALIAS result in
0115  *          uncached references to the memory of the reader's node.
0116  *  CPU_UALIAS -- 128kb in size, the bottom part of UALIAS is flipped
0117  *          depending on which CPU does the access to provide
0118  *          all CPUs with unique uncached memory at low addresses.
0119  *  LBOOT  -- 256MB in size, reads in the LBOOT area result in
0120  *          uncached references to the local hub's boot prom and
0121  *          other directory-bus connected devices.
0122  *  IALIAS -- 8MB in size, reads in the IALIAS result in uncached
0123  *          references to the local hub's registers.
0124  */
0125 
0126 #define UALIAS_BASE     HSPEC_BASE
0127 #define UALIAS_SIZE     0x10000000  /* 256 Megabytes */
0128 #define UALIAS_LIMIT        (UALIAS_BASE + UALIAS_SIZE)
0129 
0130 /*
0131  * The bottom of ualias space is flipped depending on whether you're
0132  * processor 0 or 1 within a node.
0133  */
0134 #ifdef CONFIG_SGI_IP27
0135 #define UALIAS_FLIP_BASE    UALIAS_BASE
0136 #define UALIAS_FLIP_SIZE    0x20000
0137 #define UALIAS_FLIP_BIT     0x10000
0138 #define UALIAS_FLIP_ADDR(_x)    (cputoslice(smp_processor_id()) ? \
0139                  (_x) ^ UALIAS_FLIP_BIT : (_x))
0140 
0141 #define LBOOT_BASE      (HSPEC_BASE + 0x10000000)
0142 #define LBOOT_SIZE      0x10000000
0143 #define LBOOT_LIMIT     (LBOOT_BASE + LBOOT_SIZE)
0144 #define LBOOT_STRIDE        0       /* IP27 has only one CPU PROM */
0145 
0146 #endif
0147 
0148 #define HUB_REGISTER_WIDGET 1
0149 #define IALIAS_BASE     NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
0150 #define IALIAS_SIZE     0x800000    /* 8 Megabytes */
0151 #define IS_IALIAS(_a)       (((_a) >= IALIAS_BASE) &&       \
0152                  ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
0153 
0154 /*
0155  * Macro for referring to Hub's RBOOT space
0156  */
0157 
0158 #ifdef CONFIG_SGI_IP27
0159 #define RBOOT_SIZE      0x10000000  /* 256 Megabytes */
0160 #define NODE_RBOOT_BASE(_n) (NODE_HSPEC_BASE(_n) + 0x30000000)
0161 #define NODE_RBOOT_LIMIT(_n)    (NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
0162 
0163 #endif
0164 
0165 /*
0166  * Macros for referring the Hub's back door space
0167  *
0168  *   These macros correctly process addresses in any node's space.
0169  *   WARNING: They won't work in assembler.
0170  *
0171  *   BDDIR_ENTRY_LO returns the address of the low double-word of the dir
0172  *          entry corresponding to a physical (Cac or Uncac) address.
0173  *   BDDIR_ENTRY_HI returns the address of the high double-word of the entry.
0174  *   BDPRT_ENTRY    returns the address of the double-word protection entry
0175  *          corresponding to the page containing the physical address.
0176  *   BDPRT_ENTRY_S  Stores the value into the protection entry.
0177  *   BDPRT_ENTRY_L  Load the value from the protection entry.
0178  *   BDECC_ENTRY    returns the address of the ECC byte corresponding to a
0179  *          double-word at a specified physical address.
0180  *   BDECC_ENTRY_H  returns the address of the two ECC bytes corresponding to a
0181  *          quad-word at a specified physical address.
0182  */
0183 #define NODE_BDOOR_BASE(_n) (NODE_HSPEC_BASE(_n) + (NODE_ADDRSPACE_SIZE/2))
0184 
0185 #define NODE_BDECC_BASE(_n) (NODE_BDOOR_BASE(_n))
0186 #define NODE_BDDIR_BASE(_n) (NODE_BDOOR_BASE(_n) + (NODE_ADDRSPACE_SIZE/4))
0187 #ifdef CONFIG_SGI_IP27
0188 #define BDDIR_ENTRY_LO(_pa) ((HSPEC_BASE +                    \
0189                   NODE_ADDRSPACE_SIZE * 3 / 4 +           \
0190                   0x200)                    | \
0191                  UINT64_CAST(_pa)    & NASID_MASK       | \
0192                  UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK  | \
0193                  UINT64_CAST(_pa) >> 3 & 0x1f << 4)
0194 
0195 #define BDDIR_ENTRY_HI(_pa) ((HSPEC_BASE +                    \
0196                   NODE_ADDRSPACE_SIZE * 3 / 4 +           \
0197                   0x208)                    | \
0198                  UINT64_CAST(_pa)    & NASID_MASK       | \
0199                  UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK  | \
0200                  UINT64_CAST(_pa) >> 3 & 0x1f << 4)
0201 
0202 #define BDPRT_ENTRY(_pa, _rgn)  ((HSPEC_BASE +                    \
0203                   NODE_ADDRSPACE_SIZE * 3 / 4)          | \
0204                  UINT64_CAST(_pa)    & NASID_MASK       | \
0205                  UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK  | \
0206                  (_rgn) << 3)
0207 #define BDPRT_ENTRY_ADDR(_pa, _rgn) (BDPRT_ENTRY((_pa), (_rgn)))
0208 #define BDPRT_ENTRY_S(_pa, _rgn, _val) (*(__psunsigned_t *)BDPRT_ENTRY((_pa), (_rgn))=(_val))
0209 #define BDPRT_ENTRY_L(_pa, _rgn)    (*(__psunsigned_t *)BDPRT_ENTRY((_pa), (_rgn)))
0210 
0211 #define BDECC_ENTRY(_pa)    ((HSPEC_BASE +                    \
0212                   NODE_ADDRSPACE_SIZE / 2)          | \
0213                  UINT64_CAST(_pa)    & NASID_MASK       | \
0214                  UINT64_CAST(_pa) >> 2 & BDECC_UPPER_MASK  | \
0215                  UINT64_CAST(_pa) >> 3 & 3)
0216 
0217 /*
0218  * Macro to convert a back door directory or protection address into the
0219  *   raw physical address of the associated cache line or protection page.
0220  */
0221 #define BDADDR_IS_DIR(_ba)  ((UINT64_CAST  (_ba) & 0x200) != 0)
0222 #define BDADDR_IS_PRT(_ba)  ((UINT64_CAST  (_ba) & 0x200) == 0)
0223 
0224 #define BDDIR_TO_MEM(_ba)   (UINT64_CAST (_ba) & NASID_MASK        | \
0225                  (UINT64_CAST(_ba) & BDDIR_UPPER_MASK)<<2  | \
0226                  (UINT64_CAST(_ba) & 0x1f << 4) << 3)
0227 
0228 #define BDPRT_TO_MEM(_ba)   (UINT64_CAST (_ba) & NASID_MASK     | \
0229                  (UINT64_CAST(_ba) & BDDIR_UPPER_MASK)<<2)
0230 
0231 #define BDECC_TO_MEM(_ba)   (UINT64_CAST (_ba) & NASID_MASK     | \
0232                  (UINT64_CAST(_ba) & BDECC_UPPER_MASK)<<2  | \
0233                  (UINT64_CAST(_ba) & 3) << 3)
0234 #endif /* CONFIG_SGI_IP27 */
0235 
0236 
0237 /*
0238  * The following macros produce the correct base virtual address for
0239  * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
0240  * address for the local registers.  The REMOTE_HUB_* macro produce
0241  * the address for the specified hub's registers.  The intent is
0242  * that the appropriate PI, MD, NI, or II register would be substituted
0243  * for _x.
0244  */
0245 
0246 /*
0247  * WARNING:
0248  *  When certain Hub chip workaround are defined, it's not sufficient
0249  *  to dereference the *_HUB_ADDR() macros.  You should instead use
0250  *  HUB_L() and HUB_S() if you must deal with pointers to hub registers.
0251  *  Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
0252  *  They're always safe.
0253  */
0254 #define LOCAL_HUB_ADDR(_x)  (IALIAS_BASE + (_x))
0255 #define REMOTE_HUB_ADDR(_n, _x) ((NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))
0256 
0257 #ifndef __ASSEMBLY__
0258 
0259 #define LOCAL_HUB_PTR(_x)   ((u64 *)LOCAL_HUB_ADDR((_x)))
0260 #define REMOTE_HUB_PTR(_n, _x)  ((u64 *)REMOTE_HUB_ADDR((_n), (_x)))
0261 
0262 #define LOCAL_HUB_L(_r)         __raw_readq(LOCAL_HUB_PTR(_r))
0263 #define LOCAL_HUB_S(_r, _d)     __raw_writeq((_d), LOCAL_HUB_PTR(_r))
0264 #define REMOTE_HUB_L(_n, _r)        __raw_readq(REMOTE_HUB_PTR((_n), (_r)))
0265 #define REMOTE_HUB_S(_n, _r, _d)    __raw_writeq((_d),      \
0266                         REMOTE_HUB_PTR((_n), (_r)))
0267 
0268 #endif /* !__ASSEMBLY__ */
0269 
0270 /*
0271  * Software structure locations -- permanently fixed
0272  *    See diagram in kldir.h
0273  */
0274 
0275 #define PHYS_RAMBASE        0x0
0276 #define K0_RAMBASE      PHYS_TO_K0(PHYS_RAMBASE)
0277 
0278 #define EX_HANDLER_OFFSET(slice) ((slice) << 16)
0279 #define EX_HANDLER_ADDR(nasid, slice)                   \
0280     PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice))
0281 #define EX_HANDLER_SIZE     0x0400
0282 
0283 #define EX_FRAME_OFFSET(slice)  ((slice) << 16 | 0x400)
0284 #define EX_FRAME_ADDR(nasid, slice)                 \
0285     PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice))
0286 #define EX_FRAME_SIZE       0x0c00
0287 
0288 #define ARCS_SPB_OFFSET     0x1000
0289 #define ARCS_SPB_ADDR(nasid)                        \
0290     PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
0291 #define ARCS_SPB_SIZE       0x0400
0292 
0293 #define KLDIR_OFFSET        0x2000
0294 #define KLDIR_ADDR(nasid)                       \
0295     TO_NODE_UNCAC((nasid), KLDIR_OFFSET)
0296 #define KLDIR_SIZE      0x0400
0297 
0298 
0299 /*
0300  * Software structure locations -- indirected through KLDIR
0301  *    See diagram in kldir.h
0302  *
0303  * Important:   All low memory structures must only be accessed
0304  *      uncached, except for the symmon stacks.
0305  */
0306 
0307 #define KLI_LAUNCH      0       /* Dir. entries */
0308 #define KLI_KLCONFIG        1
0309 #define KLI_NMI         2
0310 #define KLI_GDA         3
0311 #define KLI_FREEMEM     4
0312 #define KLI_SYMMON_STK      5
0313 #define KLI_PI_ERROR        6
0314 #define KLI_KERN_VARS       7
0315 #define KLI_KERN_XP     8
0316 #define KLI_KERN_PARTID     9
0317 
0318 #ifndef __ASSEMBLY__
0319 
0320 #define KLD_BASE(nasid)     ((kldir_ent_t *) KLDIR_ADDR(nasid))
0321 #define KLD_LAUNCH(nasid)   (KLD_BASE(nasid) + KLI_LAUNCH)
0322 #define KLD_NMI(nasid)      (KLD_BASE(nasid) + KLI_NMI)
0323 #define KLD_KLCONFIG(nasid) (KLD_BASE(nasid) + KLI_KLCONFIG)
0324 #define KLD_PI_ERROR(nasid) (KLD_BASE(nasid) + KLI_PI_ERROR)
0325 #define KLD_GDA(nasid)      (KLD_BASE(nasid) + KLI_GDA)
0326 #define KLD_SYMMON_STK(nasid)   (KLD_BASE(nasid) + KLI_SYMMON_STK)
0327 #define KLD_FREEMEM(nasid)  (KLD_BASE(nasid) + KLI_FREEMEM)
0328 #define KLD_KERN_VARS(nasid)    (KLD_BASE(nasid) + KLI_KERN_VARS)
0329 #define KLD_KERN_XP(nasid)  (KLD_BASE(nasid) + KLI_KERN_XP)
0330 #define KLD_KERN_PARTID(nasid)  (KLD_BASE(nasid) + KLI_KERN_PARTID)
0331 
0332 #define LAUNCH_OFFSET(nasid, slice)                 \
0333     (KLD_LAUNCH(nasid)->offset +                    \
0334      KLD_LAUNCH(nasid)->stride * (slice))
0335 #define LAUNCH_ADDR(nasid, slice)                   \
0336     TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice))
0337 #define LAUNCH_SIZE(nasid)  KLD_LAUNCH(nasid)->size
0338 
0339 #define SN_NMI_OFFSET(nasid, slice)                 \
0340     (KLD_NMI(nasid)->offset +                   \
0341      KLD_NMI(nasid)->stride * (slice))
0342 #define NMI_ADDR(nasid, slice)                      \
0343     TO_NODE_UNCAC((nasid), SN_NMI_OFFSET(nasid, slice))
0344 #define NMI_SIZE(nasid) KLD_NMI(nasid)->size
0345 
0346 #define KLCONFIG_OFFSET(nasid)  KLD_KLCONFIG(nasid)->offset
0347 #define KLCONFIG_ADDR(nasid)                        \
0348     TO_NODE_UNCAC((nasid), KLCONFIG_OFFSET(nasid))
0349 #define KLCONFIG_SIZE(nasid)    KLD_KLCONFIG(nasid)->size
0350 
0351 #define GDA_ADDR(nasid)     KLD_GDA(nasid)->pointer
0352 #define GDA_SIZE(nasid)     KLD_GDA(nasid)->size
0353 
0354 #define SYMMON_STK_OFFSET(nasid, slice)                 \
0355     (KLD_SYMMON_STK(nasid)->offset +                \
0356      KLD_SYMMON_STK(nasid)->stride * (slice))
0357 #define SYMMON_STK_STRIDE(nasid)    KLD_SYMMON_STK(nasid)->stride
0358 
0359 #define SYMMON_STK_ADDR(nasid, slice)                   \
0360     TO_NODE_CAC((nasid), SYMMON_STK_OFFSET(nasid, slice))
0361 
0362 #define SYMMON_STK_SIZE(nasid)  KLD_SYMMON_STK(nasid)->stride
0363 
0364 #define SYMMON_STK_END(nasid)   (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
0365 
0366 #define NODE_OFFSET_TO_K0(_nasid, _off)                 \
0367     PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE)
0368 #define NODE_OFFSET_TO_K1(_nasid, _off)                 \
0369     TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE)
0370 
0371 #define KERN_VARS_ADDR(nasid)   KLD_KERN_VARS(nasid)->pointer
0372 #define KERN_VARS_SIZE(nasid)   KLD_KERN_VARS(nasid)->size
0373 
0374 #endif /* !__ASSEMBLY__ */
0375 
0376 
0377 #endif /* _ASM_SN_ADDRS_H */