[SeaBIOS] [PATCH] smp: Replace QEMU SMP init assembler code with C; run only in 32bit mode.

Paolo Bonzini pbonzini at redhat.com
Sat May 31 12:12:13 CEST 2014


Il 31/05/2014 03:20, Kevin O'Connor ha scritto:
> Change the multi-processor init code to trampoline into 32bit mode on
> each of the additional processors.  Implement an atomic lock so that
> each processor performs its initialization serially.

I don't see much benefit in this change, in fact the new code is more 
complex than the old one...  But anyway, if you prefer to go this way I 
have just a couple observations on the patch:

1) acquiring the lock can be done simply by a "1: lock btsl; jc 1b"; no 
need to use the cmpxchg.

2) There's no need to acquire the lock repeatedly in the BSP, I think 
writing the loop in assembly is acceptable:

	asm volatile(
             "movl %%esp, %1\n"
	    // Release lock, other processors use the stack now
	    "mov $0, %0\n"
	    "1: cmp %3, %2\n"
	    "rep; nop\n"
	    "jne 1b\n"
	    // Reacquire lock; last processor is still using the stack!
	    "1b: lock btsl $0, %0\n"
	    "rep; nop\n"
	    "jc 1b\n" :
		"+m" (SMPLock), "=m" (SMPStack) : "r" (cmos_smp_count),
		"m" (CountCPUs) : "cc", "memory");

Paolo

> +            : "+m" (SMPLock), "+m" (SMPStack), "=&a" (eax)
> +            : "r" (lockval)
> +            : "cc", "memory");
> +    yield();
>
>      // Restore memory.
>      *(u64*)BUILD_AP_BOOT_ADDR = old;
> @@ -143,6 +142,6 @@ smp_setup(void)
>      if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
>          MaxCountCPUs = CountCPUs;
>
> -    dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", readl(&CountCPUs),
> -        MaxCountCPUs);
> +    dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", CountCPUs,
> +            MaxCountCPUs);
>  }
> diff --git a/src/romlayout.S b/src/romlayout.S
> index 0d6af39..bee3943 100644
> --- a/src/romlayout.S
> +++ b/src/romlayout.S
> @@ -274,6 +274,29 @@ entry_smi:
>          rsm
>          .code16gcc
>
> +// Entry point for QEMU smp sipi interrupts.
> +        DECLFUNC entry_smp
> +entry_smp:
> +        // Transition to 32bit mode.
> +        movl $1f + BUILD_BIOS_ADDR, %edx
> +        jmp transition32
> +        .code32
> +        // Acquire lock
> +1:      movl $1, %ecx
> +2:      xorl %eax, %eax
> +        lock cmpxchgl %ecx, SMPLock
> +        jz 3f
> +        rep nop
> +        jmp 2b
> +        // Setup stack and call handle_smp
> +3:      movl SMPStack, %esp
> +        calll _cfunc32flat_handle_smp - BUILD_BIOS_ADDR
> +        // Release lock and halt processor.
> +        movl $0, SMPLock
> +4:      hlt
> +        jmp 4b
> +        .code16gcc
> +
>  // Resume (and reboot) entry point - called from entry_post
>          DECLFUNC entry_resume
>  entry_resume:
> diff --git a/src/util.h b/src/util.h
> index b54271b..8c794c4 100644
> --- a/src/util.h
> +++ b/src/util.h
> @@ -126,7 +126,6 @@ void smm_device_setup(void);
>  void smm_setup(void);
>
>  // fw/smp.c
> -extern u32 CountCPUs;
>  extern u32 MaxCountCPUs;
>  void wrmsr_smp(u32 index, u64 val);
>  void smp_setup(void);
>




More information about the SeaBIOS mailing list