Changeset 3465


Ignore:
Timestamp:
Aug 2, 2008 5:15:23 PM (5 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.