vserver 1.9.5.x5
[linux-2.6.git] / include / asm-ia64 / sn / addrs.h
index 550365c..3ce6097 100644 (file)
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1999,2001-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_ADDRS_H
 #define _ASM_IA64_SN_ADDRS_H
 
-#include <asm/sn/sn2/addrs.h>
-
-#ifndef __ASSEMBLY__
+#include <asm/percpu.h>
 #include <asm/sn/types.h>
-#endif 
-
-#define HUBREG_CAST            (volatile mmr_t *)
-
+#include <asm/sn/pda.h>
 
 /*
- * The following macros are used to index to the beginning of a specific
- * node's address space.
+ *  Memory/SHUB Address Format:
+ *  +-+---------+--+--------------+
+ *  |0|  NASID  |AS| NodeOffset   |
+ *  +-+---------+--+--------------+
+ *
+ *  NASID: (low NASID bit is 0) Memory and SHUB MMRs
+ *   AS: 2-bit Address Space Identifier. Used only if low NASID bit is 0
+ *     00: Local Resources and MMR space
+ *           Top bit of NodeOffset
+ *               0: Local resources space
+ *                  node id:
+ *                        0: IA64/NT compatibility space
+ *                        2: Local MMR Space
+ *                        4: Local memory, regardless of local node id
+ *               1: Global MMR space
+ *     01: GET space.
+ *     10: AMO space.
+ *     11: Cacheable memory space.
+ *
+ *   NodeOffset: byte offset
+ *
+ *
+ *  TIO address format:
+ *  +-+----------+--+--------------+
+ *  |0|  NASID   |AS| Nodeoffset   |
+ *  +-+----------+--+--------------+
+ *
+ *  NASID: (low NASID bit is 1) TIO
+ *   AS: 2-bit Chiplet Identifier
+ *     00: TIO LB (Indicates TIO MMR access.)
+ *     01: TIO ICE (indicates coretalk space access.)
+ * 
+ *   NodeOffset: top bit must be set.
+ *
+ *
+ * Note that in both of the above address formats, the low
+ * NASID bit indicates if the reference is to the SHUB or TIO MMRs.
  */
 
-#define NODE_OFFSET(_n)                ((uint64_t) (_n) << NASID_SHFT)
-
-#define NODE_CAC_BASE(_n)      (CAC_BASE  + NODE_OFFSET(_n))
-#define NODE_HSPEC_BASE(_n)    (HSPEC_BASE + NODE_OFFSET(_n))
-#define NODE_IO_BASE(_n)       (IO_BASE    + NODE_OFFSET(_n))
-#define NODE_MSPEC_BASE(_n)    (MSPEC_BASE + NODE_OFFSET(_n))
-#define NODE_UNCAC_BASE(_n)    (UNCAC_BASE + NODE_OFFSET(_n))
-
-#define TO_NODE(_n, _x)                (NODE_OFFSET(_n)     | ((_x)               ))
-#define TO_NODE_CAC(_n, _x)    (NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
-#define TO_NODE_UNCAC(_n, _x)  (NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
-#define TO_NODE_MSPEC(_n, _x)  (NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
-#define TO_NODE_HSPEC(_n, _x)  (NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
 
+/*
+ * Define basic shift & mask constants for manipulating NASIDs and AS values.
+ */
+#define NASID_BITMASK          (pda->nasid_bitmask)
+#define NASID_SHIFT            (pda->nasid_shift)
+#define AS_SHIFT               (pda->as_shift)
+#define AS_BITMASK             0x3UL
 
-#define RAW_NODE_SWIN_BASE(nasid, widget)                              \
-       (NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
+#define NASID_MASK              ((u64)NASID_BITMASK << NASID_SHIFT)
+#define AS_MASK                        ((u64)AS_BITMASK << AS_SHIFT)
+#define REGION_BITS            0xe000000000000000UL
 
-#define WIDGETID_GET(addr)     ((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff))
 
 /*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
+ * AS values. These are the same on both SHUB1 & SHUB2.
  */
+#define AS_GET_VAL             1UL
+#define AS_AMO_VAL             2UL
+#define AS_CAC_VAL             3UL
+#define AS_GET_SPACE           (AS_GET_VAL << AS_SHIFT)
+#define AS_AMO_SPACE           (AS_AMO_VAL << AS_SHIFT)
+#define AS_CAC_SPACE           (AS_CAC_VAL << AS_SHIFT)
 
-#define SWIN_SIZE_BITS         24
-#define SWIN_SIZE              (1UL << 24)
-#define        SWIN_SIZEMASK           (SWIN_SIZE - 1)
-#define        SWIN_WIDGET_MASK        0xF
 
 /*
- * Convert smallwindow address to xtalk address.
- *
- * 'addr' can be physical or virtual address, but will be converted
- * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
+ * Base addresses for various address ranges.
  */
-#define        SWIN_WIDGETADDR(addr)   ((addr) & SWIN_SIZEMASK)
-#define        SWIN_WIDGETNUM(addr)    (((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
-/*
- * Verify if addr belongs to small window address on node with "nasid"
- *
- *
- * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
- * address
- *
- *
+#define CACHED                 0xe000000000000000UL
+#define UNCACHED                0xc000000000000000UL
+#define UNCACHED_PHYS           0x8000000000000000UL
+
+
+/* 
+ * Virtual Mode Local & Global MMR space.  
  */
-#define        NODE_SWIN_ADDR(nasid, addr)     \
-               (((addr) >= NODE_SWIN_BASE(nasid, 0))  && \
-                ((addr) <  (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\
-                ))
+#define SH1_LOCAL_MMR_OFFSET   0x8000000000UL
+#define SH2_LOCAL_MMR_OFFSET   0x0200000000UL
+#define LOCAL_MMR_OFFSET       (is_shub2() ? SH2_LOCAL_MMR_OFFSET : SH1_LOCAL_MMR_OFFSET)
+#define LOCAL_MMR_SPACE                (UNCACHED | LOCAL_MMR_OFFSET)
+#define LOCAL_PHYS_MMR_SPACE   (UNCACHED_PHYS | LOCAL_MMR_OFFSET)
+
+#define SH1_GLOBAL_MMR_OFFSET  0x0800000000UL
+#define SH2_GLOBAL_MMR_OFFSET  0x0300000000UL
+#define GLOBAL_MMR_OFFSET      (is_shub2() ? SH2_GLOBAL_MMR_OFFSET : SH1_GLOBAL_MMR_OFFSET)
+#define GLOBAL_MMR_SPACE       (UNCACHED | GLOBAL_MMR_OFFSET)
 
 /*
- * The following define the major position-independent aliases used
- * in SN.
- *     LBOOT  -- 256MB in size, reads in the LBOOT area result in
- *                     uncached references to the local hub's boot prom and
- *                     other directory-bus connected devices.
- *     IALIAS -- 8MB in size, reads in the IALIAS result in uncached
- *                     references to the local hub's registers.
+ * Physical mode addresses
  */
+#define GLOBAL_PHYS_MMR_SPACE  (UNCACHED_PHYS | GLOBAL_MMR_OFFSET)
 
-#define        HUB_REGISTER_WIDGET     1
-#define IALIAS_BASE            LOCAL_SWIN_BASE(HUB_REGISTER_WIDGET)
-#define IALIAS_SIZE            0x800000        /* 8 Megabytes */
-#define IS_IALIAS(_a)          (((_a) >= IALIAS_BASE) &&               \
-                                ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
 
 /*
- * The following macros produce the correct base virtual address for
- * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
- * address for the local registers.  The REMOTE_HUB_* macro produce
- * the address for the specified hub's registers.  The intent is
- * that the appropriate PI, MD, NI, or II register would be substituted
- * for _x.
+ * Clear region & AS bits.
  */
+#define TO_PHYS_MASK           (~(REGION_BITS | AS_MASK))
 
 
 /*
- * SN2 has II mmr's located inside small window space.
- * As all other non-II mmr's located at the top of big window
- * space.
+ * Misc NASID manipulation.
  */
-#define LOCAL_HUB_BASE(_x)     (LOCAL_MMR_ADDR(_x) | (((~(_x)) & BWIN_TOP)>>8))
-#define REMOTE_HUB_BASE(_x)                                            \
-        (UNCACHED | GLOBAL_MMR_SPACE |                                  \
-        (((~(_x)) & BWIN_TOP)>>8)    |                                       \
-        (((~(_x)) & BWIN_TOP)>>9)    | (_x))
+#define NASID_SPACE(n)         ((u64)(n) << NASID_SHIFT)
+#define REMOTE_ADDR(n,a)       (NASID_SPACE(n) | (a))
+#define NODE_OFFSET(x)         ((x) & (NODE_ADDRSPACE_SIZE - 1))
+#define NODE_ADDRSPACE_SIZE     (1UL << AS_SHIFT)
+#define NASID_GET(x)           (int) (((u64) (x) >> NASID_SHIFT) & NASID_BITMASK)
+#define LOCAL_MMR_ADDR(a)      (LOCAL_MMR_SPACE | (a))
+#define GLOBAL_MMR_ADDR(n,a)   (GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
+#define GLOBAL_MMR_PHYS_ADDR(n,a) (GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a))
+#define GLOBAL_CAC_ADDR(n,a)   (CAC_BASE | REMOTE_ADDR(n,a))
+#define CHANGE_NASID(n,x)      ((void *)(((u64)(x) & ~NASID_MASK) | NASID_SPACE(n)))
 
-#define LOCAL_HUB(_x) (HUBREG_CAST LOCAL_HUB_BASE(_x))
-#define REMOTE_HUB(_n, _x)                                             \
-       (HUBREG_CAST (REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
 
+/* non-II mmr's start at top of big window space (4G) */
+#define BWIN_TOP               0x0000000100000000UL
 
 /*
- * WARNING:
- *     When certain Hub chip workaround are defined, it's not sufficient
- *     to dereference the *_HUB_ADDR() macros.  You should instead use
- *     HUB_L() and HUB_S() if you must deal with pointers to hub registers.
- *     Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
- *     They're always safe.
+ * general address defines
  */
-#define LOCAL_HUB_ADDR(_x)                                                     \
-       (((_x) & BWIN_TOP) ? (HUBREG_CAST (LOCAL_MMR_ADDR(_x)))         \
-       : (HUBREG_CAST (IALIAS_BASE + (_x))))
-#define REMOTE_HUB_ADDR(_n, _x)                                                \
-       (((_x) & BWIN_TOP) ? (HUBREG_CAST (GLOBAL_MMR_ADDR(_n, _x)))    \
-       : (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))))
+#define CAC_BASE               (CACHED   | AS_CAC_SPACE)
+#define AMO_BASE               (UNCACHED | AS_AMO_SPACE)
+#define GET_BASE               (CACHED   | AS_GET_SPACE)
 
-#ifndef __ASSEMBLY__
+/*
+ * Convert Memory addresses between various addressing modes.
+ */
+#define TO_PHYS(x)             (TO_PHYS_MASK & (x))
+#define TO_CAC(x)              (CAC_BASE     | TO_PHYS(x))
+#define TO_AMO(x)              (AMO_BASE     | TO_PHYS(x))
+#define TO_GET(x)              (GET_BASE     | TO_PHYS(x))
 
-#define HUB_L(_a)                      (*((volatile typeof(*_a) *)_a))
-#define        HUB_S(_a, _d)                   (*((volatile typeof(*_a) *)_a) = (_d))
 
-#define LOCAL_HUB_L(_r)                        HUB_L(LOCAL_HUB_ADDR(_r))
-#define LOCAL_HUB_S(_r, _d)            HUB_S(LOCAL_HUB_ADDR(_r), (_d))
-#define REMOTE_HUB_L(_n, _r)           HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
-#define REMOTE_HUB_S(_n, _r, _d)       HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
-#define REMOTE_HUB_PI_L(_n, _sn, _r)   HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
-#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
+/*
+ * Covert from processor physical address to II/TIO physical address:
+ *     II - squeeze out the AS bits
+ *     TIO- requires a chiplet id in bits 38-39.  For DMA to memory,
+ *           the chiplet id is zero.  If we implement TIO-TIO dma, we might need
+ *           to insert a chiplet id into this macro.  However, it is our belief
+ *           right now that this chiplet id will be ICE, which is also zero.
+ */
+#define PHYS_TO_TIODMA(x)      ( (((u64)(x) & NASID_MASK) << 2) | NODE_OFFSET(x))
+#define PHYS_TO_DMA(x)          ( (((u64)(x) & NASID_MASK) >> 2) | NODE_OFFSET(x))
 
-#endif /* __ASSEMBLY__ */
 
 /*
- * The following macros are used to get to a hub/bridge register, given
- * the base of the register space.
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
  */
-#define HUB_REG_PTR(_base, _off)       \
-       (HUBREG_CAST ((unsigned long)(_base) + (__psunsigned_t)(_off)))
+#define BWIN_SIZE_BITS                 29      /* big window size: 512M */
+#define TIO_BWIN_SIZE_BITS             30      /* big window size: 1G */
+#define NODE_SWIN_BASE(n, w)           ((w == 0) ? NODE_BWIN_BASE((n), SWIN0_BIGWIN) \
+               : RAW_NODE_SWIN_BASE(n, w))
+#define NODE_IO_BASE(n)                        (GLOBAL_MMR_SPACE | NASID_SPACE(n))
+#define BWIN_SIZE                      (1UL << BWIN_SIZE_BITS)
+#define NODE_BWIN_BASE0(n)             (NODE_IO_BASE(n) + BWIN_SIZE)
+#define NODE_BWIN_BASE(n, w)           (NODE_BWIN_BASE0(n) + ((u64) (w) << BWIN_SIZE_BITS))
+#define RAW_NODE_SWIN_BASE(n, w)       (NODE_IO_BASE(n) + ((u64) (w) << SWIN_SIZE_BITS))
+#define BWIN_WIDGET_MASK               0x7
+#define BWIN_WINDOWNUM(x)              (((x) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+
+#define TIO_BWIN_WINDOW_SELECT_MASK    0x7
+#define TIO_BWIN_WINDOWNUM(x)          (((x) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
 
-#define HUB_REG_PTR_L(_base, _off)     \
-       HUB_L(HUB_REG_PTR((_base), (_off)))
 
-#define HUB_REG_PTR_S(_base, _off, _data)      \
-       HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
 
 /*
- * Software structure locations -- permanently fixed
- *    See diagram in kldir.h
+ * The following definitions pertain to the IO special address
+ * space.  They define the location of the big and little windows
+ * of any given node.
  */
 
-#define PHYS_RAMBASE           0x0
-#define K0_RAMBASE             PHYS_TO_K0(PHYS_RAMBASE)
+#define SWIN_SIZE_BITS                 24
+#define        SWIN_WIDGET_MASK                0xF
 
-#define ARCS_SPB_OFFSET                0x1000
-#define ARCS_SPB_ADDR(nasid)                                           \
-       PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
-#define ARCS_SPB_SIZE          0x0400
+#define TIO_SWIN_SIZE_BITS             28
+#define TIO_SWIN_SIZE                  (1UL << TIO_SWIN_SIZE_BITS)
+#define TIO_SWIN_WIDGET_MASK           0x3
 
-#define KLDIR_OFFSET           0x2000
-#define KLDIR_ADDR(nasid)                                              \
-       TO_NODE_CAC((nasid), KLDIR_OFFSET)
-#define KLDIR_SIZE             0x0400
+/*
+ * Convert smallwindow address to xtalk address.
+ *
+ * 'addr' can be physical or virtual address, but will be converted
+ * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
+ */
+#define        SWIN_WIDGETNUM(x)               (((x)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
+#define TIO_SWIN_WIDGETNUM(x)          (((x)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
 
 
 /*
- * Software structure locations -- indirected through KLDIR
- *    See diagram in kldir.h
+ * The following macros produce the correct base virtual address for
+ * the hub registers. The REMOTE_HUB_* macro produce
+ * the address for the specified hub's registers.  The intent is
+ * that the appropriate PI, MD, NI, or II register would be substituted
+ * for x.
  *
- * Important:  All low memory structures must only be accessed
- *             uncached, except for the symmon stacks.
- */
-
-#define KLI_LAUNCH             0               /* Dir. entries */
-#define KLI_KLCONFIG           1
-#define        KLI_NMI                 2
-#define KLI_GDA                        3
-#define KLI_FREEMEM            4
-#define        KLI_SYMMON_STK          5
-#define KLI_PI_ERROR           6
-#define KLI_KERN_VARS          7
-#define        KLI_KERN_XP             8
-#define        KLI_KERN_PARTID         9
-
-#ifndef __ASSEMBLY__
-
-#define KLD_BASE(nasid)                ((kldir_ent_t *) KLDIR_ADDR(nasid))
-#define KLD_LAUNCH(nasid)      (KLD_BASE(nasid) + KLI_LAUNCH)
-#define KLD_NMI(nasid)         (KLD_BASE(nasid) + KLI_NMI)
-#define KLD_KLCONFIG(nasid)    (KLD_BASE(nasid) + KLI_KLCONFIG)
-#define KLD_PI_ERROR(nasid)    (KLD_BASE(nasid) + KLI_PI_ERROR)
-#define KLD_GDA(nasid)         (KLD_BASE(nasid) + KLI_GDA)
-#define KLD_SYMMON_STK(nasid)  (KLD_BASE(nasid) + KLI_SYMMON_STK)
-#define KLD_FREEMEM(nasid)     (KLD_BASE(nasid) + KLI_FREEMEM)
-#define KLD_KERN_VARS(nasid)   (KLD_BASE(nasid) + KLI_KERN_VARS)
-#define        KLD_KERN_XP(nasid)      (KLD_BASE(nasid) + KLI_KERN_XP)
-#define        KLD_KERN_PARTID(nasid)  (KLD_BASE(nasid) + KLI_KERN_PARTID)
-
-#define KLCONFIG_OFFSET(nasid)  ia64_sn_get_klconfig_addr(nasid)
-
-#define KLCONFIG_ADDR(nasid)                                           \
-       TO_NODE_CAC((nasid), KLCONFIG_OFFSET(nasid))
-#define KLCONFIG_SIZE(nasid)   KLD_KLCONFIG(nasid)->size
-
-#define GDA_ADDR(nasid)                KLD_GDA(nasid)->pointer
-#define GDA_SIZE(nasid)                KLD_GDA(nasid)->size
-
-#define NODE_OFFSET_TO_K0(_nasid, _off)                                        \
-       (CACHEABLE_MEM_SPACE | NODE_OFFSET(_nasid) | (_off))
-
-#endif /* __ASSEMBLY__ */
+ *   WARNING:
+ *     When certain Hub chip workaround are defined, it's not sufficient
+ *     to dereference the *_HUB_ADDR() macros.  You should instead use
+ *     HUB_L() and HUB_S() if you must deal with pointers to hub registers.
+ *     Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
+ *     They're always safe.
+ */
+#define REMOTE_HUB_ADDR(n,x)                                           \
+       ((n & 1) ?                                                      \
+       /* TIO: */                                                      \
+       ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))                        \
+       : /* SHUB: */                                                   \
+       (((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\
+       : ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x)))))
+
+
+
+#define HUB_L(x)                       (*((volatile typeof(*x) *)x))
+#define        HUB_S(x,d)                      (*((volatile typeof(*x) *)x) = (d))
+
+#define REMOTE_HUB_L(n, a)             HUB_L(REMOTE_HUB_ADDR((n), (a)))
+#define REMOTE_HUB_S(n, a, d)          HUB_S(REMOTE_HUB_ADDR((n), (a)), (d))
+
 
 #endif /* _ASM_IA64_SN_ADDRS_H */