symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/apic.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  *  APIC support
       
     3  *
       
     4  *  Copyright (c) 2004-2005 Fabrice Bellard
       
     5  *
       
     6  * This library is free software; you can redistribute it and/or
       
     7  * modify it under the terms of the GNU Lesser General Public
       
     8  * License as published by the Free Software Foundation; either
       
     9  * version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This library is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  * Lesser General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU Lesser General Public
       
    17  * License along with this library; if not, write to the Free Software
       
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    19  */
       
    20 #include "hw.h"
       
    21 #include "pc.h"
       
    22 #include "qemu-timer.h"
       
    23 #include "host-utils.h"
       
    24 
       
    25 //#define DEBUG_APIC
       
    26 //#define DEBUG_IOAPIC
       
    27 
       
    28 /* APIC Local Vector Table */
       
    29 #define APIC_LVT_TIMER   0
       
    30 #define APIC_LVT_THERMAL 1
       
    31 #define APIC_LVT_PERFORM 2
       
    32 #define APIC_LVT_LINT0   3
       
    33 #define APIC_LVT_LINT1   4
       
    34 #define APIC_LVT_ERROR   5
       
    35 #define APIC_LVT_NB      6
       
    36 
       
    37 /* APIC delivery modes */
       
    38 #define APIC_DM_FIXED	0
       
    39 #define APIC_DM_LOWPRI	1
       
    40 #define APIC_DM_SMI	2
       
    41 #define APIC_DM_NMI	4
       
    42 #define APIC_DM_INIT	5
       
    43 #define APIC_DM_SIPI	6
       
    44 #define APIC_DM_EXTINT	7
       
    45 
       
    46 /* APIC destination mode */
       
    47 #define APIC_DESTMODE_FLAT	0xf
       
    48 #define APIC_DESTMODE_CLUSTER	1
       
    49 
       
    50 #define APIC_TRIGGER_EDGE  0
       
    51 #define APIC_TRIGGER_LEVEL 1
       
    52 
       
    53 #define	APIC_LVT_TIMER_PERIODIC		(1<<17)
       
    54 #define	APIC_LVT_MASKED			(1<<16)
       
    55 #define	APIC_LVT_LEVEL_TRIGGER		(1<<15)
       
    56 #define	APIC_LVT_REMOTE_IRR		(1<<14)
       
    57 #define	APIC_INPUT_POLARITY		(1<<13)
       
    58 #define	APIC_SEND_PENDING		(1<<12)
       
    59 
       
    60 #define IOAPIC_NUM_PINS			0x18
       
    61 
       
    62 #define ESR_ILLEGAL_ADDRESS (1 << 7)
       
    63 
       
    64 #define APIC_SV_ENABLE (1 << 8)
       
    65 
       
    66 #define MAX_APICS 255
       
    67 #define MAX_APIC_WORDS 8
       
    68 
       
    69 typedef struct APICState {
       
    70     CPUState *cpu_env;
       
    71     uint32_t apicbase;
       
    72     uint8_t id;
       
    73     uint8_t arb_id;
       
    74     uint8_t tpr;
       
    75     uint32_t spurious_vec;
       
    76     uint8_t log_dest;
       
    77     uint8_t dest_mode;
       
    78     uint32_t isr[8];  /* in service register */
       
    79     uint32_t tmr[8];  /* trigger mode register */
       
    80     uint32_t irr[8]; /* interrupt request register */
       
    81     uint32_t lvt[APIC_LVT_NB];
       
    82     uint32_t esr; /* error register */
       
    83     uint32_t icr[2];
       
    84 
       
    85     uint32_t divide_conf;
       
    86     int count_shift;
       
    87     uint32_t initial_count;
       
    88     int64_t initial_count_load_time, next_time;
       
    89     QEMUTimer *timer;
       
    90 } APICState;
       
    91 
       
    92 struct IOAPICState {
       
    93     uint8_t id;
       
    94     uint8_t ioregsel;
       
    95 
       
    96     uint32_t irr;
       
    97     uint64_t ioredtbl[IOAPIC_NUM_PINS];
       
    98 };
       
    99 
       
   100 static int apic_io_memory;
       
   101 static APICState *local_apics[MAX_APICS + 1];
       
   102 static int last_apic_id = 0;
       
   103 
       
   104 static void apic_init_ipi(APICState *s);
       
   105 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
       
   106 static void apic_update_irq(APICState *s);
       
   107 
       
   108 /* Find first bit starting from msb */
       
   109 static int fls_bit(uint32_t value)
       
   110 {
       
   111     return 31 - clz32(value);
       
   112 }
       
   113 
       
   114 /* Find first bit starting from lsb */
       
   115 static int ffs_bit(uint32_t value)
       
   116 {
       
   117     return ctz32(value);
       
   118 }
       
   119 
       
   120 static inline void set_bit(uint32_t *tab, int index)
       
   121 {
       
   122     int i, mask;
       
   123     i = index >> 5;
       
   124     mask = 1 << (index & 0x1f);
       
   125     tab[i] |= mask;
       
   126 }
       
   127 
       
   128 static inline void reset_bit(uint32_t *tab, int index)
       
   129 {
       
   130     int i, mask;
       
   131     i = index >> 5;
       
   132     mask = 1 << (index & 0x1f);
       
   133     tab[i] &= ~mask;
       
   134 }
       
   135 
       
   136 static void apic_local_deliver(CPUState *env, int vector)
       
   137 {
       
   138     APICState *s = env->apic_state;
       
   139     uint32_t lvt = s->lvt[vector];
       
   140     int trigger_mode;
       
   141 
       
   142     if (lvt & APIC_LVT_MASKED)
       
   143         return;
       
   144 
       
   145     switch ((lvt >> 8) & 7) {
       
   146     case APIC_DM_SMI:
       
   147         cpu_interrupt(env, CPU_INTERRUPT_SMI);
       
   148         break;
       
   149 
       
   150     case APIC_DM_NMI:
       
   151         cpu_interrupt(env, CPU_INTERRUPT_NMI);
       
   152         break;
       
   153 
       
   154     case APIC_DM_EXTINT:
       
   155         cpu_interrupt(env, CPU_INTERRUPT_HARD);
       
   156         break;
       
   157 
       
   158     case APIC_DM_FIXED:
       
   159         trigger_mode = APIC_TRIGGER_EDGE;
       
   160         if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
       
   161             (lvt & APIC_LVT_LEVEL_TRIGGER))
       
   162             trigger_mode = APIC_TRIGGER_LEVEL;
       
   163         apic_set_irq(s, lvt & 0xff, trigger_mode);
       
   164     }
       
   165 }
       
   166 
       
   167 void apic_deliver_pic_intr(CPUState *env, int level)
       
   168 {
       
   169     if (level)
       
   170         apic_local_deliver(env, APIC_LVT_LINT0);
       
   171     else {
       
   172         APICState *s = env->apic_state;
       
   173         uint32_t lvt = s->lvt[APIC_LVT_LINT0];
       
   174 
       
   175         switch ((lvt >> 8) & 7) {
       
   176         case APIC_DM_FIXED:
       
   177             if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
       
   178                 break;
       
   179             reset_bit(s->irr, lvt & 0xff);
       
   180             /* fall through */
       
   181         case APIC_DM_EXTINT:
       
   182             cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
       
   183             break;
       
   184         }
       
   185     }
       
   186 }
       
   187 
       
   188 #define foreach_apic(apic, deliver_bitmask, code) \
       
   189 {\
       
   190     int __i, __j, __mask;\
       
   191     for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
       
   192         __mask = deliver_bitmask[__i];\
       
   193         if (__mask) {\
       
   194             for(__j = 0; __j < 32; __j++) {\
       
   195                 if (__mask & (1 << __j)) {\
       
   196                     apic = local_apics[__i * 32 + __j];\
       
   197                     if (apic) {\
       
   198                         code;\
       
   199                     }\
       
   200                 }\
       
   201             }\
       
   202         }\
       
   203     }\
       
   204 }
       
   205 
       
   206 static void apic_bus_deliver(const uint32_t *deliver_bitmask,
       
   207                              uint8_t delivery_mode,
       
   208                              uint8_t vector_num, uint8_t polarity,
       
   209                              uint8_t trigger_mode)
       
   210 {
       
   211     APICState *apic_iter;
       
   212 
       
   213     switch (delivery_mode) {
       
   214         case APIC_DM_LOWPRI:
       
   215             /* XXX: search for focus processor, arbitration */
       
   216             {
       
   217                 int i, d;
       
   218                 d = -1;
       
   219                 for(i = 0; i < MAX_APIC_WORDS; i++) {
       
   220                     if (deliver_bitmask[i]) {
       
   221                         d = i * 32 + ffs_bit(deliver_bitmask[i]);
       
   222                         break;
       
   223                     }
       
   224                 }
       
   225                 if (d >= 0) {
       
   226                     apic_iter = local_apics[d];
       
   227                     if (apic_iter) {
       
   228                         apic_set_irq(apic_iter, vector_num, trigger_mode);
       
   229                     }
       
   230                 }
       
   231             }
       
   232             return;
       
   233 
       
   234         case APIC_DM_FIXED:
       
   235             break;
       
   236 
       
   237         case APIC_DM_SMI:
       
   238             foreach_apic(apic_iter, deliver_bitmask,
       
   239                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
       
   240             return;
       
   241 
       
   242         case APIC_DM_NMI:
       
   243             foreach_apic(apic_iter, deliver_bitmask,
       
   244                 cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
       
   245             return;
       
   246 
       
   247         case APIC_DM_INIT:
       
   248             /* normal INIT IPI sent to processors */
       
   249             foreach_apic(apic_iter, deliver_bitmask,
       
   250                          apic_init_ipi(apic_iter) );
       
   251             return;
       
   252 
       
   253         case APIC_DM_EXTINT:
       
   254             /* handled in I/O APIC code */
       
   255             break;
       
   256 
       
   257         default:
       
   258             return;
       
   259     }
       
   260 
       
   261     foreach_apic(apic_iter, deliver_bitmask,
       
   262                  apic_set_irq(apic_iter, vector_num, trigger_mode) );
       
   263 }
       
   264 
       
   265 void cpu_set_apic_base(CPUState *env, uint64_t val)
       
   266 {
       
   267     APICState *s = env->apic_state;
       
   268 #ifdef DEBUG_APIC
       
   269     printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
       
   270 #endif
       
   271     s->apicbase = (val & 0xfffff000) |
       
   272         (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
       
   273     /* if disabled, cannot be enabled again */
       
   274     if (!(val & MSR_IA32_APICBASE_ENABLE)) {
       
   275         s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
       
   276         env->cpuid_features &= ~CPUID_APIC;
       
   277         s->spurious_vec &= ~APIC_SV_ENABLE;
       
   278     }
       
   279 }
       
   280 
       
   281 uint64_t cpu_get_apic_base(CPUState *env)
       
   282 {
       
   283     APICState *s = env->apic_state;
       
   284 #ifdef DEBUG_APIC
       
   285     printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
       
   286 #endif
       
   287     return s->apicbase;
       
   288 }
       
   289 
       
   290 void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
       
   291 {
       
   292     APICState *s = env->apic_state;
       
   293     s->tpr = (val & 0x0f) << 4;
       
   294     apic_update_irq(s);
       
   295 }
       
   296 
       
   297 uint8_t cpu_get_apic_tpr(CPUX86State *env)
       
   298 {
       
   299     APICState *s = env->apic_state;
       
   300     return s->tpr >> 4;
       
   301 }
       
   302 
       
   303 /* return -1 if no bit is set */
       
   304 static int get_highest_priority_int(uint32_t *tab)
       
   305 {
       
   306     int i;
       
   307     for(i = 7; i >= 0; i--) {
       
   308         if (tab[i] != 0) {
       
   309             return i * 32 + fls_bit(tab[i]);
       
   310         }
       
   311     }
       
   312     return -1;
       
   313 }
       
   314 
       
   315 static int apic_get_ppr(APICState *s)
       
   316 {
       
   317     int tpr, isrv, ppr;
       
   318 
       
   319     tpr = (s->tpr >> 4);
       
   320     isrv = get_highest_priority_int(s->isr);
       
   321     if (isrv < 0)
       
   322         isrv = 0;
       
   323     isrv >>= 4;
       
   324     if (tpr >= isrv)
       
   325         ppr = s->tpr;
       
   326     else
       
   327         ppr = isrv << 4;
       
   328     return ppr;
       
   329 }
       
   330 
       
   331 static int apic_get_arb_pri(APICState *s)
       
   332 {
       
   333     /* XXX: arbitration */
       
   334     return 0;
       
   335 }
       
   336 
       
   337 /* signal the CPU if an irq is pending */
       
   338 static void apic_update_irq(APICState *s)
       
   339 {
       
   340     int irrv, ppr;
       
   341     if (!(s->spurious_vec & APIC_SV_ENABLE))
       
   342         return;
       
   343     irrv = get_highest_priority_int(s->irr);
       
   344     if (irrv < 0)
       
   345         return;
       
   346     ppr = apic_get_ppr(s);
       
   347     if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
       
   348         return;
       
   349     cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
       
   350 }
       
   351 
       
   352 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
       
   353 {
       
   354     set_bit(s->irr, vector_num);
       
   355     if (trigger_mode)
       
   356         set_bit(s->tmr, vector_num);
       
   357     else
       
   358         reset_bit(s->tmr, vector_num);
       
   359     apic_update_irq(s);
       
   360 }
       
   361 
       
   362 static void apic_eoi(APICState *s)
       
   363 {
       
   364     int isrv;
       
   365     isrv = get_highest_priority_int(s->isr);
       
   366     if (isrv < 0)
       
   367         return;
       
   368     reset_bit(s->isr, isrv);
       
   369     /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
       
   370             set the remote IRR bit for level triggered interrupts. */
       
   371     apic_update_irq(s);
       
   372 }
       
   373 
       
   374 static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
       
   375                                       uint8_t dest, uint8_t dest_mode)
       
   376 {
       
   377     APICState *apic_iter;
       
   378     int i;
       
   379 
       
   380     if (dest_mode == 0) {
       
   381         if (dest == 0xff) {
       
   382             memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
       
   383         } else {
       
   384             memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
       
   385             set_bit(deliver_bitmask, dest);
       
   386         }
       
   387     } else {
       
   388         /* XXX: cluster mode */
       
   389         memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
       
   390         for(i = 0; i < MAX_APICS; i++) {
       
   391             apic_iter = local_apics[i];
       
   392             if (apic_iter) {
       
   393                 if (apic_iter->dest_mode == 0xf) {
       
   394                     if (dest & apic_iter->log_dest)
       
   395                         set_bit(deliver_bitmask, i);
       
   396                 } else if (apic_iter->dest_mode == 0x0) {
       
   397                     if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
       
   398                         (dest & apic_iter->log_dest & 0x0f)) {
       
   399                         set_bit(deliver_bitmask, i);
       
   400                     }
       
   401                 }
       
   402             }
       
   403         }
       
   404     }
       
   405 }
       
   406 
       
   407 
       
   408 static void apic_init_ipi(APICState *s)
       
   409 {
       
   410     int i;
       
   411 
       
   412     s->tpr = 0;
       
   413     s->spurious_vec = 0xff;
       
   414     s->log_dest = 0;
       
   415     s->dest_mode = 0xf;
       
   416     memset(s->isr, 0, sizeof(s->isr));
       
   417     memset(s->tmr, 0, sizeof(s->tmr));
       
   418     memset(s->irr, 0, sizeof(s->irr));
       
   419     for(i = 0; i < APIC_LVT_NB; i++)
       
   420         s->lvt[i] = 1 << 16; /* mask LVT */
       
   421     s->esr = 0;
       
   422     memset(s->icr, 0, sizeof(s->icr));
       
   423     s->divide_conf = 0;
       
   424     s->count_shift = 0;
       
   425     s->initial_count = 0;
       
   426     s->initial_count_load_time = 0;
       
   427     s->next_time = 0;
       
   428 
       
   429     cpu_reset(s->cpu_env);
       
   430 
       
   431     if (!(s->apicbase & MSR_IA32_APICBASE_BSP))
       
   432         s->cpu_env->halted = 1;
       
   433 }
       
   434 
       
   435 /* send a SIPI message to the CPU to start it */
       
   436 static void apic_startup(APICState *s, int vector_num)
       
   437 {
       
   438     CPUState *env = s->cpu_env;
       
   439     if (!env->halted)
       
   440         return;
       
   441     env->eip = 0;
       
   442     cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
       
   443                            0xffff, 0);
       
   444     env->halted = 0;
       
   445 }
       
   446 
       
   447 static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
       
   448                          uint8_t delivery_mode, uint8_t vector_num,
       
   449                          uint8_t polarity, uint8_t trigger_mode)
       
   450 {
       
   451     uint32_t deliver_bitmask[MAX_APIC_WORDS];
       
   452     int dest_shorthand = (s->icr[0] >> 18) & 3;
       
   453     APICState *apic_iter;
       
   454 
       
   455     switch (dest_shorthand) {
       
   456     case 0:
       
   457         apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
       
   458         break;
       
   459     case 1:
       
   460         memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
       
   461         set_bit(deliver_bitmask, s->id);
       
   462         break;
       
   463     case 2:
       
   464         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
       
   465         break;
       
   466     case 3:
       
   467         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
       
   468         reset_bit(deliver_bitmask, s->id);
       
   469         break;
       
   470     }
       
   471 
       
   472     switch (delivery_mode) {
       
   473         case APIC_DM_INIT:
       
   474             {
       
   475                 int trig_mode = (s->icr[0] >> 15) & 1;
       
   476                 int level = (s->icr[0] >> 14) & 1;
       
   477                 if (level == 0 && trig_mode == 1) {
       
   478                     foreach_apic(apic_iter, deliver_bitmask,
       
   479                                  apic_iter->arb_id = apic_iter->id );
       
   480                     return;
       
   481                 }
       
   482             }
       
   483             break;
       
   484 
       
   485         case APIC_DM_SIPI:
       
   486             foreach_apic(apic_iter, deliver_bitmask,
       
   487                          apic_startup(apic_iter, vector_num) );
       
   488             return;
       
   489     }
       
   490 
       
   491     apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
       
   492                      trigger_mode);
       
   493 }
       
   494 
       
   495 int apic_get_interrupt(CPUState *env)
       
   496 {
       
   497     APICState *s = env->apic_state;
       
   498     int intno;
       
   499 
       
   500     /* if the APIC is installed or enabled, we let the 8259 handle the
       
   501        IRQs */
       
   502     if (!s)
       
   503         return -1;
       
   504     if (!(s->spurious_vec & APIC_SV_ENABLE))
       
   505         return -1;
       
   506 
       
   507     /* XXX: spurious IRQ handling */
       
   508     intno = get_highest_priority_int(s->irr);
       
   509     if (intno < 0)
       
   510         return -1;
       
   511     if (s->tpr && intno <= s->tpr)
       
   512         return s->spurious_vec & 0xff;
       
   513     reset_bit(s->irr, intno);
       
   514     set_bit(s->isr, intno);
       
   515     apic_update_irq(s);
       
   516     return intno;
       
   517 }
       
   518 
       
   519 int apic_accept_pic_intr(CPUState *env)
       
   520 {
       
   521     APICState *s = env->apic_state;
       
   522     uint32_t lvt0;
       
   523 
       
   524     if (!s)
       
   525         return -1;
       
   526 
       
   527     lvt0 = s->lvt[APIC_LVT_LINT0];
       
   528 
       
   529     if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
       
   530         (lvt0 & APIC_LVT_MASKED) == 0)
       
   531         return 1;
       
   532 
       
   533     return 0;
       
   534 }
       
   535 
       
   536 static uint32_t apic_get_current_count(APICState *s)
       
   537 {
       
   538     int64_t d;
       
   539     uint32_t val;
       
   540     d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
       
   541         s->count_shift;
       
   542     if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
       
   543         /* periodic */
       
   544         val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
       
   545     } else {
       
   546         if (d >= s->initial_count)
       
   547             val = 0;
       
   548         else
       
   549             val = s->initial_count - d;
       
   550     }
       
   551     return val;
       
   552 }
       
   553 
       
   554 static void apic_timer_update(APICState *s, int64_t current_time)
       
   555 {
       
   556     int64_t next_time, d;
       
   557 
       
   558     if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
       
   559         d = (current_time - s->initial_count_load_time) >>
       
   560             s->count_shift;
       
   561         if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
       
   562             if (!s->initial_count)
       
   563                 goto no_timer;
       
   564             d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
       
   565         } else {
       
   566             if (d >= s->initial_count)
       
   567                 goto no_timer;
       
   568             d = (uint64_t)s->initial_count + 1;
       
   569         }
       
   570         next_time = s->initial_count_load_time + (d << s->count_shift);
       
   571         qemu_mod_timer(s->timer, next_time);
       
   572         s->next_time = next_time;
       
   573     } else {
       
   574     no_timer:
       
   575         qemu_del_timer(s->timer);
       
   576     }
       
   577 }
       
   578 
       
   579 static void apic_timer(void *opaque)
       
   580 {
       
   581     APICState *s = opaque;
       
   582 
       
   583     apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
       
   584     apic_timer_update(s, s->next_time);
       
   585 }
       
   586 
       
   587 static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
       
   588 {
       
   589     return 0;
       
   590 }
       
   591 
       
   592 static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
       
   593 {
       
   594     return 0;
       
   595 }
       
   596 
       
   597 static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   598 {
       
   599 }
       
   600 
       
   601 static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   602 {
       
   603 }
       
   604 
       
   605 static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
       
   606 {
       
   607     CPUState *env;
       
   608     APICState *s;
       
   609     uint32_t val;
       
   610     int index;
       
   611 
       
   612     env = cpu_single_env;
       
   613     if (!env)
       
   614         return 0;
       
   615     s = env->apic_state;
       
   616 
       
   617     index = (addr >> 4) & 0xff;
       
   618     switch(index) {
       
   619     case 0x02: /* id */
       
   620         val = s->id << 24;
       
   621         break;
       
   622     case 0x03: /* version */
       
   623         val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
       
   624         break;
       
   625     case 0x08:
       
   626         val = s->tpr;
       
   627         break;
       
   628     case 0x09:
       
   629         val = apic_get_arb_pri(s);
       
   630         break;
       
   631     case 0x0a:
       
   632         /* ppr */
       
   633         val = apic_get_ppr(s);
       
   634         break;
       
   635     case 0x0b:
       
   636         val = 0;
       
   637         break;
       
   638     case 0x0d:
       
   639         val = s->log_dest << 24;
       
   640         break;
       
   641     case 0x0e:
       
   642         val = s->dest_mode << 28;
       
   643         break;
       
   644     case 0x0f:
       
   645         val = s->spurious_vec;
       
   646         break;
       
   647     case 0x10 ... 0x17:
       
   648         val = s->isr[index & 7];
       
   649         break;
       
   650     case 0x18 ... 0x1f:
       
   651         val = s->tmr[index & 7];
       
   652         break;
       
   653     case 0x20 ... 0x27:
       
   654         val = s->irr[index & 7];
       
   655         break;
       
   656     case 0x28:
       
   657         val = s->esr;
       
   658         break;
       
   659     case 0x30:
       
   660     case 0x31:
       
   661         val = s->icr[index & 1];
       
   662         break;
       
   663     case 0x32 ... 0x37:
       
   664         val = s->lvt[index - 0x32];
       
   665         break;
       
   666     case 0x38:
       
   667         val = s->initial_count;
       
   668         break;
       
   669     case 0x39:
       
   670         val = apic_get_current_count(s);
       
   671         break;
       
   672     case 0x3e:
       
   673         val = s->divide_conf;
       
   674         break;
       
   675     default:
       
   676         s->esr |= ESR_ILLEGAL_ADDRESS;
       
   677         val = 0;
       
   678         break;
       
   679     }
       
   680 #ifdef DEBUG_APIC
       
   681     printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
       
   682 #endif
       
   683     return val;
       
   684 }
       
   685 
       
   686 static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
   687 {
       
   688     CPUState *env;
       
   689     APICState *s;
       
   690     int index;
       
   691 
       
   692     env = cpu_single_env;
       
   693     if (!env)
       
   694         return;
       
   695     s = env->apic_state;
       
   696 
       
   697 #ifdef DEBUG_APIC
       
   698     printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
       
   699 #endif
       
   700 
       
   701     index = (addr >> 4) & 0xff;
       
   702     switch(index) {
       
   703     case 0x02:
       
   704         s->id = (val >> 24);
       
   705         break;
       
   706     case 0x03:
       
   707         break;
       
   708     case 0x08:
       
   709         s->tpr = val;
       
   710         apic_update_irq(s);
       
   711         break;
       
   712     case 0x09:
       
   713     case 0x0a:
       
   714         break;
       
   715     case 0x0b: /* EOI */
       
   716         apic_eoi(s);
       
   717         break;
       
   718     case 0x0d:
       
   719         s->log_dest = val >> 24;
       
   720         break;
       
   721     case 0x0e:
       
   722         s->dest_mode = val >> 28;
       
   723         break;
       
   724     case 0x0f:
       
   725         s->spurious_vec = val & 0x1ff;
       
   726         apic_update_irq(s);
       
   727         break;
       
   728     case 0x10 ... 0x17:
       
   729     case 0x18 ... 0x1f:
       
   730     case 0x20 ... 0x27:
       
   731     case 0x28:
       
   732         break;
       
   733     case 0x30:
       
   734         s->icr[0] = val;
       
   735         apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
       
   736                      (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
       
   737                      (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
       
   738         break;
       
   739     case 0x31:
       
   740         s->icr[1] = val;
       
   741         break;
       
   742     case 0x32 ... 0x37:
       
   743         {
       
   744             int n = index - 0x32;
       
   745             s->lvt[n] = val;
       
   746             if (n == APIC_LVT_TIMER)
       
   747                 apic_timer_update(s, qemu_get_clock(vm_clock));
       
   748         }
       
   749         break;
       
   750     case 0x38:
       
   751         s->initial_count = val;
       
   752         s->initial_count_load_time = qemu_get_clock(vm_clock);
       
   753         apic_timer_update(s, s->initial_count_load_time);
       
   754         break;
       
   755     case 0x39:
       
   756         break;
       
   757     case 0x3e:
       
   758         {
       
   759             int v;
       
   760             s->divide_conf = val & 0xb;
       
   761             v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
       
   762             s->count_shift = (v + 1) & 7;
       
   763         }
       
   764         break;
       
   765     default:
       
   766         s->esr |= ESR_ILLEGAL_ADDRESS;
       
   767         break;
       
   768     }
       
   769 }
       
   770 
       
   771 static void apic_save(QEMUFile *f, void *opaque)
       
   772 {
       
   773     APICState *s = opaque;
       
   774     int i;
       
   775 
       
   776     qemu_put_be32s(f, &s->apicbase);
       
   777     qemu_put_8s(f, &s->id);
       
   778     qemu_put_8s(f, &s->arb_id);
       
   779     qemu_put_8s(f, &s->tpr);
       
   780     qemu_put_be32s(f, &s->spurious_vec);
       
   781     qemu_put_8s(f, &s->log_dest);
       
   782     qemu_put_8s(f, &s->dest_mode);
       
   783     for (i = 0; i < 8; i++) {
       
   784         qemu_put_be32s(f, &s->isr[i]);
       
   785         qemu_put_be32s(f, &s->tmr[i]);
       
   786         qemu_put_be32s(f, &s->irr[i]);
       
   787     }
       
   788     for (i = 0; i < APIC_LVT_NB; i++) {
       
   789         qemu_put_be32s(f, &s->lvt[i]);
       
   790     }
       
   791     qemu_put_be32s(f, &s->esr);
       
   792     qemu_put_be32s(f, &s->icr[0]);
       
   793     qemu_put_be32s(f, &s->icr[1]);
       
   794     qemu_put_be32s(f, &s->divide_conf);
       
   795     qemu_put_be32(f, s->count_shift);
       
   796     qemu_put_be32s(f, &s->initial_count);
       
   797     qemu_put_be64(f, s->initial_count_load_time);
       
   798     qemu_put_be64(f, s->next_time);
       
   799 
       
   800     qemu_put_timer(f, s->timer);
       
   801 }
       
   802 
       
   803 static int apic_load(QEMUFile *f, void *opaque, int version_id)
       
   804 {
       
   805     APICState *s = opaque;
       
   806     int i;
       
   807 
       
   808     if (version_id > 2)
       
   809         return -EINVAL;
       
   810 
       
   811     /* XXX: what if the base changes? (registered memory regions) */
       
   812     qemu_get_be32s(f, &s->apicbase);
       
   813     qemu_get_8s(f, &s->id);
       
   814     qemu_get_8s(f, &s->arb_id);
       
   815     qemu_get_8s(f, &s->tpr);
       
   816     qemu_get_be32s(f, &s->spurious_vec);
       
   817     qemu_get_8s(f, &s->log_dest);
       
   818     qemu_get_8s(f, &s->dest_mode);
       
   819     for (i = 0; i < 8; i++) {
       
   820         qemu_get_be32s(f, &s->isr[i]);
       
   821         qemu_get_be32s(f, &s->tmr[i]);
       
   822         qemu_get_be32s(f, &s->irr[i]);
       
   823     }
       
   824     for (i = 0; i < APIC_LVT_NB; i++) {
       
   825         qemu_get_be32s(f, &s->lvt[i]);
       
   826     }
       
   827     qemu_get_be32s(f, &s->esr);
       
   828     qemu_get_be32s(f, &s->icr[0]);
       
   829     qemu_get_be32s(f, &s->icr[1]);
       
   830     qemu_get_be32s(f, &s->divide_conf);
       
   831     s->count_shift=qemu_get_be32(f);
       
   832     qemu_get_be32s(f, &s->initial_count);
       
   833     s->initial_count_load_time=qemu_get_be64(f);
       
   834     s->next_time=qemu_get_be64(f);
       
   835 
       
   836     if (version_id >= 2)
       
   837         qemu_get_timer(f, s->timer);
       
   838     return 0;
       
   839 }
       
   840 
       
   841 static void apic_reset(void *opaque)
       
   842 {
       
   843     APICState *s = opaque;
       
   844 
       
   845     s->apicbase = 0xfee00000 |
       
   846         (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
       
   847 
       
   848     apic_init_ipi(s);
       
   849 
       
   850     if (s->id == 0) {
       
   851         /*
       
   852          * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
       
   853          * time typically by BIOS, so PIC interrupt can be delivered to the
       
   854          * processor when local APIC is enabled.
       
   855          */
       
   856         s->lvt[APIC_LVT_LINT0] = 0x700;
       
   857     }
       
   858 }
       
   859 
       
   860 static CPUReadMemoryFunc *apic_mem_read[3] = {
       
   861     apic_mem_readb,
       
   862     apic_mem_readw,
       
   863     apic_mem_readl,
       
   864 };
       
   865 
       
   866 static CPUWriteMemoryFunc *apic_mem_write[3] = {
       
   867     apic_mem_writeb,
       
   868     apic_mem_writew,
       
   869     apic_mem_writel,
       
   870 };
       
   871 
       
   872 int apic_init(CPUState *env)
       
   873 {
       
   874     APICState *s;
       
   875 
       
   876     if (last_apic_id >= MAX_APICS)
       
   877         return -1;
       
   878     s = qemu_mallocz(sizeof(APICState));
       
   879     if (!s)
       
   880         return -1;
       
   881     env->apic_state = s;
       
   882     s->id = last_apic_id++;
       
   883     env->cpuid_apic_id = s->id;
       
   884     s->cpu_env = env;
       
   885 
       
   886     apic_reset(s);
       
   887 
       
   888     /* XXX: mapping more APICs at the same memory location */
       
   889     if (apic_io_memory == 0) {
       
   890         /* NOTE: the APIC is directly connected to the CPU - it is not
       
   891            on the global memory bus. */
       
   892         apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
       
   893                                                 apic_mem_write, NULL);
       
   894         cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
       
   895                                      apic_io_memory);
       
   896     }
       
   897     s->timer = qemu_new_timer(vm_clock, apic_timer, s);
       
   898 
       
   899     register_savevm("apic", s->id, 2, apic_save, apic_load, s);
       
   900     qemu_register_reset(apic_reset, s);
       
   901 
       
   902     local_apics[s->id] = s;
       
   903     return 0;
       
   904 }
       
   905 
       
   906 static void ioapic_service(IOAPICState *s)
       
   907 {
       
   908     uint8_t i;
       
   909     uint8_t trig_mode;
       
   910     uint8_t vector;
       
   911     uint8_t delivery_mode;
       
   912     uint32_t mask;
       
   913     uint64_t entry;
       
   914     uint8_t dest;
       
   915     uint8_t dest_mode;
       
   916     uint8_t polarity;
       
   917     uint32_t deliver_bitmask[MAX_APIC_WORDS];
       
   918 
       
   919     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
       
   920         mask = 1 << i;
       
   921         if (s->irr & mask) {
       
   922             entry = s->ioredtbl[i];
       
   923             if (!(entry & APIC_LVT_MASKED)) {
       
   924                 trig_mode = ((entry >> 15) & 1);
       
   925                 dest = entry >> 56;
       
   926                 dest_mode = (entry >> 11) & 1;
       
   927                 delivery_mode = (entry >> 8) & 7;
       
   928                 polarity = (entry >> 13) & 1;
       
   929                 if (trig_mode == APIC_TRIGGER_EDGE)
       
   930                     s->irr &= ~mask;
       
   931                 if (delivery_mode == APIC_DM_EXTINT)
       
   932                     vector = pic_read_irq(isa_pic);
       
   933                 else
       
   934                     vector = entry & 0xff;
       
   935 
       
   936                 apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
       
   937                 apic_bus_deliver(deliver_bitmask, delivery_mode,
       
   938                                  vector, polarity, trig_mode);
       
   939             }
       
   940         }
       
   941     }
       
   942 }
       
   943 
       
   944 void ioapic_set_irq(void *opaque, int vector, int level)
       
   945 {
       
   946     IOAPICState *s = opaque;
       
   947 
       
   948     /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
       
   949      * to GSI 2.  GSI maps to ioapic 1-1.  This is not
       
   950      * the cleanest way of doing it but it should work. */
       
   951 
       
   952     if (vector == 0)
       
   953         vector = 2;
       
   954 
       
   955     if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
       
   956         uint32_t mask = 1 << vector;
       
   957         uint64_t entry = s->ioredtbl[vector];
       
   958 
       
   959         if ((entry >> 15) & 1) {
       
   960             /* level triggered */
       
   961             if (level) {
       
   962                 s->irr |= mask;
       
   963                 ioapic_service(s);
       
   964             } else {
       
   965                 s->irr &= ~mask;
       
   966             }
       
   967         } else {
       
   968             /* edge triggered */
       
   969             if (level) {
       
   970                 s->irr |= mask;
       
   971                 ioapic_service(s);
       
   972             }
       
   973         }
       
   974     }
       
   975 }
       
   976 
       
   977 static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
       
   978 {
       
   979     IOAPICState *s = opaque;
       
   980     int index;
       
   981     uint32_t val = 0;
       
   982 
       
   983     addr &= 0xff;
       
   984     if (addr == 0x00) {
       
   985         val = s->ioregsel;
       
   986     } else if (addr == 0x10) {
       
   987         switch (s->ioregsel) {
       
   988             case 0x00:
       
   989                 val = s->id << 24;
       
   990                 break;
       
   991             case 0x01:
       
   992                 val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
       
   993                 break;
       
   994             case 0x02:
       
   995                 val = 0;
       
   996                 break;
       
   997             default:
       
   998                 index = (s->ioregsel - 0x10) >> 1;
       
   999                 if (index >= 0 && index < IOAPIC_NUM_PINS) {
       
  1000                     if (s->ioregsel & 1)
       
  1001                         val = s->ioredtbl[index] >> 32;
       
  1002                     else
       
  1003                         val = s->ioredtbl[index] & 0xffffffff;
       
  1004                 }
       
  1005         }
       
  1006 #ifdef DEBUG_IOAPIC
       
  1007         printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
       
  1008 #endif
       
  1009     }
       
  1010     return val;
       
  1011 }
       
  1012 
       
  1013 static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
       
  1014 {
       
  1015     IOAPICState *s = opaque;
       
  1016     int index;
       
  1017 
       
  1018     addr &= 0xff;
       
  1019     if (addr == 0x00)  {
       
  1020         s->ioregsel = val;
       
  1021         return;
       
  1022     } else if (addr == 0x10) {
       
  1023 #ifdef DEBUG_IOAPIC
       
  1024         printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
       
  1025 #endif
       
  1026         switch (s->ioregsel) {
       
  1027             case 0x00:
       
  1028                 s->id = (val >> 24) & 0xff;
       
  1029                 return;
       
  1030             case 0x01:
       
  1031             case 0x02:
       
  1032                 return;
       
  1033             default:
       
  1034                 index = (s->ioregsel - 0x10) >> 1;
       
  1035                 if (index >= 0 && index < IOAPIC_NUM_PINS) {
       
  1036                     if (s->ioregsel & 1) {
       
  1037                         s->ioredtbl[index] &= 0xffffffff;
       
  1038                         s->ioredtbl[index] |= (uint64_t)val << 32;
       
  1039                     } else {
       
  1040                         s->ioredtbl[index] &= ~0xffffffffULL;
       
  1041                         s->ioredtbl[index] |= val;
       
  1042                     }
       
  1043                     ioapic_service(s);
       
  1044                 }
       
  1045         }
       
  1046     }
       
  1047 }
       
  1048 
       
  1049 static void ioapic_save(QEMUFile *f, void *opaque)
       
  1050 {
       
  1051     IOAPICState *s = opaque;
       
  1052     int i;
       
  1053 
       
  1054     qemu_put_8s(f, &s->id);
       
  1055     qemu_put_8s(f, &s->ioregsel);
       
  1056     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
       
  1057         qemu_put_be64s(f, &s->ioredtbl[i]);
       
  1058     }
       
  1059 }
       
  1060 
       
  1061 static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
       
  1062 {
       
  1063     IOAPICState *s = opaque;
       
  1064     int i;
       
  1065 
       
  1066     if (version_id != 1)
       
  1067         return -EINVAL;
       
  1068 
       
  1069     qemu_get_8s(f, &s->id);
       
  1070     qemu_get_8s(f, &s->ioregsel);
       
  1071     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
       
  1072         qemu_get_be64s(f, &s->ioredtbl[i]);
       
  1073     }
       
  1074     return 0;
       
  1075 }
       
  1076 
       
  1077 static void ioapic_reset(void *opaque)
       
  1078 {
       
  1079     IOAPICState *s = opaque;
       
  1080     int i;
       
  1081 
       
  1082     memset(s, 0, sizeof(*s));
       
  1083     for(i = 0; i < IOAPIC_NUM_PINS; i++)
       
  1084         s->ioredtbl[i] = 1 << 16; /* mask LVT */
       
  1085 }
       
  1086 
       
  1087 static CPUReadMemoryFunc *ioapic_mem_read[3] = {
       
  1088     ioapic_mem_readl,
       
  1089     ioapic_mem_readl,
       
  1090     ioapic_mem_readl,
       
  1091 };
       
  1092 
       
  1093 static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
       
  1094     ioapic_mem_writel,
       
  1095     ioapic_mem_writel,
       
  1096     ioapic_mem_writel,
       
  1097 };
       
  1098 
       
  1099 IOAPICState *ioapic_init(void)
       
  1100 {
       
  1101     IOAPICState *s;
       
  1102     int io_memory;
       
  1103 
       
  1104     s = qemu_mallocz(sizeof(IOAPICState));
       
  1105     if (!s)
       
  1106         return NULL;
       
  1107     ioapic_reset(s);
       
  1108     s->id = last_apic_id++;
       
  1109 
       
  1110     io_memory = cpu_register_io_memory(0, ioapic_mem_read,
       
  1111                                        ioapic_mem_write, s);
       
  1112     cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
       
  1113 
       
  1114     register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
       
  1115     qemu_register_reset(ioapic_reset, s);
       
  1116 
       
  1117     return s;
       
  1118 }