2009-12-20 22:19:34 +03:00
/*
* Copyright ( C ) 2005 Intel Corporation
* Copyright ( C ) 2009 Hewlett - Packard Development Company , L . P .
*
* Alex Chiang < achiang @ hp . com >
* - Unified x86 / ia64 implementations
*/
2011-10-27 00:22:14 +04:00
# include <linux/export.h>
2013-12-03 04:49:16 +04:00
# include <linux/acpi.h>
2009-12-20 22:19:09 +03:00
# include <acpi/processor.h>
# define _COMPONENT ACPI_PROCESSOR_COMPONENT
2010-02-22 22:11:14 +03:00
ACPI_MODULE_NAME ( " processor_core " ) ;
2009-12-20 22:19:09 +03:00
2010-02-22 22:11:24 +03:00
static int map_lapic_id ( struct acpi_subtable_header * entry ,
u32 acpi_id , int * apic_id )
{
struct acpi_madt_local_apic * lapic =
2014-09-14 17:12:43 +04:00
container_of ( entry , struct acpi_madt_local_apic , header ) ;
2010-02-22 22:11:44 +03:00
if ( ! ( lapic - > lapic_flags & ACPI_MADT_ENABLED ) )
2014-01-17 08:37:02 +04:00
return - ENODEV ;
2010-02-22 22:11:44 +03:00
if ( lapic - > processor_id ! = acpi_id )
2014-01-17 08:37:02 +04:00
return - EINVAL ;
2010-02-22 22:11:44 +03:00
* apic_id = lapic - > id ;
2014-01-17 08:37:02 +04:00
return 0 ;
2010-02-22 22:11:24 +03:00
}
static int map_x2apic_id ( struct acpi_subtable_header * entry ,
int device_declaration , u32 acpi_id , int * apic_id )
{
struct acpi_madt_local_x2apic * apic =
2014-09-14 17:12:43 +04:00
container_of ( entry , struct acpi_madt_local_x2apic , header ) ;
2010-02-22 22:11:24 +03:00
if ( ! ( apic - > lapic_flags & ACPI_MADT_ENABLED ) )
2014-01-17 08:37:02 +04:00
return - ENODEV ;
2010-02-22 22:11:24 +03:00
2010-02-22 22:11:50 +03:00
if ( device_declaration & & ( apic - > uid = = acpi_id ) ) {
* apic_id = apic - > local_apic_id ;
2014-01-17 08:37:02 +04:00
return 0 ;
2010-02-22 22:11:24 +03:00
}
2014-01-17 08:37:02 +04:00
return - EINVAL ;
2010-02-22 22:11:24 +03:00
}
static int map_lsapic_id ( struct acpi_subtable_header * entry ,
int device_declaration , u32 acpi_id , int * apic_id )
{
struct acpi_madt_local_sapic * lsapic =
2014-09-14 17:12:43 +04:00
container_of ( entry , struct acpi_madt_local_sapic , header ) ;
2010-02-22 22:11:24 +03:00
if ( ! ( lsapic - > lapic_flags & ACPI_MADT_ENABLED ) )
2014-01-17 08:37:02 +04:00
return - ENODEV ;
2010-02-22 22:11:24 +03:00
if ( device_declaration ) {
2010-02-22 22:11:55 +03:00
if ( ( entry - > length < 16 ) | | ( lsapic - > uid ! = acpi_id ) )
2014-01-17 08:37:02 +04:00
return - EINVAL ;
2010-02-22 22:11:55 +03:00
} else if ( lsapic - > processor_id ! = acpi_id )
2014-01-17 08:37:02 +04:00
return - EINVAL ;
2010-02-22 22:11:24 +03:00
2010-02-22 22:11:55 +03:00
* apic_id = ( lsapic - > id < < 8 ) | lsapic - > eid ;
2014-01-17 08:37:02 +04:00
return 0 ;
2010-02-22 22:11:24 +03:00
}
static int map_madt_entry ( int type , u32 acpi_id )
{
unsigned long madt_end , entry ;
2010-02-22 22:12:00 +03:00
static struct acpi_table_madt * madt ;
static int read_madt ;
2010-02-22 22:11:24 +03:00
int apic_id = - 1 ;
2010-02-22 22:12:00 +03:00
if ( ! read_madt ) {
if ( ACPI_FAILURE ( acpi_get_table ( ACPI_SIG_MADT , 0 ,
( struct acpi_table_header * * ) & madt ) ) )
madt = NULL ;
read_madt + + ;
}
2010-02-22 22:11:24 +03:00
if ( ! madt )
return apic_id ;
entry = ( unsigned long ) madt ;
madt_end = entry + madt - > header . length ;
/* Parse all entries looking for a match. */
entry + = sizeof ( struct acpi_table_madt ) ;
while ( entry + sizeof ( struct acpi_subtable_header ) < madt_end ) {
struct acpi_subtable_header * header =
( struct acpi_subtable_header * ) entry ;
if ( header - > type = = ACPI_MADT_TYPE_LOCAL_APIC ) {
2014-01-17 08:37:02 +04:00
if ( ! map_lapic_id ( header , acpi_id , & apic_id ) )
2010-02-22 22:11:24 +03:00
break ;
} else if ( header - > type = = ACPI_MADT_TYPE_LOCAL_X2APIC ) {
2014-01-17 08:37:02 +04:00
if ( ! map_x2apic_id ( header , type , acpi_id , & apic_id ) )
2010-02-22 22:11:24 +03:00
break ;
} else if ( header - > type = = ACPI_MADT_TYPE_LOCAL_SAPIC ) {
2014-01-17 08:37:02 +04:00
if ( ! map_lsapic_id ( header , type , acpi_id , & apic_id ) )
2010-02-22 22:11:24 +03:00
break ;
}
entry + = header - > length ;
}
return apic_id ;
}
static int map_mat_entry ( acpi_handle handle , int type , u32 acpi_id )
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER , NULL } ;
union acpi_object * obj ;
struct acpi_subtable_header * header ;
int apic_id = - 1 ;
if ( ACPI_FAILURE ( acpi_evaluate_object ( handle , " _MAT " , NULL , & buffer ) ) )
goto exit ;
if ( ! buffer . length | | ! buffer . pointer )
goto exit ;
obj = buffer . pointer ;
if ( obj - > type ! = ACPI_TYPE_BUFFER | |
obj - > buffer . length < sizeof ( struct acpi_subtable_header ) ) {
goto exit ;
}
header = ( struct acpi_subtable_header * ) obj - > buffer . pointer ;
if ( header - > type = = ACPI_MADT_TYPE_LOCAL_APIC ) {
map_lapic_id ( header , acpi_id , & apic_id ) ;
} else if ( header - > type = = ACPI_MADT_TYPE_LOCAL_SAPIC ) {
map_lsapic_id ( header , type , acpi_id , & apic_id ) ;
2014-07-29 07:27:50 +04:00
} else if ( header - > type = = ACPI_MADT_TYPE_LOCAL_X2APIC ) {
map_x2apic_id ( header , type , acpi_id , & apic_id ) ;
2010-02-22 22:11:24 +03:00
}
exit :
2013-02-25 03:12:53 +04:00
kfree ( buffer . pointer ) ;
2010-02-22 22:11:24 +03:00
return apic_id ;
}
2013-09-02 07:57:34 +04:00
int acpi_get_apicid ( acpi_handle handle , int type , u32 acpi_id )
2010-02-22 22:11:24 +03:00
{
2013-09-02 07:57:34 +04:00
int apic_id ;
2010-02-22 22:11:24 +03:00
apic_id = map_mat_entry ( handle , type , acpi_id ) ;
if ( apic_id = = - 1 )
apic_id = map_madt_entry ( type , acpi_id ) ;
2013-09-02 07:57:34 +04:00
return apic_id ;
}
int acpi_map_cpuid ( int apic_id , u32 acpi_id )
{
# ifdef CONFIG_SMP
int i ;
# endif
ACPI: processor: fix acpi_get_cpuid for UP processor
For UP processor, it is likely that no _MAT method or MADT table defined.
So currently acpi_get_cpuid(...) always return -1 for UP processor.
This is wrong. It should return valid value for CPU0.
In the other hand, BIOS may define multiple CPU handles even for UP
processor, for example
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}
We should only return valid value for CPU0's acpi handle.
And return invalid value for others.
http://marc.info/?t=132329819900003&r=1&w=2
Cc: stable@vger.kernel.org
Reported-and-tested-by: wallak@free.fr
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-12-13 05:36:03 +04:00
if ( apic_id = = - 1 ) {
/*
* On UP processor , there is no _MAT or MADT table .
* So above apic_id is always set to - 1.
*
* BIOS may define multiple CPU handles even for UP processor .
* For example ,
*
* Scope ( _PR )
* {
* Processor ( CPU0 , 0x00 , 0x00000410 , 0x06 ) { }
* Processor ( CPU1 , 0x01 , 0x00000410 , 0x06 ) { }
* Processor ( CPU2 , 0x02 , 0x00000410 , 0x06 ) { }
* Processor ( CPU3 , 0x03 , 0x00000410 , 0x06 ) { }
* }
*
2012-07-12 14:24:33 +04:00
* Ignores apic_id and always returns 0 for the processor
* handle with acpi id 0 if nr_cpu_ids is 1.
* This should be the case if SMP tables are not found .
ACPI: processor: fix acpi_get_cpuid for UP processor
For UP processor, it is likely that no _MAT method or MADT table defined.
So currently acpi_get_cpuid(...) always return -1 for UP processor.
This is wrong. It should return valid value for CPU0.
In the other hand, BIOS may define multiple CPU handles even for UP
processor, for example
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}
We should only return valid value for CPU0's acpi handle.
And return invalid value for others.
http://marc.info/?t=132329819900003&r=1&w=2
Cc: stable@vger.kernel.org
Reported-and-tested-by: wallak@free.fr
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-12-13 05:36:03 +04:00
* Return - 1 for other CPU ' s handle .
*/
2012-07-12 14:24:33 +04:00
if ( nr_cpu_ids < = 1 & & acpi_id = = 0 )
ACPI: processor: fix acpi_get_cpuid for UP processor
For UP processor, it is likely that no _MAT method or MADT table defined.
So currently acpi_get_cpuid(...) always return -1 for UP processor.
This is wrong. It should return valid value for CPU0.
In the other hand, BIOS may define multiple CPU handles even for UP
processor, for example
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}
We should only return valid value for CPU0's acpi handle.
And return invalid value for others.
http://marc.info/?t=132329819900003&r=1&w=2
Cc: stable@vger.kernel.org
Reported-and-tested-by: wallak@free.fr
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-12-13 05:36:03 +04:00
return acpi_id ;
else
return apic_id ;
}
2010-02-22 22:11:24 +03:00
ACPI: processor: fix processor_physically_present in UP kernel
Usually, there are multiple processors defined in ACPI table, for
example
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}
processor_physically_present(...) will be called to check whether those
processors are physically present.
Currently we have below codes in processor_physically_present,
cpuid = acpi_get_cpuid(...);
if ((cpuid == -1) && (num_possible_cpus() > 1))
return false;
return true;
In UP kernel, acpi_get_cpuid(...) always return -1 and
num_possible_cpus() always return 1, so
processor_physically_present(...) always returns true for all passed in
processor handles.
This is wrong for UP processor or SMP processor running UP kernel.
This patch removes the !SMP version of acpi_get_cpuid(), so both UP and
SMP kernel use the same acpi_get_cpuid function.
And for UP kernel, only processor 0 is valid.
https://bugzilla.kernel.org/show_bug.cgi?id=16548
https://bugzilla.kernel.org/show_bug.cgi?id=16357
Tested-by: Anton Kochkov <anton.kochkov@gmail.com>
Tested-by: Ambroz Bizjak <ambrop7@gmail.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-05-16 05:11:00 +04:00
# ifdef CONFIG_SMP
2010-02-22 22:11:24 +03:00
for_each_possible_cpu ( i ) {
if ( cpu_physical_id ( i ) = = apic_id )
return i ;
}
ACPI: processor: fix processor_physically_present in UP kernel
Usually, there are multiple processors defined in ACPI table, for
example
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}
processor_physically_present(...) will be called to check whether those
processors are physically present.
Currently we have below codes in processor_physically_present,
cpuid = acpi_get_cpuid(...);
if ((cpuid == -1) && (num_possible_cpus() > 1))
return false;
return true;
In UP kernel, acpi_get_cpuid(...) always return -1 and
num_possible_cpus() always return 1, so
processor_physically_present(...) always returns true for all passed in
processor handles.
This is wrong for UP processor or SMP processor running UP kernel.
This patch removes the !SMP version of acpi_get_cpuid(), so both UP and
SMP kernel use the same acpi_get_cpuid function.
And for UP kernel, only processor 0 is valid.
https://bugzilla.kernel.org/show_bug.cgi?id=16548
https://bugzilla.kernel.org/show_bug.cgi?id=16357
Tested-by: Anton Kochkov <anton.kochkov@gmail.com>
Tested-by: Ambroz Bizjak <ambrop7@gmail.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-05-16 05:11:00 +04:00
# else
/* In UP kernel, only processor 0 is valid */
if ( apic_id = = 0 )
return apic_id ;
# endif
2010-02-22 22:11:24 +03:00
return - 1 ;
}
2013-09-02 07:57:34 +04:00
int acpi_get_cpuid ( acpi_handle handle , int type , u32 acpi_id )
{
int apic_id ;
apic_id = acpi_get_apicid ( handle , type , acpi_id ) ;
return acpi_map_cpuid ( apic_id , acpi_id ) ;
}
2010-02-22 22:11:24 +03:00
EXPORT_SYMBOL_GPL ( acpi_get_cpuid ) ;