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