2005-04-16 18:20:36 -04:00
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/smp.h>
|
|
|
|
|
|
|
|
#include <asm/smp.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
|
|
|
|
#include "cobalt.h"
|
|
|
|
#include "mach_apic.h"
|
|
|
|
|
|
|
|
/* Have we found an MP table */
|
|
|
|
int smp_found_config;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Various Linux-internal data structures created from the
|
|
|
|
* MP-table.
|
|
|
|
*/
|
|
|
|
int apic_version [MAX_APICS];
|
|
|
|
|
|
|
|
int pic_mode;
|
|
|
|
unsigned long mp_lapic_addr;
|
|
|
|
|
|
|
|
/* Processor that is doing the boot up */
|
|
|
|
unsigned int boot_cpu_physical_apicid = -1U;
|
|
|
|
|
|
|
|
/* Bitmask of physically existing CPUs */
|
|
|
|
physid_mask_t phys_cpu_present_map;
|
|
|
|
|
|
|
|
unsigned int __initdata maxcpus = NR_CPUS;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The Visual Workstation is Intel MP compliant in the hardware
|
|
|
|
* sense, but it doesn't have a BIOS(-configuration table).
|
|
|
|
* No problem for Linux.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void __init MP_processor_info (struct mpc_config_processor *m)
|
|
|
|
{
|
2008-01-30 07:30:35 -05:00
|
|
|
int ver, logical_apicid;
|
2005-04-16 18:20:36 -04:00
|
|
|
physid_mask_t apic_cpus;
|
2008-01-30 07:30:35 -05:00
|
|
|
|
2005-04-16 18:20:36 -04:00
|
|
|
if (!(m->mpc_cpuflag & CPU_ENABLED))
|
|
|
|
return;
|
|
|
|
|
|
|
|
logical_apicid = m->mpc_apicid;
|
2008-01-30 07:30:35 -05:00
|
|
|
printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n",
|
|
|
|
m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
|
|
|
|
m->mpc_apicid,
|
|
|
|
(m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
|
|
|
|
(m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
|
|
|
|
m->mpc_apicver);
|
2005-04-16 18:20:36 -04:00
|
|
|
|
2005-06-25 17:59:12 -04:00
|
|
|
if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
|
2005-04-16 18:20:36 -04:00
|
|
|
boot_cpu_physical_apicid = m->mpc_apicid;
|
|
|
|
|
|
|
|
ver = m->mpc_apicver;
|
|
|
|
if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
|
|
|
|
printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
|
|
|
|
m->mpc_apicid, MAX_APICS);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
|
|
|
|
physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
|
|
|
|
/*
|
|
|
|
* Validate version
|
|
|
|
*/
|
|
|
|
if (ver == 0x0) {
|
|
|
|
printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! "
|
|
|
|
"fixing up to 0x10. (tell your hw vendor)\n",
|
|
|
|
m->mpc_apicid);
|
|
|
|
ver = 0x10;
|
|
|
|
}
|
|
|
|
apic_version[m->mpc_apicid] = ver;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __init find_smp_config(void)
|
|
|
|
{
|
|
|
|
struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
|
|
|
|
unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
|
|
|
|
|
|
|
|
if (ncpus > CO_CPU_MAX) {
|
|
|
|
printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n",
|
|
|
|
ncpus, mp);
|
|
|
|
|
|
|
|
ncpus = CO_CPU_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ncpus > maxcpus)
|
|
|
|
ncpus = maxcpus;
|
|
|
|
|
|
|
|
smp_found_config = 1;
|
|
|
|
while (ncpus--)
|
|
|
|
MP_processor_info(mp++);
|
|
|
|
|
|
|
|
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __init get_smp_config (void)
|
|
|
|
{
|
|
|
|
}
|