Changeset 8418c7d in mainline


Ignore:
Timestamp:
2005-11-23T17:19:32Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f701b236
Parents:
a83a802
Message:

APIC code cleanup.

Location:
arch/ia32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/smp/apic.h

    ra83a802 r8418c7d  
    4040#define IPI_STARTUP     0
    4141
    42 #define DLVRMODE_FIXED  (0<<8)
    43 #define DLVRMODE_INIT   (5<<8)
    44 #define DLVRMODE_STUP   (6<<8)
    45 #define DESTMODE_PHYS   (0<<11)
    46 #define DESTMODE_LOGIC  (1<<11)
    47 #define LEVEL_ASSERT    (1<<14)
    48 #define LEVEL_DEASSERT  (0<<14)
    49 #define TRGRMODE_LEVEL  (1<<15)
    50 #define TRGRMODE_EDGE   (0<<15)
    51 #define SHORTHAND_DEST  (0<<18)
    52 #define SHORTHAND_INCL  (2<<18)
    53 #define SHORTHAND_EXCL  (3<<18)
    54 
    55 #define SEND_PENDING    (1<<12)
    56 
    57 /* Interrupt Command Register */
    58 #define ICRlo           (0x300/sizeof(__u32))
    59 #define ICRhi           (0x310/sizeof(__u32))
    60 #define ICRloClear      ((1<<13)|(3<<16)|(0xfff<<20))
    61 #define ICRhiClear      (0xffffff<<0)
    62 
    63 /* End Of Interrupt */
    64 #define EOI             (0x0b0/sizeof(__u32))
    65 
    66 /* Error Status Register */
    67 #define ESR             (0x280/sizeof(__u32))
    68 #define ESRClear        ((0xffffff<<8)|(1<<4))
    69 
    70 /* Task Priority Register */
    71 #define TPR             (0x080/sizeof(__u32))
    72 #define TPRClear        0xffffff00
    73 
    74 /* Spurious Vector Register */
    75 #define SVR             (0x0f0/sizeof(__u32))
    76 #define SVRClear        (~0x3f0)
    77 
    78 /* Time Divide Configuratio Register */
    79 #define TDCR            (0x3e0/sizeof(__u32))
    80 #define TDCRClear       (~0xb)
    81 
    82 /* Initial Count Register for Timer */
    83 #define ICRT            (0x380/sizeof(__u32))
    84 
    85 /* Current Count Register for Timer */
    86 #define CCRT            (0x390/sizeof(__u32))
    87 
    88 /* LVT */
    89 #define LVT_Tm          (0x320/sizeof(__u32))
    90 #define LVT_LINT0       (0x350/sizeof(__u32))
    91 #define LVT_LINT1       (0x360/sizeof(__u32))
    92 #define LVT_Err         (0x370/sizeof(__u32))
    93 #define LVT_PCINT       (0x340/sizeof(__u32))
    94 
    95 /* Local APIC ID Register */
    96 #define L_APIC_ID       (0x020/sizeof(__u32))
    97 #define L_APIC_IDClear  (~(0xf<<24))
    98 #define L_APIC_IDShift  24
    99 #define L_APIC_IDMask   0xf
    100 
    101 /* Local APIC Version Register */
    102 #define LAVR            (0x030/sizeof(__u32))
    103 #define LAVR_Mask       0xff
    104 #define is_local_apic(x)        (((x)&LAVR_Mask&0xf0)==0x1)
    105 #define is_82489DX_apic(x)      ((((x)&LAVR_Mask&0xf0)==0x0))
    106 #define is_local_xapic(x)       (((x)&LAVR_Mask)==0x14)
    107 
    108 /* IO APIC */
    109 #define IOREGSEL        (0x00/sizeof(__u32))
    110 #define IOWIN           (0x10/sizeof(__u32))
    111 
    112 #define IOAPICID        0x00
    113 #define IOAPICVER       0x01
    114 #define IOAPICARB       0x02
    115 #define IOREDTBL        0x10
    116 
    11742/** Delivery modes. */
    11843#define DELMOD_FIXED    0x0
     
    12247#define DELMOD_NMI      0x4
    12348#define DELMOD_INIT     0x5
    124 /* 0x6 reserved */
     49#define DELMOD_STARTUP  0x6
    12550#define DELMOD_EXTINT   0x7
    12651
     
    13358#define TRIGMOD_LEVEL   0x1
    13459
     60/** Levels. */
     61#define LEVEL_DEASSERT  0x0
     62#define LEVEL_ASSERT    0x1
     63
     64/** Destination Shorthands. */
     65#define SHORTHAND_NONE          0x0
     66#define SHORTHAND_SELF          0x1
     67#define SHORTHAND_ALL_INCL      0x2
     68#define SHORTHAND_ALL_EXCL      0x3
     69
    13570/** Interrupt Input Pin Polarities. */
    13671#define POLARITY_HIGH   0x0
    13772#define POLARITY_LOW    0x1
    13873
     74#define SEND_PENDING    (1<<12)
     75
     76/** Interrupt Command Register. */
     77#define ICRlo           (0x300/sizeof(__u32))
     78#define ICRhi           (0x310/sizeof(__u32))
     79struct icr {
     80        union {
     81                __u32 lo;
     82                struct {
     83                        __u8 vector;                    /**< Interrupt Vector. */
     84                        unsigned delmod : 3;            /**< Delivery Mode. */
     85                        unsigned destmod : 1;           /**< Destination Mode. */
     86                        unsigned delivs : 1;            /**< Delivery status (RO). */
     87                        unsigned : 1;                   /**< Reserved. */
     88                        unsigned level : 1;             /**< Level. */
     89                        unsigned trigger_mode : 1;      /**< Trigger Mode. */
     90                        unsigned : 2;                   /**< Reserved. */
     91                        unsigned shorthand : 2;         /**< Destination Shorthand. */
     92                        unsigned : 12;                  /**< Reserved. */
     93                } __attribute__ ((packed));
     94        };
     95        union {
     96                __u32 hi;
     97                struct {
     98                        unsigned : 24;                  /**< Reserved. */
     99                        __u8 dest;                      /**< Destination field. */
     100                } __attribute__ ((packed));
     101        };
     102} __attribute__ ((packed));
     103typedef struct icr icr_t;
     104
     105/* End Of Interrupt */
     106#define EOI             (0x0b0/sizeof(__u32))
     107
     108/* Error Status Register */
     109#define ESR             (0x280/sizeof(__u32))
     110#define ESRClear        ((0xffffff<<8)|(1<<4))
     111
     112/* Task Priority Register */
     113#define TPR             (0x080/sizeof(__u32))
     114#define TPRClear        0xffffff00
     115
     116/** Spurious-Interrupt Vector Register. */
     117#define SVR             (0x0f0/sizeof(__u32))
     118union svr {
     119        __u32 value;
     120        struct {
     121                __u8 vector;                    /**< Spurious Vector */
     122                unsigned lapic_enabled : 1;     /**< APIC Software Enable/Disable */
     123                unsigned focus_checking : 1;    /**< Focus Processor Checking */
     124                unsigned : 22;                  /**< Reserved. */
     125        } __attribute__ ((packed));
     126};
     127typedef union svr svr_t;
     128
     129/* Time Divide Configuration Register */
     130#define TDCR            (0x3e0/sizeof(__u32))
     131#define TDCRClear       (~0xb)
     132
     133/* Initial Count Register for Timer */
     134#define ICRT            (0x380/sizeof(__u32))
     135
     136/* Current Count Register for Timer */
     137#define CCRT            (0x390/sizeof(__u32))
     138
     139/** Timer Modes. */
     140#define TIMER_ONESHOT   0x0
     141#define TIMER_PERIODIC  0x1
     142
     143/** LVT Timer register. */
     144#define LVT_Tm          (0x320/sizeof(__u32))
     145union lvt_tm {
     146        __u32 value;
     147        struct {
     148                __u8 vector;            /**< Local Timer Interrupt vector. */
     149                unsigned : 4;           /**< Reserved. */
     150                unsigned delivs : 1;    /**< Delivery status (RO). */
     151                unsigned : 3;           /**< Reserved. */
     152                unsigned masked : 1;    /**< Interrupt Mask. */
     153                unsigned mode : 1;      /**< Timer Mode. */
     154                unsigned : 14;          /**< Reserved. */
     155        } __attribute__ ((packed));
     156};
     157typedef union lvt_tm lvt_tm_t;
     158
     159/** LVT LINT registers. */
     160#define LVT_LINT0       (0x350/sizeof(__u32))
     161#define LVT_LINT1       (0x360/sizeof(__u32))
     162union lvt_lint {
     163        __u32 value;
     164        struct {
     165                __u8 vector;                    /**< LINT Interrupt vector. */
     166                unsigned delmod : 3;            /**< Delivery Mode. */
     167                unsigned : 1;                   /**< Reserved. */
     168                unsigned delivs : 1;            /**< Delivery status (RO). */
     169                unsigned intpol : 1;            /**< Interrupt Input Pin Polarity. */
     170                unsigned irr : 1;               /**< Remote IRR (RO). */
     171                unsigned trigger_mode : 1;      /**< Trigger Mode. */
     172                unsigned masked : 1;            /**< Interrupt Mask. */
     173                unsigned : 15;                  /**< Reserved. */
     174        } __attribute__ ((packed));
     175};
     176typedef union lvt_lint lvt_lint_t;
     177
     178/** LVT Error register. */
     179#define LVT_Err         (0x370/sizeof(__u32))
     180union lvt_error {
     181        __u32 value;
     182        struct {
     183                __u8 vector;            /**< Local Timer Interrupt vector. */
     184                unsigned : 4;           /**< Reserved. */
     185                unsigned delivs : 1;    /**< Delivery status (RO). */
     186                unsigned : 3;           /**< Reserved. */
     187                unsigned masked : 1;    /**< Interrupt Mask. */
     188                unsigned : 15;          /**< Reserved. */
     189        } __attribute__ ((packed));
     190};
     191typedef union lvt_error lvt_error_t;
     192
     193
     194#define LVT_PCINT       (0x340/sizeof(__u32))
     195
     196/* Local APIC ID Register */
     197#define L_APIC_ID       (0x020/sizeof(__u32))
     198#define L_APIC_IDClear  (~(0xf<<24))
     199#define L_APIC_IDShift  24
     200#define L_APIC_IDMask   0xf
     201
     202/* Local APIC Version Register */
     203#define LAVR            (0x030/sizeof(__u32))
     204#define LAVR_Mask       0xff
     205#define is_local_apic(x)        (((x)&LAVR_Mask&0xf0)==0x1)
     206#define is_82489DX_apic(x)      ((((x)&LAVR_Mask&0xf0)==0x0))
     207#define is_local_xapic(x)       (((x)&LAVR_Mask)==0x14)
     208
     209/* IO APIC */
     210#define IOREGSEL        (0x00/sizeof(__u32))
     211#define IOWIN           (0x10/sizeof(__u32))
     212
     213#define IOAPICID        0x00
     214#define IOAPICVER       0x01
     215#define IOAPICARB       0x02
     216#define IOREDTBL        0x10
     217
    139218/** I/O Redirection Register. */
    140219struct io_redirection_reg {
     
    142221                __u32 lo;
    143222                struct {
    144                         unsigned intvec : 8;            /**< Interrupt Vector. */
     223                        __u8 intvec;                    /**< Interrupt Vector. */
    145224                        unsigned delmod : 3;            /**< Delivery Mode. */
    146225                        unsigned destmod : 1;           /**< Destination mode. */
     
    151230                        unsigned masked : 1;            /**< Interrupt Mask. */
    152231                        unsigned : 15;                  /**< Reserved. */
    153                 };
     232                } __attribute__ ((packed));
    154233        };
    155234        union {
     
    157236                struct {
    158237                        unsigned : 24;                  /**< Reserved. */
    159                         unsigned dest : 8;              /**< Destination Field. */
    160                 };
     238                        __u8 dest : 8;          /**< Destination Field. */
     239                } __attribute__ ((packed));
    161240        };
    162241       
  • arch/ia32/src/smp/apic.c

    ra83a802 r8418c7d  
    4444 * Tested on:
    4545 *      Bochs 2.0.2 - Bochs 2.2 with 2-8 CPUs
    46  *      Simics 2.0.28 - Simics 2.2.14 2-4 CPUs
     46 *      Simics 2.0.28 - Simics 2.2.19 2-8 CPUs
    4747 *      ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
    4848 *      ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
     
    6565int apic_poll_errors(void);
    6666
     67/** Initialize APIC on BSP. */
    6768void apic_init(void)
    6869{
     
    8687       
    8788                if ((pin = smp_irq_to_pin(i)) != -1) {
    88                         io_apic_change_ioredtbl(pin,0xff,IVT_IRQBASE+i,LOPRI);
     89                        io_apic_change_ioredtbl(pin, 0xff, IVT_IRQBASE+i, LOPRI);
    8990                }
    9091        }
     
    148149int l_apic_broadcast_custom_ipi(__u8 vector)
    149150{
    150         __u32 lo;
    151 
    152         /*
    153          * Read the ICR register in and zero all non-reserved fields.
    154          */
    155         lo = l_apic[ICRlo] & ICRloClear;
    156 
    157         lo |= DLVRMODE_FIXED | DESTMODE_LOGIC | LEVEL_ASSERT | SHORTHAND_EXCL | TRGRMODE_LEVEL | vector;
    158        
    159         l_apic[ICRlo] = lo;
    160 
    161         lo = l_apic[ICRlo] & ICRloClear;
    162         if (lo & SEND_PENDING)
     151        icr_t icr;
     152
     153        icr.lo = l_apic[ICRlo];
     154        icr.delmod = DELMOD_FIXED;
     155        icr.destmod = DESTMOD_LOGIC;
     156        icr.level = LEVEL_ASSERT;
     157        icr.shorthand = SHORTHAND_ALL_EXCL;
     158        icr.trigger_mode = TRIGMOD_LEVEL;
     159        icr.vector = vector;
     160
     161        l_apic[ICRlo] = icr.lo;
     162
     163        icr.lo = l_apic[ICRlo];
     164        if (icr.lo & SEND_PENDING)
    163165                printf("IPI is pending.\n");
    164166
     
    171173int l_apic_send_init_ipi(__u8 apicid)
    172174{
    173         __u32 lo, hi;
     175        icr_t icr;
    174176        int i;
    175177
     
    177179         * Read the ICR register in and zero all non-reserved fields.
    178180         */
    179         lo = l_apic[ICRlo] & ICRloClear;
    180         hi = l_apic[ICRhi] & ICRhiClear;
    181        
    182         lo |= DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
    183         hi |= apicid << 24;
    184        
    185         l_apic[ICRhi] = hi;
    186         l_apic[ICRlo] = lo;
     181        icr.lo = l_apic[ICRlo];
     182        icr.hi = l_apic[ICRhi];
     183       
     184        icr.delmod = DELMOD_INIT;
     185        icr.destmod = DESTMOD_PHYS;
     186        icr.level = LEVEL_ASSERT;
     187        icr.trigger_mode = TRIGMOD_LEVEL;
     188        icr.shorthand = SHORTHAND_NONE;
     189        icr.vector = 0;
     190        icr.dest = apicid;
     191       
     192        l_apic[ICRhi] = icr.hi;
     193        l_apic[ICRlo] = icr.lo;
    187194
    188195        /*
     
    194201        if (!apic_poll_errors()) return 0;
    195202
    196         lo = l_apic[ICRlo] & ICRloClear;
    197         if (lo & SEND_PENDING)
     203        icr.lo = l_apic[ICRlo];
     204        if (icr.lo & SEND_PENDING)
    198205                printf("IPI is pending.\n");
    199206
    200         l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
     207        icr.delmod = DELMOD_INIT;
     208        icr.destmod = DESTMOD_PHYS;
     209        icr.level = LEVEL_DEASSERT;
     210        icr.shorthand = SHORTHAND_NONE;
     211        icr.trigger_mode = TRIGMOD_LEVEL;
     212        icr.vector = 0;
     213        l_apic[ICRlo] = icr.lo;
    201214
    202215        /*
     
    210223                 */
    211224                for (i = 0; i<2; i++) {
    212                         lo = l_apic[ICRlo] & ICRloClear;
    213                         lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */
    214                         l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
     225                        icr.lo = l_apic[ICRlo];
     226                        icr.vector = ((__address) ap_boot) / 4096; /* calculate the reset vector */
     227                        icr.delmod = DELMOD_STARTUP;
     228                        icr.destmod = DESTMOD_PHYS;
     229                        icr.level = LEVEL_ASSERT;
     230                        icr.shorthand = SHORTHAND_NONE;
     231                        icr.trigger_mode = TRIGMOD_LEVEL;
     232                        l_apic[ICRlo] = icr.lo;
    215233                        delay(200);
    216234                }
     
    223241void l_apic_init(void)
    224242{
    225         __u32 tmp, t1, t2;
    226 
    227         l_apic[LVT_Err] |= (1<<16);
    228         l_apic[LVT_LINT0] |= (1<<16);
    229         l_apic[LVT_LINT1] |= (1<<16);
    230 
    231         tmp = l_apic[SVR] & SVRClear;
    232         l_apic[SVR] = tmp | (1<<8) | (VECTOR_APIC_SPUR);
     243        lvt_error_t error;
     244        lvt_lint_t lint;
     245        svr_t svr;
     246        lvt_tm_t tm;
     247        icr_t icr;
     248        __u32 t1, t2;
     249
     250        /* Initialize LVT Error register. */
     251        error.value = l_apic[LVT_Err];
     252        error.masked = true;
     253        l_apic[LVT_Err] = error.value;
     254
     255        /* Initialize LVT LINT0 register. */
     256        lint.value = l_apic[LVT_LINT0];
     257        lint.masked = true;
     258        l_apic[LVT_LINT0] = lint.value;
     259
     260        /* Initialize LVT LINT1 register. */
     261        lint.value = l_apic[LVT_LINT1];
     262        lint.masked = true;
     263        l_apic[LVT_LINT1] = lint.value;
     264       
     265        /* Spurious-Interrupt Vector Register initialization. */
     266        svr.value = l_apic[SVR];
     267        svr.vector = VECTOR_APIC_SPUR;
     268        svr.lapic_enabled = true;
     269        l_apic[SVR] = svr.value;
    233270
    234271        l_apic[TPR] &= TPRClear;
     
    237274                enable_l_apic_in_msr();
    238275       
    239         tmp = l_apic[ICRlo] & ICRloClear;
    240         l_apic[ICRlo] = tmp | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_INCL | TRGRMODE_LEVEL;
     276        /* Interrupt Command Register initialization. */
     277        icr.lo = l_apic[ICRlo];
     278        icr.delmod = DELMOD_INIT;
     279        icr.destmod = DESTMOD_PHYS;
     280        icr.level = LEVEL_DEASSERT;
     281        icr.shorthand = SHORTHAND_ALL_INCL;
     282        icr.trigger_mode = TRIGMOD_LEVEL;
     283        l_apic[ICRlo] = icr.lo;
    241284       
    242285        /*
     
    246289        l_apic[TDCR] &= TDCRClear;
    247290        l_apic[TDCR] |= 0xb;
    248         tmp = l_apic[LVT_Tm] | (1<<17) | (VECTOR_CLK);
    249         l_apic[LVT_Tm] = tmp & ~(1<<16);
     291
     292        tm.value = l_apic[LVT_Tm];
     293        tm.vector = VECTOR_CLK;
     294        tm.mode = TIMER_PERIODIC;
     295        tm.masked = false;
     296        l_apic[LVT_Tm] = tm.value;
    250297
    251298        t1 = l_apic[CCRT];
Note: See TracChangeset for help on using the changeset viewer.