ia64/xen-unstable

changeset 4888:2bc4d7e40d11

bitkeeper revision 1.1389.1.52 (42839937dfdfndUpTNENRU4pLS6XDw)

Add 'apic={verbose,debug}' option to Xen. Same meaning as on Linux
command line, and automatically propagated to domain0 command line.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu May 12 17:58:15 2005 +0000 (2005-05-12)
parents ace579e991fe
children 1c0f716646d1
files docs/src/user.tex xen/arch/x86/apic.c xen/arch/x86/setup.c
line diff
     1.1 --- a/docs/src/user.tex	Thu May 12 15:43:49 2005 +0000
     1.2 +++ b/docs/src/user.tex	Thu May 12 17:58:15 2005 +0000
     1.3 @@ -1791,6 +1791,9 @@ unchanged semantics.
     1.4   Instruct Xen (and domain 0) to ignore any IOAPICs that are present in
     1.5   the system, and instead continue to use the legacy PIC.
     1.6  
     1.7 +\item [apic=debug,verbose ]
     1.8 + Print more detailed information about local APIC and IOAPIC configuration.
     1.9 +
    1.10  \end{description} 
    1.11  
    1.12  \section{XenLinux Boot Options}
     2.1 --- a/xen/arch/x86/apic.c	Thu May 12 15:43:49 2005 +0000
     2.2 +++ b/xen/arch/x86/apic.c	Thu May 12 17:58:15 2005 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - *      based on linux-2.6.10/arch/i386/kernel/apic.c
     2.6 + *      based on linux-2.6.11/arch/i386/kernel/apic.c
     2.7   *
     2.8   *  Local APIC handling, local APIC timers
     2.9   *
    2.10 @@ -37,11 +37,14 @@
    2.11  #include <mach_apic.h>
    2.12  #include <io_ports.h>
    2.13  
    2.14 +/*
    2.15 + * Debug level
    2.16 + */
    2.17 +int apic_verbosity;
    2.18 +
    2.19  /* Using APIC to generate smp_local_timer_interrupt? */
    2.20  int using_apic_timer = 0;
    2.21  
    2.22 -int apic_verbosity;
    2.23 -
    2.24  static int enabled_via_apicbase;
    2.25  
    2.26  int get_physical_broadcast(void)
    2.27 @@ -126,7 +129,8 @@ void __init connect_bsp_APIC(void)
    2.28           * PIC mode, enable APIC mode in the IMCR, i.e.
    2.29           * connect BSP's local APIC to INT and NMI lines.
    2.30           */
    2.31 -        printk("leaving PIC mode, enabling APIC mode.\n");
    2.32 +        apic_printk(APIC_VERBOSE, "leaving PIC mode, "
    2.33 +                    "enabling APIC mode.\n");
    2.34          outb(0x70, 0x22);
    2.35          outb(0x01, 0x23);
    2.36      }
    2.37 @@ -141,7 +145,8 @@ void disconnect_bsp_APIC(void)
    2.38           * interrupts, including IPIs, won't work beyond
    2.39           * this point!  The only exception are INIT IPIs.
    2.40           */
    2.41 -        printk("disabling APIC mode, entering PIC mode.\n");
    2.42 +        apic_printk(APIC_VERBOSE, "disabling APIC mode, "
    2.43 +                    "entering PIC mode.\n");
    2.44          outb(0x70, 0x22);
    2.45          outb(0x00, 0x23);
    2.46      }
    2.47 @@ -182,10 +187,10 @@ int __init verify_local_APIC(void)
    2.48       * The version register is read-only in a real APIC.
    2.49       */
    2.50      reg0 = apic_read(APIC_LVR);
    2.51 -    Dprintk("Getting VERSION: %x\n", reg0);
    2.52 +    apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
    2.53      apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
    2.54      reg1 = apic_read(APIC_LVR);
    2.55 -    Dprintk("Getting VERSION: %x\n", reg1);
    2.56 +    apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
    2.57  
    2.58      /*
    2.59       * The two version reads above should print the same
    2.60 @@ -209,7 +214,7 @@ int __init verify_local_APIC(void)
    2.61       * The ID register is read/write in a real APIC.
    2.62       */
    2.63      reg0 = apic_read(APIC_ID);
    2.64 -    Dprintk("Getting ID: %x\n", reg0);
    2.65 +    apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
    2.66  
    2.67      /*
    2.68       * The next two are just to see if we have sane values.
    2.69 @@ -217,9 +222,9 @@ int __init verify_local_APIC(void)
    2.70       * compatibility mode, but most boxes are anymore.
    2.71       */
    2.72      reg0 = apic_read(APIC_LVT0);
    2.73 -    Dprintk("Getting LVT0: %x\n", reg0);
    2.74 +    apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
    2.75      reg1 = apic_read(APIC_LVT1);
    2.76 -    Dprintk("Getting LVT1: %x\n", reg1);
    2.77 +    apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
    2.78  
    2.79      return 1;
    2.80  }
    2.81 @@ -235,20 +240,23 @@ void __init sync_Arb_IDs(void)
    2.82       */
    2.83      apic_wait_icr_idle();
    2.84  
    2.85 -    Dprintk("Synchronizing Arb IDs.\n");
    2.86 +    apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
    2.87      apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
    2.88                        | APIC_DM_INIT);
    2.89  }
    2.90  
    2.91  extern void __error_in_apic_c (void);
    2.92  
    2.93 +/*
    2.94 + * An initial setup of the virtual wire mode.
    2.95 + */
    2.96  void __init init_bsp_APIC(void)
    2.97  {
    2.98      unsigned long value, ver;
    2.99  
   2.100      /*
   2.101 -     * Don't do the setup now if we have a SMP BIOS as the through-I/O-APIC 
   2.102 -     * virtual wire mode might be active.
   2.103 +     * Don't do the setup now if we have a SMP BIOS as the
   2.104 +     * through-I/O-APIC virtual wire mode might be active.
   2.105       */
   2.106      if (smp_found_config || !cpu_has_apic)
   2.107          return;
   2.108 @@ -380,10 +388,12 @@ void __init setup_local_APIC (void)
   2.109      value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
   2.110      if (!smp_processor_id() && (pic_mode || !value)) {
   2.111          value = APIC_DM_EXTINT;
   2.112 -        printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
   2.113 +        apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
   2.114 +                    smp_processor_id());
   2.115      } else {
   2.116          value = APIC_DM_EXTINT | APIC_LVT_MASKED;
   2.117 -        printk("masked ExtINT on CPU#%d\n", smp_processor_id());
   2.118 +        apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
   2.119 +                    smp_processor_id());
   2.120      }
   2.121      apic_write_around(APIC_LVT0, value);
   2.122  
   2.123 @@ -413,8 +423,9 @@ void __init setup_local_APIC (void)
   2.124              apic_write(APIC_ESR, 0);
   2.125          value = apic_read(APIC_ESR);
   2.126          if (value != oldvalue)
   2.127 -            printk("ESR value before enabling vector: 0x%08lx "
   2.128 -                "after: 0x%08lx\n", oldvalue, value);
   2.129 +            apic_printk(APIC_VERBOSE, "ESR value before enabling "
   2.130 +                        "vector: 0x%08lx  after: 0x%08lx\n",
   2.131 +                        oldvalue, value);
   2.132      } else {
   2.133          if (esr_disable)    
   2.134              /* 
   2.135 @@ -424,8 +435,8 @@ void __init setup_local_APIC (void)
   2.136               * errors anyway - mbligh
   2.137               */
   2.138              printk("Leaving ESR disabled.\n");
   2.139 -        else 
   2.140 -        printk("No ESR for 82489DX.\n");
   2.141 +        else
   2.142 +            printk("No ESR for 82489DX.\n");
   2.143      }
   2.144  
   2.145      if (nmi_watchdog == NMI_LOCAL_APIC)
   2.146 @@ -437,6 +448,18 @@ void __init setup_local_APIC (void)
   2.147   * Original code written by Keir Fraser.
   2.148   */
   2.149  
   2.150 +static void __init apic_set_verbosity(char *str)
   2.151 +{
   2.152 +    if (strcmp("debug", str) == 0)
   2.153 +        apic_verbosity = APIC_DEBUG;
   2.154 +    else if (strcmp("verbose", str) == 0)
   2.155 +        apic_verbosity = APIC_VERBOSE;
   2.156 +    else
   2.157 +        printk(KERN_WARNING "APIC Verbosity level %s not recognised"
   2.158 +               " use apic=verbose or apic=debug", str);
   2.159 +}
   2.160 +custom_param("apic", apic_set_verbosity);
   2.161 +
   2.162  static int __init detect_init_APIC (void)
   2.163  {
   2.164      u32 h, l, features;
   2.165 @@ -476,8 +499,10 @@ static int __init detect_init_APIC (void
   2.166              enabled_via_apicbase = 1;
   2.167          }
   2.168      }
   2.169 -
   2.170 -    /* The APIC feature bit should now be enabled in `cpuid' */
   2.171 +    /*
   2.172 +     * The APIC feature bit should now be enabled
   2.173 +     * in `cpuid'
   2.174 +     */
   2.175      features = cpuid_edx(1);
   2.176      if (!(features & (1 << X86_FEATURE_APIC))) {
   2.177          printk("Could not enable APIC!\n");
   2.178 @@ -520,7 +545,8 @@ void __init init_apic_mappings(void)
   2.179          apic_phys = mp_lapic_addr;
   2.180  
   2.181      set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
   2.182 -    Dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
   2.183 +    apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", APIC_BASE,
   2.184 +                apic_phys);
   2.185  
   2.186      /*
   2.187       * Fetch the APIC ID of the BSP in case we have a
   2.188 @@ -552,8 +578,8 @@ fake_ioapic_page:
   2.189                  ioapic_phys = __pa(ioapic_phys);
   2.190              }
   2.191              set_fixmap_nocache(idx, ioapic_phys);
   2.192 -            Dprintk("mapped IOAPIC to %08lx (%08lx)\n",
   2.193 -                    fix_to_virt(idx), ioapic_phys);
   2.194 +            apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
   2.195 +                        __fix_to_virt(idx), ioapic_phys);
   2.196              idx++;
   2.197          }
   2.198      }
   2.199 @@ -604,37 +630,32 @@ static unsigned int __init get_8254_time
   2.200  /* next tick in 8254 can be caught by catching timer wraparound */
   2.201  static void __init wait_8254_wraparound(void)
   2.202  {
   2.203 -    unsigned int curr_count, prev_count=~0;
   2.204 -    int delta;
   2.205 -
   2.206 +    unsigned int curr_count, prev_count;
   2.207 +    
   2.208      curr_count = get_8254_timer_count();
   2.209 -
   2.210      do {
   2.211          prev_count = curr_count;
   2.212          curr_count = get_8254_timer_count();
   2.213 -        delta = curr_count-prev_count;
   2.214  
   2.215 -        /*
   2.216 -         * This limit for delta seems arbitrary, but it isn't, it's slightly
   2.217 -         * above the level of error a buggy Mercury/Neptune chipset timer can
   2.218 -         * cause.
   2.219 -         */
   2.220 -    } while (delta < 300);
   2.221 +        /* workaround for broken Mercury/Neptune */
   2.222 +        if (prev_count >= curr_count + 0x100)
   2.223 +            curr_count = get_8254_timer_count();
   2.224 +        
   2.225 +    } while (prev_count >= curr_count);
   2.226  }
   2.227  
   2.228  /*
   2.229   * Default initialization for 8254 timers. If we use other timers like HPET,
   2.230   * we override this later
   2.231   */
   2.232 -void (*wait_timer_tick)(void) = wait_8254_wraparound;
   2.233 +void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound;
   2.234  
   2.235  /*
   2.236   * This function sets up the local APIC timer, with a timeout of
   2.237   * 'clocks' APIC bus clock. During calibration we actually call
   2.238 - * this function with a very large value and read the current time after
   2.239 - * a well defined period of time as expired.
   2.240 - *
   2.241 - * Calibration is only performed once, for CPU0!
   2.242 + * this function twice on the boot CPU, once with a bogus timeout
   2.243 + * value, second time for real. The other (noncalibrating) CPUs
   2.244 + * call this function only once, with the real, calibrated value.
   2.245   *
   2.246   * We do reads before writes even if unnecessary, to get around the
   2.247   * P5 APIC double write bug.
   2.248 @@ -693,7 +714,7 @@ int __init calibrate_APIC_clock(void)
   2.249      int i;
   2.250      const int LOOPS = HZ/10;
   2.251  
   2.252 -    printk("Calibrating APIC timer for CPU%d...\n",  smp_processor_id());
   2.253 +    apic_printk(APIC_VERBOSE, "calibrating APIC timer ...\n");
   2.254  
   2.255      /*
   2.256       * Put whatever arbitrary (but long enough) timeout
   2.257 @@ -730,26 +751,29 @@ int __init calibrate_APIC_clock(void)
   2.258       * The APIC bus clock counter is 32 bits only, it
   2.259       * might have overflown, but note that we use signed
   2.260       * longs, thus no extra care needed.
   2.261 -     * [underflown to be exact, as the timer counts down ;)]
   2.262 +     *
   2.263 +     * underflown to be exact, as the timer counts down ;)
   2.264       */
   2.265  
   2.266      result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
   2.267  
   2.268      if (cpu_has_tsc)
   2.269 -        printk("..... CPU clock speed is %ld.%04ld MHz.\n",
   2.270 -            ((long)(t2-t1)/LOOPS)/(1000000/HZ),
   2.271 -            ((long)(t2-t1)/LOOPS)%(1000000/HZ));
   2.272 +        apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
   2.273 +                    "%ld.%04ld MHz.\n",
   2.274 +                    ((long)(t2-t1)/LOOPS)/(1000000/HZ),
   2.275 +                    ((long)(t2-t1)/LOOPS)%(1000000/HZ));
   2.276  
   2.277 -    printk("..... host bus clock speed is %ld.%04ld MHz.\n",
   2.278 -        result/(1000000/HZ),
   2.279 -        result%(1000000/HZ));
   2.280 +    apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
   2.281 +		"%ld.%04ld MHz.\n",
   2.282 +		result/(1000000/HZ),
   2.283 +		result%(1000000/HZ));
   2.284  
   2.285      /* set up multipliers for accurate timer code */
   2.286      bus_freq   = result*HZ;
   2.287      bus_cycle  = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
   2.288      bus_scale  = (1000*262144)/bus_cycle;
   2.289  
   2.290 -    printk("..... bus_scale = 0x%08X\n", bus_scale);
   2.291 +    apic_printk(APIC_VERBOSE, "..... bus_scale = 0x%08X\n", bus_scale);
   2.292      /* reset APIC to zero timeout value */
   2.293      __setup_APIC_LVTT(0);
   2.294  
   2.295 @@ -762,7 +786,6 @@ int __init calibrate_APIC_clock(void)
   2.296   */
   2.297  void __init setup_APIC_clocks (void)
   2.298  {
   2.299 -    printk("Using local APIC timer interrupts.\n");
   2.300      using_apic_timer = 1;
   2.301      __cli();
   2.302      /* calibrate CPU0 for CPU speed and BUS speed */
   2.303 @@ -908,7 +931,7 @@ int __init APIC_init_uniprocessor (void)
   2.304       * Complain if the BIOS pretends there is one.
   2.305       */
   2.306      if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
   2.307 -        printk("BIOS bug, local APIC #%d not detected!...\n",
   2.308 +        printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
   2.309                 boot_cpu_physical_apicid);
   2.310          return -1;
   2.311      }
     3.1 --- a/xen/arch/x86/setup.c	Thu May 12 15:43:49 2005 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Thu May 12 17:58:15 2005 +0000
     3.3 @@ -615,6 +615,13 @@ void __init __start_xen(multiboot_info_t
     3.4              strcat(cmdline, " acpi=");
     3.5              strcat(cmdline, acpi_param);
     3.6          }
     3.7 +        if ( !strstr(cmdline, "apic=") )
     3.8 +        {
     3.9 +            if ( apic_verbosity == APIC_VERBOSE )
    3.10 +                strcat(cmdline, " apic=verbose");
    3.11 +            else if ( apic_verbosity == APIC_DEBUG )
    3.12 +                strcat(cmdline, " apic=debug");
    3.13 +        }
    3.14      }
    3.15  
    3.16      /*