On 10/09/19 15:22, Igor Mammedov wrote:
> Clarify values of "CPU selector' register and add workflows for
>   * finding CPU with pending 'insert/remove' event
>   * enumerating present/non present CPUs
> 
> Signed-off-by: Igor Mammedov <imamm...@redhat.com>
> ---
>  docs/specs/acpi_cpu_hotplug.txt | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/docs/specs/acpi_cpu_hotplug.txt b/docs/specs/acpi_cpu_hotplug.txt
> index ac5903b2b1..43c5a193f0 100644
> --- a/docs/specs/acpi_cpu_hotplug.txt
> +++ b/docs/specs/acpi_cpu_hotplug.txt
> @@ -54,6 +54,7 @@ write access:
>      [0x0-0x3] CPU selector: (DWORD access)
>                selects active CPU device. All following accesses to other
>                registers will read/store data from/to selected CPU.
> +              Valid values: [0 .. max_cpus)
>      [0x4] CPU device control fields: (1 byte access)
>          bits:
>              0: reserved, OSPM must clear it before writing to register.
> @@ -93,3 +94,24 @@ Selecting CPU device beyond possible range has no effect 
> on platform:
>       ignored
>     - read accesses to CPU hot-plug registers not documented above return
>       all bits set to 0.
> +
> +Typical usecases:
> +   - Get a cpu with pending event
> +     1. write 0x0 into 'Command field' register
> +     2. read from 'Command data' register, CPU selector value (CPU's UID in 
> ACPI
> +        tables) and event for selected CPU from 'CPU device status fields'
> +        register. If there aren't pending events, CPU selector value doesn't
> +        change and 'insert' and 'remove' bits are not set.

Okay, so based on the "Command data" documentation I'm suggesting in
<cd0713b5-fd64-d3e1-7f83-3a0725b819a3@redhat.com">http://mid.mail-archive.com/cd0713b5-fd64-d3e1-7f83-3a0725b819a3@redhat.com>,
I propose:

1. Store 0x0 to the 'CPU selector' register.
2. Store 0x0 to the 'Command field' register.
3. Read the 'CPU device status fields' register.
4. If both bit#1 and bit#2 are clear in the value read, there is no CPU
   with a pending event.
5. Otherwise, read the 'Command data' register. The value read is the
   selector of the CPU with the pending event (which is already
   selected).

> +   - Enumerate CPUs present/non present CPUs.
> +     1. set iterator to 0x0
> +     2. write 0x0 into 'Command field' register and then iterator
> +        into 'CPU selector' register.
> +     3. read 'enabled' flag for selected CPU from 'CPU device status fields'
> +        register
> +     4. to continue to the next CPU, increment iterator and repeat step 2
> +     5. read 'Command data' register
> +     5.1 if 'Command data' register matches iterator continue to step 3.
> +         (read presence bit for the next CPU)
> +     5.2 if 'Command data' register has not changed, there is not CPU
> +         corresponding to iterator value and the last valid iterator value
> +         equals to 'max_cpus' + 1
> 

How about:

01. Set the present CPU count to 0.
02. Set the iterator to 0.
03. Store 0x0 to the 'Command field' register.
04. Store 0x0 to the 'CPU selector' register.
05. Read the 'CPU device status fields' register.
06. If bit#0 is set, increment the present CPU count.
07. Increment the iterator.
08. Store the iterator to the 'CPU selector' register.
09. Read the 'Command data' register.
10. If the value read is zero, then the iterator equals "max_cpus";
    exit now.
11. Goto 05.

Thanks
Laszlo

Reply via email to