Print this page
    
8620 pcplusmp shouldn't support x2APIC mode
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/i86pc/sys/apic.h
          +++ new/usr/src/uts/i86pc/sys/apic.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2017 Joyent, Inc.
  23   24   */
  24      -
  25   25  /*
  26   26   * Copyright (c) 2010, Intel Corporation.
  27   27   * All rights reserved.
  28   28   */
  29   29  
  30   30  #ifndef _SYS_APIC_APIC_H
  31   31  #define _SYS_APIC_APIC_H
  32   32  
  33   33  #include <sys/psm_types.h>
  34   34  #include <sys/avintr.h>
  35   35  #include <sys/pci.h>
  36   36  
  37   37  #ifdef  __cplusplus
  38   38  extern "C" {
  39   39  #endif
  40   40  
  41   41  #include <sys/psm_common.h>
  42   42  
  43   43  #define APIC_PCPLUSMP_NAME      "pcplusmp"
  44   44  #define APIC_APIX_NAME          "apix"
  45   45  
  46   46  #define APIC_IO_ADDR    0xfec00000
  47   47  #define APIC_LOCAL_ADDR 0xfee00000
  48   48  #define APIC_IO_MEMLEN  0xf
  49   49  #define APIC_LOCAL_MEMLEN       0xfffff
  50   50  
  51   51  /* Local Unit ID register */
  52   52  #define APIC_LID_REG            0x8
  53   53  
  54   54  /* I/o Unit Version Register */
  55   55  #define APIC_VERS_REG           0xc
  56   56  
  57   57  /* Task Priority register */
  58   58  #define APIC_TASK_REG           0x20
  59   59  
  60   60  /* EOI register */
  61   61  #define APIC_EOI_REG            0x2c
  62   62  
  63   63  /* Remote Read register         */
  64   64  #define APIC_REMOTE_READ        0x30
  65   65  
  66   66  /* Logical Destination register */
  67   67  #define APIC_DEST_REG           0x34
  68   68  
  69   69  /* Destination Format register */
  70   70  #define APIC_FORMAT_REG         0x38
  71   71  
  72   72  /* Spurious Interrupt Vector register */
  73   73  #define APIC_SPUR_INT_REG       0x3c
  74   74  
  75   75  /* Error Status Register */
  76   76  #define APIC_ERROR_STATUS       0xa0
  77   77  
  78   78  /* Interrupt Command registers */
  79   79  #define APIC_INT_CMD1           0xc0
  80   80  #define APIC_INT_CMD2           0xc4
  81   81  
  82   82  /* Local Interrupt Vector registers */
  83   83  #define APIC_CMCI_VECT          0xbc
  84   84  #define APIC_THERM_VECT         0xcc
  85   85  #define APIC_PCINT_VECT         0xd0
  86   86  #define APIC_INT_VECT0          0xd4
  87   87  #define APIC_INT_VECT1          0xd8
  88   88  #define APIC_ERR_VECT           0xdc
  89   89  
  90   90  /* IPL for performance counter interrupts */
  91   91  #define APIC_PCINT_IPL          0xe
  92   92  #define APIC_LVT_MASK           0x10000         /* Mask bit (16) in LVT */
  93   93  
  94   94  /* Initial Count register */
  95   95  #define APIC_INIT_COUNT         0xe0
  96   96  
  97   97  /* Current Count Register */
  98   98  #define APIC_CURR_COUNT         0xe4
  99   99  #define APIC_CURR_ADD           0x39    /* used for remote read command */
 100  100  #define CURR_COUNT_OFFSET       (sizeof (int32_t) * APIC_CURR_COUNT)
 101  101  
 102  102  /* Divider Configuration Register */
 103  103  #define APIC_DIVIDE_REG         0xf8
 104  104  
 105  105  /* Various mode for local APIC. Modes are mutually exclusive  */
 106  106  typedef enum apic_mode {
 107  107          APIC_IS_DISABLED = 0,
 108  108          APIC_MODE_NOTSET,
 109  109          LOCAL_APIC,
  
    | 
      ↓ open down ↓ | 
    75 lines elided | 
    
      ↑ open up ↑ | 
  
 110  110          LOCAL_X2APIC
 111  111  } apic_mode_t;
 112  112  
 113  113  /* x2APIC SELF IPI Register */
 114  114  #define X2APIC_SELF_IPI         0xFC
 115  115  
 116  116  /* General x2APIC constants used at various places */
 117  117  #define APIC_SVR_SUPPRESS_BROADCAST_EOI         0x1000
 118  118  #define APIC_DIRECTED_EOI_BIT                   0x1000000
 119  119  
      120 +/* x2APIC enable bit in REG_APIC_BASE_MSR */
      121 +#define X2APIC_ENABLE_BIT       10
      122 +
 120  123  /* IRR register */
 121  124  #define APIC_IRR_REG            0x80
 122  125  
 123  126  /* ISR register */
 124  127  #define APIC_ISR_REG            0x40
 125  128  
 126  129  #define APIC_IO_REG             0x0
 127  130  #define APIC_IO_DATA            0x4
 128  131  #define APIC_IO_EOI             0x10
 129  132  
 130  133  /* Bit offset of APIC ID in LID_REG, INT_CMD and in DEST_REG */
 131  134  #define APIC_ID_BIT_OFFSET      24
 132  135  #define APIC_ICR_ID_BIT_OFFSET  24
 133  136  #define APIC_LDR_ID_BIT_OFFSET  24
 134  137  
 135  138  /*
 136  139   * Choose between flat and clustered models by writing the following to the
 137  140   * FORMAT_REG. 82489 DX documentation seemed to suggest that writing 0 will
 138  141   * disable logical destination mode.
 139  142   * Does not seem to be in the docs for local APICs on the processors.
 140  143   */
 141  144  #define APIC_FLAT_MODEL         0xFFFFFFFFUL
 142  145  #define APIC_CLUSTER_MODEL      0x0FFFFFFF
 143  146  
 144  147  /*
 145  148   * The commands which follow are window selectors written to APIC_IO_REG
 146  149   * before data can be read/written from/to APIC_IO_DATA
 147  150   */
 148  151  
 149  152  #define APIC_ID_CMD             0x0
 150  153  #define APIC_VERS_CMD           0x1
 151  154  #define APIC_RDT_CMD            0x10
 152  155  #define APIC_RDT_CMD2           0x11
 153  156  
 154  157  #define APIC_INTEGRATED_VERS    0x10    /* 0x10 & above indicates integrated */
 155  158  #define IOAPIC_VER_82489DX      0x01    /* Version ID: 82489DX External APIC */
 156  159  
 157  160  #define APIC_INT_SPURIOUS       -1
 158  161  
 159  162  #define APIC_IMCR_P1    0x22            /* int mode conf register port 1 */
 160  163  #define APIC_IMCR_P2    0x23            /* int mode conf register port 2 */
 161  164  #define APIC_IMCR_SELECT 0x70           /* select imcr by writing into P1 */
 162  165  #define APIC_IMCR_PIC   0x0             /* selects PIC mode (8259-> BSP) */
 163  166  #define APIC_IMCR_APIC  0x1             /* selects APIC mode (8259->APIC) */
 164  167  
 165  168  #define APIC_CT_VECT    0x4ac           /* conf table vector            */
 166  169  #define APIC_CT_SIZE    1024            /* conf table size              */
 167  170  
 168  171  #define APIC_ID         'MPAT'          /* conf table signature         */
 169  172  
 170  173  #define VENID_AMD               0x1022
 171  174  #define DEVID_8131_IOAPIC       0x7451
 172  175  #define DEVID_8132_IOAPIC       0x7459
 173  176  
 174  177  #define IOAPICS_NODE_NAME       "ioapics"
 175  178  #define IOAPICS_CHILD_NAME      "ioapic"
 176  179  #define IOAPICS_DEV_TYPE        "ioapic"
 177  180  #define IOAPICS_PROP_VENID      "vendor-id"
 178  181  #define IOAPICS_PROP_DEVID      "device-id"
 179  182  
 180  183  #define IS_CLASS_IOAPIC(b, s, p) \
 181  184          ((b) == PCI_CLASS_PERIPH && (s) == PCI_PERIPH_PIC &&    \
 182  185          ((p) == PCI_PERIPH_PIC_IF_IO_APIC ||                    \
 183  186          (p) == PCI_PERIPH_PIC_IF_IOX_APIC))
 184  187  
 185  188  /*
 186  189   * These macros are used in frequently called routines like
 187  190   * apic_intr_enter().
 188  191   */
 189  192  #define X2APIC_WRITE(reg, v) \
 190  193          wrmsr((REG_X2APIC_BASE_MSR + (reg >> 2)), v)
 191  194  
 192  195  #define LOCAL_APIC_WRITE_REG(reg, v) \
 193  196          apicadr[reg] = v
 194  197  
 195  198  /*
 196  199   * MP floating pointer structure defined in Intel MP Spec 1.1
 197  200   */
 198  201  struct apic_mpfps_hdr {
 199  202          uint32_t        mpfps_sig;      /* _MP_ (0x5F4D505F)            */
 200  203          uint32_t        mpfps_mpct_paddr; /* paddr of MP configuration tbl */
 201  204          uchar_t mpfps_length;           /* in paragraph (16-bytes units) */
 202  205          uchar_t mpfps_spec_rev;         /* version number of MP spec     */
 203  206          uchar_t mpfps_checksum;         /* checksum of complete structure */
 204  207          uchar_t mpfps_featinfo1;        /* mp feature info bytes 1       */
 205  208          uchar_t mpfps_featinfo2;        /* mp feature info bytes 2       */
 206  209          uchar_t mpfps_featinfo3;        /* mp feature info bytes 3       */
 207  210          uchar_t mpfps_featinfo4;        /* mp feature info bytes 4       */
 208  211          uchar_t mpfps_featinfo5;        /* mp feature info bytes 5       */
 209  212  };
 210  213  
 211  214  #define MPFPS_FEATINFO2_IMCRP           0x80    /* IMCRP presence bit   */
 212  215  
 213  216  #define APIC_MPS_OEM_ID_LEN             8
 214  217  #define APIC_MPS_PROD_ID_LEN            12
 215  218  
 216  219  struct apic_mp_cnf_hdr {
 217  220          uint_t  mpcnf_sig;
 218  221  
 219  222          uint_t  mpcnf_tbl_length:       16,
 220  223                  mpcnf_spec:             8,
 221  224                  mpcnf_cksum:            8;
 222  225  
 223  226          char    mpcnf_oem_str[APIC_MPS_OEM_ID_LEN];
 224  227  
 225  228          char    mpcnf_prod_str[APIC_MPS_PROD_ID_LEN];
 226  229  
 227  230          uint_t  mpcnf_oem_ptr;
 228  231  
 229  232          uint_t  mpcnf_oem_tbl_size:     16,
 230  233                  mpcnf_entry_cnt:        16;
 231  234  
 232  235          uint_t  mpcnf_local_apic;
 233  236  
 234  237          uint_t  mpcnf_resv;
 235  238  };
 236  239  
 237  240  struct apic_procent {
 238  241          uint_t  proc_entry:             8,
 239  242                  proc_apicid:            8,
 240  243                  proc_version:           8,
 241  244                  proc_cpuflags:          8;
 242  245  
 243  246          uint_t  proc_stepping:          4,
 244  247                  proc_model:             4,
 245  248                  proc_family:            4,
 246  249                  proc_type:              2,      /* undocumented feature */
 247  250                  proc_resv1:             18;
 248  251  
 249  252          uint_t  proc_feature;
 250  253  
 251  254          uint_t  proc_resv2;
 252  255  
 253  256          uint_t  proc_resv3;
 254  257  };
 255  258  
 256  259  /*
 257  260   * proc_cpuflags definitions
 258  261   */
 259  262  #define CPUFLAGS_EN     1       /* if not set, this processor is unusable */
 260  263  #define CPUFLAGS_BP     2       /* set if this is the bootstrap processor */
 261  264  
 262  265  
 263  266  struct apic_bus {
 264  267          uchar_t bus_entry;
 265  268          uchar_t bus_id;
 266  269          ushort_t        bus_str1;
 267  270          uint_t  bus_str2;
 268  271  };
 269  272  
 270  273  struct apic_io_entry {
 271  274          uint_t  io_entry:               8,
 272  275                  io_apicid:              8,
 273  276                  io_version:             8,
 274  277                  io_flags:               8;
 275  278  
 276  279          uint_t  io_apic_addr;
 277  280  };
 278  281  
 279  282  #define IOAPIC_FLAGS_EN         0x01    /* this I/O apic is enable or not */
 280  283  
 281  284  #define MAX_IO_APIC             32      /* maximum # of IOAPICs supported */
 282  285  
 283  286  struct apic_io_intr {
 284  287          uint_t  intr_entry:             8,
 285  288                  intr_type:              8,
 286  289                  intr_po:                2,
 287  290                  intr_el:                2,
 288  291                  intr_resv:              12;
 289  292  
 290  293          uint_t  intr_busid:             8,
 291  294                  intr_irq:               8,
 292  295                  intr_destid:            8,
 293  296                  intr_destintin:         8;
 294  297  };
 295  298  
 296  299  /*
 297  300   * intr_type definitions
 298  301   */
 299  302  #define IO_INTR_INT     0x00
 300  303  #define IO_INTR_NMI     0x01
 301  304  #define IO_INTR_SMI     0x02
 302  305  #define IO_INTR_EXTINT  0x03
 303  306  
 304  307  /*
 305  308   * destination APIC ID
 306  309   */
 307  310  #define INTR_ALL_APIC           0xff
 308  311  
 309  312  
 310  313  /* local vector table                                                   */
 311  314  #define AV_MASK         0x10000
 312  315  
 313  316  /* interrupt command register 32-63                                     */
 314  317  #define AV_TOALL        0x7fffffff
 315  318  #define AV_HIGH_ORDER   0x40000000
 316  319  #define AV_IM_OFF       0x40000000
 317  320  
 318  321  /* interrupt command register 0-31                                      */
 319  322  #define AV_DELIV_MODE   0x700
 320  323  
 321  324  #define AV_FIXED        0x000
 322  325  #define AV_LOPRI        0x100
 323  326  #define AV_SMI          0x200
 324  327  #define AV_REMOTE       0x300
 325  328  #define AV_NMI          0x400
 326  329  #define AV_RESET        0x500
 327  330  #define AV_STARTUP      0x600
 328  331  #define AV_EXTINT       0x700
 329  332  
 330  333  #define AV_PDEST        0x000
 331  334  #define AV_LDEST        0x800
 332  335  
 333  336  /* IO & Local APIC Bit Definitions */
 334  337  #define RDT_VECTOR(x)   ((uchar_t)((x) & 0xFF))
 335  338  #define AV_PENDING      0x1000
 336  339  #define AV_ACTIVE_LOW   0x2000          /* only for integrated APIC */
 337  340  #define AV_REMOTE_IRR   0x4000          /* IOAPIC RDT-specific */
 338  341  #define AV_LEVEL        0x8000
 339  342  #define AV_DEASSERT     AV_LEVEL
 340  343  #define AV_ASSERT       0xc000
 341  344  
 342  345  #define AV_READ_PENDING 0x10000
 343  346  #define AV_REMOTE_STATUS        0x20000 /* 1 = valid, 0 = invalid */
 344  347  
 345  348  #define AV_SH_SELF              0x40000 /* Short hand for self */
 346  349  #define AV_SH_ALL_INCSELF       0x80000 /* All processors */
 347  350  #define AV_SH_ALL_EXCSELF       0xc0000 /* All excluding self */
 348  351  /* spurious interrupt vector register                                   */
 349  352  #define AV_UNIT_ENABLE  0x100
 350  353  
 351  354  #define APIC_MAXVAL     0xffffffffUL
 352  355  #define APIC_TIME_MIN   0x5000
 353  356  #define APIC_TIME_COUNT 0x4000
 354  357  
 355  358  /*
 356  359   * Range of the low byte value in apic_tick before starting calibration
 357  360   */
 358  361  #define APIC_LB_MIN     0x60
 359  362  #define APIC_LB_MAX     0xe0
 360  363  
 361  364  #define APIC_MAX_VECTOR         255
 362  365  #define APIC_RESV_VECT          0x00
 363  366  #define APIC_RESV_IRQ           0xfe
 364  367  #define APIC_BASE_VECT          0x20    /* This will come in as interrupt 0 */
 365  368  #define APIC_AVAIL_VECTOR       (APIC_MAX_VECTOR+1-APIC_BASE_VECT)
 366  369  #define APIC_VECTOR_PER_IPL     0x10    /* # of vectors before PRI changes */
 367  370  #define APIC_VECTOR(ipl)        (apic_ipltopri[ipl] | APIC_RESV_VECT)
 368  371  #define APIC_VECTOR_MASK        0x0f
 369  372  #define APIC_HI_PRI_VECTS       2       /* vects reserved for hi pri reqs */
 370  373  #define APIC_IPL_MASK           0xf0
 371  374  #define APIC_IPL_SHIFT          4       /* >> to get ipl part of vector */
 372  375  #define APIC_FIRST_FREE_IRQ     0x10
 373  376  #define APIC_MAX_ISA_IRQ        15
 374  377  #define APIC_IPL0               0x0f    /* let IDLE_IPL be the lowest */
 375  378  #define APIC_IDLE_IPL           0x00
 376  379  
 377  380  #define APIC_MASK_ALL           0xf0    /* Mask all interrupts */
 378  381  
 379  382  /* spurious interrupt vector                                            */
 380  383  #define APIC_SPUR_INTR          0xFF
 381  384  
 382  385  /* special or reserve vectors */
 383  386  #define APIC_CHECK_RESERVE_VECTORS(v) \
 384  387          (((v) == T_FASTTRAP) || ((v) == APIC_SPUR_INTR) || \
 385  388          ((v) == T_SYSCALLINT) || ((v) == T_DTRACE_RET))
 386  389  
 387  390  /* cmos shutdown code for BIOS                                          */
 388  391  #define BIOS_SHUTDOWN           0x0a
 389  392  
 390  393  /* define the entry types for BIOS information tables as defined in PC+MP */
 391  394  #define APIC_CPU_ENTRY          0
 392  395  #define APIC_BUS_ENTRY          1
 393  396  #define APIC_IO_ENTRY           2
 394  397  #define APIC_IO_INTR_ENTRY      3
 395  398  #define APIC_LOCAL_INTR_ENTRY   4
 396  399  #define APIC_MPTBL_ADDR         (639 * 1024)
 397  400  /*
 398  401   * The MP Floating Point structure could be in 1st 1KB of EBDA or last KB
 399  402   * of system base memory or in ROM between 0xF0000 and 0xFFFFF
 400  403   */
 401  404  #define MPFPS_RAM_WIN_LEN       1024
 402  405  #define MPFPS_ROM_WIN_START     (uint32_t)0xf0000
 403  406  #define MPFPS_ROM_WIN_LEN       0x10000
 404  407  
 405  408  #define EISA_LEVEL_CNTL         0x4D0
 406  409  
 407  410  /* definitions for apic_irq_table */
 408  411  #define FREE_INDEX              (short)-1       /* empty slot */
 409  412  #define RESERVE_INDEX           (short)-2       /* ipi, softintr, clkintr */
 410  413  #define ACPI_INDEX              (short)-3       /* ACPI */
 411  414  #define MSI_INDEX               (short)-4       /* MSI */
 412  415  #define MSIX_INDEX              (short)-5       /* MSI-X */
 413  416  #define DEFAULT_INDEX           (short)0x7FFF
 414  417          /* biggest positive no. to avoid conflict with actual index */
 415  418  
 416  419  #define APIC_IS_MSI_OR_MSIX_INDEX(index) \
 417  420          ((index) == MSI_INDEX || (index) == MSIX_INDEX)
 418  421  
 419  422  /*
 420  423   * definitions for MSI Address
 421  424   */
 422  425  #define MSI_ADDR_HDR            APIC_LOCAL_ADDR
 423  426  #define MSI_ADDR_DEST_SHIFT     12      /* Destination CPU's apic id */
 424  427  #define MSI_ADDR_RH_FIXED       0x0     /* Redirection Hint Fixed */
 425  428  #define MSI_ADDR_RH_LOPRI       0x1     /* Redirection Hint Lowest priority */
 426  429  #define MSI_ADDR_RH_SHIFT       3
 427  430  #define MSI_ADDR_DM_PHYSICAL    0x0     /* Physical Destination Mode */
 428  431  #define MSI_ADDR_DM_LOGICAL     0x1     /* Logical Destination Mode */
 429  432  #define MSI_ADDR_DM_SHIFT       2
 430  433  
 431  434  /*
 432  435   * TM is either edge or level.
 433  436   */
 434  437  #define TRIGGER_MODE_EDGE               0x0     /* edge sensitive */
 435  438  #define TRIGGER_MODE_LEVEL              0x1     /* level sensitive */
 436  439  
 437  440  /*
 438  441   * definitions for MSI Data
 439  442   */
 440  443  #define MSI_DATA_DELIVERY_FIXED         0x0     /* Fixed delivery */
 441  444  #define MSI_DATA_DELIVERY_LOPRI         0x1     /* Lowest priority delivery */
 442  445  #define MSI_DATA_DELIVERY_SMI           0x2
 443  446  #define MSI_DATA_DELIVERY_NMI           0x4
 444  447  #define MSI_DATA_DELIVERY_INIT          0x5
 445  448  #define MSI_DATA_DELIVERY_EXTINT        0x7
 446  449  #define MSI_DATA_DELIVERY_SHIFT         8
 447  450  #define MSI_DATA_TM_EDGE                TRIGGER_MODE_EDGE
 448  451  #define MSI_DATA_TM_LEVEL               TRIGGER_MODE_LEVEL
 449  452  #define MSI_DATA_TM_SHIFT               15
 450  453  #define MSI_DATA_LEVEL_DEASSERT         0x0
 451  454  #define MSI_DATA_LEVEL_ASSERT           0x1     /* Edge always assert */
 452  455  #define MSI_DATA_LEVEL_SHIFT            14
 453  456  
 454  457  /*
 455  458   * use to define each irq setup by the apic
 456  459   */
 457  460  typedef struct  apic_irq {
 458  461          short   airq_mps_intr_index;    /* index into mps interrupt entries */
 459  462                                          /*  table */
 460  463          uchar_t airq_intin_no;
 461  464          uchar_t airq_ioapicindex;
 462  465          dev_info_t      *airq_dip; /* device corresponding to this interrupt */
 463  466          /*
 464  467           * IRQ could be shared (in H/W) in which case dip & major will be
 465  468           * for the one that was last added at this level. We cannot keep a
 466  469           * linked list as delspl does not tell us which device has just
 467  470           * been unloaded. For most servers where we are worried about
 468  471           * performance, interrupt should not be shared & should not be
 469  472           * a problem. This does not cause any correctness issue - dip is
 470  473           * used only as an optimisation to avoid going thru all the tables
 471  474           * in translate IRQ (which is always called twice due to brokenness
 472  475           * in the way IPLs are determined for devices). major is used only
 473  476           * to bind interrupts corresponding to the same device on the same
 474  477           * CPU. Not finding major will just cause it to be potentially bound
 475  478           * to another CPU.
 476  479           */
 477  480          major_t airq_major;     /* major number corresponding to the device */
 478  481          ushort_t airq_rdt_entry;        /* level, polarity & trig mode */
 479  482          uint32_t airq_cpu;              /* target CPU, non-reserved IRQ only */
 480  483          uint32_t airq_temp_cpu;   /* non-reserved IRQ only, for disable_intr */
 481  484          uchar_t airq_vector;            /* Vector chosen for this irq */
 482  485          uchar_t airq_share;             /* number of interrupts at this irq */
 483  486          uchar_t airq_share_id;          /* id to identify source from irqno */
 484  487          uchar_t airq_ipl;               /* The ipl at which this is handled */
 485  488          iflag_t airq_iflag;             /* interrupt flag */
 486  489          uchar_t airq_origirq;           /* original irq passed in */
 487  490          uint_t  airq_busy;              /* How frequently did clock find */
 488  491                                          /* us in this */
 489  492          struct apic_irq *airq_next;     /* chain of intpts sharing a vector */
 490  493          void            *airq_intrmap_private; /* intr remap private data */
 491  494  } apic_irq_t;
 492  495  
 493  496  #define IRQ_USER_BOUND  0x80000000 /* user requested bind if set in airq_cpu */
 494  497  #define IRQ_UNBOUND     (uint32_t)-1    /* set in airq_cpu and airq_temp_cpu */
 495  498  #define IRQ_UNINIT      (uint32_t)-2 /* in airq_temp_cpu till addspl called */
 496  499  
 497  500  /* Macros to help deal with shared interrupts */
 498  501  #define VIRTIRQ(irqno, share_id)        ((irqno) | ((share_id) << 8))
 499  502  #define IRQINDEX(irq)   ((irq) & 0xFF)  /* Mask to get irq from virtual irq */
 500  503  
 501  504  /*
 502  505   * We align apic_cpus_info at 64-byte cache line boundary. Please make sure we
 503  506   * adjust APIC_PADSZ as we add/modify any member of apic_cpus_info. We also
 504  507   * don't want the compiler to optimize apic_cpus_info.
 505  508   */
 506  509  #define APIC_PADSZ      15
 507  510  
 508  511  #pragma pack(1)
 509  512  typedef struct apic_cpus_info {
 510  513          uint32_t aci_local_id;
 511  514          uchar_t aci_local_ver;
 512  515          uchar_t aci_status;
 513  516          uchar_t aci_redistribute;       /* Selected for redistribution */
 514  517          uint_t  aci_busy;               /* Number of ticks we were in ISR */
 515  518          uint_t  aci_spur_cnt;           /* # of spurious intpts on this cpu */
 516  519          uint_t  aci_ISR_in_progress;    /* big enough to hold 1 << MAXIPL */
 517  520          uchar_t aci_curipl;             /* IPL of current ISR */
 518  521          uchar_t aci_current[MAXIPL];    /* Current IRQ at each IPL */
 519  522          uint32_t aci_bound;             /* # of user requested binds ? */
 520  523          uint32_t aci_temp_bound;        /* # of non user IRQ binds */
 521  524          uint32_t aci_processor_id;      /* Only used in ACPI mode. */
 522  525          uchar_t aci_idle;               /* The CPU is idle */
 523  526          /*
 524  527           * Fill to make sure each struct is in separate 64-byte cache line.
 525  528           */
 526  529          uchar_t aci_pad[APIC_PADSZ];    /* padding for 64-byte cache line */
 527  530  } apic_cpus_info_t;
 528  531  #pragma pack()
 529  532  
 530  533  #define APIC_CPU_ONLINE         0x1
 531  534  #define APIC_CPU_INTR_ENABLE    0x2
 532  535  #define APIC_CPU_FREE           0x4     /* APIC CPU slot is free */
 533  536  #define APIC_CPU_DIRTY          0x8     /* Slot was once used */
 534  537  #define APIC_CPU_SUSPEND        0x10
 535  538  
 536  539  /*
 537  540   * APIC ops to support various flavors of APIC like APIC and x2APIC.
 538  541   */
 539  542  typedef struct apic_regs_ops {
 540  543          uint64_t        (*apic_read)(uint32_t);
 541  544          void            (*apic_write)(uint32_t, uint64_t);
 542  545          int             (*apic_get_pri)(void);
 543  546          void            (*apic_write_task_reg)(uint64_t);
 544  547          void            (*apic_write_int_cmd)(uint32_t, uint32_t);
 545  548          void            (*apic_send_eoi)(uint32_t);
 546  549  } apic_reg_ops_t;
 547  550  
 548  551  /*
 549  552   * interrupt structure for ioapic and msi
 550  553   */
 551  554  typedef struct ioapic_rdt {
 552  555          uint32_t        ir_lo;
 553  556          uint32_t        ir_hi;
 554  557  } ioapic_rdt_t;
 555  558  
 556  559  typedef struct msi_regs {
 557  560          uint32_t        mr_data;
 558  561          uint64_t        mr_addr;
 559  562  }msi_regs_t;
 560  563  
 561  564  /*
 562  565   * APIC ops to support intel interrupt remapping
 563  566   */
 564  567  typedef struct apic_intrmap_ops {
 565  568          int     (*apic_intrmap_init)(int);
 566  569          void    (*apic_intrmap_enable)(int);
 567  570          void    (*apic_intrmap_alloc_entry)(void **, dev_info_t *, uint16_t,
 568  571                      int, uchar_t);
 569  572          void    (*apic_intrmap_map_entry)(void *, void *, uint16_t, int);
 570  573          void    (*apic_intrmap_free_entry)(void **);
 571  574          void    (*apic_intrmap_record_rdt)(void *, ioapic_rdt_t *);
 572  575          void    (*apic_intrmap_record_msi)(void *, msi_regs_t *);
 573  576  } apic_intrmap_ops_t;
 574  577  
 575  578  /*
 576  579   * Various poweroff methods and ports & bits for them
 577  580   */
 578  581  #define APIC_POWEROFF_NONE              0
 579  582  #define APIC_POWEROFF_VIA_RTC           1
 580  583  #define APIC_POWEROFF_VIA_ASPEN_BMC     2
 581  584  #define APIC_POWEROFF_VIA_SITKA_BMC     3
 582  585  
 583  586  /* For RTC */
 584  587  #define RTC_REGA                0x0a
 585  588  #define PFR_REG                 0x4a    /* extended control register */
 586  589  #define PAB_CBIT                0x08
 587  590  #define WF_FLAG                 0x02
 588  591  #define KS_FLAG                 0x01
 589  592  #define EXT_BANK                0x10
 590  593  
 591  594  /* For Aspen/Drake BMC */
 592  595  
 593  596  #define CC_SMS_GET_STATUS       0x40
 594  597  #define CC_SMS_WR_START         0x41
 595  598  #define CC_SMS_WR_NEXT          0x42
 596  599  #define CC_SMS_WR_END           0x43
 597  600  
 598  601  #define MISMIC_DATA_REGISTER    0x0ca9
 599  602  #define MISMIC_CNTL_REGISTER    0x0caa
 600  603  #define MISMIC_FLAG_REGISTER    0x0cab
 601  604  
 602  605  #define MISMIC_BUSY_MASK        0x01
 603  606  
 604  607  /* For Sitka/Cabrillo BMC */
 605  608  
 606  609  #define SMS_GET_STATUS          0x60
 607  610  #define SMS_WRITE_START         0x61
 608  611  #define SMS_WRITE_END           0x62
 609  612  
 610  613  #define SMS_DATA_REGISTER       0x0ca2
 611  614  #define SMS_STATUS_REGISTER     0x0ca3
 612  615  #define SMS_COMMAND_REGISTER    0x0ca3
 613  616  
 614  617  #define SMS_IBF_MASK            0x02
 615  618  #define SMS_STATE_MASK          0xc0
 616  619  
 617  620  #define SMS_IDLE_STATE          0x00
 618  621  #define SMS_READ_STATE          0x40
 619  622  #define SMS_WRITE_STATE         0x80
 620  623  #define SMS_ERROR_STATE         0xc0
 621  624  
 622  625  extern uint32_t ioapic_read(int ioapic_ix, uint32_t reg);
 623  626  extern void ioapic_write(int ioapic_ix, uint32_t reg, uint32_t value);
 624  627  extern void ioapic_write_eoi(int ioapic_ix, uint32_t value);
 625  628  
 626  629  /* Macros for reading/writing the IOAPIC RDT entries */
 627  630  #define READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \
 628  631          ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)))
 629  632  
 630  633  #define READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \
 631  634          ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)))
 632  635  
 633  636  #define WRITE_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin, value) \
 634  637          ioapic_write(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)), value)
 635  638  
 636  639  #define WRITE_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin, value) \
 637  640          ioapic_write(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)), value)
 638  641  
 639  642  /* Used by PSM_INTR_OP_GET_INTR to return device information. */
 640  643  typedef struct {
 641  644          uint16_t        avgi_req_flags; /* request flags - to kernel */
 642  645          uint8_t         avgi_num_devs;  /* # devs on this ino - from kernel */
 643  646          uint8_t         avgi_vector;    /* vector */
 644  647          uint32_t        avgi_cpu_id;    /* cpu of interrupt - from kernel */
 645  648          dev_info_t      **avgi_dip_list; /* kmem_alloc'ed list of dev_infos. */
 646  649                                          /* Contains num_devs elements. */
 647  650  } apic_get_intr_t;
 648  651  
 649  652  /* Used by PSM_INTR_OP_GET_TYPE to return platform information. */
 650  653  typedef struct {
 651  654          char            *avgi_type;     /*  platform type - from kernel */
 652  655          uint32_t        avgi_num_intr;  /*  max intr number - from kernel */
 653  656          uint32_t        avgi_num_cpu;   /*  max cpu number - from kernel */
 654  657  } apic_get_type_t;
 655  658  
 656  659  /* Masks for avgi_req_flags. */
 657  660  #define PSMGI_REQ_CPUID         0x1     /* Request CPU ID */
 658  661  #define PSMGI_REQ_NUM_DEVS      0x2     /* Request num of devices on vector */
 659  662  #define PSMGI_REQ_VECTOR        0x4
 660  663  #define PSMGI_REQ_GET_DEVS      0x8     /* Request device list */
 661  664  #define PSMGI_REQ_ALL           0xf     /* Request everything */
 662  665  
 663  666  /* Other flags */
 664  667  #define PSMGI_INTRBY_VEC        0       /* Vec passed.  xlate to IRQ needed */
 665  668  #define PSMGI_INTRBY_IRQ        0x8000  /* IRQ passed.  no xlate needed */
 666  669  #define PSMGI_INTRBY_DEFAULT    0x4000  /* PSM specific default value */
 667  670  #define PSMGI_INTRBY_FLAGS      0xc000  /* Mask for this flag */
 668  671  
 669  672  extern int      apic_verbose;
 670  673  
 671  674  /* Flag definitions for apic_verbose */
 672  675  #define APIC_VERBOSE_IOAPIC_FLAG                0x00000001
 673  676  #define APIC_VERBOSE_IRQ_FLAG                   0x00000002
 674  677  #define APIC_VERBOSE_POWEROFF_FLAG              0x00000004
 675  678  #define APIC_VERBOSE_POWEROFF_PAUSE_FLAG        0x00000008
 676  679  #define APIC_VERBOSE_INIT                       0x00000010
 677  680  #define APIC_VERBOSE_REBIND                     0x00000020
 678  681  #define APIC_VERBOSE_ALLOC                      0x00000040
 679  682  #define APIC_VERBOSE_IPI                        0x00000080
 680  683  #define APIC_VERBOSE_INTR                       0x00000100
 681  684  
 682  685  /* required test to wait until APIC command is sent on the bus */
 683  686  #define APIC_AV_PENDING_SET() \
 684  687          while (apic_reg_ops->apic_read(APIC_INT_CMD1) & AV_PENDING) \
 685  688                  apic_ret();
 686  689  
 687  690  #ifdef  DEBUG
 688  691  
 689  692  #define DENT            0x0001
 690  693  extern int      apic_debug;
 691  694  /*
 692  695   * set apic_restrict_vector to the # of vectors we want to allow per range
 693  696   * useful in testing shared interrupt logic by setting it to 2 or 3
 694  697   */
 695  698  extern int      apic_restrict_vector;
 696  699  
 697  700  #define APIC_DEBUG_MSGBUFSIZE   2048
 698  701  extern int      apic_debug_msgbuf[];
 699  702  extern int      apic_debug_msgbufindex;
 700  703  
 701  704  /*
 702  705   * Put "int" info into debug buffer. No MP consistency, but light weight.
 703  706   * Good enough for most debugging.
 704  707   */
 705  708  #define APIC_DEBUG_BUF_PUT(x) \
 706  709          apic_debug_msgbuf[apic_debug_msgbufindex++] = x; \
 707  710          if (apic_debug_msgbufindex >= (APIC_DEBUG_MSGBUFSIZE - NCPU)) \
 708  711                  apic_debug_msgbufindex = 0;
 709  712  
 710  713  #define APIC_VERBOSE(flag, fmt)                      \
 711  714          if (apic_verbose & APIC_VERBOSE_##flag) \
 712  715                  cmn_err fmt;
 713  716  
 714  717  #define APIC_VERBOSE_POWEROFF(fmt) \
 715  718          if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG) \
 716  719                  prom_printf fmt;
 717  720  
 718  721  #else   /* DEBUG */
 719  722  
 720  723  #define APIC_VERBOSE(flag, fmt)
 721  724  #define APIC_VERBOSE_POWEROFF(fmt)
 722  725  
 723  726  #endif  /* DEBUG */
 724  727  
 725  728  #define APIC_VERBOSE_IOAPIC(fmt)        APIC_VERBOSE(IOAPIC_FLAG, fmt)
 726  729  #define APIC_VERBOSE_IRQ(fmt)           APIC_VERBOSE(IRQ_FLAG, fmt)
 727  730  
 728  731  extern int      apic_error;
 729  732  /* values which apic_error can take. Not catastrophic, but may help debug */
 730  733  #define APIC_ERR_BOOT_EOI               0x1
 731  734  #define APIC_ERR_GET_IPIVECT_FAIL       0x2
 732  735  #define APIC_ERR_INVALID_INDEX          0x4
 733  736  #define APIC_ERR_MARK_VECTOR_FAIL       0x8
 734  737  #define APIC_ERR_APIC_ERROR             0x40000000
 735  738  #define APIC_ERR_NMI                    0x80000000
 736  739  
 737  740  /*
 738  741   * ACPI definitions
 739  742   */
 740  743  /* _PIC method arguments */
 741  744  #define ACPI_PIC_MODE   0
 742  745  #define ACPI_APIC_MODE  1
 743  746  
 744  747  /* APIC error flags we care about */
 745  748  #define APIC_SEND_CS_ERROR      0x01
 746  749  #define APIC_RECV_CS_ERROR      0x02
 747  750  #define APIC_CS_ERRORS          (APIC_SEND_CS_ERROR|APIC_RECV_CS_ERROR)
 748  751  
 749  752  /* Maximum number of times to retry reprogramming at apic_intr_exit time */
 750  753  #define APIC_REPROGRAM_MAX_TRIES 10000
 751  754  
 752  755  /* Parameter to ioapic_init_intr(): Should ioapic ints be masked? */
 753  756  #define IOAPIC_MASK 1
 754  757  #define IOAPIC_NOMASK 0
 755  758  
 756  759  #define INTR_ROUND_ROBIN_WITH_AFFINITY  0
 757  760  #define INTR_ROUND_ROBIN                1
 758  761  #define INTR_LOWEST_PRIORITY            2
 759  762  
 760  763  struct ioapic_reprogram_data {
 761  764          boolean_t                       done;
 762  765          apic_irq_t                      *irqp;
 763  766          /* The CPU to which the int will be bound */
 764  767          int                             bindcpu;
 765  768          /* # times the reprogram timeout was called */
 766  769          unsigned                        tries;
 767  770  };
 768  771  
 769  772  /* The irq # is implicit in the array index: */
 770  773  extern struct ioapic_reprogram_data apic_reprogram_info[];
 771  774  
 772  775  extern void apic_intr_exit(int ipl, int irq);
 773  776  extern void x2apic_intr_exit(int ipl, int irq);
 774  777  extern int apic_probe_common();
 775  778  extern void apic_init_common();
 776  779  extern void ioapic_init_intr();
 777  780  extern void ioapic_disable_redirection();
 778  781  extern int apic_addspl_common(int irqno, int ipl, int min_ipl, int max_ipl);
 779  782  extern int apic_delspl_common(int irqno, int ipl, int min_ipl, int max_ipl);
 780  783  extern void apic_cleanup_busy();
 781  784  extern void apic_intr_redistribute();
 782  785  extern uchar_t apic_xlate_vector(uchar_t vector);
 783  786  extern uchar_t apic_allocate_vector(int ipl, int irq, int pri);
 784  787  extern void apic_free_vector(uchar_t vector);
 785  788  extern int apic_allocate_irq(int irq);
 786  789  extern uint32_t apic_bind_intr(dev_info_t *dip, int irq, uchar_t ioapicid,
 787  790      uchar_t intin);
 788  791  extern int apic_rebind(apic_irq_t *irq_ptr, int bind_cpu,
 789  792      struct ioapic_reprogram_data *drep);
 790  793  extern int apic_rebind_all(apic_irq_t *irq_ptr, int bind_cpu);
 791  794  extern int apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type);
 792  795  extern int apic_intr_ops(dev_info_t *dip, ddi_intr_handle_impl_t *hdlp,
 793  796      psm_intr_op_t intr_op, int *result);
 794  797  extern int apic_state(psm_state_request_t *);
 795  798  extern boolean_t apic_cpu_in_range(int cpu);
 796  799  extern int apic_check_msi_support();
 797  800  extern apic_irq_t *apic_find_irq(dev_info_t *dip, struct intrspec *ispec,
 798  801      int type);
 799  802  extern int apic_navail_vector(dev_info_t *dip, int pri);
 800  803  extern int apic_alloc_msi_vectors(dev_info_t *dip, int inum, int count,
 801  804      int pri, int behavior);
 802  805  extern int apic_alloc_msix_vectors(dev_info_t *dip, int inum, int count,
 803  806      int pri, int behavior);
 804  807  extern void  apic_free_vectors(dev_info_t *dip, int inum, int count, int pri,
 805  808      int type);
 806  809  extern int apic_get_vector_intr_info(int vecirq,
 807  810      apic_get_intr_t *intr_params_p);
 808  811  extern uchar_t apic_find_multi_vectors(int pri, int count);
 809  812  extern int apic_setup_io_intr(void *p, int irq, boolean_t deferred);
 810  813  extern uint32_t *mapin_apic(uint32_t addr, size_t len, int flags);
 811  814  extern uint32_t *mapin_ioapic(uint32_t addr, size_t len, int flags);
 812  815  extern void mapout_apic(caddr_t addr, size_t len);
 813  816  extern void mapout_ioapic(caddr_t addr, size_t len);
 814  817  extern uchar_t apic_modify_vector(uchar_t vector, int irq);
 815  818  extern void apic_pci_msi_unconfigure(dev_info_t *rdip, int type, int inum);
 816  819  extern void apic_pci_msi_disable_mode(dev_info_t *rdip, int type);
 817  820  extern void apic_pci_msi_enable_mode(dev_info_t *rdip, int type, int inum);
 818  821  extern void apic_pci_msi_enable_vector(apic_irq_t *, int type, int inum,
 819  822      int vector, int count, int target_apic_id);
 820  823  extern char *apic_get_apic_type();
 821  824  extern uint16_t apic_get_apic_version();
 822  825  extern void x2apic_send_ipi();
 823  826  extern void apic_ret();
 824  827  extern int apic_detect_x2apic();
 825  828  extern void apic_enable_x2apic();
 826  829  extern int apic_local_mode();
 827  830  extern void apic_change_eoi();
 828  831  extern void apic_send_EOI(uint32_t);
 829  832  extern void apic_send_directed_EOI(uint32_t);
 830  833  extern uint_t apic_calibrate(volatile uint32_t *, uint16_t *);
 831  834  
 832  835  extern volatile uint32_t *apicadr;      /* virtual addr of local APIC   */
 833  836  extern int apic_forceload;
 834  837  extern apic_cpus_info_t *apic_cpus;
 835  838  #ifdef _MACHDEP
 836  839  extern cpuset_t apic_cpumask;
 837  840  #endif
 838  841  extern uint_t apic_picinit_called;
 839  842  extern uchar_t apic_ipltopri[MAXIPL+1];
 840  843  extern uchar_t apic_vector_to_irq[APIC_MAX_VECTOR+1];
 841  844  extern int apic_max_device_irq;
 842  845  extern int apic_min_device_irq;
 843  846  extern apic_irq_t *apic_irq_table[APIC_MAX_VECTOR+1];
 844  847  extern volatile uint32_t *apicioadr[MAX_IO_APIC];
 845  848  extern uchar_t apic_io_id[MAX_IO_APIC];
 846  849  extern lock_t apic_ioapic_lock;
 847  850  extern uint32_t apic_physaddr[MAX_IO_APIC];
 848  851  extern kmutex_t airq_mutex;
 849  852  extern int apic_first_avail_irq;
 850  853  extern uchar_t apic_vectortoipl[APIC_AVAIL_VECTOR / APIC_VECTOR_PER_IPL];
 851  854  extern int apic_imcrp;
 852  855  extern int apic_revector_pending;
 853  856  extern char apic_level_intr[APIC_MAX_VECTOR+1];
 854  857  extern uchar_t apic_resv_vector[MAXIPL+1];
 855  858  extern int apic_sample_factor_redistribution;
 856  859  extern int apic_int_busy_mark;
 857  860  extern int apic_int_free_mark;
 858  861  extern int apic_diff_for_redistribution;
 859  862  extern int apic_poweroff_method;
  
    | 
      ↓ open down ↓ | 
    730 lines elided | 
    
      ↑ open up ↑ | 
  
 860  863  extern int apic_enable_acpi;
 861  864  extern int apic_nproc;
 862  865  extern int apic_max_nproc;
 863  866  extern int apic_next_bind_cpu;
 864  867  extern int apic_redistribute_sample_interval;
 865  868  extern int apic_multi_msi_enable;
 866  869  extern int apic_sci_vect;
 867  870  extern int apic_hpet_vect;
 868  871  extern uchar_t apic_ipls[];
 869  872  extern apic_reg_ops_t *apic_reg_ops;
      873 +extern apic_reg_ops_t local_apic_regs_ops;
 870  874  extern apic_mode_t apic_mode;
 871  875  extern void x2apic_update_psm();
 872  876  extern void apic_change_ops();
 873  877  extern void apic_common_send_ipi(int, int);
 874  878  extern void apic_set_directed_EOI_handler();
 875  879  extern int apic_directed_EOI_supported();
 876  880  
 877  881  extern apic_intrmap_ops_t *apic_vt_ops;
 878  882  
 879  883  #ifdef  __cplusplus
 880  884  }
 881  885  #endif
 882  886  
 883  887  #endif  /* _SYS_APIC_APIC_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX