20
20
#include <asm/types.h>
21
21
#include <asm/percpu.h>
22
22
#include <asm/uv/uv_mmrs.h>
23
+ #include <asm/uv/bios.h>
23
24
#include <asm/irq_vectors.h>
24
25
#include <asm/io_apic.h>
25
26
104
105
* processor APICID register.
105
106
*/
106
107
107
-
108
108
/*
109
109
* Maximum number of bricks in all partitions and in all coherency domains.
110
110
* This is the total number of bricks accessible in the numalink fabric. It
@@ -139,6 +139,14 @@ struct uv_scir_s {
139
139
unsigned char enabled ;
140
140
};
141
141
142
+ /* GAM (globally addressed memory) range table */
143
+ struct uv_gam_range_s {
144
+ u32 limit ; /* PA bits 56:26 (GAM_RANGE_SHFT) */
145
+ u16 nasid ; /* node's global physical address */
146
+ s8 base ; /* entry index of node's base addr */
147
+ u8 reserved ;
148
+ };
149
+
142
150
/*
143
151
* The following defines attributes of the HUB chip. These attributes are
144
152
* frequently referenced and are kept in a common per hub struct.
@@ -152,8 +160,12 @@ struct uv_hub_info_s {
152
160
unsigned short * socket_to_node ;
153
161
unsigned short * socket_to_pnode ;
154
162
unsigned short * pnode_to_socket ;
163
+ struct uv_gam_range_s * gr_table ;
155
164
unsigned short min_socket ;
156
165
unsigned short min_pnode ;
166
+ unsigned char m_val ;
167
+ unsigned char n_val ;
168
+ unsigned char gr_table_len ;
157
169
unsigned char hub_revision ;
158
170
unsigned char apic_pnode_shift ;
159
171
unsigned char gpa_shift ;
@@ -169,8 +181,6 @@ struct uv_hub_info_s {
169
181
unsigned short pnode_mask ;
170
182
unsigned short coherency_domain_number ;
171
183
unsigned short numa_blade_id ;
172
- unsigned char m_val ;
173
- unsigned char n_val ;
174
184
unsigned short nr_possible_cpus ;
175
185
unsigned short nr_online_cpus ;
176
186
short memory_nid ;
@@ -419,18 +429,74 @@ union uvh_apicid {
419
429
* between socket virtual and socket physical addresses.
420
430
*/
421
431
432
+ /* global bits offset - number of local address bits in gpa for this UV arch */
433
+ static inline unsigned int uv_gpa_shift (void )
434
+ {
435
+ return uv_hub_info -> gpa_shift ;
436
+ }
437
+ #define _uv_gpa_shift
438
+
439
+ /* Find node that has the address range that contains global address */
440
+ static inline struct uv_gam_range_s * uv_gam_range (unsigned long pa )
441
+ {
442
+ struct uv_gam_range_s * gr = uv_hub_info -> gr_table ;
443
+ unsigned long pal = (pa & uv_hub_info -> gpa_mask ) >> UV_GAM_RANGE_SHFT ;
444
+ int i , num = uv_hub_info -> gr_table_len ;
445
+
446
+ if (gr ) {
447
+ for (i = 0 ; i < num ; i ++ , gr ++ ) {
448
+ if (pal < gr -> limit )
449
+ return gr ;
450
+ }
451
+ }
452
+ pr_crit ("UV: GAM Range for 0x%lx not found at %p!\n" , pa , gr );
453
+ BUG ();
454
+ }
455
+
456
+ /* Return base address of node that contains global address */
457
+ static inline unsigned long uv_gam_range_base (unsigned long pa )
458
+ {
459
+ struct uv_gam_range_s * gr = uv_gam_range (pa );
460
+ int base = gr -> base ;
461
+
462
+ if (base < 0 )
463
+ return 0UL ;
464
+
465
+ return uv_hub_info -> gr_table [base ].limit ;
466
+ }
467
+
468
+ /* socket phys RAM --> UV global NASID (UV4+) */
469
+ static inline unsigned long uv_soc_phys_ram_to_nasid (unsigned long paddr )
470
+ {
471
+ return uv_gam_range (paddr )-> nasid ;
472
+ }
473
+ #define _uv_soc_phys_ram_to_nasid
474
+
475
+ /* socket virtual --> UV global NASID (UV4+) */
476
+ static inline unsigned long uv_gpa_nasid (void * v )
477
+ {
478
+ return uv_soc_phys_ram_to_nasid (__pa (v ));
479
+ }
480
+
422
481
/* socket phys RAM --> UV global physical address */
423
482
static inline unsigned long uv_soc_phys_ram_to_gpa (unsigned long paddr )
424
483
{
484
+ unsigned int m_val = uv_hub_info -> m_val ;
485
+
425
486
if (paddr < uv_hub_info -> lowmem_remap_top )
426
487
paddr |= uv_hub_info -> lowmem_remap_base ;
427
488
paddr |= uv_hub_info -> gnode_upper ;
428
- paddr = ((paddr << uv_hub_info -> m_shift ) >> uv_hub_info -> m_shift ) |
429
- ((paddr >> uv_hub_info -> m_val ) << uv_hub_info -> n_lshift );
489
+ if (m_val )
490
+ paddr = ((paddr << uv_hub_info -> m_shift )
491
+ >> uv_hub_info -> m_shift ) |
492
+ ((paddr >> uv_hub_info -> m_val )
493
+ << uv_hub_info -> n_lshift );
494
+ else
495
+ paddr |= uv_soc_phys_ram_to_nasid (paddr )
496
+ << uv_hub_info -> gpa_shift ;
430
497
return paddr ;
431
498
}
432
499
433
-
434
500
/* socket virtual --> UV global physical address */
435
501
static inline unsigned long uv_gpa (void * v )
436
502
{
@@ -450,20 +516,27 @@ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
450
516
unsigned long paddr ;
451
517
unsigned long remap_base = uv_hub_info -> lowmem_remap_base ;
452
518
unsigned long remap_top = uv_hub_info -> lowmem_remap_top ;
519
+ unsigned int m_val = uv_hub_info -> m_val ;
520
+
521
+ if (m_val )
522
+ gpa = ((gpa << uv_hub_info -> m_shift ) >> uv_hub_info -> m_shift ) |
523
+ ((gpa >> uv_hub_info -> n_lshift ) << uv_hub_info -> m_val );
453
524
454
- gpa = ((gpa << uv_hub_info -> m_shift ) >> uv_hub_info -> m_shift ) |
455
- ((gpa >> uv_hub_info -> n_lshift ) << uv_hub_info -> m_val );
456
525
paddr = gpa & uv_hub_info -> gpa_mask ;
457
526
if (paddr >= remap_base && paddr < remap_base + remap_top )
458
527
paddr -= remap_base ;
459
528
return paddr ;
460
529
}
461
530
462
-
463
531
/* gpa -> gnode */
464
532
static inline unsigned long uv_gpa_to_gnode (unsigned long gpa )
465
533
{
466
- return gpa >> uv_hub_info -> n_lshift ;
534
+ unsigned int n_lshift = uv_hub_info -> n_lshift ;
535
+
536
+ if (n_lshift )
537
+ return gpa >> n_lshift ;
538
+
539
+ return uv_gam_range (gpa )-> nasid >> 1 ;
467
540
}
468
541
469
542
/* gpa -> pnode */
@@ -475,21 +548,45 @@ static inline int uv_gpa_to_pnode(unsigned long gpa)
475
548
/* gpa -> node offset */
476
549
static inline unsigned long uv_gpa_to_offset (unsigned long gpa )
477
550
{
478
- return (gpa << uv_hub_info -> m_shift ) >> uv_hub_info -> m_shift ;
551
+ unsigned int m_shift = uv_hub_info -> m_shift ;
552
+
553
+ if (m_shift )
554
+ return (gpa << m_shift ) >> m_shift ;
555
+
556
+ return (gpa & uv_hub_info -> gpa_mask ) - uv_gam_range_base (gpa );
479
557
}
480
558
481
- /* pnode, offset --> socket virtual */
482
- static inline void * uv_pnode_offset_to_vaddr (int pnode , unsigned long offset )
559
+ /* Convert socket to node */
560
+ static inline int _uv_socket_to_node (int socket , unsigned short * s2nid )
483
561
{
484
- return __va ((( unsigned long ) pnode << uv_hub_info -> m_val ) | offset ) ;
562
+ return s2nid ? s2nid [ socket - uv_hub_info -> min_socket ] : socket ;
485
563
}
486
564
487
- /* Convert socket to node */
488
565
static inline int uv_socket_to_node (int socket )
489
566
{
490
- unsigned short * s2nid = uv_hub_info -> socket_to_node ;
567
+ return _uv_socket_to_node (socket , uv_hub_info -> socket_to_node );
568
+ }
491
569
492
- return s2nid ? s2nid [socket - uv_hub_info -> min_socket ] : socket ;
570
+ /* pnode, offset --> socket virtual */
571
+ static inline void * uv_pnode_offset_to_vaddr (int pnode , unsigned long offset )
572
+ {
573
+ unsigned int m_val = uv_hub_info -> m_val ;
574
+ unsigned long base ;
575
+ unsigned short sockid , node , * p2s ;
576
+
577
+ if (m_val )
578
+ return __va (((unsigned long )pnode << m_val ) | offset );
579
+
580
+ p2s = uv_hub_info -> pnode_to_socket ;
581
+ sockid = p2s ? p2s [pnode - uv_hub_info -> min_pnode ] : pnode ;
582
+ node = uv_socket_to_node (sockid );
583
+
584
+ /* limit address of previous socket is our base, except node 0 is 0 */
585
+ if (!node )
586
+ return __va ((unsigned long )offset );
587
+
588
+ base = (unsigned long )(uv_hub_info -> gr_table [node - 1 ].limit );
589
+ return __va (base << UV_GAM_RANGE_SHFT | offset );
493
590
}
494
591
495
592
/* Extract/Convert a PNODE from an APICID (full apicid, not processor subset) */
0 commit comments