Merge branch '3.2-without-smb2' of git://git.samba.org/sfrench/cifs-2.6
[pandora-kernel.git] / arch / x86 / include / asm / uv / uv_hub.h
index f26544a..54a13aa 100644 (file)
  *     PNODE   - the low N bits of the GNODE. The PNODE is the most useful variant
  *               of the nasid for socket usage.
  *
+ *     GPA     - (global physical address) a socket physical address converted
+ *               so that it can be used by the GRU as a global address. Socket
+ *               physical addresses 1) need additional NASID (node) bits added
+ *               to the high end of the address, and 2) unaliased if the
+ *               partition does not have a physical address 0. In addition, on
+ *               UV2 rev 1, GPAs need the gnode left shifted to bits 39 or 40.
+ *
  *
  *  NumaLink Global Physical Address Format:
  *  +--------------------------------+---------------------+
@@ -141,6 +148,8 @@ struct uv_hub_info_s {
        unsigned int            gnode_extra;
        unsigned char           hub_revision;
        unsigned char           apic_pnode_shift;
+       unsigned char           m_shift;
+       unsigned char           n_lshift;
        unsigned long           gnode_upper;
        unsigned long           lowmem_remap_top;
        unsigned long           lowmem_remap_base;
@@ -177,6 +186,16 @@ static inline int is_uv2_hub(void)
        return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE;
 }
 
+static inline int is_uv2_1_hub(void)
+{
+       return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE;
+}
+
+static inline int is_uv2_2_hub(void)
+{
+       return uv_hub_info->hub_revision == UV2_HUB_REVISION_BASE + 1;
+}
+
 union uvh_apicid {
     unsigned long       v;
     struct uvh_apicid_s {
@@ -276,7 +295,10 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr)
 {
        if (paddr < uv_hub_info->lowmem_remap_top)
                paddr |= uv_hub_info->lowmem_remap_base;
-       return paddr | uv_hub_info->gnode_upper;
+       paddr |= uv_hub_info->gnode_upper;
+       paddr = ((paddr << uv_hub_info->m_shift) >> uv_hub_info->m_shift) |
+               ((paddr >> uv_hub_info->m_val) << uv_hub_info->n_lshift);
+       return paddr;
 }
 
 
@@ -300,16 +322,19 @@ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
        unsigned long remap_base = uv_hub_info->lowmem_remap_base;
        unsigned long remap_top =  uv_hub_info->lowmem_remap_top;
 
+       gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) |
+               ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val);
+       gpa = gpa & uv_hub_info->gpa_mask;
        if (paddr >= remap_base && paddr < remap_base + remap_top)
                paddr -= remap_base;
        return paddr;
 }
 
 
-/* gnode -> pnode */
+/* gpa -> pnode */
 static inline unsigned long uv_gpa_to_gnode(unsigned long gpa)
 {
-       return gpa >> uv_hub_info->m_val;
+       return gpa >> uv_hub_info->n_lshift;
 }
 
 /* gpa -> pnode */
@@ -320,6 +345,12 @@ static inline int uv_gpa_to_pnode(unsigned long gpa)
        return uv_gpa_to_gnode(gpa) & n_mask;
 }
 
+/* gpa -> node offset*/
+static inline unsigned long uv_gpa_to_offset(unsigned long gpa)
+{
+       return (gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift;
+}
+
 /* pnode, offset --> socket virtual */
 static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
 {