[coreboot] [PATCH] [v2] add returning to SIPI WAIT for MP systems

Peter Stuge peter at stuge.se
Sat Aug 2 17:05:29 CEST 2008


On Sat, Aug 02, 2008 at 04:43:34PM +0200, Stefan Reinauer wrote:
> 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 at coresystems.de>

Acked-by: Peter Stuge <peter at stuge.se>


> Index: src/include/cpu/x86/lapic.h
> ===================================================================
> --- src/include/cpu/x86/lapic.h	(revision 3461)
> +++ src/include/cpu/x86/lapic.h	(working copy)
> @@ -51,6 +51,11 @@
>  	return lapic_read(LAPIC_ID) >> 24;
>  }
>  
> +
> +#if CONFIG_AP_IN_SIPI_WAIT != 1
> +/* If we need to go back to sipi wait, we use the long non-inlined version of
> + * this function in lapic_cpu_init.c
> + */
>  static inline __attribute__((always_inline)) void stop_this_cpu(void)
>  {
>  
> @@ -59,6 +64,7 @@
>  		hlt();
>  	}
>  }
> +#endif
>  
>  #if ! defined (__ROMCC__)
>  
> @@ -98,7 +104,7 @@
>  }
>  
>  
> -extern inline void lapic_write_atomic(unsigned long reg, unsigned long v)
> +static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
>  {
>  	xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v);
>  }
> Index: src/cpu/x86/lapic/lapic_cpu_init.c
> ===================================================================
> --- src/cpu/x86/lapic/lapic_cpu_init.c	(revision 3461)
> +++ src/cpu/x86/lapic/lapic_cpu_init.c	(working copy)
> @@ -1,6 +1,7 @@
>  /*
>  	2005.12 yhlu add coreboot_ram cross the vga font buffer handling
>  	2005.12 yhlu add _RAMBASE above 1M support for SMP
> +	2008.05 stepan add support for going back to sipi wait state
>  */
>  
>  #include <cpu/x86/lapic.h>
> @@ -16,6 +17,7 @@
>  
>  #if CONFIG_SMP == 1
>  
> +#if _RAMBASE >= 0x100000
>  /* This is a lot more paranoid now, since Linux can NOT handle
>   * being told there is a CPU when none exists. So any errors 
>   * will return 0, meaning no CPU. 
> @@ -27,6 +29,7 @@
>  {
>  	return (unsigned long)orig_start_eip & 0xffff; // 16 bit to avoid 0xa0000 
>  }
> +#endif
>  
>  static void copy_secondary_start_to_1m_below(void) 
>  {
> @@ -277,9 +280,73 @@
>  	return result;
>  }
>  
> +#if CONFIG_AP_IN_SIPI_WAIT == 1
> +/**
> + * Normally this function is defined in lapic.h as an always inline function
> + * that just keeps the CPU in a hlt() loop. This does not work on all CPUs.
> + * I think all hyperthreading CPUs might need this version, but I could only
> + * verify this on the Intel Core Duo
> + */
> +void stop_this_cpu(void)
> +{
> +	int timeout;
> +	unsigned long send_status;
> +	unsigned long lapicid;
> +
> +	lapicid = lapic_read(LAPIC_ID) >> 24;
> +
> +	printk_debug("CPU %d going down...\n", lapicid);
> +
> +	/* send an LAPIC INIT to myself */
> +	lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
> +	lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
> +
> +	/* wait for the ipi send to finish */
> +#if 0
> +	// When these two printk_spew calls are not removed, the
> +	// machine will hang when log level is SPEW. Why?
> +	printk_spew("Waiting for send to finish...\n");
> +#endif
> +	timeout = 0;
> +	do {
> +#if 0
> +		printk_spew("+");
> +#endif
> +		udelay(100);
> +		send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
> +	} while (send_status && (timeout++ < 1000));
> +	if (timeout >= 1000) {
> +		printk_err("timed out\n");
> +	}
> +	mdelay(10);
> +
> +	printk_spew("Deasserting INIT.\n");
> +	/* Deassert the LAPIC INIT */
> +	lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));	
> +	lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
> +
> +	printk_spew("Waiting for send to finish...\n");
> +	timeout = 0;
> +	do {
> +		printk_spew("+");
> +		udelay(100);
> +		send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
> +	} while (send_status && (timeout++ < 1000));
> +	if (timeout >= 1000) {
> +		printk_err("timed out\n");
> +	}
> +
> +	while(1) {
> +		hlt();
> +	}
> +}
> +#endif
> +
>  /* C entry point of secondary cpus */
>  void secondary_cpu_init(void)
>  {
> +	unsigned long cpunum;
> +
>  	atomic_inc(&active_cpus);
>  #if SERIAL_CPU_INIT == 1
>    #if CONFIG_MAX_CPUS>2
> @@ -294,6 +361,7 @@
>  #endif
>  
>  	atomic_dec(&active_cpus);
> +
>  	stop_this_cpu();
>  }
>  
> @@ -356,7 +424,6 @@
>  		if (!cpu->initialized) {
>  			printk_err("CPU 0x%02x did not initialize!\n", 
>  				cpu->path.u.apic.apic_id);
> -#warning "FIXME do I need a mainboard_cpu_fixup function?"
>  		}
>  	}
>  	printk_debug("All AP CPUs stopped\n");
> Index: src/config/Options.lb
> ===================================================================
> --- src/config/Options.lb	(revision 3461)
> +++ src/config/Options.lb	(working copy)
> @@ -574,6 +574,11 @@
>  	export always
>  	comment "Should multiple cpus per die be enabled?"
>  end
> +define CONFIG_AP_IN_SIPI_WAIT
> +	default 0
> +	export always
> +	comment "Should application processors go to SIPI wait state after initialization? (Required for Intel Core Duo)"
> +end
>  define HAVE_MP_TABLE
>  	default none
>  	export used
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20080802/b97ab806/attachment.sig>


More information about the coreboot mailing list