Changeset 3465


Ignore:
Timestamp:
Aug 2, 2008, 5:15:23 PM (7 years ago)
Author:
stepan
Message:

Go back to SIPI WAIT state for those CPUS defining the newly introduced
CONFIG_AP_IN_SIPI_WAIT flag. Newer Intel CPUs need this to operate with
multiple cores.

Signed-off-by: Stefan Reinauer <stepan@…>
Acked-by: Peter Stuge <peter@…>

Location:
trunk/coreboot-v2/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/coreboot-v2/src/config/Options.lb

    r3436 r3465  
    574574        export always
    575575        comment "Should multiple cpus per die be enabled?"
     576end
     577define CONFIG_AP_IN_SIPI_WAIT
     578        default 0
     579        export always
     580        comment "Should application processors go to SIPI wait state after initialization? (Required for Intel Core Duo)"
    576581end
    577582define HAVE_MP_TABLE
  • trunk/coreboot-v2/src/cpu/x86/lapic/lapic_cpu_init.c

    r3053 r3465  
    22        2005.12 yhlu add coreboot_ram cross the vga font buffer handling
    33        2005.12 yhlu add _RAMBASE above 1M support for SMP
     4        2008.05 stepan add support for going back to sipi wait state
    45*/
    56
     
    1718#if CONFIG_SMP == 1
    1819
     20#if _RAMBASE >= 0x100000
    1921/* This is a lot more paranoid now, since Linux can NOT handle
    2022 * being told there is a CPU when none exists. So any errors
     
    2830        return (unsigned long)orig_start_eip & 0xffff; // 16 bit to avoid 0xa0000
    2931}
     32#endif
    3033
    3134static void copy_secondary_start_to_1m_below(void)
     
    278281}
    279282
     283#if CONFIG_AP_IN_SIPI_WAIT == 1
     284/**
     285 * Normally this function is defined in lapic.h as an always inline function
     286 * that just keeps the CPU in a hlt() loop. This does not work on all CPUs.
     287 * I think all hyperthreading CPUs might need this version, but I could only
     288 * verify this on the Intel Core Duo
     289 */
     290void stop_this_cpu(void)
     291{
     292        int timeout;
     293        unsigned long send_status;
     294        unsigned long lapicid;
     295
     296        lapicid = lapic_read(LAPIC_ID) >> 24;
     297
     298        printk_debug("CPU %d going down...\n", lapicid);
     299
     300        /* send an LAPIC INIT to myself */
     301        lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
     302        lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
     303
     304        /* wait for the ipi send to finish */
     305#if 0
     306        // When these two printk_spew calls are not removed, the
     307        // machine will hang when log level is SPEW. Why?
     308        printk_spew("Waiting for send to finish...\n");
     309#endif
     310        timeout = 0;
     311        do {
     312#if 0
     313                printk_spew("+");
     314#endif
     315                udelay(100);
     316                send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
     317        } while (send_status && (timeout++ < 1000));
     318        if (timeout >= 1000) {
     319                printk_err("timed out\n");
     320        }
     321        mdelay(10);
     322
     323        printk_spew("Deasserting INIT.\n");
     324        /* Deassert the LAPIC INIT */
     325        lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid)); 
     326        lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
     327
     328        printk_spew("Waiting for send to finish...\n");
     329        timeout = 0;
     330        do {
     331                printk_spew("+");
     332                udelay(100);
     333                send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
     334        } while (send_status && (timeout++ < 1000));
     335        if (timeout >= 1000) {
     336                printk_err("timed out\n");
     337        }
     338
     339        while(1) {
     340                hlt();
     341        }
     342}
     343#endif
     344
    280345/* C entry point of secondary cpus */
    281346void secondary_cpu_init(void)
    282347{
     348        unsigned long cpunum;
     349
    283350        atomic_inc(&active_cpus);
    284351#if SERIAL_CPU_INIT == 1
     
    295362
    296363        atomic_dec(&active_cpus);
     364
    297365        stop_this_cpu();
    298366}
     
    357425                        printk_err("CPU 0x%02x did not initialize!\n",
    358426                                cpu->path.u.apic.apic_id);
    359 #warning "FIXME do I need a mainboard_cpu_fixup function?"
    360427                }
    361428        }
  • trunk/coreboot-v2/src/include/cpu/x86/lapic.h

    r3017 r3465  
    5252}
    5353
     54
     55#if CONFIG_AP_IN_SIPI_WAIT != 1
     56/* If we need to go back to sipi wait, we use the long non-inlined version of
     57 * this function in lapic_cpu_init.c
     58 */
    5459static inline __attribute__((always_inline)) void stop_this_cpu(void)
    5560{
     
    6065        }
    6166}
     67#endif
    6268
    6369#if ! defined (__ROMCC__)
     
    99105
    100106
    101 extern inline void lapic_write_atomic(unsigned long reg, unsigned long v)
     107static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
    102108{
    103109        xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v);
Note: See TracChangeset for help on using the changeset viewer.