From 09b4d1ee881c8593bfad2a42f838d85070365c3e Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 14 Dec 2005 15:05:00 -0500 Subject: P-state software coordination for acpi-cpufreq http://bugzilla.kernel.org/show_bug.cgi?id=5737 Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 285 +++++++++++++++++++--------- 1 file changed, 197 insertions(+), 88 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 3852d0a4c1b5..4c7c6e089e87 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -48,12 +48,13 @@ MODULE_LICENSE("GPL"); struct cpufreq_acpi_io { - struct acpi_processor_performance acpi_data; + struct acpi_processor_performance *acpi_data; struct cpufreq_frequency_table *freq_table; unsigned int resume; }; static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; +static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; static struct cpufreq_driver acpi_cpufreq_driver; @@ -104,64 +105,43 @@ acpi_processor_set_performance ( { u16 port = 0; u8 bit_width = 0; + int i = 0; int ret = 0; u32 value = 0; - int i = 0; - struct cpufreq_freqs cpufreq_freqs; - cpumask_t saved_mask; int retval; + struct acpi_processor_performance *perf; dprintk("acpi_processor_set_performance\n"); - /* - * TBD: Use something other than set_cpus_allowed. - * As set_cpus_allowed is a bit racy, - * with any other set_cpus_allowed for this process. - */ - saved_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (smp_processor_id() != cpu) { - return (-EAGAIN); - } - - if (state == data->acpi_data.state) { + retval = 0; + perf = data->acpi_data; + if (state == perf->state) { if (unlikely(data->resume)) { dprintk("Called after resume, resetting to P%d\n", state); data->resume = 0; } else { dprintk("Already at target state (P%d)\n", state); - retval = 0; - goto migrate_end; + return (retval); } } - dprintk("Transitioning from P%d to P%d\n", - data->acpi_data.state, state); - - /* cpufreq frequency struct */ - cpufreq_freqs.cpu = cpu; - cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency; - cpufreq_freqs.new = data->freq_table[state].frequency; - - /* notify cpufreq */ - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + dprintk("Transitioning from P%d to P%d\n", perf->state, state); /* * First we write the target state's 'control' value to the * control_register. */ - port = data->acpi_data.control_register.address; - bit_width = data->acpi_data.control_register.bit_width; - value = (u32) data->acpi_data.states[state].control; + port = perf->control_register.address; + bit_width = perf->control_register.bit_width; + value = (u32) perf->states[state].control; dprintk("Writing 0x%08x to port 0x%04x\n", value, port); ret = acpi_processor_write_port(port, bit_width, value); if (ret) { dprintk("Invalid port width 0x%04x\n", bit_width); - retval = ret; - goto migrate_end; + return (ret); } /* @@ -177,49 +157,36 @@ acpi_processor_set_performance ( * before giving up. */ - port = data->acpi_data.status_register.address; - bit_width = data->acpi_data.status_register.bit_width; + port = perf->status_register.address; + bit_width = perf->status_register.bit_width; dprintk("Looking for 0x%08x from port 0x%04x\n", - (u32) data->acpi_data.states[state].status, port); + (u32) perf->states[state].status, port); - for (i=0; i<100; i++) { + for (i = 0; i < 100; i++) { ret = acpi_processor_read_port(port, bit_width, &value); if (ret) { dprintk("Invalid port width 0x%04x\n", bit_width); - retval = ret; - goto migrate_end; + return (ret); } - if (value == (u32) data->acpi_data.states[state].status) + if (value == (u32) perf->states[state].status) break; udelay(10); } } else { i = 0; - value = (u32) data->acpi_data.states[state].status; + value = (u32) perf->states[state].status; } - /* notify cpufreq */ - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); - - if (unlikely(value != (u32) data->acpi_data.states[state].status)) { - unsigned int tmp = cpufreq_freqs.new; - cpufreq_freqs.new = cpufreq_freqs.old; - cpufreq_freqs.old = tmp; - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + if (unlikely(value != (u32) perf->states[state].status)) { printk(KERN_WARNING "acpi-cpufreq: Transition failed\n"); retval = -ENODEV; - goto migrate_end; + return (retval); } dprintk("Transition successful after %d microseconds\n", i * 10); - data->acpi_data.state = state; - - retval = 0; -migrate_end: - set_cpus_allowed(current, saved_mask); + perf->state = state; return (retval); } @@ -231,8 +198,17 @@ acpi_cpufreq_target ( unsigned int relation) { struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; + struct acpi_processor_performance *perf; + struct cpufreq_freqs freqs; + cpumask_t online_policy_cpus; + cpumask_t saved_mask; + cpumask_t set_mask; + cpumask_t covered_cpus; + unsigned int cur_state = 0; unsigned int next_state = 0; unsigned int result = 0; + unsigned int j; + unsigned int tmp; dprintk("acpi_cpufreq_setpolicy\n"); @@ -241,11 +217,91 @@ acpi_cpufreq_target ( target_freq, relation, &next_state); - if (result) + if (unlikely(result)) return (result); - result = acpi_processor_set_performance (data, policy->cpu, next_state); + perf = data->acpi_data; + cur_state = perf->state; + freqs.old = data->freq_table[cur_state].frequency; + freqs.new = data->freq_table[next_state].frequency; + + /* cpufreq holds the hotplug lock, so we are safe from here on */ + cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); + for_each_cpu_mask(j, online_policy_cpus) { + freqs.cpu = j; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + + /* + * We need to call driver->target() on all or any CPU in + * policy->cpus, depending on policy->shared_type. + */ + saved_mask = current->cpus_allowed; + cpus_clear(covered_cpus); + for_each_cpu_mask(j, online_policy_cpus) { + /* + * Support for SMP systems. + * Make sure we are running on CPU that wants to change freq + */ + cpus_clear(set_mask); + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + cpus_or(set_mask, set_mask, online_policy_cpus); + else + cpu_set(j, set_mask); + + set_cpus_allowed(current, set_mask); + if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { + dprintk("couldn't limit to CPUs in this domain\n"); + result = -EAGAIN; + break; + } + + result = acpi_processor_set_performance (data, j, next_state); + if (result) { + result = -EAGAIN; + break; + } + + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + break; + + cpu_set(j, covered_cpus); + } + + for_each_cpu_mask(j, online_policy_cpus) { + freqs.cpu = j; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + + if (unlikely(result)) { + /* + * We have failed halfway through the frequency change. + * We have sent callbacks to online_policy_cpus and + * acpi_processor_set_performance() has been called on + * coverd_cpus. Best effort undo.. + */ + + if (!cpus_empty(covered_cpus)) { + for_each_cpu_mask(j, covered_cpus) { + policy->cpu = j; + acpi_processor_set_performance (data, + j, + cur_state); + } + } + + tmp = freqs.new; + freqs.new = freqs.old; + freqs.old = tmp; + for_each_cpu_mask(j, online_policy_cpus) { + freqs.cpu = j; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + } + + set_cpus_allowed(current, saved_mask); return (result); } @@ -271,30 +327,65 @@ acpi_cpufreq_guess_freq ( struct cpufreq_acpi_io *data, unsigned int cpu) { + struct acpi_processor_performance *perf = data->acpi_data; + if (cpu_khz) { /* search the closest match to cpu_khz */ unsigned int i; unsigned long freq; - unsigned long freqn = data->acpi_data.states[0].core_frequency * 1000; + unsigned long freqn = perf->states[0].core_frequency * 1000; - for (i=0; i < (data->acpi_data.state_count - 1); i++) { + for (i = 0; i < (perf->state_count - 1); i++) { freq = freqn; - freqn = data->acpi_data.states[i+1].core_frequency * 1000; + freqn = perf->states[i+1].core_frequency * 1000; if ((2 * cpu_khz) > (freqn + freq)) { - data->acpi_data.state = i; + perf->state = i; return (freq); } } - data->acpi_data.state = data->acpi_data.state_count - 1; + perf->state = perf->state_count - 1; return (freqn); - } else + } else { /* assume CPU is at P0... */ - data->acpi_data.state = 0; - return data->acpi_data.states[0].core_frequency * 1000; - + perf->state = 0; + return perf->states[0].core_frequency * 1000; + } } +/* + * acpi_cpufreq_early_init - initialize ACPI P-States library + * + * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c) + * in order to determine correct frequency and voltage pairings. We can + * do _PDC and _PSD and find out the processor dependency for the + * actual init that will happen later... + */ +static int acpi_cpufreq_early_init_acpi(void) +{ + struct acpi_processor_performance *data; + unsigned int i, j; + + dprintk("acpi_cpufreq_early_init\n"); + + for_each_cpu(i) { + data = kzalloc(sizeof(struct acpi_processor_performance), + GFP_KERNEL); + if (!data) { + for_each_cpu(j) { + kfree(acpi_perf_data[j]); + acpi_perf_data[j] = NULL; + } + return (-ENOMEM); + } + acpi_perf_data[i] = data; + } + + /* Do initialization in ACPI core */ + acpi_processor_preregister_performance(acpi_perf_data); + return 0; +} + static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -304,41 +395,51 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; + struct acpi_processor_performance *perf; dprintk("acpi_cpufreq_cpu_init\n"); + if (!acpi_perf_data[cpu]) + return (-ENODEV); + data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) return (-ENOMEM); + data->acpi_data = acpi_perf_data[cpu]; acpi_io_data[cpu] = data; - result = acpi_processor_register_performance(&data->acpi_data, cpu); + result = acpi_processor_register_performance(data->acpi_data, cpu); if (result) goto err_free; + perf = data->acpi_data; + policy->cpus = perf->shared_cpu_map; + policy->shared_type = perf->shared_type; + if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; } /* capability check */ - if (data->acpi_data.state_count <= 1) { + if (perf->state_count <= 1) { dprintk("No P-States\n"); result = -ENODEV; goto err_unreg; } - if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || - (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { + + if ((perf->control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || + (perf->status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { dprintk("Unsupported address space [%d, %d]\n", - (u32) (data->acpi_data.control_register.space_id), - (u32) (data->acpi_data.status_register.space_id)); + (u32) (perf->control_register.space_id), + (u32) (perf->status_register.space_id)); result = -ENODEV; goto err_unreg; } /* alloc freq_table */ - data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL); + data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (perf->state_count + 1), GFP_KERNEL); if (!data->freq_table) { result = -ENOMEM; goto err_unreg; @@ -346,9 +447,9 @@ acpi_cpufreq_cpu_init ( /* detect transition latency */ policy->cpuinfo.transition_latency = 0; - for (i=0; iacpi_data.state_count; i++) { - if ((data->acpi_data.states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) - policy->cpuinfo.transition_latency = data->acpi_data.states[i].transition_latency * 1000; + for (i=0; istate_count; i++) { + if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) + policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; } policy->governor = CPUFREQ_DEFAULT_GOVERNOR; @@ -356,11 +457,11 @@ acpi_cpufreq_cpu_init ( policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); /* table init */ - for (i=0; i<=data->acpi_data.state_count; i++) + for (i=0; i<=perf->state_count; i++) { data->freq_table[i].index = i; - if (iacpi_data.state_count) - data->freq_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; + if (istate_count) + data->freq_table[i].frequency = perf->states[i].core_frequency * 1000; else data->freq_table[i].frequency = CPUFREQ_TABLE_END; } @@ -375,12 +476,12 @@ acpi_cpufreq_cpu_init ( printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n", cpu); - for (i = 0; i < data->acpi_data.state_count; i++) + for (i = 0; i < perf->state_count; i++) dprintk(" %cP%d: %d MHz, %d mW, %d uS\n", - (i == data->acpi_data.state?'*':' '), i, - (u32) data->acpi_data.states[i].core_frequency, - (u32) data->acpi_data.states[i].power, - (u32) data->acpi_data.states[i].transition_latency); + (i == perf->state?'*':' '), i, + (u32) perf->states[i].core_frequency, + (u32) perf->states[i].power, + (u32) perf->states[i].transition_latency); cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); @@ -395,7 +496,7 @@ acpi_cpufreq_cpu_init ( err_freqfree: kfree(data->freq_table); err_unreg: - acpi_processor_unregister_performance(&data->acpi_data, cpu); + acpi_processor_unregister_performance(perf, cpu); err_free: kfree(data); acpi_io_data[cpu] = NULL; @@ -416,7 +517,7 @@ acpi_cpufreq_cpu_exit ( if (data) { cpufreq_frequency_table_put_attr(policy->cpu); acpi_io_data[policy->cpu] = NULL; - acpi_processor_unregister_performance(&data->acpi_data, policy->cpu); + acpi_processor_unregister_performance(data->acpi_data, policy->cpu); kfree(data); } @@ -462,7 +563,10 @@ acpi_cpufreq_init (void) dprintk("acpi_cpufreq_init\n"); - result = cpufreq_register_driver(&acpi_cpufreq_driver); + result = acpi_cpufreq_early_init_acpi(); + + if (!result) + result = cpufreq_register_driver(&acpi_cpufreq_driver); return (result); } @@ -471,10 +575,15 @@ acpi_cpufreq_init (void) static void __exit acpi_cpufreq_exit (void) { + unsigned int i; dprintk("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); + for_each_cpu(i) { + kfree(acpi_perf_data[i]); + acpi_perf_data[i] = NULL; + } return; } -- cgit v1.2.3 From c52851b60cc0aaaf974ff0e49989fb698220447d Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 14 Dec 2005 15:05:00 -0500 Subject: P-state software coordination for speedstep-centrino http://bugzilla.kernel.org/show_bug.cgi?id=5737 Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 246 ++++++++++++++++------ 1 file changed, 180 insertions(+), 66 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index c173c0fa117a..37dee862f0d3 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -351,7 +351,36 @@ static unsigned int get_cur_freq(unsigned int cpu) #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI -static struct acpi_processor_performance p; +static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; + +/* + * centrino_cpu_early_init_acpi - Do the preregistering with ACPI P-States + * library + * + * Before doing the actual init, we need to do _PSD related setup whenever + * supported by the BIOS. These are handled by this early_init routine. + */ +static int centrino_cpu_early_init_acpi(void) +{ + unsigned int i, j; + struct acpi_processor_performance *data; + + for_each_cpu(i) { + data = kzalloc(sizeof(struct acpi_processor_performance), + GFP_KERNEL); + if (!data) { + for_each_cpu(j) { + kfree(acpi_perf_data[j]); + acpi_perf_data[j] = NULL; + } + return (-ENOMEM); + } + acpi_perf_data[i] = data; + } + + acpi_processor_preregister_performance(acpi_perf_data); + return 0; +} /* * centrino_cpu_init_acpi - register with ACPI P-States library @@ -365,46 +394,51 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) unsigned long cur_freq; int result = 0, i; unsigned int cpu = policy->cpu; + struct acpi_processor_performance *p; + + p = acpi_perf_data[cpu]; /* register with ACPI core */ - if (acpi_processor_register_performance(&p, cpu)) { + if (acpi_processor_register_performance(p, cpu)) { dprintk(KERN_INFO PFX "obtaining ACPI data failed\n"); return -EIO; } + policy->cpus = p->shared_cpu_map; + policy->shared_type = p->shared_type; /* verify the acpi_data */ - if (p.state_count <= 1) { + if (p->state_count <= 1) { dprintk("No P-States\n"); result = -ENODEV; goto err_unreg; } - if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || - (p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { + if ((p->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || + (p->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { dprintk("Invalid control/status registers (%x - %x)\n", - p.control_register.space_id, p.status_register.space_id); + p->control_register.space_id, p->status_register.space_id); result = -EIO; goto err_unreg; } - for (i=0; istate_count; i++) { + if (p->states[i].control != p->states[i].status) { dprintk("Different control (%llu) and status values (%llu)\n", - p.states[i].control, p.states[i].status); + p->states[i].control, p->states[i].status); result = -EINVAL; goto err_unreg; } - if (!p.states[i].core_frequency) { + if (!p->states[i].core_frequency) { dprintk("Zero core frequency for state %u\n", i); result = -EINVAL; goto err_unreg; } - if (p.states[i].core_frequency > p.states[0].core_frequency) { + if (p->states[i].core_frequency > p->states[0].core_frequency) { dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i, - p.states[i].core_frequency, p.states[0].core_frequency); - p.states[i].core_frequency = 0; + p->states[i].core_frequency, p->states[0].core_frequency); + p->states[i].core_frequency = 0; continue; } } @@ -416,26 +450,26 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) } centrino_model[cpu]->model_name=NULL; - centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; + centrino_model[cpu]->max_freq = p->states[0].core_frequency * 1000; centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) * - (p.state_count + 1), GFP_KERNEL); + (p->state_count + 1), GFP_KERNEL); if (!centrino_model[cpu]->op_points) { result = -ENOMEM; goto err_kfree; } - for (i=0; iop_points[i].index = p.states[i].control; - centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000; + for (i=0; istate_count; i++) { + centrino_model[cpu]->op_points[i].index = p->states[i].control; + centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000; dprintk("adding state %i with frequency %u and control value %04x\n", i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index); } - centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END; + centrino_model[cpu]->op_points[p->state_count].frequency = CPUFREQ_TABLE_END; cur_freq = get_cur_freq(cpu); - for (i=0; istate_count; i++) { + if (!p->states[i].core_frequency) { dprintk("skipping state %u\n", i); centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID; continue; @@ -451,7 +485,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) } if (cur_freq == centrino_model[cpu]->op_points[i].frequency) - p.state = i; + p->state = i; } /* notify BIOS that we exist */ @@ -464,12 +498,13 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) err_kfree: kfree(centrino_model[cpu]); err_unreg: - acpi_processor_unregister_performance(&p, cpu); + acpi_processor_unregister_performance(p, cpu); dprintk(KERN_INFO PFX "invalid ACPI data\n"); return (result); } #else static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; } +static inline int centrino_cpu_early_init_acpi(void) { return 0; } #endif static int centrino_cpu_init(struct cpufreq_policy *policy) @@ -557,10 +592,15 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI if (!centrino_model[cpu]->model_name) { - dprintk("unregistering and freeing ACPI data\n"); - acpi_processor_unregister_performance(&p, cpu); - kfree(centrino_model[cpu]->op_points); - kfree(centrino_model[cpu]); + static struct acpi_processor_performance *p; + + if (acpi_perf_data[cpu]) { + p = acpi_perf_data[cpu]; + dprintk("unregistering and freeing ACPI data\n"); + acpi_processor_unregister_performance(p, cpu); + kfree(centrino_model[cpu]->op_points); + kfree(centrino_model[cpu]); + } } #endif @@ -594,63 +634,124 @@ static int centrino_target (struct cpufreq_policy *policy, unsigned int relation) { unsigned int newstate = 0; - unsigned int msr, oldmsr, h, cpu = policy->cpu; + unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; struct cpufreq_freqs freqs; + cpumask_t online_policy_cpus; cpumask_t saved_mask; - int retval; + cpumask_t set_mask; + cpumask_t covered_cpus; + int retval = 0; + unsigned int j, k, first_cpu, tmp; - if (centrino_model[cpu] == NULL) + if (unlikely(centrino_model[cpu] == NULL)) return -ENODEV; - /* - * Support for SMP systems. - * Make sure we are running on the CPU that wants to change frequency - */ - saved_mask = current->cpus_allowed; - set_cpus_allowed(current, policy->cpus); - if (!cpu_isset(smp_processor_id(), policy->cpus)) { - dprintk("couldn't limit to CPUs in this domain\n"); - return(-EAGAIN); + if (unlikely(cpufreq_frequency_table_target(policy, + centrino_model[cpu]->op_points, + target_freq, + relation, + &newstate))) { + return -EINVAL; } - if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq, - relation, &newstate)) { - retval = -EINVAL; - goto migrate_end; - } + /* cpufreq holds the hotplug lock, so we are safe from here on */ + cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); - msr = centrino_model[cpu]->op_points[newstate].index; - rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); + saved_mask = current->cpus_allowed; + first_cpu = 1; + cpus_clear(covered_cpus); + for_each_cpu_mask(j, online_policy_cpus) { + /* + * Support for SMP systems. + * Make sure we are running on CPU that wants to change freq + */ + cpus_clear(set_mask); + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + cpus_or(set_mask, set_mask, online_policy_cpus); + else + cpu_set(j, set_mask); + + set_cpus_allowed(current, set_mask); + if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { + dprintk("couldn't limit to CPUs in this domain\n"); + retval = -EAGAIN; + if (first_cpu) { + /* We haven't started the transition yet. */ + goto migrate_end; + } + break; + } - if (msr == (oldmsr & 0xffff)) { - retval = 0; - dprintk("no change needed - msr was and needs to be %x\n", oldmsr); - goto migrate_end; - } + msr = centrino_model[cpu]->op_points[newstate].index; + + if (first_cpu) { + rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); + if (msr == (oldmsr & 0xffff)) { + dprintk("no change needed - msr was and needs " + "to be %x\n", oldmsr); + retval = 0; + goto migrate_end; + } + + freqs.old = extract_clock(oldmsr, cpu, 0); + freqs.new = extract_clock(msr, cpu, 0); + + dprintk("target=%dkHz old=%d new=%d msr=%04x\n", + target_freq, freqs.old, freqs.new, msr); + + for_each_cpu_mask(k, online_policy_cpus) { + freqs.cpu = k; + cpufreq_notify_transition(&freqs, + CPUFREQ_PRECHANGE); + } + + first_cpu = 0; + /* all but 16 LSB are reserved, treat them with care */ + oldmsr &= ~0xffff; + msr &= 0xffff; + oldmsr |= msr; + } - freqs.cpu = cpu; - freqs.old = extract_clock(oldmsr, cpu, 0); - freqs.new = extract_clock(msr, cpu, 0); + wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + break; - dprintk("target=%dkHz old=%d new=%d msr=%04x\n", - target_freq, freqs.old, freqs.new, msr); + cpu_set(j, covered_cpus); + } - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + for_each_cpu_mask(k, online_policy_cpus) { + freqs.cpu = k; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } - /* all but 16 LSB are "reserved", so treat them with - care */ - oldmsr &= ~0xffff; - msr &= 0xffff; - oldmsr |= msr; + if (unlikely(retval)) { + /* + * We have failed halfway through the frequency change. + * We have sent callbacks to policy->cpus and + * MSRs have already been written on coverd_cpus. + * Best effort undo.. + */ - wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); + if (!cpus_empty(covered_cpus)) { + for_each_cpu_mask(j, covered_cpus) { + set_cpus_allowed(current, cpumask_of_cpu(j)); + wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); + } + } - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + tmp = freqs.new; + freqs.new = freqs.old; + freqs.old = tmp; + for_each_cpu_mask(j, online_policy_cpus) { + freqs.cpu = j; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + } - retval = 0; migrate_end: set_cpus_allowed(current, saved_mask); - return (retval); + return 0; } static struct freq_attr* centrino_attr[] = { @@ -692,12 +793,25 @@ static int __init centrino_init(void) if (!cpu_has(cpu, X86_FEATURE_EST)) return -ENODEV; + centrino_cpu_early_init_acpi(); + return cpufreq_register_driver(¢rino_driver); } static void __exit centrino_exit(void) { +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI + unsigned int j; +#endif + cpufreq_unregister_driver(¢rino_driver); + +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI + for_each_cpu(j) { + kfree(acpi_perf_data[j]); + acpi_perf_data[j] = NULL; + } +#endif } MODULE_AUTHOR ("Jeremy Fitzhardinge "); -- cgit v1.2.3 From d52bb94d56676acd9bdac8e097257a87b4b1b2e1 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 14 Dec 2005 15:05:00 -0500 Subject: Enable P-state software coordination via _PDC http://bugzilla.kernel.org/show_bug.cgi?id=5737 Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- arch/i386/kernel/acpi/processor.c | 2 +- arch/x86_64/kernel/acpi/processor.c | 2 +- include/acpi/pdc_intel.h | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/processor.c b/arch/i386/kernel/acpi/processor.c index 9f4cc02717ec..b54fded49834 100644 --- a/arch/i386/kernel/acpi/processor.c +++ b/arch/i386/kernel/acpi/processor.c @@ -47,7 +47,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) buf[2] = ACPI_PDC_C_CAPABILITY_SMP; if (cpu_has(c, X86_FEATURE_EST)) - buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; + buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; diff --git a/arch/x86_64/kernel/acpi/processor.c b/arch/x86_64/kernel/acpi/processor.c index 3bdc2baa5bb1..81fcb3f869f2 100644 --- a/arch/x86_64/kernel/acpi/processor.c +++ b/arch/x86_64/kernel/acpi/processor.c @@ -44,7 +44,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; - buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; + buf[2] = ACPI_PDC_EST_CAPABILITY_SWSMP; obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h index 3fa81d55cd0c..c5472be6f3a2 100644 --- a/include/acpi/pdc_intel.h +++ b/include/acpi/pdc_intel.h @@ -18,6 +18,11 @@ ACPI_PDC_C_C1_HALT | \ ACPI_PDC_P_FFH) +#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_SMP_P_SWCOORD | \ + ACPI_PDC_P_FFH) + #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT) -- cgit v1.2.3 From 9cfda2c94df61c9f859b474abe774c65a4464d0a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 27 Mar 2006 02:24:32 -0500 Subject: [ACPI] fix "nolapic" flag in ACPI mode Signed-off-by: Len Brown --- arch/i386/kernel/acpi/boot.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 033066176b3e..d0980c79a5d2 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -215,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { struct acpi_table_madt *madt = NULL; - if (!phys_addr || !size) + if (!phys_addr || !size || !cpu_has_apic) return -EINVAL; madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); @@ -751,6 +751,9 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } + if (!cpu_has_apic) + return -ENODEV; + /* * if "noapic" boot option, don't look for IO-APICs */ -- cgit v1.2.3 From 7e1f19e50371e1d148226b64c8edc77fec47fa5b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 28 Mar 2006 17:03:00 -0500 Subject: ACPI: UP build fix for bugzilla-5737 cpu_online_map doesn't exist if !CONFIG_SMP. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 4 ++++ arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 4c7c6e089e87..11da3ca237e3 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -225,8 +225,12 @@ acpi_cpufreq_target ( freqs.old = data->freq_table[cur_state].frequency; freqs.new = data->freq_table[next_state].frequency; +#ifdef CONFIG_HOTPLUG_CPU /* cpufreq holds the hotplug lock, so we are safe from here on */ cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); +#else + online_policy_cpus = policy->cpus; +#endif for_each_cpu_mask(j, online_policy_cpus) { freqs.cpu = j; diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 37dee862f0d3..9a65993396ed 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -654,8 +654,12 @@ static int centrino_target (struct cpufreq_policy *policy, return -EINVAL; } +#ifdef CONFIG_HOTPLUG_CPU /* cpufreq holds the hotplug lock, so we are safe from here on */ cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); +#else + online_policy_cpus = policy->cpus; +#endif saved_mask = current->cpus_allowed; first_cpu = 1; -- cgit v1.2.3 From 2e3f8faaa73f5065ae653a84997b5cd4d5876e1a Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:25:14 -0400 Subject: [CPUFREQ] Typo in powernow-k8 (Also fix some horked indentation) Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 71fffa174425..88425bd55e12 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -20,7 +20,7 @@ * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD * Opteron Processors" available for download from www.amd.com * - * Tables for specific CPUs can be infrerred from + * Tables for specific CPUs can be inferred from * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf */ @@ -896,7 +896,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde for_each_cpu_mask(i, cpu_core_map[data->cpu]) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } + } return res; } -- cgit v1.2.3 From 8cbe0169053ffa185ad349088eb0901946c14a09 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:26:08 -0400 Subject: [CPUFREQ] Disambiguate loop indexes in powernow-k7 This shouldn't have actually caused any problems (as we return if we 'corrupt' 'i', but it's still not very pretty. For the sake of adding another local variable, this got cleaner. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 2bf4237cb94e..5d2b601425b8 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -452,23 +452,23 @@ static int powernow_decode_bios (int maxfid, int startvid) pst = (struct pst_s *) p; - for (i = 0 ; i numpst; i++) { + for (j=0; jnumpst; j++) { pst = (struct pst_s *) p; number_scales = pst->numpstates; if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) && (maxfid==pst->maxfid) && (startvid==pst->startvid)) { - dprintk ("PST:%d (@%p)\n", i, pst); + dprintk ("PST:%d (@%p)\n", j, pst); dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); ret = get_ranges ((char *) pst + sizeof (struct pst_s)); return ret; - } else { + unsigned int k; p = (char *) pst + sizeof (struct pst_s); - for (j=0 ; j < number_scales; j++) + for (k=0; k Date: Tue, 30 May 2006 17:37:15 -0400 Subject: [CPUFREQ] Clean up longhaul's speed pretty-printer Getting ready to move to core cpufreq. - Use snprintf - Remove unnecessary nesting improving readability. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 8ef38544453c..31600576b7ee 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -77,13 +77,17 @@ static char speedbuffer[8]; static char *print_speed(int speed) { - if (speed > 1000) { - if (speed%1000 == 0) - sprintf (speedbuffer, "%dGHz", speed/1000); - else - sprintf (speedbuffer, "%d.%dGHz", speed/1000, (speed%1000)/100); - } else - sprintf (speedbuffer, "%dMHz", speed); + if (speed < 1000) { + snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed); + return speedbuffer; + } + + if (speed%1000 == 0) + snprintf(speedbuffer, sizeof(speedbuffer), + "%dGHz", speed/1000); + else + snprintf(speedbuffer, sizeof(speedbuffer), + "%d.%dGHz", speed/1000, (speed%1000)/100); return speedbuffer; } -- cgit v1.2.3 From 8eebf1a4c3682f71dbda3348abfcdd4d2a751fd3 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:40:16 -0400 Subject: [CPUFREQ] Remove redundant initialisation from longhaul. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 31600576b7ee..146f607e9c44 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -679,7 +679,7 @@ static int __init longhaul_init(void) static void __exit longhaul_exit(void) { - int i=0; + int i; for (i=0; i < numscales; i++) { if (clock_ratio[i] == maxmult) { -- cgit v1.2.3 From 83844510ec9dc89a676e71d3cc28289905c2caec Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:43:54 -0400 Subject: [CPUFREQ] Remove pointless reinitialisation from powernow-k8 This var is already set at entry to the function. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 88425bd55e12..517de6cb0d0a 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -933,10 +933,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", pol->cpu, targfreq, pol->min, pol->max, relation); - if (query_current_values_with_pending_wait(data)) { - ret = -EIO; + if (query_current_values_with_pending_wait(data)) goto err_out; - } dprintk("targ: curr fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); -- cgit v1.2.3 From b6571da9f328999a6bce429b5f614a3d64b926ee Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:50:22 -0400 Subject: [CPUFREQ] Remove pointless reinitialisations in acpi-cpufreq Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 3852d0a4c1b5..030e741642f6 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -104,7 +104,7 @@ acpi_processor_set_performance ( { u16 port = 0; u8 bit_width = 0; - int ret = 0; + int ret; u32 value = 0; int i = 0; struct cpufreq_freqs cpufreq_freqs; @@ -195,7 +195,6 @@ acpi_processor_set_performance ( udelay(10); } } else { - i = 0; value = (u32) data->acpi_data.states[state].status; } -- cgit v1.2.3 From 851777b7b686c80e417fd811cdea3e5aa5305745 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 30 May 2006 17:55:01 -0400 Subject: [CPUFREQ] Remove duplicate assignment from cpufreq-nforce2 Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index f275e0d4aee5..b0e0006f47a4 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -117,8 +117,7 @@ static void nforce2_write_pll(int pll) int temp; /* Set the pll addr. to 0x00 */ - temp = 0x00; - pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp); + pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0); /* Now write the value in all 64 registers */ for (temp = 0; temp <= 0x3f; temp++) -- cgit v1.2.3 From 9a8fca0499c611ab37b5c0d4481ca09d3f6e8101 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 30 May 2006 20:32:15 -0700 Subject: Revert "[PATCH] i386/x86_64: Force pci=noacpi on HP XW9300" This reverts commit 5491d0f3e206beb95eeb506510d62a1dab462df1. As per Andi: "After some discussion with people who have the affected system it seems best to revert for 2.6.17. It broke a common BIOS workaround and PCI-X still doesn't work. Alternative is for people to change the BIOS which seems to be better right now." Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/boot.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index daee69579b1c..40e5aba3ad3d 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -1066,14 +1066,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), }, }, - { - .callback = disable_acpi_pci, - .ident = "HP xw9300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"), - }, - }, {} }; -- cgit v1.2.3 From 75de7d55f8e148848cadefc92140d8f083d13924 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 31 May 2006 16:13:14 -0400 Subject: [CPUFREQ] Remove strange No-op from longrun.c ORing something with zero is meaningless. ACKed-by: Dominik Brodowski Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longrun.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c index e3868de4dc2e..b2689514295a 100644 --- a/arch/i386/kernel/cpu/cpufreq/longrun.c +++ b/arch/i386/kernel/cpu/cpufreq/longrun.c @@ -223,7 +223,6 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, /* set to 0 to try_hi perf_pctg */ msr_lo &= 0xFFFFFF80; msr_hi &= 0xFFFFFF80; - msr_lo |= 0; msr_hi |= try_hi; wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); -- cgit v1.2.3 From 911cb74bb9e77e40749abc2fca6fe74d87d940f3 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 1 Jun 2006 11:38:28 -0400 Subject: [CPUFREQ] Make acpi-cpufreq 'sticky'. This prevents annoying messages being printed when it gets loaded on a machine that doesn't have support scaling via ACPI. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 030e741642f6..1a7bdcef1926 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -443,14 +443,15 @@ static struct freq_attr* acpi_cpufreq_attr[] = { }; static struct cpufreq_driver acpi_cpufreq_driver = { - .verify = acpi_cpufreq_verify, - .target = acpi_cpufreq_target, - .init = acpi_cpufreq_cpu_init, - .exit = acpi_cpufreq_cpu_exit, - .resume = acpi_cpufreq_resume, - .name = "acpi-cpufreq", - .owner = THIS_MODULE, - .attr = acpi_cpufreq_attr, + .verify = acpi_cpufreq_verify, + .target = acpi_cpufreq_target, + .init = acpi_cpufreq_cpu_init, + .exit = acpi_cpufreq_cpu_exit, + .resume = acpi_cpufreq_resume, + .name = "acpi-cpufreq", + .owner = THIS_MODULE, + .attr = acpi_cpufreq_attr, + .flags = CPUFREQ_STICKY, }; -- cgit v1.2.3 From 1f729e0660f974cec1f0f7f4fba03ea4c2c4b9a9 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sun, 4 Jun 2006 19:37:58 -0400 Subject: [CPUFREQ] Prepare powernow-k8 for future CPUs. Forthcoming AMD products will use a different algorithm for transitioning pstates than the current generation Opteron products do. The attached patch allows the powernow-k8 driver to work with those products. Signed-off-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 336 ++++++++++++++++++++++------- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 40 +++- 2 files changed, 290 insertions(+), 86 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 517de6cb0d0a..b4277f58f40c 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1,5 +1,5 @@ /* - * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. + * (c) 2003-2006 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -14,7 +14,7 @@ * Based upon datasheets & sample CPUs kindly provided by AMD. * * Valuable input gratefully received from Dave Jones, Pavel Machek, - * Dominik Brodowski, and others. + * Dominik Brodowski, Jacob Shin, and others. * Originally developed by Paul Devriendt. * Processor information obtained from Chapter 9 (Power and Thermal Management) * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD @@ -46,7 +46,7 @@ #define PFX "powernow-k8: " #define BFX PFX "BIOS error: " -#define VERSION "version 1.60.2" +#define VERSION "version 2.00.00" #include "powernow-k8.h" /* serialize freq changes */ @@ -54,6 +54,8 @@ static DEFINE_MUTEX(fidvid_mutex); static struct powernow_k8_data *powernow_data[NR_CPUS]; +static int cpu_family = CPU_OPTERON; + #ifndef CONFIG_SMP static cpumask_t cpu_core_map[1]; #endif @@ -64,16 +66,36 @@ static u32 find_freq_from_fid(u32 fid) return 800 + (fid * 100); } + /* Return a frequency in KHz, given an input fid */ static u32 find_khz_freq_from_fid(u32 fid) { return 1000 * find_freq_from_fid(fid); } -/* Return a voltage in miliVolts, given an input vid */ -static u32 find_millivolts_from_vid(struct powernow_k8_data *data, u32 vid) +/* Return a frequency in MHz, given an input fid and did */ +static u32 find_freq_from_fiddid(u32 fid, u32 did) +{ + return 100 * (fid + 0x10) >> did; +} + +static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) { - return 1550-vid*25; + return 1000 * find_freq_from_fiddid(fid, did); +} + +static u32 find_fid_from_pstate(u32 pstate) +{ + u32 hi, lo; + rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi); + return lo & HW_PSTATE_FID_MASK; +} + +static u32 find_did_from_pstate(u32 pstate) +{ + u32 hi, lo; + rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi); + return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; } /* Return the vco fid for an input fid @@ -98,6 +120,9 @@ static int pending_bit_stuck(void) { u32 lo, hi; + if (cpu_family) + return 0; + rdmsr(MSR_FIDVID_STATUS, lo, hi); return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0; } @@ -111,6 +136,14 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) u32 lo, hi; u32 i = 0; + if (cpu_family) { + rdmsr(MSR_PSTATE_STATUS, lo, hi); + i = lo & HW_PSTATE_MASK; + rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); + data->currfid = lo & HW_PSTATE_FID_MASK; + data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; + return 0; + } do { if (i++ > 10000) { dprintk("detected change pending stuck\n"); @@ -175,7 +208,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) do { wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); if (i++ > 100) { - printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); + printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n"); return 1; } } while (query_current_values_with_pending_wait(data)); @@ -255,7 +288,15 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, return 0; } -/* Change the fid and vid, by the 3 phases. */ +/* Change hardware pstate by single MSR write */ +static int transition_pstate(struct powernow_k8_data *data, u32 pstate) +{ + wrmsr(MSR_PSTATE_CTRL, pstate, 0); + data->currfid = find_fid_from_pstate(pstate); + return 0; +} + +/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid) { if (core_voltage_pre_transition(data, reqvid)) @@ -474,26 +515,35 @@ static int check_supported_cpu(unsigned int cpu) goto out; eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - if ((eax & CPUID_XFAM) != CPUID_XFAM_K8) + if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) && + ((eax & CPUID_XFAM) < CPUID_XFAM_10H)) goto out; - if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || - ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { - printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); - goto out; - } + if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { + if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || + ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { + printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); + goto out; + } - eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); - if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { - printk(KERN_INFO PFX - "No frequency change capabilities detected\n"); - goto out; - } + eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); + if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { + printk(KERN_INFO PFX + "No frequency change capabilities detected\n"); + goto out; + } - cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); - if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) { - printk(KERN_INFO PFX "Power state transitions not supported\n"); - goto out; + cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); + if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) { + printk(KERN_INFO PFX "Power state transitions not supported\n"); + goto out; + } + } else { /* must be a HW Pstate capable processor */ + cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); + if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE) + cpu_family = CPU_HW_PSTATE; + else + goto out; } rc = 1; @@ -547,12 +597,18 @@ static void print_basics(struct powernow_k8_data *data) { int j; for (j = 0; j < data->numps; j++) { - if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) - printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j, + if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { + if (cpu_family) { + printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, + (data->powernow_table[j].index & 0xff0000) >> 16, + data->powernow_table[j].frequency/1000); + } else { + printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", j, data->powernow_table[j].index & 0xff, data->powernow_table[j].frequency/1000, - data->powernow_table[j].index >> 8, - find_millivolts_from_vid(data, data->powernow_table[j].index >> 8)); + data->powernow_table[j].index >> 8); + } + } } if (data->batps) printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps); @@ -702,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data) #ifdef CONFIG_X86_POWERNOW_K8_ACPI static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { - if (!data->acpi_data.state_count) + if (!data->acpi_data.state_count || cpu_family) return; data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; @@ -715,9 +771,8 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { - int i; - int cntlofreq = 0; struct cpufreq_frequency_table *powernow_table; + int ret_val; if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { dprintk("register performance failed: bad ACPI data\n"); @@ -746,6 +801,85 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) goto err_out; } + if (cpu_family) + ret_val = fill_powernow_table_pstate(data, powernow_table); + else + ret_val = fill_powernow_table_fidvid(data, powernow_table); + if (ret_val) + goto err_out_mem; + + powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END; + powernow_table[data->acpi_data.state_count].index = 0; + data->powernow_table = powernow_table; + + /* fill in data */ + data->numps = data->acpi_data.state_count; + print_basics(data); + powernow_k8_acpi_pst_values(data, 0); + + /* notify BIOS that we exist */ + acpi_processor_notify_smm(THIS_MODULE); + + return 0; + +err_out_mem: + kfree(powernow_table); + +err_out: + acpi_processor_unregister_performance(&data->acpi_data, data->cpu); + + /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ + data->acpi_data.state_count = 0; + + return -ENODEV; +} + +static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) +{ + int i; + + for (i = 0; i < data->acpi_data.state_count; i++) { + u32 index; + u32 hi = 0, lo = 0; + u32 fid; + u32 did; + + index = data->acpi_data.states[i].control & HW_PSTATE_MASK; + if (index > MAX_HW_PSTATE) { + printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); + printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); + } + rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); + if (!(hi & HW_PSTATE_VALID_MASK)) { + dprintk("invalid pstate %d, ignoring\n", index); + powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; + continue; + } + + fid = lo & HW_PSTATE_FID_MASK; + did = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; + + dprintk(" %d : fid 0x%x, did 0x%x\n", index, fid, did); + + powernow_table[i].index = index | (fid << HW_FID_INDEX_SHIFT) | (did << HW_DID_INDEX_SHIFT); + + powernow_table[i].frequency = find_khz_freq_from_fiddid(fid, did); + + if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { + printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", + powernow_table[i].frequency, + (unsigned int) (data->acpi_data.states[i].core_frequency * 1000)); + powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; + continue; + } + } + return 0; +} + +static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) +{ + int i; + int cntlofreq = 0; for (i = 0; i < data->acpi_data.state_count; i++) { u32 fid; u32 vid; @@ -786,7 +920,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || (powernow_table[i].index != powernow_table[cntlofreq].index)) { printk(KERN_ERR PFX "Too many lo freq table entries\n"); - goto err_out_mem; + return 1; } dprintk("double low frequency table entry, ignoring it.\n"); @@ -804,31 +938,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) continue; } } - - powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END; - powernow_table[data->acpi_data.state_count].index = 0; - data->powernow_table = powernow_table; - - /* fill in data */ - data->numps = data->acpi_data.state_count; - print_basics(data); - powernow_k8_acpi_pst_values(data, 0); - - /* notify BIOS that we exist */ - acpi_processor_notify_smm(THIS_MODULE); - return 0; - -err_out_mem: - kfree(powernow_table); - -err_out: - acpi_processor_unregister_performance(&data->acpi_data, data->cpu); - - /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ - data->acpi_data.state_count = 0; - - return -ENODEV; } static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) @@ -844,20 +954,20 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ /* Take a frequency, and issue the fid/vid transition command */ -static int transition_frequency(struct powernow_k8_data *data, unsigned int index) +static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index) { - u32 fid; - u32 vid; + u32 fid = 0; + u32 vid = 0; int res, i; struct cpufreq_freqs freqs; dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); + /* fid/vid correctness check for k8 */ /* fid are the lower 8 bits of the index we stored into - * the cpufreq frequency table in find_psb_table, vid are - * the upper 8 bits. + * the cpufreq frequency table in find_psb_table, vid + * are the upper 8 bits. */ - fid = data->powernow_table[index].index & 0xFF; vid = (data->powernow_table[index].index & 0xFF00) >> 8; @@ -881,19 +991,55 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n", smp_processor_id(), fid, vid); - - freqs.cpu = data->cpu; freqs.old = find_khz_freq_from_fid(data->currfid); freqs.new = find_khz_freq_from_fid(fid); - for_each_cpu_mask(i, cpu_core_map[data->cpu]) { + + for_each_cpu_mask(i, *(data->available_cores)) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); } res = transition_fid_vid(data, fid, vid); - freqs.new = find_khz_freq_from_fid(data->currfid); - for_each_cpu_mask(i, cpu_core_map[data->cpu]) { + + for_each_cpu_mask(i, *(data->available_cores)) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + return res; +} + +/* Take a frequency, and issue the hardware pstate transition command */ +static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index) +{ + u32 fid = 0; + u32 did = 0; + u32 pstate = 0; + int res, i; + struct cpufreq_freqs freqs; + + dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); + + /* get fid did for hardware pstate transition */ + pstate = index & HW_PSTATE_MASK; + if (pstate > MAX_HW_PSTATE) + return 0; + fid = (index & HW_FID_INDEX_MASK) >> HW_FID_INDEX_SHIFT; + did = (index & HW_DID_INDEX_MASK) >> HW_DID_INDEX_SHIFT; + freqs.old = find_khz_freq_from_fiddid(data->currfid, data->currdid); + freqs.new = find_khz_freq_from_fiddid(fid, did); + + for_each_cpu_mask(i, *(data->available_cores)) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + + res = transition_pstate(data, pstate); + data->currfid = find_fid_from_pstate(pstate); + data->currdid = find_did_from_pstate(pstate); + freqs.new = find_khz_freq_from_fiddid(data->currfid, data->currdid); + + for_each_cpu_mask(i, *(data->available_cores)) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } @@ -936,13 +1082,18 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi if (query_current_values_with_pending_wait(data)) goto err_out; - dprintk("targ: curr fid 0x%x, vid 0x%x\n", + if (cpu_family) + dprintk("targ: curr fid 0x%x, did 0x%x\n", + data->currfid, data->currvid); + else { + dprintk("targ: curr fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); - if ((checkvid != data->currvid) || (checkfid != data->currfid)) { - printk(KERN_INFO PFX - "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", - checkfid, data->currfid, checkvid, data->currvid); + if ((checkvid != data->currvid) || (checkfid != data->currfid)) { + printk(KERN_INFO PFX + "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", + checkfid, data->currfid, checkvid, data->currvid); + } } if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) @@ -952,7 +1103,11 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi powernow_k8_acpi_pst_values(data, newstate); - if (transition_frequency(data, newstate)) { + if (cpu_family) + ret = transition_frequency_pstate(data, newstate); + else + ret = transition_frequency_fidvid(data, newstate); + if (ret) { printk(KERN_ERR PFX "transition frequency failed\n"); ret = 1; mutex_unlock(&fidvid_mutex); @@ -960,7 +1115,10 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi } mutex_unlock(&fidvid_mutex); - pol->cur = find_khz_freq_from_fid(data->currfid); + if (cpu_family) + pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); + else + pol->cur = find_khz_freq_from_fid(data->currfid); ret = 0; err_out: @@ -1005,14 +1163,13 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. */ - if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); kfree(data); return -ENODEV; } if (pol->cpu != 0) { - printk(KERN_ERR PFX "init not cpu 0\n"); + printk(KERN_ERR PFX "No _PSS objects for CPU other than CPU0\n"); kfree(data); return -ENODEV; } @@ -1040,20 +1197,28 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) if (query_current_values_with_pending_wait(data)) goto err_out; - fidvid_msr_init(); + if (!cpu_family) + fidvid_msr_init(); /* run on any CPU again */ set_cpus_allowed(current, oldmask); pol->governor = CPUFREQ_DEFAULT_GOVERNOR; - pol->cpus = cpu_core_map[pol->cpu]; + if (cpu_family) + pol->cpus = cpumask_of_cpu(pol->cpu); + else + pol->cpus = cpu_core_map[pol->cpu]; + data->available_cores = &(pol->cpus); /* Take a crude guess here. * That guess was in microseconds, so multiply with 1000 */ pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) + (3 * (1 << data->irt) * 10)) * 1000; - pol->cur = find_khz_freq_from_fid(data->currfid); + if (cpu_family) + pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); + else + pol->cur = find_khz_freq_from_fid(data->currfid); dprintk("policy current frequency %d kHz\n", pol->cur); /* min/max the cpu is capable of */ @@ -1067,8 +1232,12 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); - printk("cpu_init done, current fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); + if (cpu_family) + dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", + data->currfid, data->currdid); + else + dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", + data->currfid, data->currvid); powernow_data[pol->cpu] = data; @@ -1154,8 +1323,9 @@ static int __cpuinit powernowk8_init(void) } if (supported_cpus == num_online_cpus()) { - printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron " - "processors (" VERSION ")\n", supported_cpus); + printk(KERN_INFO PFX "Found %d %s " + "processors (" VERSION ")\n", supported_cpus, + boot_cpu_data.x86_model_id); return cpufreq_register_driver(&cpufreq_amd64_driver); } diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 79a7c5c87edc..bf8ad9e43da3 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -1,5 +1,5 @@ /* - * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. + * (c) 2003-2006 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -21,8 +21,8 @@ struct powernow_k8_data { u32 plllock; /* pll lock time, units 1 us */ u32 exttype; /* extended interface = 1 */ - /* keep track of the current fid / vid */ - u32 currvid, currfid; + /* keep track of the current fid / vid or did */ + u32 currvid, currfid, currdid; /* the powernow_table includes all frequency and vid/fid pairings: * fid are the lower 8 bits of the index, vid are the upper 8 bits. @@ -34,6 +34,10 @@ struct powernow_k8_data { * used to determine valid frequency/vid/fid states */ struct acpi_processor_performance acpi_data; #endif + /* we need to keep track of associated cores, but let cpufreq + * handle hotplug events - so just point at cpufreq pol->cpus + * structure */ + cpumask_t *available_cores; }; @@ -43,6 +47,7 @@ struct powernow_k8_data { #define CPUID_XFAM_K8 0 #define CPUID_XMOD 0x000f0000 /* extended model */ #define CPUID_XMOD_REV_G 0x00060000 +#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ #define CPUID_USE_XFAM_XMOD 0x00000f00 #define CPUID_GET_MAX_CAPABILITIES 0x80000000 #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 @@ -79,6 +84,32 @@ struct powernow_k8_data { #define MSR_S_HI_CURRENT_VID 0x0000003f #define MSR_C_HI_STP_GNT_BENIGN 0x00000001 + +/* Hardware Pstate _PSS and MSR definitions */ +#define USE_HW_PSTATE 0x00000080 +#define HW_PSTATE_FID_MASK 0x0000003f +#define HW_PSTATE_DID_MASK 0x000001c0 +#define HW_PSTATE_DID_SHIFT 6 +#define HW_PSTATE_MASK 0x00000007 +#define HW_PSTATE_VALID_MASK 0x80000000 +#define HW_FID_INDEX_SHIFT 8 +#define HW_FID_INDEX_MASK 0x0000ff00 +#define HW_DID_INDEX_SHIFT 16 +#define HW_DID_INDEX_MASK 0x00ff0000 +#define HW_WATTS_MASK 0xff +#define HW_PWR_DVR_MASK 0x300 +#define HW_PWR_DVR_SHIFT 8 +#define HW_PWR_MAX_MULT 3 +#define MAX_HW_PSTATE 8 /* hw pstate supports up to 8 */ +#define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */ +#define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */ +#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */ + +/* define the two driver architectures */ +#define CPU_OPTERON 0 +#define CPU_HW_PSTATE 1 + + /* * There are restrictions frequencies have to follow: * - only 1 entry in the low fid table ( <=1.4GHz ) @@ -182,6 +213,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); +static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); +static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); + #ifdef CONFIG_SMP static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) { -- cgit v1.2.3 From 0fc25dd17eaea64b21612f8e2816a4695b418100 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 26 Apr 2006 15:40:02 +0200 Subject: [CPUFREQ] dprintk adjustments to cpufreq-nforce2 Remove KERN_* suffixes from some NForce2 cpufreq driver's dprintk-s. Signed-off-by: Jan Beulich Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index b0e0006f47a4..cbfd23483d1f 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -265,7 +265,7 @@ static int nforce2_target(struct cpufreq_policy *policy, if (freqs.old == freqs.new) return 0; - dprintk(KERN_INFO "cpufreq: Old CPU frequency %d kHz, new %d kHz\n", + dprintk("Old CPU frequency %d kHz, new %d kHz\n", freqs.old, freqs.new); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); @@ -277,7 +277,7 @@ static int nforce2_target(struct cpufreq_policy *policy, printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n", target_fsb); else - dprintk(KERN_INFO "cpufreq: Changed FSB successfully to %d\n", + dprintk("Changed FSB successfully to %d\n", target_fsb); /* Enable IRQs */ -- cgit v1.2.3 From 8c362a5d62c98ee117b229c3555f402e72f5c21e Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 26 Apr 2006 15:41:22 +0200 Subject: [CPUFREQ] dprintk adjustments to cpufreq-speedstep-centrino Remove KERN_* suffixes from some Centrino cpufreq driver's dprintk-s. Signed-off-by: Jan Beulich Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index b0ff9075708c..ce54ff12c15d 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -250,7 +250,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy) if (model->cpu_id == NULL) { /* No match at all */ - dprintk(KERN_INFO PFX "no support for CPU model \"%s\": " + dprintk("no support for CPU model \"%s\": " "send /proc/cpuinfo to " MAINTAINER "\n", cpu->x86_model_id); return -ENOENT; @@ -258,10 +258,10 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy) if (model->op_points == NULL) { /* Matched a non-match */ - dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n", + dprintk("no table support for CPU model \"%s\"\n", cpu->x86_model_id); #ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n"); + dprintk("try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n"); #endif return -ENOENT; } @@ -368,7 +368,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) /* register with ACPI core */ if (acpi_processor_register_performance(&p, cpu)) { - dprintk(KERN_INFO PFX "obtaining ACPI data failed\n"); + dprintk("obtaining ACPI data failed\n"); return -EIO; } @@ -465,7 +465,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) kfree(centrino_model[cpu]); err_unreg: acpi_processor_unregister_performance(&p, cpu); - dprintk(KERN_INFO PFX "invalid ACPI data\n"); + dprintk("invalid ACPI data\n"); return (result); } #else @@ -499,7 +499,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) centrino_cpu[policy->cpu] = &cpu_ids[i]; if (!centrino_cpu[policy->cpu]) { - dprintk(KERN_INFO PFX "found unsupported CPU with " + dprintk("found unsupported CPU with " "Enhanced SpeedStep: send /proc/cpuinfo to " MAINTAINER "\n"); return -ENODEV; -- cgit v1.2.3 From 436fe7b8b4a5016ef1fcb32bff77bde84003e15d Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 5 Jun 2006 14:03:50 -0400 Subject: [CPUFREQ] Make powernow-k7 work on SMP kernels. Even though powernow-k7 doesn't work in SMP environments, it can work on an SMP configured kernel if there's only one CPU present, however recalibrate_cpu_khz was returning -EINVAL on such kernels, so we failed to init the cpufreq driver. Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 5d2b601425b8..694d4793bf6a 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -581,10 +581,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); - /* recalibrate cpu_khz */ - result = recalibrate_cpu_khz(); - if (result) - return result; + recalibrate_cpu_khz(); fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; if (!fsb) { -- cgit v1.2.3 From 6ccf58ab22499139bacc683493c9fd70af55adbb Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 5 Jun 2006 15:25:20 -0400 Subject: [CPUFREQ] sets nforce2 minimum PLL divider to 2. Sets minimum PLL divider to 2. No negative impact when tested with two nForce2 based boards. Alexander Choporov reported (06/01/06) that xdiv = 1 does not work on his Abit NF7S2. Although there shouldn't be much cases that lead to xdiv = 1. (Updates also the (C) year) Signed-off-by: Sebastian Witt Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index cbfd23483d1f..0d49d73d1b71 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -1,5 +1,5 @@ /* - * (C) 2004 Sebastian Witt + * (C) 2004-2006 Sebastian Witt * * Licensed under the terms of the GNU GPL License version 2. * Based upon reverse engineered information @@ -90,7 +90,7 @@ static int nforce2_calc_pll(unsigned int fsb) /* Try to calculate multiplier and divider up to 4 times */ while (((mul == 0) || (div == 0)) && (tried <= 3)) { - for (xdiv = 1; xdiv <= 0x80; xdiv++) + for (xdiv = 2; xdiv <= 0x80; xdiv++) for (xmul = 1; xmul <= 0xfe; xmul++) if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) == fsb + tried) { -- cgit v1.2.3 From d44647b0a6e48d18a1402dfa9052d85c4fe98341 Mon Sep 17 00:00:00 2001 From: Andy Currid Date: Thu, 8 Jun 2006 00:43:38 -0700 Subject: [PATCH] Fix HPET operation on 32-bit NVIDIA platforms From: "Andy Currid" This patch fixes a kernel panic during boot that occurs on NVIDIA platforms that have HPET enabled. When HPET is enabled, the standard timer IRQ is routed to IOAPIC pin 2 and is advertised as such in the ACPI APIC table - but an earlier workaround in the kernel was ignoring this override. The fix is to honor timer IRQ overrides from ACPI when HPET is detected on an NVIDIA platform. Signed-off-by: Andy Currid Cc: "Brown, Len" Cc: "Yu, Luming" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/earlyquirk.c | 23 ++++++++++++++++++++--- arch/i386/kernel/setup.c | 11 +++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 2e3b643a4dc4..1649a175a206 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -5,17 +5,34 @@ #include #include #include +#include + #include #include #include +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + static int __init check_bridge(int vendor, int device) { #ifdef CONFIG_ACPI - /* According to Nvidia all timer overrides are bogus. Just ignore - them all. */ + /* According to Nvidia all timer overrides are bogus unless HPET + is enabled. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { - acpi_skip_timer_override = 1; + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + } } #endif if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 846e1639ef7c..dd6b0e3386ce 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1547,15 +1547,18 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_map_memmap(); -#ifdef CONFIG_X86_IO_APIC - check_acpi_pci(); /* Checks more than just ACPI actually */ -#endif - #ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. */ acpi_boot_table_init(); +#endif + +#ifdef CONFIG_X86_IO_APIC + check_acpi_pci(); /* Checks more than just ACPI actually */ +#endif + +#ifdef CONFIG_ACPI acpi_boot_init(); #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) -- cgit v1.2.3 From 793c2388cae3fd023b3b5166354931752d42353c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 31 Mar 2006 00:00:00 -0500 Subject: ACPI: ACPICA 20060331 Implemented header file support for the following additional ACPI tables: ASF!, BOOT, CPEP, DBGP, MCFG, SPCR, SPMI, TCPA, and WDRT. With this support, all current and known ACPI tables are now defined in the ACPICA headers and are available for use by device drivers and other software. Implemented support to allow tables that contain ACPI names with invalid characters to be loaded. Previously, this would cause the table load to fail, but since there are several known cases of such tables on existing machines, this change was made to enable ACPI support for them. Also, this matches the behavior of the Microsoft ACPI implementation. https://bugzilla.novell.com/show_bug.cgi?id=147621 Fixed a couple regressions introduced during the memory optimization in the 20060317 release. The namespace node definition required additional reorganization and an internal datatype that had been changed to 8-bit was restored to 32-bit. (Valery Podrezov) Fixed a problem where a null pointer passed to acpi_ut_delete_generic_state() could be passed through to acpi_os_release_object which is unexpected. Such null pointers are now trapped and ignored, matching the behavior of the previous implementation before the deployment of acpi_os_release_object(). (Valery Podrezov, Fiodor Suietov) Fixed a memory mapping leak during the deletion of a SystemMemory operation region where a cached memory mapping was not deleted. This became a noticeable problem for operation regions that are defined within frequently used control methods. (Dana Meyers) Reorganized the ACPI table header files into two main files: one for the ACPI tables consumed by the ACPICA core, and another for the miscellaneous ACPI tables that are consumed by the drivers and other software. The various FADT definitions were merged into one common section and three different tables (ACPI 1.0, 1.0+, and 2.0) Signed-off-by: Bob Moore Signed-off-by: Len Brown --- arch/i386/kernel/acpi/boot.c | 4 +- drivers/acpi/bus.c | 2 +- drivers/acpi/dispatcher/dsmethod.c | 2 +- drivers/acpi/dispatcher/dswexec.c | 1 - drivers/acpi/events/evrgnini.c | 13 +- drivers/acpi/executer/exdump.c | 6 +- drivers/acpi/executer/exnames.c | 2 +- drivers/acpi/hardware/hwtimer.c | 4 +- drivers/acpi/namespace/nsalloc.c | 2 + drivers/acpi/namespace/nsdump.c | 3 + drivers/acpi/namespace/nssearch.c | 50 +-- drivers/acpi/parser/psloop.c | 12 + drivers/acpi/parser/psscope.c | 4 +- drivers/acpi/resources/rslist.c | 8 +- drivers/acpi/system.c | 2 +- drivers/acpi/tables.c | 4 +- drivers/acpi/tables/tbconvrt.c | 31 +- drivers/acpi/tables/tbrsdt.c | 3 +- drivers/acpi/tables/tbutils.c | 122 ++++--- drivers/acpi/tables/tbxfroot.c | 9 +- drivers/acpi/utilities/utdebug.c | 38 ++- drivers/acpi/utilities/utdelete.c | 16 +- drivers/acpi/utilities/utglobal.c | 2 +- drivers/acpi/utilities/utinit.c | 6 +- drivers/acpi/utilities/utmisc.c | 104 +++++- drivers/acpi/utilities/utresrc.c | 6 +- drivers/acpi/utilities/utstate.c | 10 +- include/acpi/acconfig.h | 2 +- include/acpi/acdisasm.h | 141 +++++++- include/acpi/acglobal.h | 7 +- include/acpi/aclocal.h | 14 +- include/acpi/acmacros.h | 7 +- include/acpi/acobject.h | 4 + include/acpi/acparser.h | 9 +- include/acpi/acpi_bus.h | 2 +- include/acpi/acpiosxf.h | 2 - include/acpi/acstruct.h | 2 +- include/acpi/actables.h | 6 +- include/acpi/actbl.h | 400 +++++++++++++---------- include/acpi/actbl1.h | 639 +++++++++++++++++++++++++++++++++---- include/acpi/actbl2.h | 230 +------------ include/acpi/acutils.h | 10 +- include/acpi/platform/acenv.h | 4 +- 43 files changed, 1314 insertions(+), 631 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 033066176b3e..a6fe91225202 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -621,9 +621,9 @@ extern u32 pmtmr_ioport; static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) { - struct fadt_descriptor_rev2 *fadt = NULL; + struct fadt_descriptor *fadt = NULL; - fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); + fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size); if (!fadt) { printk(KERN_WARNING PREFIX "Unable to map FADT\n"); return 0; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9c4ac0191f64..b3a214db56f6 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -43,7 +43,7 @@ ACPI_MODULE_NAME("acpi_bus") extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); #endif -FADT_DESCRIPTOR acpi_fadt; +struct fadt_descriptor acpi_fadt; EXPORT_SYMBOL(acpi_fadt); struct acpi_device *acpi_root; diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 238916ce5412..7dc59fc7344f 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -502,7 +502,7 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) * Delete any namespace entries created immediately underneath * the method */ - if (method_node->child) { + if (method_node && method_node->child) { acpi_ns_delete_namespace_subtree(method_node); } diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 198949f41048..8b740b370eb1 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -49,7 +49,6 @@ #include #include #include -#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswexec") diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index db98747fe54d..d1809f4240a4 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -75,7 +75,18 @@ acpi_ev_system_memory_region_setup(acpi_handle handle, if (function == ACPI_REGION_DEACTIVATE) { if (*region_context) { - ACPI_FREE(*region_context); + local_region_context = + (struct acpi_mem_space_context *)*region_context; + + /* Delete a cached mapping if present */ + + if (local_region_context->mapped_length) { + acpi_os_unmap_memory(local_region_context-> + mapped_logical_address, + local_region_context-> + mapped_length); + } + ACPI_FREE(local_region_context); *region_context = NULL; } return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 56db58b8e23a..1dfebf9e7074 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -61,6 +61,10 @@ static void acpi_ex_out_pointer(char *title, void *value); static void acpi_ex_out_address(char *title, acpi_physical_address value); +static void +acpi_ex_dump_object(union acpi_operand_object *obj_desc, + struct acpi_exdump_info *info); + static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc); static void @@ -263,7 +267,7 @@ static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} }; -static struct acpi_exdump_info acpi_ex_dump_node[6] = { +static struct acpi_exdump_info acpi_ex_dump_node[5] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"}, diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index 80bbc20756a1..085b18f8dd00 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c @@ -179,7 +179,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) for (index = 0; (index < ACPI_NAME_SIZE) - && (acpi_ut_valid_acpi_character(*aml_address)); index++) { + && (acpi_ut_valid_acpi_char(*aml_address, 0)); index++) { char_buf[index] = *aml_address++; ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index])); } diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index 9d53e46bc331..a559ac17b132 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c @@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) return_ACPI_STATUS(AE_BAD_PARAMETER); } - if (0 == acpi_gbl_FADT->tmr_val_ext) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { *resolution = 24; } else { *resolution = 32; @@ -153,7 +153,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; } else if (start_ticks > end_ticks) { - if (0 == acpi_gbl_FADT->tmr_val_ext) { + if (acpi_gbl_FADT->tmr_val_ext == 0) { /* 24-bit Timer */ diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 8b921c96d6a5..c92c03693a16 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -211,6 +211,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp acpi_ut_get_node_name(parent_node), acpi_ut_get_type_name(parent_node->type), parent_node)); + + return_VOID; } /******************************************************************************* diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index e275373b1705..5662d2def62f 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -204,6 +204,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { + this_node->name.integer = + acpi_ut_repair_name(this_node->name.integer); + ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); } diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index c929f45071c0..51adec5a23d6 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -128,9 +128,8 @@ acpi_ns_search_node(u32 target_name, next_node->object); } - /* - * Found matching entry. - */ + /* Found matching entry */ + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", ACPI_CAST_PTR(char, &target_name), @@ -248,10 +247,8 @@ acpi_ns_search_parent_tree(u32 target_name, return_ACPI_STATUS(status); } - /* - * Not found here, go up another level - * (until we reach the root) - */ + /* Not found here, go up another level (until we reach the root) */ + parent_node = acpi_ns_get_parent_node(parent_node); } @@ -307,12 +304,29 @@ acpi_ns_search_and_enter(u32 target_name, return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Name must consist of printable characters */ - + /* + * Name must consist of valid ACPI characters. We will repair the name if + * necessary because we don't want to abort because of this, but we want + * all namespace names to be printable. A warning message is appropriate. + * + * This issue came up because there are in fact machines that exhibit + * this problem, and we want to be able to enable ACPI support for them, + * even though there are a few bad names. + */ if (!acpi_ut_valid_acpi_name(target_name)) { - ACPI_ERROR((AE_INFO, "Bad character in ACPI Name: %X", - target_name)); - return_ACPI_STATUS(AE_BAD_CHARACTER); + target_name = acpi_ut_repair_name(target_name); + + /* Report warning only if in strict mode or debug mode */ + + if (!acpi_gbl_enable_interpreter_slack) { + ACPI_WARNING((AE_INFO, + "Found bad character(s) in name, repaired: [%4.4s]\n", + ACPI_CAST_PTR(char, &target_name))); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Found bad character(s) in name, repaired: [%4.4s]\n", + ACPI_CAST_PTR(char, &target_name))); + } } /* Try to find the name in the namespace level specified by the caller */ @@ -328,10 +342,8 @@ acpi_ns_search_and_enter(u32 target_name, status = AE_ALREADY_EXISTS; } - /* - * Either found it or there was an error - * -- finished either way - */ + /* Either found it or there was an error: finished either way */ + return_ACPI_STATUS(status); } @@ -357,9 +369,8 @@ acpi_ns_search_and_enter(u32 target_name, } } - /* - * In execute mode, just search, never add names. Exit now. - */ + /* In execute mode, just search, never add names. Exit now */ + if (interpreter_mode == ACPI_IMODE_EXECUTE) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", @@ -379,6 +390,5 @@ acpi_ns_search_and_enter(u32 target_name, acpi_ns_install_node(walk_state, node, new_node, type); *return_node = new_node; - return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index 14052cb648c1..3a29ce680370 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c @@ -747,7 +747,19 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } + + status2 = + acpi_ds_result_stack_pop + (walk_state); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } + + acpi_ut_delete_generic_state + (acpi_ut_pop_generic_state + (&walk_state->control_state)); } + acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 9233a4044d6b..424ab1c20da5 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c @@ -143,7 +143,7 @@ acpi_ps_init_scope(struct acpi_parse_state * parser_state, acpi_status acpi_ps_push_scope(struct acpi_parse_state *parser_state, union acpi_parse_object *op, - u32 remaining_args, u8 arg_count) + u32 remaining_args, u32 arg_count) { union acpi_generic_state *scope; @@ -196,7 +196,7 @@ acpi_ps_push_scope(struct acpi_parse_state *parser_state, void acpi_ps_pop_scope(struct acpi_parse_state *parser_state, - union acpi_parse_object **op, u32 * arg_list, u8 * arg_count) + union acpi_parse_object **op, u32 * arg_list, u32 * arg_count) { union acpi_generic_state *scope = parser_state->scope; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 50bbb19bf4ae..1b2d1e717e74 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -64,10 +64,11 @@ ACPI_MODULE_NAME("rslist") acpi_status acpi_rs_convert_aml_to_resources(u8 * aml, u32 length, - u32 offset, - u8 resource_index, void **resource_ptr) + u32 offset, u8 resource_index, void **context) { - struct acpi_resource *resource = *resource_ptr; + struct acpi_resource **resource_ptr = + ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context); + struct acpi_resource *resource; acpi_status status; ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); @@ -76,6 +77,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml, * Check that the input buffer and all subsequent pointers into it * are aligned on a native word boundary. Most important on IA64 */ + resource = *resource_ptr; if (ACPI_IS_MISALIGNED(resource)) { ACPI_WARNING((AE_INFO, "Misaligned resource pointer %p", resource)); diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index e4308c7a6743..1943bec18848 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -39,7 +39,7 @@ ACPI_MODULE_NAME("acpi_system") #define ACPI_SYSTEM_FILE_EVENT "event" #define ACPI_SYSTEM_FILE_DSDT "dsdt" #define ACPI_SYSTEM_FILE_FADT "fadt" -extern FADT_DESCRIPTOR acpi_fadt; +extern struct fadt_descriptor acpi_fadt; /* -------------------------------------------------------------------------- FS Interface (/proc) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 7f37c7cc5ef1..ed5e8816d83d 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -282,8 +282,8 @@ acpi_get_table_header_early(enum acpi_table_id id, /* Map the DSDT header via the pointer in the FADT */ if (id == ACPI_DSDT) { - struct fadt_descriptor_rev2 *fadt = - (struct fadt_descriptor_rev2 *)*header; + struct fadt_descriptor *fadt = + (struct fadt_descriptor *)*header; if (fadt->revision == 3 && fadt->Xdsdt) { *header = (void *)__acpi_map_table(fadt->Xdsdt, diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index 5155b27cf032..a913a927d321 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -54,12 +54,12 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, acpi_physical_address address); static void -acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt, +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, struct fadt_descriptor_rev1 *original_fadt); static void -acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt, - struct fadt_descriptor_rev2 *original_fadt); +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt); u8 acpi_fadt_is_v1; ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) @@ -120,7 +120,7 @@ acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) { acpi_size table_size; u32 i; - XSDT_DESCRIPTOR *new_table; + struct xsdt_descriptor *new_table; ACPI_FUNCTION_ENTRY(); @@ -151,12 +151,12 @@ acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], (ACPI_CAST_PTR - (struct rsdt_descriptor_rev1, + (struct rsdt_descriptor, table_info->pointer))-> table_offset_entry[i]); } else { new_table->table_offset_entry[i] = - (ACPI_CAST_PTR(XSDT_DESCRIPTOR, + (ACPI_CAST_PTR(struct xsdt_descriptor, table_info->pointer))-> table_offset_entry[i]; } @@ -218,7 +218,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, ******************************************************************************/ static void -acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt, +acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, struct fadt_descriptor_rev1 *original_fadt) { @@ -364,14 +364,13 @@ acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt, ******************************************************************************/ static void -acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt, - struct fadt_descriptor_rev2 *original_fadt) +acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, + struct fadt_descriptor *original_fadt) { /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ - ACPI_MEMCPY(local_fadt, original_fadt, - sizeof(struct fadt_descriptor_rev2)); + ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); /* * "X" fields are optional extensions to the original V1.0 fields, so @@ -490,7 +489,7 @@ acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt, acpi_status acpi_tb_convert_table_fadt(void) { - struct fadt_descriptor_rev2 *local_fadt; + struct fadt_descriptor *local_fadt; struct acpi_table_desc *table_desc; ACPI_FUNCTION_TRACE("tb_convert_table_fadt"); @@ -507,13 +506,13 @@ acpi_status acpi_tb_convert_table_fadt(void) /* Allocate buffer for the ACPI 2.0(+) FADT */ - local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor_rev2)); + local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); if (!local_fadt) { return_ACPI_STATUS(AE_NO_MEMORY); } if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { - if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev2)) { + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { /* Length is too short to be a V2.0 table */ @@ -538,7 +537,7 @@ acpi_status acpi_tb_convert_table_fadt(void) /* Global FADT pointer will point to the new common V2.0 FADT */ acpi_gbl_FADT = local_fadt; - acpi_gbl_FADT->length = sizeof(FADT_DESCRIPTOR); + acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); /* Free the original table */ @@ -550,7 +549,7 @@ acpi_status acpi_tb_convert_table_fadt(void) table_desc->pointer = ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); table_desc->allocation = ACPI_MEM_ALLOCATED; - table_desc->length = sizeof(struct fadt_descriptor_rev2); + table_desc->length = sizeof(struct fadt_descriptor); /* Dump the entire FADT */ diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 946d2f2d611d..9e0ebe625ed9 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c @@ -280,7 +280,8 @@ acpi_status acpi_tb_get_table_rsdt(void) return_ACPI_STATUS(status); } - acpi_gbl_XSDT = ACPI_CAST_PTR(XSDT_DESCRIPTOR, table_info.pointer); + acpi_gbl_XSDT = + ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); return_ACPI_STATUS(status); diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index b463d4b88823..f8d28ae8811d 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -193,73 +193,119 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) /******************************************************************************* * - * FUNCTION: acpi_tb_verify_table_checksum + * FUNCTION: acpi_tb_sum_table * - * PARAMETERS: *table_header - ACPI table to verify + * PARAMETERS: Buffer - Buffer to sum + * Length - Size of the buffer * - * RETURN: 8 bit checksum of table + * RETURN: 8 bit sum of buffer * - * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct - * table should have a checksum of 0. + * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. * ******************************************************************************/ -acpi_status -acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) +u8 acpi_tb_sum_table(void *buffer, u32 length) +{ + acpi_native_uint i; + u8 sum = 0; + + if (!buffer || !length) { + return (0); + } + + for (i = 0; i < length; i++) { + sum = (u8) (sum + ((u8 *) buffer)[i]); + } + return (sum); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_generate_checksum + * + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) + * + * RETURN: 8 bit checksum of buffer + * + * DESCRIPTION: Computes an 8 bit checksum of the table. + * + ******************************************************************************/ + +u8 acpi_tb_generate_checksum(struct acpi_table_header * table) { u8 checksum; - acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); + /* Sum the entire table as-is */ - /* Compute the checksum on the table */ + checksum = acpi_tb_sum_table(table, table->length); - checksum = - acpi_tb_generate_checksum(table_header, table_header->length); + /* Subtract off the existing checksum value in the table */ - /* Return the appropriate exception */ + checksum = (u8) (checksum - table->checksum); - if (checksum) { - ACPI_WARNING((AE_INFO, - "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)", - table_header->signature, - (u32) table_header->checksum, (u32) checksum)); + /* Compute the final checksum */ - status = AE_BAD_CHECKSUM; - } - return_ACPI_STATUS(status); + checksum = (u8) (0 - checksum); + return (checksum); } /******************************************************************************* * - * FUNCTION: acpi_tb_generate_checksum + * FUNCTION: acpi_tb_set_checksum * - * PARAMETERS: Buffer - Buffer to checksum - * Length - Size of the buffer + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) * - * RETURN: 8 bit checksum of buffer + * RETURN: None. Sets the table checksum field * - * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. + * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the + * checksum into the table header. * ******************************************************************************/ -u8 acpi_tb_generate_checksum(void *buffer, u32 length) +void acpi_tb_set_checksum(struct acpi_table_header *table) { - u8 *end_buffer; - u8 *rover; - u8 sum = 0; - if (buffer && length) { + table->checksum = acpi_tb_generate_checksum(table); +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_verify_table_checksum + * + * PARAMETERS: *table_header - ACPI table to verify + * + * RETURN: 8 bit checksum of table + * + * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares + * it to the existing checksum value. + * + ******************************************************************************/ + +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) +{ + u8 checksum; + + ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); + + /* Compute the checksum on the table */ - /* Buffer and Length are valid */ + checksum = acpi_tb_generate_checksum(table_header); - end_buffer = ACPI_ADD_PTR(u8, buffer, length); + /* Checksum ok? */ - for (rover = buffer; rover < end_buffer; rover++) { - sum = (u8) (sum + *rover); - } + if (checksum == table_header->checksum) { + return_ACPI_STATUS(AE_OK); } - return (sum); + + ACPI_WARNING((AE_INFO, + "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", + table_header->signature, table_header->checksum, + checksum)); + + return_ACPI_STATUS(AE_BAD_CHECKSUM); } #ifdef ACPI_OBSOLETE_FUNCTIONS @@ -278,7 +324,7 @@ u8 acpi_tb_generate_checksum(void *buffer, u32 length) acpi_status acpi_tb_handle_to_object(u16 table_id, - struct acpi_table_desc ** return_table_desc) + struct acpi_table_desc **return_table_desc) { u32 i; struct acpi_table_desc *table_desc; diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index 1b6d8c510e95..550284f5d1ed 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -81,15 +81,14 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) /* Check the standard checksum */ - if (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((rsdp->revision >= 2) && - (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != - 0)) { + (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { return (AE_BAD_CHECKSUM); } @@ -308,12 +307,12 @@ acpi_get_firmware_table(acpi_string signature, if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { address.pointer.value = (ACPI_CAST_PTR - (RSDT_DESCRIPTOR, + (struct rsdt_descriptor, rsdt_info->pointer))->table_offset_entry[i]; } else { address.pointer.value = (ACPI_CAST_PTR - (XSDT_DESCRIPTOR, + (struct xsdt_descriptor, rsdt_info->pointer))->table_offset_entry[i]; } diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index a8c350643d57..5ec1cfcc611d 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -517,20 +517,13 @@ acpi_ut_ptr_exit(u32 line_number, * ******************************************************************************/ -void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) +void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) { acpi_native_uint i = 0; acpi_native_uint j; u32 temp32; u8 buf_char; - /* Only dump the buffer if tracing is enabled */ - - if (!((ACPI_LV_TABLES & acpi_dbg_level) && - (component_id & acpi_dbg_layer))) { - return; - } - if ((count < 4) || (count & 0x01)) { display = DB_BYTE_DISPLAY; } @@ -556,6 +549,7 @@ void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) } switch (display) { + case DB_BYTE_DISPLAY: default: /* Default is BYTE display */ acpi_os_printf("%02X ", buffer[i + j]); @@ -613,3 +607,31 @@ void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) return; } + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_buffer + * + * PARAMETERS: Buffer - Buffer to dump + * Count - Amount to dump, in bytes + * Display - BYTE, WORD, DWORD, or QWORD display + * component_iD - Caller's component ID + * + * RETURN: None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii. + * + ******************************************************************************/ + +void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) +{ + + /* Only dump the buffer if tracing is enabled */ + + if (!((ACPI_LV_TABLES & acpi_dbg_level) && + (component_id & acpi_dbg_layer))) { + return; + } + + acpi_ut_dump_buffer2(buffer, count, display); +} diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 51356e8eb999..b4e34a2f81f7 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -202,8 +202,20 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) if (handler_desc) { if (handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { - obj_pointer = - second_desc->extra.region_context; + + /* Deactivate region and free region context */ + + if (handler_desc->address_space.setup) { + (void)handler_desc-> + address_space.setup(object, + ACPI_REGION_DEACTIVATE, + handler_desc-> + address_space. + context, + &second_desc-> + extra. + region_context); + } } acpi_ut_remove_reference(handler_desc); diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 8a05bb5ef4fe..e8ae417c9848 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -642,7 +642,7 @@ char *acpi_ut_get_node_name(void *object) /* Name must be a valid ACPI name */ if (!acpi_ut_valid_acpi_name(node->name.integer)) { - return ("????"); + node->name.integer = acpi_ut_repair_name(node->name.integer); } /* Return the name */ diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index 40313de6977d..7538b165b6e5 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utinit") /* Local prototypes */ static void -acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset); +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset); static void acpi_ut_terminate(void); @@ -69,12 +69,12 @@ static void acpi_ut_terminate(void); ******************************************************************************/ static void -acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset) +acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) { ACPI_WARNING((AE_INFO, "Invalid FADT value %s=%X at offset %X FADT=%p", - register_name, value, (u32) offset, acpi_gbl_FADT)); + register_name, value, offset, acpi_gbl_FADT)); } /****************************************************************************** diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 017a87ebc40b..4623d7e215d3 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -47,6 +47,33 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") +/******************************************************************************* + * + * FUNCTION: acpi_ut_is_aml_table + * + * PARAMETERS: Table - An ACPI table + * + * RETURN: TRUE if table contains executable AML; FALSE otherwise + * + * DESCRIPTION: Check ACPI Signature for a table that contains AML code. + * Currently, these are DSDT,SSDT,PSDT. All other table types are + * data tables that do not contain AML code. + * + ******************************************************************************/ +u8 acpi_ut_is_aml_table(struct acpi_table_header *table) +{ + + /* Ignore tables that contain AML */ + + if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || + ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { + return (TRUE); + } + + return (FALSE); +} + /******************************************************************************* * * FUNCTION: acpi_ut_allocate_owner_id @@ -60,6 +87,7 @@ ACPI_MODULE_NAME("utmisc") * when the method exits or the table is unloaded. * ******************************************************************************/ + acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { acpi_native_uint i; @@ -467,6 +495,41 @@ acpi_ut_display_init_pathname(u8 type, } #endif +/******************************************************************************* + * + * FUNCTION: acpi_ut_valid_acpi_char + * + * PARAMETERS: Char - The character to be examined + * + * RETURN: TRUE if the character is valid, FALSE otherwise + * + * DESCRIPTION: Check for a valid ACPI character. Must be one of: + * 1) Upper case alpha + * 2) numeric + * 3) underscore + * + * We allow a '!' as the last character because of the ASF! table + * + ******************************************************************************/ + +u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) +{ + + if (!((character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9') || (character == '_'))) { + + /* Allow a '!' in the last position */ + + if (character == '!' && position == 3) { + return (TRUE); + } + + return (FALSE); + } + + return (TRUE); +} + /******************************************************************************* * * FUNCTION: acpi_ut_valid_acpi_name @@ -484,19 +547,13 @@ acpi_ut_display_init_pathname(u8 type, u8 acpi_ut_valid_acpi_name(u32 name) { - char *name_ptr = (char *)&name; - char character; acpi_native_uint i; ACPI_FUNCTION_ENTRY(); for (i = 0; i < ACPI_NAME_SIZE; i++) { - character = *name_ptr; - name_ptr++; - - if (!((character == '_') || - (character >= 'A' && character <= 'Z') || - (character >= '0' && character <= '9'))) { + if (!acpi_ut_valid_acpi_char + ((ACPI_CAST_PTR(char, &name))[i], i)) { return (FALSE); } } @@ -506,24 +563,37 @@ u8 acpi_ut_valid_acpi_name(u32 name) /******************************************************************************* * - * FUNCTION: acpi_ut_valid_acpi_character + * FUNCTION: acpi_ut_repair_name * - * PARAMETERS: Character - The character to be examined + * PARAMETERS: Name - The ACPI name to be repaired * - * RETURN: 1 if Character may appear in a name, else 0 + * RETURN: Repaired version of the name * - * DESCRIPTION: Check for a printable character + * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and + * return the new name. * ******************************************************************************/ -u8 acpi_ut_valid_acpi_character(char character) +acpi_name acpi_ut_repair_name(acpi_name name) { + char *name_ptr = ACPI_CAST_PTR(char, &name); + char new_name[ACPI_NAME_SIZE]; + acpi_native_uint i; - ACPI_FUNCTION_ENTRY(); + for (i = 0; i < ACPI_NAME_SIZE; i++) { + new_name[i] = name_ptr[i]; + + /* + * Replace a bad character with something printable, yet technically + * still invalid. This prevents any collisions with existing "good" + * names in the namespace. + */ + if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { + new_name[i] = '*'; + } + } - return ((u8) ((character == '_') || - (character >= 'A' && character <= 'Z') || - (character >= '0' && character <= '9'))); + return (*ACPI_CAST_PTR(u32, new_name)); } /******************************************************************************* diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index 4c24e6d5400a..1e680794c6df 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -258,7 +258,7 @@ static const u8 acpi_gbl_resource_types[] = { acpi_status acpi_ut_walk_aml_resources(u8 * aml, acpi_size aml_length, - acpi_walk_aml_callback user_function, void *context) + acpi_walk_aml_callback user_function, void **context) { acpi_status status; u8 *end_aml; @@ -319,7 +319,7 @@ acpi_ut_walk_aml_resources(u8 * aml, /* Return the pointer to the end_tag if requested */ if (!user_function) { - *(void **)context = aml; + *context = aml; } /* Normal exit */ @@ -610,7 +610,7 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer, obj_desc->buffer.length, NULL, - end_tag); + (void **)end_tag); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index 637c5f964879..aec5034cd978 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c @@ -321,8 +321,8 @@ union acpi_generic_state *acpi_ut_create_control_state(void) * * RETURN: None * - * DESCRIPTION: Put a state object back into the global state cache. The object - * is not actually freed at this time. + * DESCRIPTION: Release a state object to the state cache. NULL state objects + * are ignored. * ******************************************************************************/ @@ -330,6 +330,10 @@ void acpi_ut_delete_generic_state(union acpi_generic_state *state) { ACPI_FUNCTION_TRACE("ut_delete_generic_state"); - (void)acpi_os_release_object(acpi_gbl_state_cache, state); + /* Ignore null state */ + + if (state) { + (void)acpi_os_release_object(acpi_gbl_state_cache, state); + } return_VOID; } diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index f3acfd9249fc..b6bba7db52d9 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20060317 +#define ACPI_CA_VERSION 0x20060331 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index f004461a7753..70b52ffa969e 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -59,14 +59,52 @@ struct acpi_external_list { extern struct acpi_external_list *acpi_gbl_external_list; -/* Strings used for decoding flags to ASL keywords */ +typedef const struct acpi_dmtable_info { + u8 opcode; + u8 offset; + char *name; -extern const char *acpi_gbl_word_decode[4]; -extern const char *acpi_gbl_irq_decode[2]; -extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES]; -extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES]; -extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES]; -extern const char *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS]; +} acpi_dmtable_info; + +/* + * Values for Opcode above. + * Note: 0-7 must not change, used as a flag shift value + */ +#define ACPI_DMT_FLAG0 0 +#define ACPI_DMT_FLAG1 1 +#define ACPI_DMT_FLAG2 2 +#define ACPI_DMT_FLAG3 3 +#define ACPI_DMT_FLAG4 4 +#define ACPI_DMT_FLAG5 5 +#define ACPI_DMT_FLAG6 6 +#define ACPI_DMT_FLAG7 7 +#define ACPI_DMT_FLAGS0 8 +#define ACPI_DMT_FLAGS2 9 +#define ACPI_DMT_UINT8 10 +#define ACPI_DMT_UINT16 11 +#define ACPI_DMT_UINT24 12 +#define ACPI_DMT_UINT32 13 +#define ACPI_DMT_UINT56 14 +#define ACPI_DMT_UINT64 15 +#define ACPI_DMT_STRING 16 +#define ACPI_DMT_NAME4 17 +#define ACPI_DMT_NAME6 18 +#define ACPI_DMT_NAME8 19 +#define ACPI_DMT_CHKSUM 20 +#define ACPI_DMT_SPACEID 21 +#define ACPI_DMT_GAS 22 +#define ACPI_DMT_MADT 23 +#define ACPI_DMT_SRAT 24 +#define ACPI_DMT_EXIT 25 + +typedef +void (*ACPI_TABLE_HANDLER) (struct acpi_table_header * table); + +struct acpi_dmtable_data { + char *signature; + struct acpi_dmtable_info *table_info; + ACPI_TABLE_HANDLER table_handler; +}; struct acpi_op_walk_info { u32 level; @@ -84,6 +122,95 @@ struct acpi_resource_tag { char *tag; }; +/* Strings used for decoding flags to ASL keywords */ + +extern const char *acpi_gbl_word_decode[4]; +extern const char *acpi_gbl_irq_decode[2]; +extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES]; +extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES]; +extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES]; +extern const char *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS]; + +extern struct acpi_dmtable_info acpi_dm_table_info_asf0[]; +extern struct acpi_dmtable_info acpi_dm_table_info_asf1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_asf2[]; +extern struct acpi_dmtable_info acpi_dm_table_info_asf3[]; +extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; +extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; +extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; +extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; +extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; +extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; +extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; +extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; +extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_fadt2[]; +extern struct acpi_dmtable_info acpi_dm_table_info_gas[]; +extern struct acpi_dmtable_info acpi_dm_table_info_header[]; +extern struct acpi_dmtable_info acpi_dm_table_info_hpet[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt0[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt2[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt3[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt4[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt5[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt6[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt7[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt8[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt_hdr[]; +extern struct acpi_dmtable_info acpi_dm_table_info_mcfg[]; +extern struct acpi_dmtable_info acpi_dm_table_info_mcfg0[]; +extern struct acpi_dmtable_info acpi_dm_table_info_rsdp1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_rsdp2[]; +extern struct acpi_dmtable_info acpi_dm_table_info_sbst[]; +extern struct acpi_dmtable_info acpi_dm_table_info_slit[]; +extern struct acpi_dmtable_info acpi_dm_table_info_spcr[]; +extern struct acpi_dmtable_info acpi_dm_table_info_spmi[]; +extern struct acpi_dmtable_info acpi_dm_table_info_srat[]; +extern struct acpi_dmtable_info acpi_dm_table_info_srat0[]; +extern struct acpi_dmtable_info acpi_dm_table_info_srat1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_tcpa[]; +extern struct acpi_dmtable_info acpi_dm_table_info_wdrt[]; + +/* + * dmtable + */ +void acpi_dm_dump_data_table(struct acpi_table_header *table); + +void +acpi_dm_dump_table(u32 table_length, + u32 table_offset, + void *table, + u32 sub_table_length, struct acpi_dmtable_info *info); + +void acpi_dm_line_header(u32 offset, u32 byte_length, char *name); + +void acpi_dm_line_header2(u32 offset, u32 byte_length, char *name, u32 value); + +/* + * dmtbdump + */ +void acpi_dm_dump_asf(struct acpi_table_header *table); + +void acpi_dm_dump_cpep(struct acpi_table_header *table); + +void acpi_dm_dump_fadt(struct acpi_table_header *table); + +void acpi_dm_dump_srat(struct acpi_table_header *table); + +void acpi_dm_dump_mcfg(struct acpi_table_header *table); + +void acpi_dm_dump_madt(struct acpi_table_header *table); + +u32 acpi_dm_dump_rsdp(struct acpi_table_header *table); + +void acpi_dm_dump_rsdt(struct acpi_table_header *table); + +void acpi_dm_dump_slit(struct acpi_table_header *table); + +void acpi_dm_dump_xsdt(struct acpi_table_header *table); + /* * dmwalk */ diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index f9eb5925511f..17c5b462676e 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -107,6 +107,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; * 3) Allow access to uninitialized locals/args (auto-init to integer 0) * 4) Allow ANY object type to be a source operand for the Store() operator * 5) Allow unresolved references (invalid target name) in package objects + * 6) Enable warning messages for behavior that is not ACPI spec compliant */ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); @@ -149,10 +150,10 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); ACPI_EXTERN u32 acpi_gbl_table_flags; ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP; -ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT; -ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; +ACPI_EXTERN struct xsdt_descriptor *acpi_gbl_XSDT; +ACPI_EXTERN struct fadt_descriptor *acpi_gbl_FADT; ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; -ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS; +ACPI_EXTERN struct facs_descriptor *acpi_gbl_FACS; ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; /* * Since there may be multiple SSDTs and PSDTs, a single pointer is not diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 5956431784d5..99785bae59b3 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -174,22 +174,28 @@ union acpi_name_union { * * The node is optimized for both 32-bit and 64-bit platforms: * 20 bytes for the 32-bit case, 32 bytes for the 64-bit case. + * + * Note: The descriptor_type and Type fields must appear in the identical + * position in both the struct acpi_namespace_node and union acpi_operand_object + * structures. */ struct acpi_namespace_node { union acpi_operand_object *object; /* Interpreter object */ u8 descriptor_type; /* Differentiate object descriptor types */ + u8 type; /* ACPI Type associated with this name */ u8 flags; /* Miscellaneous flags */ acpi_owner_id owner_id; /* Node creator */ - u8 type; /* ACPI Type associated with this name */ union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ struct acpi_namespace_node *child; /* First child */ struct acpi_namespace_node *peer; /* Peer. Parent if ANOBJ_END_OF_PEER_LIST set */ - /* Fields used by the ASL compiler and disassembler only: */ - + /* + * The following fields are used by the ASL compiler and disassembler only + */ #ifdef ACPI_LARGE_NAMESPACE_NODE union acpi_parse_object *op; u32 value; + u32 length; #endif }; @@ -470,7 +476,7 @@ struct acpi_scope_state { }; struct acpi_pscope_state { - ACPI_STATE_COMMON u8 arg_count; /* Number of fixed arguments */ + ACPI_STATE_COMMON u32 arg_count; /* Number of fixed arguments */ union acpi_parse_object *op; /* Current op being parsed */ u8 *arg_end; /* Current argument end */ u8 *pkg_end; /* Current package end */ diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index c495670aa11a..60ceed4c81bf 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -130,7 +130,6 @@ #define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) -#define ACPI_FADT_OFFSET(f) ACPI_OFFSET (FADT_DESCRIPTOR, f) #if ACPI_MACHINE_WIDTH == 16 #define ACPI_STORE_POINTER(d,s) ACPI_MOVE_32_TO_32(d,s) @@ -141,6 +140,12 @@ #define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) #endif +#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED +#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32,(a)) == *ACPI_CAST_PTR (u32,(b))) +#else +#define ACPI_COMPARE_NAME(a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char,(a)), ACPI_CAST_PTR (char,(b)), 4)) +#endif + /* * Macros for moving data around to/from buffers that are possibly unaligned. * If the hardware supports the transfer of unaligned data, just do the store. diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 28241aa15de9..d9442d346b9b 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -65,6 +65,10 @@ * * descriptor_type is used to differentiate between internal descriptors, and * must be in the same place across all descriptors + * + * Note: The descriptor_type and Type fields must appear in the identical + * position in both the struct acpi_namespace_node and union acpi_operand_object + * structures. */ #define ACPI_OBJECT_COMMON_HEADER \ union acpi_operand_object *next_object; /* Objects linked to parent NS node */\ diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h index 53ac4ce8753a..de14492a5985 100644 --- a/include/acpi/acparser.h +++ b/include/acpi/acparser.h @@ -46,9 +46,9 @@ #define OP_HAS_RETURN_VALUE 1 -/* variable # arguments */ +/* Variable number of arguments. This field must be 32 bits */ -#define ACPI_VAR_ARGS ACPI_UINT8_MAX +#define ACPI_VAR_ARGS ACPI_UINT32_MAX #define ACPI_PARSE_DELETE_TREE 0x0001 #define ACPI_PARSE_NO_TREE_DELETE 0x0000 @@ -146,12 +146,13 @@ u8 acpi_ps_has_completed_scope(struct acpi_parse_state *parser_state); void acpi_ps_pop_scope(struct acpi_parse_state *parser_state, - union acpi_parse_object **op, u32 * arg_list, u8 * arg_count); + union acpi_parse_object **op, + u32 * arg_list, u32 * arg_count); acpi_status acpi_ps_push_scope(struct acpi_parse_state *parser_state, union acpi_parse_object *op, - u32 remaining_args, u8 arg_count); + u32 remaining_args, u32 arg_count); void acpi_ps_cleanup_scope(struct acpi_parse_state *state); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 6dca3d542080..43f8c2a23a24 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -59,7 +59,7 @@ acpi_evaluate_reference(acpi_handle handle, #define ACPI_BUS_FILE_ROOT "acpi" extern struct proc_dir_entry *acpi_root_dir; -extern FADT_DESCRIPTOR acpi_fadt; +extern struct fadt_descriptor acpi_fadt; enum acpi_bus_removal_type { ACPI_BUS_REMOVAL_NORMAL = 0, diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 91c3cdff28bb..42307d948c1b 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -169,8 +169,6 @@ acpi_os_queue_for_execution(u32 priority, void acpi_os_wait_events_complete(void *context); -void acpi_os_wait_events_complete(void *context); - void acpi_os_sleep(acpi_integer milliseconds); void acpi_os_stall(u32 microseconds); diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index 04e8966a377d..b8a6d6110d57 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -86,7 +86,7 @@ struct acpi_walk_state { struct acpi_parse_state parser_state; /* Current state of parser */ u32 prev_arg_types; - u8 arg_count; /* push for fixed or var args */ + u32 arg_count; /* push for fixed or var args */ struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */ struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */ diff --git a/include/acpi/actables.h b/include/acpi/actables.h index 30a47542e1c8..4dbaf02fe526 100644 --- a/include/acpi/actables.h +++ b/include/acpi/actables.h @@ -136,7 +136,11 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc); acpi_status acpi_tb_verify_table_checksum(struct acpi_table_header *table_header); -u8 acpi_tb_generate_checksum(void *buffer, u32 length); +u8 acpi_tb_sum_table(void *buffer, u32 length); + +u8 acpi_tb_generate_checksum(struct acpi_table_header *table); + +void acpi_tb_set_checksum(struct acpi_table_header *table); acpi_status acpi_tb_validate_table_header(struct acpi_table_header *table_header); diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index ed53f842dad4..e1a40135f707 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Name: actbl.h - Table data structures defined in ACPI specification + * Name: actbl.h - Basic ACPI Table Definitions * *****************************************************************************/ @@ -45,66 +45,45 @@ #define __ACTBL_H__ /* - * Note about bitfields: The u8 type is used for bitfields in ACPI tables. - * This is the only type that is even remotely portable. Anything else is not - * portable, so do not use any other bitfield types. - */ - -/* - * Values for description table header signatures + * Values for description table header signatures. Useful because they make + * it more difficult to inadvertently type in the wrong signature. */ -#define RSDP_NAME "RSDP" -#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ -#define APIC_SIG "APIC" /* Multiple APIC Description Table */ #define DSDT_SIG "DSDT" /* Differentiated System Description Table */ #define FADT_SIG "FACP" /* Fixed ACPI Description Table */ #define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ #define PSDT_SIG "PSDT" /* Persistent System Description Table */ +#define RSDP_SIG "RSD PTR " /* Root System Description Pointer */ #define RSDT_SIG "RSDT" /* Root System Description Table */ #define XSDT_SIG "XSDT" /* Extended System Description Table */ #define SSDT_SIG "SSDT" /* Secondary System Description Table */ -#define SBST_SIG "SBST" /* Smart Battery Specification Table */ -#define SPIC_SIG "SPIC" /* IOSAPIC table */ -#define BOOT_SIG "BOOT" /* Boot table */ - -#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ +#define RSDP_NAME "RSDP" /* - * Common table types. The base code can remain - * constant if the underlying tables are changed + * All tables and structures must be byte-packed to match the ACPI + * specification, since the tables are provided by the system BIOS */ -#define RSDT_DESCRIPTOR struct rsdt_descriptor_rev2 -#define XSDT_DESCRIPTOR struct xsdt_descriptor_rev2 -#define FACS_DESCRIPTOR struct facs_descriptor_rev2 -#define FADT_DESCRIPTOR struct fadt_descriptor_rev2 - #pragma pack(1) /* - * ACPI Version-independent tables + * These are the ACPI tables that are directly consumed by the subsystem. + * + * The RSDP and FACS do not use the common ACPI table header. All other ACPI + * tables use the header. * - * NOTE: The tables that are specific to ACPI versions (1.0, 2.0, etc.) - * are in separate files. + * Note about bitfields: The u8 type is used for bitfields in ACPI tables. + * This is the only type that is even remotely portable. Anything else is not + * portable, so do not use any other bitfield types. */ -struct rsdp_descriptor { /* Root System Descriptor Pointer */ - char signature[8]; /* ACPI signature, contains "RSD PTR " */ - u8 checksum; /* ACPI 1.0 checksum */ - char oem_id[6]; /* OEM identification */ - u8 revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */ - u32 rsdt_physical_address; /* 32-bit physical address of the RSDT */ - u32 length; /* XSDT Length in bytes, including header */ - u64 xsdt_physical_address; /* 64-bit physical address of the XSDT */ - u8 extended_checksum; /* Checksum of entire table (ACPI 2.0) */ - char reserved[3]; /* Reserved, must be zero */ -}; -struct acpi_common_facs { /* Common FACS for internal use */ - u32 *global_lock; - u64 *firmware_waking_vector; - u8 vector_width; -}; +/******************************************************************************* + * + * ACPI Table Header. This common header is used by all tables except the + * RSDP and FACS. The define is used for direct inclusion of header into + * other ACPI tables + * + ******************************************************************************/ -#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ +#define ACPI_TABLE_HEADER_DEF \ char signature[4]; /* ASCII table signature */\ u32 length; /* Length of table in bytes, including this header */\ u8 revision; /* ACPI Specification minor version # */\ @@ -112,153 +91,238 @@ struct acpi_common_facs { /* Common FACS for internal use */ char oem_id[6]; /* ASCII OEM identification */\ char oem_table_id[8]; /* ASCII OEM table identification */\ u32 oem_revision; /* OEM revision number */\ - char asl_compiler_id [4]; /* ASCII ASL compiler vendor ID */\ + char asl_compiler_id[4]; /* ASCII ASL compiler vendor ID */\ u32 asl_compiler_revision; /* ASL compiler version */ -struct acpi_table_header { /* ACPI common table header */ +struct acpi_table_header { ACPI_TABLE_HEADER_DEF}; /* - * MADT values and structures + * GAS - Generic Address Structure (ACPI 2.0+) */ +struct acpi_generic_address { + u8 address_space_id; /* Address space where struct or register exists */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ + u8 access_width; /* Minimum Access size (ACPI 3.0) */ + u64 address; /* 64-bit address of struct or register */ +}; -/* Values for MADT PCATCompat */ +/******************************************************************************* + * + * RSDP - Root System Description Pointer (Signature is "RSD PTR ") + * + ******************************************************************************/ + +struct rsdp_descriptor { + char signature[8]; /* ACPI signature, contains "RSD PTR " */ + u8 checksum; /* ACPI 1.0 checksum */ + char oem_id[6]; /* OEM identification */ + u8 revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */ + u32 rsdt_physical_address; /* 32-bit physical address of the RSDT */ + u32 length; /* Table length in bytes, including header (ACPI 2.0+) */ + u64 xsdt_physical_address; /* 64-bit physical address of the XSDT (ACPI 2.0+) */ + u8 extended_checksum; /* Checksum of entire table (ACPI 2.0+) */ + u8 reserved[3]; /* Reserved, must be zero */ +}; -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 +#define ACPI_RSDP_REV0_SIZE 20 /* Size of original ACPI 1.0 RSDP */ -/* Master MADT */ +/******************************************************************************* + * + * RSDT/XSDT - Root System Description Tables + * + ******************************************************************************/ -struct multiple_apic_table { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 local_apic_address; /* Physical address of local APIC */ +struct rsdt_descriptor { + ACPI_TABLE_HEADER_DEF u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +}; + +struct xsdt_descriptor { + ACPI_TABLE_HEADER_DEF u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ +}; + +/******************************************************************************* + * + * FACS - Firmware ACPI Control Structure (FACS) + * + ******************************************************************************/ + +struct facs_descriptor { + char signature[4]; /* ASCII table signature */ + u32 length; /* Length of structure, in bytes */ + u32 hardware_signature; /* Hardware configuration signature */ + u32 firmware_waking_vector; /* 32-bit physical address of the Firmware Waking Vector */ + u32 global_lock; /* Global Lock for shared hardware resources */ /* Flags (32 bits) */ - u8 PCATcompat:1; /* 00: System also has dual 8259s */ + u8 S4bios_f:1; /* 00: S4BIOS support is present */ u8:7; /* 01-07: Reserved, must be zero */ u8 reserved1[3]; /* 08-31: Reserved, must be zero */ -}; -/* Values for Type in APIC_HEADER_DEF */ + u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ + u8 version; /* Version of this table (ACPI 2.0+) */ + u8 reserved[31]; /* Reserved, must be zero */ +}; -#define APIC_PROCESSOR 0 -#define APIC_IO 1 -#define APIC_XRUPT_OVERRIDE 2 -#define APIC_NMI 3 -#define APIC_LOCAL_NMI 4 -#define APIC_ADDRESS_OVERRIDE 5 -#define APIC_IO_SAPIC 6 -#define APIC_LOCAL_SAPIC 7 -#define APIC_XRUPT_SOURCE 8 -#define APIC_RESERVED 9 /* 9 and greater are reserved */ +#define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ +#define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ /* - * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) + * Common FACS - This is a version-independent FACS structure used for internal use only */ -#define APIC_HEADER_DEF /* Common APIC sub-structure header */\ - u8 type; \ - u8 length; - -struct apic_header { -APIC_HEADER_DEF}; - -/* Values for MPS INTI flags */ - -#define POLARITY_CONFORMS 0 -#define POLARITY_ACTIVE_HIGH 1 -#define POLARITY_RESERVED 2 -#define POLARITY_ACTIVE_LOW 3 - -#define TRIGGER_CONFORMS 0 -#define TRIGGER_EDGE 1 -#define TRIGGER_RESERVED 2 -#define TRIGGER_LEVEL 3 - -/* Common flag definitions (16 bits each) */ - -#define MPS_INTI_FLAGS \ - u8 polarity : 2; /* 00-01: Polarity of APIC I/O input signals */\ - u8 trigger_mode : 2; /* 02-03: Trigger mode of APIC input signals */\ - u8 : 4; /* 04-07: Reserved, must be zero */\ - u8 reserved1; /* 08-15: Reserved, must be zero */ - -#define LOCAL_APIC_FLAGS \ - u8 processor_enabled: 1; /* 00: Processor is usable if set */\ - u8 : 7; /* 01-07: Reserved, must be zero */\ - u8 reserved2; /* 08-15: Reserved, must be zero */ - -/* Sub-structures for MADT */ - -struct madt_processor_apic { - APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ - u8 local_apic_id; /* Processor's local APIC id */ - LOCAL_APIC_FLAGS}; - -struct madt_io_apic { - APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */ - u8 reserved; /* Reserved - must be zero */ - u32 address; /* APIC physical address */ - u32 interrupt; /* Global system interrupt where INTI - * lines start */ +struct acpi_common_facs { + u32 *global_lock; + u64 *firmware_waking_vector; + u8 vector_width; }; -struct madt_interrupt_override { - APIC_HEADER_DEF u8 bus; /* 0 - ISA */ - u8 source; /* Interrupt source (IRQ) */ - u32 interrupt; /* Global system interrupt */ - MPS_INTI_FLAGS}; +/******************************************************************************* + * + * FADT - Fixed ACPI Description Table (Signature "FACP") + * + ******************************************************************************/ + +/* Fields common to all versions of the FADT */ + +#define ACPI_FADT_COMMON \ + ACPI_TABLE_HEADER_DEF \ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ \ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ \ + u16 sci_int; /* System vector of SCI interrupt */ \ + u32 smi_cmd; /* Port address of SMI command port */ \ + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \ + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \ + u8 pstate_cnt; /* Processor performance state control*/ \ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Event Reg Blk */ \ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Event Reg Blk */ \ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \ + u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \ + u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ \ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ \ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ \ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \ + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ \ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ \ + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \ + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \ + u16 flush_size; /* Processor's memory cache line width, in bytes */ \ + u16 flush_stride; /* Number of flush strides that need to be read */ \ + u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ \ + u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ \ + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \ + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \ + u8 century; /* Index to century in RTC CMOS RAM */ \ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ \ + u8 reserved2; /* Reserved, must be zero */ -struct madt_nmi_source { - APIC_HEADER_DEF MPS_INTI_FLAGS u32 interrupt; /* Global system interrupt */ +/* + * ACPI 2.0+ FADT + */ +struct fadt_descriptor { + ACPI_FADT_COMMON + /* Flags (32 bits) */ + u8 wb_invd:1; /* 00: The wbinvd instruction works properly */ + u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */ + u8 proc_c1:1; /* 02: All processors support C1 state */ + u8 plvl2_up:1; /* 03: C2 state works on MP system */ + u8 pwr_button:1; /* 04: Power button is handled as a generic feature */ + u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */ + u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */ + u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */ + u8 tmr_val_ext:1; /* 08: tmr_val is 32 bits 0=24-bits */ + u8 dock_cap:1; /* 09: Docking supported */ + u8 reset_reg_sup:1; /* 10: System reset via the FADT RESET_REG supported */ + u8 sealed_case:1; /* 11: No internal expansion capabilities and case is sealed */ + u8 headless:1; /* 12: No local video capabilities or local input devices */ + u8 cpu_sw_sleep:1; /* 13: Must execute native instruction after writing SLP_TYPx register */ + + u8 pci_exp_wak:1; /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ + u8 use_platform_clock:1; /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ + u8 S4rtc_sts_valid:1; /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ + u8 remote_power_on_capable:1; /* 17: System is compatible with remote power on (ACPI 3.0) */ + u8 force_apic_cluster_model:1; /* 18: All local APICs must use cluster model (ACPI 3.0) */ + u8 force_apic_physical_destination_mode:1; /* 19: all local x_aPICs must use physical dest mode (ACPI 3.0) */ + u8:4; /* 20-23: Reserved, must be zero */ + u8 reserved3; /* 24-31: Reserved, must be zero */ + + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the reset_register port to reset the system */ + u8 reserved4[3]; /* These three bytes must be zero */ + u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ + u64 Xdsdt; /* 64-bit physical address of DSDT */ + struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ + struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ + struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ + struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ }; -struct madt_local_apic_nmi { - APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ - MPS_INTI_FLAGS u8 lint; /* LINTn to which NMI is connected */ +/* + * "Down-revved" ACPI 2.0 FADT descriptor + * Defined here to allow compiler to generate the length of the struct + */ +struct fadt_descriptor_rev2_minus { + ACPI_FADT_COMMON u32 flags; + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the reset_register port to reset the system. */ + u8 reserved7[3]; /* Reserved, must be zero */ }; -struct madt_address_override { - APIC_HEADER_DEF u16 reserved; /* Reserved, must be zero */ - u64 address; /* APIC physical address */ +/* + * ACPI 1.0 FADT + * Defined here to allow compiler to generate the length of the struct + */ +struct fadt_descriptor_rev1 { + ACPI_FADT_COMMON u32 flags; }; -struct madt_io_sapic { - APIC_HEADER_DEF u8 io_sapic_id; /* I/O SAPIC ID */ - u8 reserved; /* Reserved, must be zero */ - u32 interrupt_base; /* Glocal interrupt for SAPIC start */ - u64 address; /* SAPIC physical address */ -}; +/* FADT: Prefered Power Management Profiles */ -struct madt_local_sapic { - APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ - u8 local_sapic_id; /* SAPIC ID */ - u8 local_sapic_eid; /* SAPIC EID */ - u8 reserved[3]; /* Reserved, must be zero */ - LOCAL_APIC_FLAGS u32 processor_uID; /* Numeric UID - ACPI 3.0 */ - char processor_uIDstring[1]; /* String UID - ACPI 3.0 */ -}; +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 -struct madt_interrupt_source { - APIC_HEADER_DEF MPS_INTI_FLAGS u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */ - u8 processor_id; /* Processor ID */ - u8 processor_eid; /* Processor EID */ - u8 io_sapic_vector; /* Vector value for PMI interrupts */ - u32 interrupt; /* Global system interrupt */ - u32 flags; /* Interrupt Source Flags */ -}; +/* FADT: Boot Arch Flags */ -/* - * Smart Battery - */ -struct smart_battery_table { - ACPI_TABLE_HEADER_DEF u32 warning_level; - u32 low_level; - u32 critical_level; -}; +#define BAF_LEGACY_DEVICES 0x0001 +#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 + +#define FADT2_REVISION_ID 3 +#define FADT2_MINUS_REVISION_ID 2 + +/* Reset to default packing */ #pragma pack() +/* + * This macro is temporary until the table bitfield flag definitions + * are removed and replaced by a Flags field. + */ +#define ACPI_FLAG_OFFSET(d,f,o) (u8) (ACPI_OFFSET (d,f) + \ + sizeof(((d *)0)->f) + o) +/* + * Get the remaining ACPI tables + */ +#include "actbl1.h" + /* * ACPI Table information. We save the table address, length, * and type of memory allocation (mapped or allocated) for each @@ -290,27 +354,17 @@ struct acpi_table_support { u8 flags; }; -/* - * Get the ACPI version-specific tables - */ -#include "actbl1.h" /* Acpi 1.0 table definitions */ -#include "actbl2.h" /* Acpi 2.0 table definitions */ - extern u8 acpi_fadt_is_v1; /* is set to 1 if FADT is revision 1, * needed for certain workarounds */ +/* Macros used to generate offsets to specific table fields */ -#pragma pack(1) -/* - * High performance timer - */ -struct hpet_table { - ACPI_TABLE_HEADER_DEF u32 hardware_id; - struct acpi_generic_address base_address; - u8 hpet_number; - u16 clock_tick; - u8 attributes; -}; +#define ACPI_FACS_OFFSET(f) (u8) ACPI_OFFSET (struct facs_descriptor,f) +#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct fadt_descriptor, f) +#define ACPI_GAS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_generic_address,f) +#define ACPI_HDR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_header,f) +#define ACPI_RSDP_OFFSET(f) (u8) ACPI_OFFSET (struct rsdp_descriptor,f) -#pragma pack() +#define ACPI_FADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct fadt_descriptor,f,o) +#define ACPI_FACS_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct facs_descriptor,f,o) #endif /* __ACTBL_H__ */ diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index cd428d57add0..745a6445a4f9 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Name: actbl1.h - ACPI 1.0 tables + * Name: actbl1.h - Additional ACPI table definitions * *****************************************************************************/ @@ -44,92 +44,599 @@ #ifndef __ACTBL1_H__ #define __ACTBL1_H__ +/******************************************************************************* + * + * Additional ACPI Tables + * + * These tables are not consumed directly by the ACPICA subsystem, but are + * included here to support device drivers and the AML disassembler. + * + ******************************************************************************/ + +/* + * Values for description table header signatures. Useful because they make + * it more difficult to inadvertently type in the wrong signature. + */ +#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ +#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ +#define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ +#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ +#define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ +#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ +#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ +#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ +#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ +#define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ +#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ +#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ +#define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ +#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ +#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ + +/* Legacy names */ + +#define APIC_SIG "APIC" /* Multiple APIC Description Table */ +#define BOOT_SIG "BOOT" /* Simple Boot Flag Table */ +#define SBST_SIG "SBST" /* Smart Battery Specification Table */ + +/* + * All tables must be byte-packed to match the ACPI specification, since + * the tables are provided by the system BIOS. + */ #pragma pack(1) /* - * ACPI 1.0 Root System Description Table (RSDT) + * Note about bitfields: The u8 type is used for bitfields in ACPI tables. + * This is the only type that is even remotely portable. Anything else is not + * portable, so do not use any other bitfield types. */ -struct rsdt_descriptor_rev1 { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ -}; + +/******************************************************************************* + * + * ASF - Alert Standard Format table (Signature "ASF!") + * + ******************************************************************************/ + +struct acpi_table_asf { +ACPI_TABLE_HEADER_DEF}; + +#define ACPI_ASF_HEADER_DEF \ + u8 type; \ + u8 reserved; \ + u16 length; + +struct acpi_asf_header { +ACPI_ASF_HEADER_DEF}; + +/* Values for Type field */ + +#define ASF_INFO 0 +#define ASF_ALERT 1 +#define ASF_CONTROL 2 +#define ASF_BOOT 3 +#define ASF_ADDRESS 4 +#define ASF_RESERVED 5 /* - * ACPI 1.0 Firmware ACPI Control Structure (FACS) + * ASF subtables */ -struct facs_descriptor_rev1 { - char signature[4]; /* ASCII table signature */ - u32 length; /* Length of structure in bytes */ - u32 hardware_signature; /* Hardware configuration signature */ - u32 firmware_waking_vector; /* ACPI OS waking vector */ - u32 global_lock; /* Global Lock */ + +/* 0: ASF Information */ + +struct acpi_asf_info { + ACPI_ASF_HEADER_DEF u8 min_reset_value; + u8 min_poll_interval; + u16 system_id; + u32 mfg_id; + u8 flags; + u8 reserved2[3]; +}; + +/* 1: ASF Alerts */ + +struct acpi_asf_alert { + ACPI_ASF_HEADER_DEF u8 assert_mask; + u8 deassert_mask; + u8 alerts; + u8 data_length; + u8 array[1]; +}; + +/* 2: ASF Remote Control */ + +struct acpi_asf_remote { + ACPI_ASF_HEADER_DEF u8 controls; + u8 data_length; + u16 reserved2; + u8 array[1]; +}; + +/* 3: ASF RMCP Boot Options */ + +struct acpi_asf_rmcp { + ACPI_ASF_HEADER_DEF u8 capabilities[7]; + u8 completion_code; + u32 enterprise_id; + u8 command; + u16 parameter; + u16 boot_options; + u16 oem_parameters; +}; + +/* 4: ASF Address */ + +struct acpi_asf_address { + ACPI_ASF_HEADER_DEF u8 eprom_address; + u8 devices; + u8 smbus_addresses[1]; +}; + +/******************************************************************************* + * + * BOOT - Simple Boot Flag Table + * + ******************************************************************************/ + +struct acpi_table_boot { + ACPI_TABLE_HEADER_DEF u8 cmos_index; /* Index in CMOS RAM for the boot register */ + u8 reserved[3]; +}; + +/******************************************************************************* + * + * CPEP - Corrected Platform Error Polling table + * + ******************************************************************************/ + +struct acpi_table_cpep { + ACPI_TABLE_HEADER_DEF u64 reserved; +}; + +/* Subtable */ + +struct acpi_cpep_polling { + u8 type; + u8 length; + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ + u32 polling_interval; /* Polling interval (msec) */ +}; + +/******************************************************************************* + * + * DBGP - Debug Port table + * + ******************************************************************************/ + +struct acpi_table_dbgp { + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ + u8 reserved[3]; + struct acpi_generic_address debug_port; +}; + +/******************************************************************************* + * + * ECDT - Embedded Controller Boot Resources Table + * + ******************************************************************************/ + +struct ec_boot_resources { + ACPI_TABLE_HEADER_DEF struct acpi_generic_address ec_control; /* Address of EC command/status register */ + struct acpi_generic_address ec_data; /* Address of EC data register */ + u32 uid; /* Unique ID - must be same as the EC _UID method */ + u8 gpe_bit; /* The GPE for the EC */ + u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */ +}; + +/******************************************************************************* + * + * HPET - High Precision Event Timer table + * + ******************************************************************************/ + +struct acpi_hpet_table { + ACPI_TABLE_HEADER_DEF u32 hardware_id; /* Hardware ID of event timer block */ + struct acpi_generic_address base_address; /* Address of event timer block */ + u8 hpet_number; /* HPET sequence number */ + u16 clock_tick; /* Main counter min tick, periodic mode */ + u8 attributes; +}; + +#if 0 /* HPET flags to be converted to macros */ +struct { /* Flags (8 bits) */ + u8 page_protect:1; /* 00: No page protection */ + u8 page_protect4:1; /* 01: 4_kB page protected */ + u8 page_protect64:1; /* 02: 64_kB page protected */ + u8:5; /* 03-07: Reserved, must be zero */ +} flags; +#endif + +/******************************************************************************* + * + * MADT - Multiple APIC Description Table + * + ******************************************************************************/ + +struct multiple_apic_table { + ACPI_TABLE_HEADER_DEF u32 local_apic_address; /* Physical address of local APIC */ /* Flags (32 bits) */ - u8 S4bios_f:1; /* 00: S4BIOS support is present */ + u8 PCATcompat:1; /* 00: System also has dual 8259s */ u8:7; /* 01-07: Reserved, must be zero */ u8 reserved1[3]; /* 08-31: Reserved, must be zero */ - - u8 reserved2[40]; /* Reserved, must be zero */ }; +/* Values for MADT PCATCompat */ + +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 + +/* Common MADT Sub-table header */ + +#define APIC_HEADER_DEF \ + u8 type; \ + u8 length; + +struct apic_header { +APIC_HEADER_DEF}; + +/* Values for Type in struct apic_header */ + +#define APIC_PROCESSOR 0 +#define APIC_IO 1 +#define APIC_XRUPT_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_NMI 4 +#define APIC_ADDRESS_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_XRUPT_SOURCE 8 +#define APIC_RESERVED 9 /* 9 and greater are reserved */ + +/* Flag definitions for MADT sub-tables */ + +#define ACPI_MADT_IFLAGS /* INTI flags (16 bits) */ \ + u8 polarity : 2; /* 00-01: Polarity of APIC I/O input signals */\ + u8 trigger_mode : 2; /* 02-03: Trigger mode of APIC input signals */\ + u8 : 4; /* 04-07: Reserved, must be zero */\ + u8 reserved1; /* 08-15: Reserved, must be zero */ + +#define ACPI_MADT_LFLAGS /* Local Sapic flags (32 bits) */ \ + u8 processor_enabled: 1; /* 00: Processor is usable if set */\ + u8 : 7; /* 01-07: Reserved, must be zero */\ + u8 reserved2[3]; /* 08-31: Reserved, must be zero */ + +/* Values for MPS INTI flags */ + +#define POLARITY_CONFORMS 0 +#define POLARITY_ACTIVE_HIGH 1 +#define POLARITY_RESERVED 2 +#define POLARITY_ACTIVE_LOW 3 + +#define TRIGGER_CONFORMS 0 +#define TRIGGER_EDGE 1 +#define TRIGGER_RESERVED 2 +#define TRIGGER_LEVEL 3 + /* - * ACPI 1.0 Fixed ACPI Description Table (FADT) + * MADT Sub-tables, correspond to Type in struct apic_header */ -struct fadt_descriptor_rev1 { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 firmware_ctrl; /* Physical address of FACS */ - u32 dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 reserved1; /* Reserved, must be zero */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* Reserved, must be zero */ - u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ - u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ - u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ - u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ - u8 reserved3; /* Reserved, must be zero */ - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Size of area read to flush caches */ - u16 flush_stride; /* Stride used in flushing caches */ - u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */ - u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */ - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u8 reserved4[3]; /* Reserved, must be zero */ + +/* 0: processor APIC */ + +struct madt_processor_apic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_apic_id; /* Processor's local APIC id */ + ACPI_MADT_LFLAGS}; + +/* 1: IO APIC */ + +struct madt_io_apic { + APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */ + u8 reserved; /* Reserved - must be zero */ + u32 address; /* APIC physical address */ + u32 interrupt; /* Global system interrupt where INTI lines start */ +}; + +/* 2: Interrupt Override */ + +struct madt_interrupt_override { + APIC_HEADER_DEF u8 bus; /* 0 - ISA */ + u8 source; /* Interrupt source (IRQ) */ + u32 interrupt; /* Global system interrupt */ + ACPI_MADT_IFLAGS}; + +/* 3: NMI Sources */ + +struct madt_nmi_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u32 interrupt; /* Global system interrupt */ +}; + +/* 4: Local APIC NMI */ + +struct madt_local_apic_nmi { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + ACPI_MADT_IFLAGS u8 lint; /* LINTn to which NMI is connected */ +}; + +/* 5: Address Override */ + +struct madt_address_override { + APIC_HEADER_DEF u16 reserved; /* Reserved, must be zero */ + u64 address; /* APIC physical address */ +}; + +/* 6: I/O Sapic */ + +struct madt_io_sapic { + APIC_HEADER_DEF u8 io_sapic_id; /* I/O SAPIC ID */ + u8 reserved; /* Reserved, must be zero */ + u32 interrupt_base; /* Glocal interrupt for SAPIC start */ + u64 address; /* SAPIC physical address */ +}; + +/* 7: Local Sapic */ + +struct madt_local_sapic { + APIC_HEADER_DEF u8 processor_id; /* ACPI processor id */ + u8 local_sapic_id; /* SAPIC ID */ + u8 local_sapic_eid; /* SAPIC EID */ + u8 reserved[3]; /* Reserved, must be zero */ + ACPI_MADT_LFLAGS u32 processor_uID; /* Numeric UID - ACPI 3.0 */ + char processor_uIDstring[1]; /* String UID - ACPI 3.0 */ +}; + +/* 8: Platform Interrupt Source */ + +struct madt_interrupt_source { + APIC_HEADER_DEF ACPI_MADT_IFLAGS u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ + u8 io_sapic_vector; /* Vector value for PMI interrupts */ + u32 interrupt; /* Global system interrupt */ + u32 flags; /* Interrupt Source Flags */ +}; + +#ifdef DUPLICATE_DEFINITION_WITH_LINUX_ACPI_H +/******************************************************************************* + * + * MCFG - PCI Memory Mapped Configuration table and sub-table + * + ******************************************************************************/ + +struct acpi_table_mcfg { + ACPI_TABLE_HEADER_DEF u8 reserved[8]; +}; + +struct acpi_mcfg_allocation { + u64 base_address; /* Base address, processor-relative */ + u16 pci_segment; /* PCI segment group number */ + u8 start_bus_number; /* Starting PCI Bus number */ + u8 end_bus_number; /* Final PCI Bus number */ + u32 reserved; +}; +#endif + +/******************************************************************************* + * + * SBST - Smart Battery Specification Table + * + ******************************************************************************/ + +struct smart_battery_table { + ACPI_TABLE_HEADER_DEF u32 warning_level; + u32 low_level; + u32 critical_level; +}; + +/******************************************************************************* + * + * SLIT - System Locality Distance Information Table + * + ******************************************************************************/ + +struct system_locality_info { + ACPI_TABLE_HEADER_DEF u64 locality_count; + u8 entry[1][1]; +}; + +/******************************************************************************* + * + * SPCR - Serial Port Console Redirection table + * + ******************************************************************************/ + +struct acpi_table_spcr { + ACPI_TABLE_HEADER_DEF u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ + u8 reserved[3]; + struct acpi_generic_address serial_port; + u8 interrupt_type; + u8 pc_interrupt; + u32 interrupt; + u8 baud_rate; + u8 parity; + u8 stop_bits; + u8 flow_control; + u8 terminal_type; + u8 reserved2; + u16 pci_device_id; + u16 pci_vendor_id; + u8 pci_bus; + u8 pci_device; + u8 pci_function; + u32 pci_flags; + u8 pci_segment; + u32 reserved3; +}; + +/******************************************************************************* + * + * SPMI - Server Platform Management Interface table + * + ******************************************************************************/ + +struct acpi_table_spmi { + ACPI_TABLE_HEADER_DEF u8 reserved; + u8 interface_type; + u16 spec_revision; /* Version of IPMI */ + u8 interrupt_type; + u8 gpe_number; /* GPE assigned */ + u8 reserved2; + u8 pci_device_flag; + u32 interrupt; + struct acpi_generic_address ipmi_register; + u8 pci_segment; + u8 pci_bus; + u8 pci_device; + u8 pci_function; +}; + +/******************************************************************************* + * + * SRAT - System Resource Affinity Table + * + ******************************************************************************/ + +struct system_resource_affinity { + ACPI_TABLE_HEADER_DEF u32 reserved1; /* Must be value '1' */ + u64 reserved2; /* Reserved, must be zero */ +}; + +/* SRAT common sub-table header */ + +#define SRAT_SUBTABLE_HEADER \ + u8 type; \ + u8 length; + +/* Values for Type above */ + +#define SRAT_CPU_AFFINITY 0 +#define SRAT_MEMORY_AFFINITY 1 +#define SRAT_RESERVED 2 + +/* SRAT sub-tables */ + +struct static_resource_alloc { + SRAT_SUBTABLE_HEADER u8 proximity_domain_lo; + u8 apic_id; + + /* Flags (32 bits) */ + + u8 enabled:1; /* 00: Use affinity structure */ + u8:7; /* 01-07: Reserved, must be zero */ + u8 reserved3[3]; /* 08-31: Reserved, must be zero */ + + u8 local_sapic_eid; + u8 proximity_domain_hi[3]; + u32 reserved4; /* Reserved, must be zero */ +}; + +struct memory_affinity { + SRAT_SUBTABLE_HEADER u32 proximity_domain; + u16 reserved3; + u64 base_address; + u64 address_length; + u32 reserved4; /* Flags (32 bits) */ - u8 wb_invd:1; /* 00: The wbinvd instruction works properly */ - u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */ - u8 proc_c1:1; /* 02: All processors support C1 state */ - u8 plvl2_up:1; /* 03: C2 state works on MP system */ - u8 pwr_button:1; /* 04: Power button is handled as a generic feature */ - u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */ - u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */ - u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */ - u8 tmr_val_ext:1; /* 08: tmr_val width is 32 bits (0 = 24 bits) */ - u8:7; /* 09-15: Reserved, must be zero */ - u8 reserved5[2]; /* 16-31: Reserved, must be zero */ + u8 enabled:1; /* 00: Use affinity structure */ + u8 hot_pluggable:1; /* 01: Memory region is hot pluggable */ + u8 non_volatile:1; /* 02: Memory is non-volatile */ + u8:5; /* 03-07: Reserved, must be zero */ + u8 reserved5[3]; /* 08-31: Reserved, must be zero */ + + u64 reserved6; /* Reserved, must be zero */ +}; + +/******************************************************************************* + * + * TCPA - Trusted Computing Platform Alliance table + * + ******************************************************************************/ + +struct acpi_table_tcpa { + ACPI_TABLE_HEADER_DEF u16 reserved; + u32 max_log_length; /* Maximum length for the event log area */ + u64 log_address; /* Address of the event log area */ }; +/******************************************************************************* + * + * WDRT - Watchdog Resource Table + * + ******************************************************************************/ + +struct acpi_table_wdrt { + ACPI_TABLE_HEADER_DEF u32 header_length; /* Watchdog Header Length */ + u8 pci_segment; /* PCI Segment number */ + u8 pci_bus; /* PCI Bus number */ + u8 pci_device; /* PCI Device number */ + u8 pci_function; /* PCI Function number */ + u32 timer_period; /* Period of one timer count (msec) */ + u32 max_count; /* Maximum counter value supported */ + u32 min_count; /* Minimum counter value */ + u8 flags; + u8 reserved[3]; + u32 entries; /* Number of watchdog entries that follow */ +}; + +#if 0 /* Flags, will be converted to macros */ +u8 enabled:1; /* 00: Timer enabled */ +u8:6; /* 01-06: Reserved */ +u8 sleep_stop:1; /* 07: Timer stopped in sleep state */ +#endif + +/* Macros used to generate offsets to specific table fields */ + +#define ACPI_ASF0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_info,f) +#define ACPI_ASF1_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_alert,f) +#define ACPI_ASF2_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_remote,f) +#define ACPI_ASF3_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_rmcp,f) +#define ACPI_ASF4_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_asf_address,f) +#define ACPI_BOOT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_boot,f) +#define ACPI_CPEP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_cpep,f) +#define ACPI_CPEP0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_cpep_polling,f) +#define ACPI_DBGP_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_dbgp,f) +#define ACPI_ECDT_OFFSET(f) (u8) ACPI_OFFSET (struct ec_boot_resources,f) +#define ACPI_HPET_OFFSET(f) (u8) ACPI_OFFSET (struct hpet_table,f) +#define ACPI_MADT_OFFSET(f) (u8) ACPI_OFFSET (struct multiple_apic_table,f) +#define ACPI_MADT0_OFFSET(f) (u8) ACPI_OFFSET (struct madt_processor_apic,f) +#define ACPI_MADT1_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_apic,f) +#define ACPI_MADT2_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_override,f) +#define ACPI_MADT3_OFFSET(f) (u8) ACPI_OFFSET (struct madt_nmi_source,f) +#define ACPI_MADT4_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_apic_nmi,f) +#define ACPI_MADT5_OFFSET(f) (u8) ACPI_OFFSET (struct madt_address_override,f) +#define ACPI_MADT6_OFFSET(f) (u8) ACPI_OFFSET (struct madt_io_sapic,f) +#define ACPI_MADT7_OFFSET(f) (u8) ACPI_OFFSET (struct madt_local_sapic,f) +#define ACPI_MADT8_OFFSET(f) (u8) ACPI_OFFSET (struct madt_interrupt_source,f) +#define ACPI_MADTH_OFFSET(f) (u8) ACPI_OFFSET (struct apic_header,f) +#define ACPI_MCFG_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_mcfg,f) +#define ACPI_MCFG0_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_mcfg_allocation,f) +#define ACPI_SBST_OFFSET(f) (u8) ACPI_OFFSET (struct smart_battery_table,f) +#define ACPI_SLIT_OFFSET(f) (u8) ACPI_OFFSET (struct system_locality_info,f) +#define ACPI_SPCR_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spcr,f) +#define ACPI_SPMI_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_spmi,f) +#define ACPI_SRAT_OFFSET(f) (u8) ACPI_OFFSET (struct system_resource_affinity,f) +#define ACPI_SRAT0_OFFSET(f) (u8) ACPI_OFFSET (struct static_resource_alloc,f) +#define ACPI_SRAT1_OFFSET(f) (u8) ACPI_OFFSET (struct memory_affinity,f) +#define ACPI_TCPA_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_tcpa,f) +#define ACPI_WDRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_wdrt,f) + +#define ACPI_HPET_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct hpet_table,f,o) +#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct static_resource_alloc,f,o) +#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct memory_affinity,f,o) +#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct multiple_apic_table,f,o) +#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_processor_apic,f,o) +#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_override,f,o) +#define ACPI_MADT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_nmi_source,f,o) +#define ACPI_MADT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_apic_nmi,f,o) +#define ACPI_MADT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_local_sapic,f,o) +#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (struct madt_interrupt_source,f,o) + +/* Reset to default packing */ + #pragma pack() #endif /* __ACTBL1_H__ */ diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index dfc7ac1094bb..67efe6cad27b 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -44,234 +44,6 @@ #ifndef __ACTBL2_H__ #define __ACTBL2_H__ -/* - * Prefered Power Management Profiles - */ -#define PM_UNSPECIFIED 0 -#define PM_DESKTOP 1 -#define PM_MOBILE 2 -#define PM_WORKSTATION 3 -#define PM_ENTERPRISE_SERVER 4 -#define PM_SOHO_SERVER 5 -#define PM_APPLIANCE_PC 6 - -/* - * ACPI Boot Arch Flags - */ -#define BAF_LEGACY_DEVICES 0x0001 -#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 - -#define FADT2_REVISION_ID 3 -#define FADT2_MINUS_REVISION_ID 2 - -#pragma pack(1) - -/* - * ACPI 2.0 Root System Description Table (RSDT) - */ -struct rsdt_descriptor_rev2 { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 table_offset_entry[1]; /* Array of pointers to ACPI tables */ -}; - -/* - * ACPI 2.0 Extended System Description Table (XSDT) - */ -struct xsdt_descriptor_rev2 { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u64 table_offset_entry[1]; /* Array of pointers to ACPI tables */ -}; - -/* - * ACPI 2.0 Firmware ACPI Control Structure (FACS) - */ -struct facs_descriptor_rev2 { - char signature[4]; /* ASCII table signature */ - u32 length; /* Length of structure, in bytes */ - u32 hardware_signature; /* Hardware configuration signature */ - u32 firmware_waking_vector; /* 32-bit physical address of the Firmware Waking Vector. */ - u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ - - /* Flags (32 bits) */ - - u8 S4bios_f:1; /* 00: S4BIOS support is present */ - u8:7; /* 01-07: Reserved, must be zero */ - u8 reserved1[3]; /* 08-31: Reserved, must be zero */ - - u64 xfirmware_waking_vector; /* 64-bit physical address of the Firmware Waking Vector. */ - u8 version; /* Version of this table */ - u8 reserved3[31]; /* Reserved, must be zero */ -}; - -/* - * ACPI 2.0+ Generic Address Structure (GAS) - */ -struct acpi_generic_address { - u8 address_space_id; /* Address space where struct or register exists. */ - u8 register_bit_width; /* Size in bits of given register */ - u8 register_bit_offset; /* Bit offset within the register */ - u8 access_width; /* Minimum Access size (ACPI 3.0) */ - u64 address; /* 64-bit address of struct or register */ -}; - -#define FADT_REV2_COMMON \ - u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \ - u32 V1_dsdt; /* 32-bit physical address of DSDT */ \ - u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \ - u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ \ - u16 sci_int; /* System vector of SCI interrupt */ \ - u32 smi_cmd; /* Port address of SMI command port */ \ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \ - u8 pstate_cnt; /* Processor performance state control*/ \ - u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ \ - u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ \ - u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \ - u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \ - u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \ - u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \ - u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \ - u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ \ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ \ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ \ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \ - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ \ - u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ \ - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \ - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \ - u16 flush_size; /* Number of flush strides that need to be read */ \ - u16 flush_stride; /* Processor's memory cache line width, in bytes */ \ - u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ \ - u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ \ - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \ - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \ - u8 century; /* Index to century in RTC CMOS RAM */ \ - u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ - -/* - * ACPI 2.0+ Fixed ACPI Description Table (FADT) - */ -struct fadt_descriptor_rev2 { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - FADT_REV2_COMMON u8 reserved2; /* Reserved, must be zero */ - - /* Flags (32 bits) */ - - u8 wb_invd:1; /* 00: The wbinvd instruction works properly */ - u8 wb_invd_flush:1; /* 01: The wbinvd flushes but does not invalidate */ - u8 proc_c1:1; /* 02: All processors support C1 state */ - u8 plvl2_up:1; /* 03: C2 state works on MP system */ - u8 pwr_button:1; /* 04: Power button is handled as a generic feature */ - u8 sleep_button:1; /* 05: Sleep button is handled as a generic feature, or not present */ - u8 fixed_rTC:1; /* 06: RTC wakeup stat not in fixed register space */ - u8 rtcs4:1; /* 07: RTC wakeup stat not possible from S4 */ - u8 tmr_val_ext:1; /* 08: tmr_val is 32 bits 0=24-bits */ - u8 dock_cap:1; /* 09: Docking supported */ - u8 reset_reg_sup:1; /* 10: System reset via the FADT RESET_REG supported */ - u8 sealed_case:1; /* 11: No internal expansion capabilities and case is sealed */ - u8 headless:1; /* 12: No local video capabilities or local input devices */ - u8 cpu_sw_sleep:1; /* 13: Must execute native instruction after writing SLP_TYPx register */ - - u8 pci_exp_wak:1; /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */ - u8 use_platform_clock:1; /* 15: OSPM should use platform-provided timer (ACPI 3.0) */ - u8 S4rtc_sts_valid:1; /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */ - u8 remote_power_on_capable:1; /* 17: System is compatible with remote power on (ACPI 3.0) */ - u8 force_apic_cluster_model:1; /* 18: All local APICs must use cluster model (ACPI 3.0) */ - u8 force_apic_physical_destination_mode:1; /* 19: all local x_aPICs must use physical dest mode (ACPI 3.0) */ - u8:4; /* 20-23: Reserved, must be zero */ - u8 reserved3; /* 24-31: Reserved, must be zero */ - - struct acpi_generic_address reset_register; /* Reset register address in GAS format */ - u8 reset_value; /* Value to write to the reset_register port to reset the system */ - u8 reserved4[3]; /* These three bytes must be zero */ - u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ - u64 Xdsdt; /* 64-bit physical address of DSDT */ - struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ - struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ - struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ - struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ - struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ - struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ - struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ - struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ -}; - -/* "Down-revved" ACPI 2.0 FADT descriptor */ - -struct fadt_descriptor_rev2_minus { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - FADT_REV2_COMMON u8 reserved2; /* Reserved, must be zero */ - u32 flags; - struct acpi_generic_address reset_register; /* Reset register address in GAS format */ - u8 reset_value; /* Value to write to the reset_register port to reset the system. */ - u8 reserved7[3]; /* Reserved, must be zero */ -}; - -/* ECDT - Embedded Controller Boot Resources Table */ - -struct ec_boot_resources { - ACPI_TABLE_HEADER_DEF struct acpi_generic_address ec_control; /* Address of EC command/status register */ - struct acpi_generic_address ec_data; /* Address of EC data register */ - u32 uid; /* Unique ID - must be same as the EC _UID method */ - u8 gpe_bit; /* The GPE for the EC */ - u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */ -}; - -/* SRAT - System Resource Affinity Table */ - -struct static_resource_alloc { - u8 type; - u8 length; - u8 proximity_domain_lo; - u8 apic_id; - - /* Flags (32 bits) */ - - u8 enabled:1; /* 00: Use affinity structure */ - u8:7; /* 01-07: Reserved, must be zero */ - u8 reserved3[3]; /* 08-31: Reserved, must be zero */ - - u8 local_sapic_eid; - u8 proximity_domain_hi[3]; - u32 reserved4; /* Reserved, must be zero */ -}; - -struct memory_affinity { - u8 type; - u8 length; - u32 proximity_domain; - u16 reserved3; - u64 base_address; - u64 address_length; - u32 reserved4; - - /* Flags (32 bits) */ - - u8 enabled:1; /* 00: Use affinity structure */ - u8 hot_pluggable:1; /* 01: Memory region is hot pluggable */ - u8 non_volatile:1; /* 02: Memory is non-volatile */ - u8:5; /* 03-07: Reserved, must be zero */ - u8 reserved5[3]; /* 08-31: Reserved, must be zero */ - - u64 reserved6; /* Reserved, must be zero */ -}; - -struct system_resource_affinity { - ACPI_TABLE_HEADER_DEF u32 reserved1; /* Must be value '1' */ - u64 reserved2; /* Reserved, must be zero */ -}; - -/* SLIT - System Locality Distance Information Table */ - -struct system_locality_info { - ACPI_TABLE_HEADER_DEF u64 locality_count; - u8 entry[1][1]; -}; - -#pragma pack() +/* Code moved to both actbl.h and actbl1.h */ #endif /* __ACTBL2_H__ */ diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 5e69a80c7850..115b0cbc370f 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -283,6 +283,8 @@ acpi_ut_ptr_exit(u32 line_number, void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); +void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display); + void acpi_ut_report_error(char *module_name, u32 line_number); void acpi_ut_report_info(char *module_name, u32 line_number); @@ -451,6 +453,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, /* * utmisc */ +u8 acpi_ut_is_aml_table(struct acpi_table_header *table); + acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); void acpi_ut_release_owner_id(acpi_owner_id * owner_id); @@ -466,7 +470,9 @@ void acpi_ut_print_string(char *string, u8 max_length); u8 acpi_ut_valid_acpi_name(u32 name); -u8 acpi_ut_valid_acpi_character(char character); +acpi_name acpi_ut_repair_name(acpi_name name); + +u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position); acpi_status acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); @@ -492,7 +498,7 @@ acpi_ut_display_init_pathname(u8 type, acpi_status acpi_ut_walk_aml_resources(u8 * aml, acpi_size aml_length, - acpi_walk_aml_callback user_function, void *context); + acpi_walk_aml_callback user_function, void **context); acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index); diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 2270bdd5e530..fd189d425c78 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -60,6 +60,7 @@ #define ACPI_DISASSEMBLER #define ACPI_NO_METHOD_EXECUTION #define ACPI_LARGE_NAMESPACE_NODE +#define ACPI_DATA_TABLE_DISASSEMBLY #endif #ifdef ACPI_EXEC_APP @@ -79,6 +80,7 @@ #define ACPI_DISASSEMBLER #define ACPI_CONSTANT_EVAL_ONLY #define ACPI_LARGE_NAMESPACE_NODE +#define ACPI_DATA_TABLE_DISASSEMBLY #endif #ifdef ACPI_APPLICATION @@ -140,7 +142,7 @@ #elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */ #include "acdos16.h" -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include "acfreebsd.h" #elif defined(__NetBSD__) -- cgit v1.2.3 From e7bdd7a531320eb4a4a8160afbe0c7cc98ac7187 Mon Sep 17 00:00:00 2001 From: "Langsdorf, Mark" Date: Thu, 8 Jun 2006 10:30:17 -0500 Subject: [CPUFREQ] Clarify powernow-k8 cpu_family statements This patch clarifies the meaning of the cpu_family if statements in the hw pstate driver patch for powernow-k8 Signed-off-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index b4277f58f40c..d8be4b01488d 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -120,7 +120,7 @@ static int pending_bit_stuck(void) { u32 lo, hi; - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) return 0; rdmsr(MSR_FIDVID_STATUS, lo, hi); @@ -136,7 +136,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) u32 lo, hi; u32 i = 0; - if (cpu_family) { + if (cpu_family == CPU_HW_PSTATE) { rdmsr(MSR_PSTATE_STATUS, lo, hi); i = lo & HW_PSTATE_MASK; rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); @@ -598,7 +598,7 @@ static void print_basics(struct powernow_k8_data *data) int j; for (j = 0; j < data->numps; j++) { if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { - if (cpu_family) { + if (cpu_family == CPU_HW_PSTATE) { printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, (data->powernow_table[j].index & 0xff0000) >> 16, data->powernow_table[j].frequency/1000); @@ -758,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data) #ifdef CONFIG_X86_POWERNOW_K8_ACPI static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { - if (!data->acpi_data.state_count || cpu_family) + if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) return; data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; @@ -801,7 +801,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) goto err_out; } - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) ret_val = fill_powernow_table_pstate(data, powernow_table); else ret_val = fill_powernow_table_fidvid(data, powernow_table); @@ -1082,7 +1082,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi if (query_current_values_with_pending_wait(data)) goto err_out; - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) dprintk("targ: curr fid 0x%x, did 0x%x\n", data->currfid, data->currvid); else { @@ -1103,7 +1103,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi powernow_k8_acpi_pst_values(data, newstate); - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) ret = transition_frequency_pstate(data, newstate); else ret = transition_frequency_fidvid(data, newstate); @@ -1115,7 +1115,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi } mutex_unlock(&fidvid_mutex); - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); else pol->cur = find_khz_freq_from_fid(data->currfid); @@ -1197,14 +1197,14 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) if (query_current_values_with_pending_wait(data)) goto err_out; - if (!cpu_family) + if (cpu_family == CPU_OPTERON) fidvid_msr_init(); /* run on any CPU again */ set_cpus_allowed(current, oldmask); pol->governor = CPUFREQ_DEFAULT_GOVERNOR; - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) pol->cpus = cpumask_of_cpu(pol->cpu); else pol->cpus = cpu_core_map[pol->cpu]; @@ -1215,7 +1215,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) + (3 * (1 << data->irt) * 10)) * 1000; - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); else pol->cur = find_khz_freq_from_fid(data->currfid); @@ -1232,7 +1232,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); - if (cpu_family) + if (cpu_family == CPU_HW_PSTATE) dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", data->currfid, data->currdid); else -- cgit v1.2.3 From 6cad647da228486f36a9794137ad459e39b02590 Mon Sep 17 00:00:00 2001 From: "Langsdorf, Mark" Date: Thu, 8 Jun 2006 10:33:19 -0500 Subject: [CPUFREQ] correct powernow-k8 fid/vid masks for extended parts The fid/vid masks for parts using the extended parts are slightly incorrect and can result in incorrect fid/vid codes being applied. No instances of this problem have been reported in the field but it could be a problem with future parts. Signed-off-by: Mark Langsdorf Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 4 ++-- arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index d8be4b01488d..756d0a333ed6 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -885,8 +885,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf u32 vid; if (data->exttype) { - fid = data->acpi_data.states[i].status & FID_MASK; - vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; + fid = data->acpi_data.states[i].status & EXT_FID_MASK; + vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; } else { fid = data->acpi_data.states[i].control & FID_MASK; vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index bf8ad9e43da3..0fb2a3001ba5 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -169,7 +169,9 @@ struct powernow_k8_data { #define MVS_MASK 3 #define VST_MASK 0x7f #define VID_MASK 0x1f -#define FID_MASK 0x3f +#define FID_MASK 0x1f +#define EXT_VID_MASK 0x3f +#define EXT_FID_MASK 0x3f /* -- cgit v1.2.3 From acc7c2e0b73a46122ec370bf8a3aa9f19065d331 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Date: Thu, 15 Jun 2006 12:08:30 -0400 Subject: [PATCH] PCI: fix memory leak in MMCONFIG error path This a bit late (yours patch was posted about a year ago), but a co-worker of spotted part of the code that looks like a memory leak. Looking at the code it seems that pci_mmcfg_config should be free-ed if MMCONFIG is above 4GB. From: Konrad Rzeszutek Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/acpi/boot.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 40e5aba3ad3d..fbe93084244c 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -202,6 +202,8 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + kfree(pci_mmcfg_config); + pci_mmcfg_config_num = 0; return -ENODEV; } } -- cgit v1.2.3 From 491b07c98f2ac75f1a4370af76ae2403a4c579f5 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 21 Jun 2006 13:15:48 -0700 Subject: [PATCH] redirect speedstep-centrino maintainer mail to cpufreq list I haven't really maintained this driver for a while, and I'm not keeping up with the latest in Intel power management. I get a steady stream of mail which I don't really do anything useful with; the cpufreq list seems like a better destination, unless someone wants to get the mail directly. Also clean up a couple of ancient comments which don't really apply anymore (as far as I know, nobody has ever damaged a CPU with this driver). Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index ce54ff12c15d..f1a82c5de1ba 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -2,19 +2,15 @@ * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium * M (part of the Centrino chipset). * + * Since the original Pentium M, most new Intel CPUs support Enhanced + * SpeedStep. + * * Despite the "SpeedStep" in the name, this is almost entirely unlike * traditional SpeedStep. * * Modelled on speedstep.c * * Copyright (C) 2003 Jeremy Fitzhardinge - * - * WARNING WARNING WARNING - * - * This driver manipulates the PERF_CTL MSR, which is only somewhat - * documented. While it seems to work on my laptop, it has not been - * tested anywhere else, and it may not work for you, do strange - * things or simply crash. */ #include @@ -36,7 +32,7 @@ #include #define PFX "speedstep-centrino: " -#define MAINTAINER "Jeremy Fitzhardinge " +#define MAINTAINER "cpufreq@lists.linux.org.uk" #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) -- cgit v1.2.3 From 9ed059e1551bf36092215b965838502ac21f42e4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 20 Jun 2006 22:32:56 -0700 Subject: [CPUFREQ] Fix powernow-k8 SMP kernel on UP hardware bug. Fix powernow-k8 doesn't load bug. Reference: https://launchpad.net/distros/ubuntu/+source/linux-source-2.6.15/+bug/35145 Signed-off-by: Ben Collins Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 756d0a333ed6..2d6491672559 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1163,7 +1163,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. */ - if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { + if (num_online_cpus() != 1) { printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); kfree(data); return -ENODEV; -- cgit v1.2.3 From 762834e8bf46bf41ce9034d062a7c1f8563175f3 Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Fri, 23 Jun 2006 02:03:19 -0700 Subject: [PATCH] Unify pxm_to_node() and node_to_pxm() Consolidate the various arch-specific implementations of pxm_to_node() and node_to_pxm() into a single generic version. Signed-off-by: Yasunori Goto Cc: "Luck, Tony" Cc: Andi Kleen Cc: Dave Hansen Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 6 ++++++ arch/i386/kernel/srat.c | 19 ++-------------- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/kernel/acpi.c | 24 +++++++-------------- arch/ia64/pci/pci.c | 2 +- arch/ia64/sn/kernel/setup.c | 4 ++-- arch/x86_64/mm/srat.c | 33 +--------------------------- drivers/acpi/Kconfig | 2 +- drivers/acpi/numa.c | 48 +++++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_numa.h | 23 ++++++++++++++++++++ include/asm-x86_64/numa.h | 1 - include/linux/acpi.h | 9 ++++++++ 12 files changed, 102 insertions(+), 71 deletions(-) create mode 100644 include/acpi/acpi_numa.h (limited to 'arch/i386/kernel') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 8dfa3054f10f..15d23da2455f 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -173,6 +173,12 @@ config ACPI_SRAT bool default y depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) + select ACPI_NUMA + +config HAVE_ARCH_PARSE_SRAT + bool + default y + depends on ACPI_SRAT config X86_SUMMIT_NUMA bool diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c index 52b3ed5d2cb5..989c85255dbe 100644 --- a/arch/i386/kernel/srat.c +++ b/arch/i386/kernel/srat.c @@ -39,7 +39,6 @@ #define NODE_ARRAY_OFFSET(x) ((x) % 8) /* 8 bits/char */ #define BMAP_SET(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit)) #define BMAP_TEST(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit))) -#define MAX_PXM_DOMAINS 256 /* 1 byte and no promises about values */ /* bitmap length; _PXM is at most 255 */ #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ @@ -213,19 +212,11 @@ static __init void node_read_chunk(int nid, struct node_memory_chunk_s *memory_c node_end_pfn[nid] = memory_chunk->end_pfn; } -static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ - -int pxm_to_node(int pxm) -{ - return pxm_to_nid_map[pxm]; -} - /* Parse the ACPI Static Resource Affinity Table */ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) { u8 *start, *end, *p; int i, j, nid; - u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */ start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ p = start; @@ -235,10 +226,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); memset(zholes_size, 0, sizeof(zholes_size)); - /* -1 in these maps means not available */ - memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); - memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); - num_memory_chunks = 0; while (p < end) { switch (*p) { @@ -278,9 +265,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (BMAP_TEST(pxm_bitmap, i)) { - nid = num_online_nodes(); - pxm_to_nid_map[i] = nid; - nid_to_pxm_map[nid] = i; + int nid = acpi_map_pxm_to_node(i); node_set_online(nid); } } @@ -288,7 +273,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) /* set cnode id in memory chunk structure */ for (i = 0; i < num_memory_chunks; i++) - node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm]; + node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm); printk("pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index bdccd0b1eb60..3ce443e6c016 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1958,7 +1958,7 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) if (pxm < 0) return; - node = pxm_to_nid_map[pxm]; + node = pxm_to_node(pxm); if (node >= MAX_NUMNODES || !node_online(node)) return; diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 58c93a30348c..d1c52cf67882 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -415,9 +415,6 @@ static int __initdata srat_num_cpus; /* number of cpus */ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN]; #define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag)) #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) -/* maps to convert between proximity domain and logical node ID */ -int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS]; -int __initdata nid_to_pxm_map[MAX_NUMNODES]; static struct acpi_table_slit __initdata *slit_table; static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa) @@ -533,22 +530,17 @@ void __init acpi_numa_arch_fixup(void) * MCD - This can probably be dropped now. No need for pxm ID to node ID * mapping with sparse node numbering iff MAX_PXM_DOMAINS <= MAX_NUMNODES. */ - /* calculate total number of nodes in system from PXM bitmap */ - memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); - memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (pxm_bit_test(i)) { - int nid = num_online_nodes(); - pxm_to_nid_map[i] = nid; - nid_to_pxm_map[nid] = i; + int nid = acpi_map_pxm_to_node(i); node_set_online(nid); } } /* set logical node id in memory chunk structure */ for (i = 0; i < num_node_memblks; i++) - node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid]; + node_memblk[i].nid = pxm_to_node(node_memblk[i].nid); /* assign memory bank numbers for each chunk on each node */ for_each_online_node(i) { @@ -562,7 +554,7 @@ void __init acpi_numa_arch_fixup(void) /* set logical node id in cpu structure */ for (i = 0; i < srat_num_cpus; i++) - node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid]; + node_cpuid[i].nid = pxm_to_node(node_cpuid[i].nid); printk(KERN_INFO "Number of logical nodes in system = %d\n", num_online_nodes()); @@ -575,11 +567,11 @@ void __init acpi_numa_arch_fixup(void) for (i = 0; i < slit_table->localities; i++) { if (!pxm_bit_test(i)) continue; - node_from = pxm_to_nid_map[i]; + node_from = pxm_to_node(i); for (j = 0; j < slit_table->localities; j++) { if (!pxm_bit_test(j)) continue; - node_to = pxm_to_nid_map[j]; + node_to = pxm_to_node(j); node_distance(node_from, node_to) = slit_table->entry[i * slit_table->localities + j]; } @@ -785,9 +777,9 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid) /* * Assuming that the container driver would have set the proximity - * domain and would have initialized pxm_to_nid_map[pxm_id] && pxm_flag + * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag */ - node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_nid_map[pxm_id]; + node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id); node_cpuid[cpu].phys_id = physid; #endif @@ -966,7 +958,7 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) if (pxm < 0) return AE_OK; - node = pxm_to_nid_map[pxm]; + node = pxm_to_node(pxm); if (node >= MAX_NUMNODES || !node_online(node) || cpus_empty(node_to_cpumask(node))) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index ab829a22f8a4..cf7751b99d1c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -352,7 +352,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) pxm = acpi_get_pxm(controller->acpi_handle); #ifdef CONFIG_NUMA if (pxm >= 0) - controller->node = pxm_to_nid_map[pxm]; + controller->node = pxm_to_node(pxm); #endif acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 30988dfbddff..93577abae36d 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -139,7 +139,7 @@ static int __init pxm_to_nasid(int pxm) int i; int nid; - nid = pxm_to_nid_map[pxm]; + nid = pxm_to_node(pxm); for (i = 0; i < num_node_memblks; i++) { if (node_memblk[i].nid == nid) { return NASID_GET(node_memblk[i].start_paddr); @@ -704,7 +704,7 @@ void __init build_cnode_tables(void) * cnode == node for all C & M bricks. */ for_each_online_node(node) { - nasid = pxm_to_nasid(nid_to_pxm_map[node]); + nasid = pxm_to_nasid(node_to_pxm(node)); sn_cnodeid_to_nasid[node] = nasid; physical_node_map[nasid] = node; } diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 474df22c6ed2..502fce65e96a 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c @@ -30,7 +30,6 @@ static struct acpi_table_slit *acpi_slit; static nodemask_t nodes_parsed __initdata; -static nodemask_t nodes_found __initdata; static struct bootnode nodes[MAX_NUMNODES] __initdata; static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static int found_add_area __initdata; @@ -38,33 +37,14 @@ int hotadd_percent __initdata = 0; #ifndef RESERVE_HOTADD #define hotadd_percent 0 /* Ignore all settings */ #endif -static u8 pxm2node[256] = { [0 ... 255] = 0xff }; /* Too small nodes confuse the VM badly. Usually they result from BIOS bugs. */ #define NODE_MIN_SIZE (4*1024*1024) -static int node_to_pxm(int n); - -int pxm_to_node(int pxm) -{ - if ((unsigned)pxm >= 256) - return -1; - /* Extend 0xff to (int)-1 */ - return (signed char)pxm2node[pxm]; -} - static __init int setup_node(int pxm) { - unsigned node = pxm2node[pxm]; - if (node == 0xff) { - if (nodes_weight(nodes_found) >= MAX_NUMNODES) - return -1; - node = first_unset_node(nodes_found); - node_set(node, nodes_found); - pxm2node[pxm] = node; - } - return pxm2node[pxm]; + return acpi_map_pxm_to_node(pxm); } static __init int conflicting_nodes(unsigned long start, unsigned long end) @@ -440,17 +420,6 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) return 0; } -static int node_to_pxm(int n) -{ - int i; - if (pxm2node[n] == n) - return n; - for (i = 0; i < 256; i++) - if (pxm2node[i] == n) - return i; - return 0; -} - void __init srat_reserve_add_area(int nodeid) { if (found_add_area && nodes_add[nodeid].end) { diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index c24652d31bf9..230c53852231 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -162,7 +162,7 @@ config ACPI_THERMAL config ACPI_NUMA bool "NUMA support" depends on NUMA - depends on (IA64 || X86_64) + depends on (X86 || IA64) default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 64b98e82feb7..e2c1a16078c9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -36,12 +36,60 @@ #define _COMPONENT ACPI_NUMA ACPI_MODULE_NAME("numa") +static nodemask_t nodes_found_map = NODE_MASK_NONE; +#define PXM_INVAL -1 +#define NID_INVAL -1 + +/* maps to convert between proximity domain and logical node ID */ +int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] + = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL }; +int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] + = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; + extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries); +int __cpuinit pxm_to_node(int pxm) +{ + if (pxm < 0) + return NID_INVAL; + return pxm_to_node_map[pxm]; +} + +int __cpuinit node_to_pxm(int node) +{ + if (node < 0) + return PXM_INVAL; + return node_to_pxm_map[node]; +} + +int __cpuinit acpi_map_pxm_to_node(int pxm) +{ + int node = pxm_to_node_map[pxm]; + + if (node < 0){ + if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) + return NID_INVAL; + node = first_unset_node(nodes_found_map); + pxm_to_node_map[pxm] = node; + node_to_pxm_map[node] = pxm; + node_set(node, nodes_found_map); + } + + return node; +} + +void __cpuinit acpi_unmap_pxm_to_node(int node) +{ + int pxm = node_to_pxm_map[node]; + pxm_to_node_map[pxm] = NID_INVAL; + node_to_pxm_map[node] = PXM_INVAL; + node_clear(node, nodes_found_map); +} + void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) { diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h new file mode 100644 index 000000000000..1049f2a0a6db --- /dev/null +++ b/include/acpi/acpi_numa.h @@ -0,0 +1,23 @@ +#ifndef __ACPI_NUMA_H +#define __ACPI_NUMA_H + +#ifdef CONFIG_ACPI_NUMA +#include + +/* Proximity bitmap length */ +#if MAX_NUMNODES > 256 +#define MAX_PXM_DOMAINS MAX_NUMNODES +#else +#define MAX_PXM_DOMAINS (256) /* Old pxm spec is defined 8 bit */ +#endif + +extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]; +extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]; + +extern int __cpuinit pxm_to_node(int); +extern int __cpuinit node_to_pxm(int); +extern int __cpuinit acpi_map_pxm_to_node(int); +extern void __cpuinit acpi_unmap_pxm_to_node(int); + +#endif /* CONFIG_ACPI_NUMA */ +#endif /* __ACP_NUMA_H */ diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h index 1cc92fe02503..933ff11ece15 100644 --- a/include/asm-x86_64/numa.h +++ b/include/asm-x86_64/numa.h @@ -8,7 +8,6 @@ struct bootnode { }; extern int compute_hash_shift(struct bootnode *nodes, int numnodes); -extern int pxm_to_node(int nid); #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1cf0b91d05bd..90d6df1551ed 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -407,10 +408,18 @@ void acpi_table_print_madt_entry (acpi_table_entry_header *madt); void acpi_table_print_srat_entry (acpi_table_entry_header *srat); /* the following four functions are architecture-dependent */ +#ifdef CONFIG_HAVE_ARCH_PARSE_SRAT +#define NR_NODE_MEMBLKS MAX_NUMNODES +#define acpi_numa_slit_init(slit) do {} while (0) +#define acpi_numa_processor_affinity_init(pa) do {} while (0) +#define acpi_numa_memory_affinity_init(ma) do {} while (0) +#define acpi_numa_arch_fixup() do {} while (0) +#else void acpi_numa_slit_init (struct acpi_table_slit *slit); void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa); void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma); void acpi_numa_arch_fixup(void); +#endif #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -- cgit v1.2.3 From 1b2db9fb7adc4d67d9ce7d16ce79c41ee84730fe Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:56 -0700 Subject: [PATCH] sys_move_pages: 32bit support (i386, x86_64) sys_move_pages() support for 32bit (i386 plus x86_64 compat layer) Add support for move_pages() on i386 and also add the compat functions necessary to run 32 bit binaries on x86_64. Add compat_sys_move_pages to the x86_64 32bit binary layer. Note that it is not up to date so I added the missing pieces. Not sure if this is done the right way. [akpm@osdl.org: compile fix] Signed-off-by: Christoph Lameter Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/syscall_table.S | 1 + arch/x86_64/ia32/ia32entry.S | 1 + include/asm-i386/unistd.h | 3 ++- include/linux/syscalls.h | 5 +++++ kernel/compat.c | 23 +++++++++++++++++++++++ kernel/sys_ni.c | 1 + 6 files changed, 33 insertions(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index af56987f69b0..dd63d4775398 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S @@ -316,3 +316,4 @@ ENTRY(sys_call_table) .long sys_sync_file_range .long sys_tee /* 315 */ .long sys_vmsplice + .long sys_move_pages diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 5a92fed2d1d5..4ec594ab1a98 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -696,4 +696,5 @@ ia32_sys_call_table: .quad sys_sync_file_range .quad sys_tee .quad compat_sys_vmsplice + .quad compat_sys_move_pages ia32_syscall_end: diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index de2ccc149e34..fc1c8ddae149 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -322,10 +322,11 @@ #define __NR_sync_file_range 314 #define __NR_tee 315 #define __NR_vmsplice 316 +#define __NR_move_pages 317 #ifdef __KERNEL__ -#define NR_syscalls 317 +#define NR_syscalls 318 /* * user-visible error numbers are in the range -1 - -128: see diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 7e3f23490918..e42738c69166 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -521,6 +521,11 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, const int __user *nodes, int __user *status, int flags); +asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, + void __user *pages, + const int __user *nodes, + int __user *status, + int flags); asmlinkage long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user *nmask, diff --git a/kernel/compat.c b/kernel/compat.c index c1601a84f8d8..ccea93e28954 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -934,3 +935,25 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) return ret; } + +#ifdef CONFIG_NUMA +asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages, + void __user *pages32, + const int __user *nodes, + int __user *status, + int flags) +{ + const void __user * __user *pages; + int i; + + pages = compat_alloc_user_space(nr_pages * sizeof(void *)); + for (i = 0; i < nr_pages; i++) { + compat_uptr_t p; + + if (get_user(p, (compat_uptr_t *)(pages32 + i)) || + put_user(compat_ptr(p), pages + i)) + return -EFAULT; + } + return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); +} +#endif diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 597229749dec..6991bece67e8 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -133,3 +133,4 @@ cond_syscall(sys_mincore); cond_syscall(sys_madvise); cond_syscall(sys_mremap); cond_syscall(sys_remap_file_pages); +cond_syscall(compat_sys_move_pages); -- cgit v1.2.3 From a0b4da91f4c5710b9c20219a19e905145647b48b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 23 Jun 2006 02:04:17 -0700 Subject: [PATCH] arch/i386/kernel/apic.c: make modern_apic() static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apic.c | 2 +- include/asm-i386/apic.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 3d4b2f3d116a..261796ff83c3 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -62,7 +62,7 @@ int apic_verbosity; static void apic_pm_activate(void); -int modern_apic(void) +static int modern_apic(void) { unsigned int lvr, version; /* AMD systems use old APIC versions, so check the CPU */ diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index cc9b940fb7e8..1d8362cb2c5d 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h @@ -138,8 +138,6 @@ void switch_ipi_to_APIC_timer(void *cpumask); extern int timer_over_8254; -extern int modern_apic(void); - #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } -- cgit v1.2.3 From 87af2ffd4ccd0e6a2ff316fd008a9bedb4a4cb66 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 23 Jun 2006 02:04:17 -0700 Subject: [PATCH] i386 apm.c optimization - avoid expensive modulo (integer division) which happened since APM_MAX_EVENTS is 20 (non-power-of-2) - kill compiler warnings by initializing two variables - add __read_mostly to some important static variables that are read often (by idle loop etc.) - constify several structures Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apm.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index df0e1745f189..9e819eb68229 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -374,14 +374,14 @@ static struct { unsigned short segment; } apm_bios_entry; static int clock_slowed; -static int idle_threshold = DEFAULT_IDLE_THRESHOLD; -static int idle_period = DEFAULT_IDLE_PERIOD; +static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; +static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; static int set_pm_idle; static int suspends_pending; static int standbys_pending; static int ignore_sys_suspend; static int ignore_normal_resume; -static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; +static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; #ifdef CONFIG_APM_RTC_IS_GMT # define clock_cmos_diff 0 @@ -390,8 +390,8 @@ static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; static long clock_cmos_diff; static int got_clock_diff; #endif -static int debug; -static int smp; +static int debug __read_mostly; +static int smp __read_mostly; static int apm_disabled = -1; #ifdef CONFIG_SMP static int power_off; @@ -403,8 +403,8 @@ static int realmode_power_off = 1; #else static int realmode_power_off; #endif -static int exit_kapmd; -static int kapmd_running; +static int exit_kapmd __read_mostly; +static int kapmd_running __read_mostly; #ifdef CONFIG_APM_ALLOW_INTS static int allow_ints = 1; #else @@ -416,15 +416,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static struct apm_user * user_list; static DEFINE_SPINLOCK(user_list_lock); -static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; +static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; -static char driver_version[] = "1.16ac"; /* no spaces */ +static const char driver_version[] = "1.16ac"; /* no spaces */ /* * APM event names taken from the APM 1.2 specification. These are * the message codes that the BIOS uses to tell us about events */ -static char * apm_event_name[] = { +static const char * const apm_event_name[] = { "system standby", "system suspend", "normal resume", @@ -616,7 +616,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, * @ecx_in: ECX register value for BIOS call * @eax: EAX register on return from the BIOS call * - * Make a BIOS call that does only returns one value, or just status. + * Make a BIOS call that returns one value only, or just status. * If there is an error, then the error code is returned in AH * (bits 8-15 of eax) and this function returns non-zero. This is * used for simpler BIOS operations. This call may hold interrupts @@ -822,7 +822,7 @@ static void apm_do_busy(void) #define IDLE_CALC_LIMIT (HZ * 100) #define IDLE_LEAKY_MAX 16 -static void (*original_pm_idle)(void); +static void (*original_pm_idle)(void) __read_mostly; /** * apm_cpu_idle - cpu idling for APM capable Linux @@ -1063,7 +1063,8 @@ static int apm_engage_power_management(u_short device, int enable) static int apm_console_blank(int blank) { - int error, i; + int error = APM_NOT_ENGAGED; /* silence gcc */ + int i; u_short state; static const u_short dev[3] = { 0x100, 0x1FF, 0x101 }; @@ -1104,7 +1105,8 @@ static int queue_empty(struct apm_user *as) static apm_event_t get_queued_event(struct apm_user *as) { - as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; + if (++as->event_tail >= APM_MAX_EVENTS) + as->event_tail = 0; return as->events[as->event_tail]; } @@ -1118,13 +1120,16 @@ static void queue_event(apm_event_t event, struct apm_user *sender) for (as = user_list; as != NULL; as = as->next) { if ((as == sender) || (!as->reader)) continue; - as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; + if (++as->event_head >= APM_MAX_EVENTS) + as->event_head = 0; + if (as->event_head == as->event_tail) { static int notified; if (notified++ == 0) printk(KERN_ERR "apm: an event queue overflowed\n"); - as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; + if (++as->event_tail >= APM_MAX_EVENTS) + as->event_tail = 0; } as->events[as->event_head] = event; if ((!as->suser) || (!as->writer)) @@ -1282,7 +1287,7 @@ static void standby(void) static apm_event_t get_event(void) { int error; - apm_event_t event; + apm_event_t event = APM_NO_EVENTS; /* silence gcc */ apm_eventinfo_t info; static int notified; -- cgit v1.2.3 From 27b07da7332f03a935cd13b6a6beb780bf19e7a4 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 23 Jun 2006 02:04:18 -0700 Subject: [PATCH] Don't trigger full rebuild via CONFIG_MTRR Only drm, framebuffer, mtrr parts + misc files here and there. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/common.c | 1 + arch/i386/power/cpu.c | 1 + include/asm-i386/mtrr.h | 4 ++++ include/asm-i386/processor.h | 8 -------- 4 files changed, 6 insertions(+), 8 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index a06a49075f10..f2a2b0ac9a18 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #include diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 79b2370c7fac..63d25ca6306f 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c @@ -10,6 +10,7 @@ #include #include #include +#include static struct saved_context saved_context; diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h index 5a46de08efea..07f063ae26ea 100644 --- a/include/asm-i386/mtrr.h +++ b/include/asm-i386/mtrr.h @@ -76,6 +76,8 @@ extern int mtrr_add_page (unsigned long base, unsigned long size, extern int mtrr_del (int reg, unsigned long base, unsigned long size); extern int mtrr_del_page (int reg, unsigned long base, unsigned long size); extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); +extern void mtrr_ap_init(void); +extern void mtrr_bp_init(void); # else static __inline__ int mtrr_add (unsigned long base, unsigned long size, unsigned int type, char increment) @@ -100,6 +102,8 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base, static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} +#define mtrr_ap_init() do {} while (0) +#define mtrr_bp_init() do {} while (0) # endif #endif diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 4df3818e4122..5116465272ec 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -728,14 +728,6 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -#ifdef CONFIG_MTRR -extern void mtrr_ap_init(void); -extern void mtrr_bp_init(void); -#else -#define mtrr_ap_init() do {} while (0) -#define mtrr_bp_init() do {} while (0) -#endif - #ifdef CONFIG_X86_MCE extern void mcheck_init(struct cpuinfo_x86 *c); #else -- cgit v1.2.3 From ba528f2854e8632c8d04ddcd45f06c47bc7188b0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 23 Jun 2006 02:04:19 -0700 Subject: [PATCH] fix x86 microcode driver handling of multiple matching revisions When multiple updates matching a given CPU are found in the update file, the action taken by the microcode update driver was inappropriate: - when lower revision microcode was found before matching or higher revision one, the driver would needlessly complain that it would not downgrade the CPU - when microcode matching the currently installed revision was found before newer revision code, no update would actually take place To change this behavior, the driver now concludes about possibly updates and issues messages only when the entire input was parsed. Additionally, this adds back (in different places, and conditionalized upon a new module option) some messages removed by a previous patch. Signed-off-by: Jan Beulich Cc: "Siddha, Suresh B" Cc: Tigran Aivazian Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/microcode.c | 73 +++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 24 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index e7c138f66c5a..0a865889b2a9 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -91,7 +91,10 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); MODULE_AUTHOR("Tigran Aivazian "); MODULE_LICENSE("GPL"); -#define MICROCODE_VERSION "1.14" +static int verbose; +module_param(verbose, int, 0644); + +#define MICROCODE_VERSION "1.14a" #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ #define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ @@ -122,14 +125,15 @@ static unsigned int user_buffer_size; /* it's size */ typedef enum mc_error_code { MC_SUCCESS = 0, - MC_NOTFOUND = 1, - MC_MARKED = 2, - MC_ALLOCATED = 3, + MC_IGNORED = 1, + MC_NOTFOUND = 2, + MC_MARKED = 3, + MC_ALLOCATED = 4, } mc_error_code_t; static struct ucode_cpu_info { unsigned int sig; - unsigned int pf; + unsigned int pf, orig_pf; unsigned int rev; unsigned int cksum; mc_error_code_t err; @@ -164,6 +168,7 @@ static void collect_cpu_info (void *unused) rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); uci->pf = 1 << ((val[1] >> 18) & 7); } + uci->orig_pf = uci->pf; } wrmsr(MSR_IA32_UCODE_REV, 0, 0); @@ -197,21 +202,34 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he pr_debug(" Checksum 0x%x\n", cksum); if (mc_header->rev < uci->rev) { - printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" - " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); - goto out; + if (uci->err == MC_NOTFOUND) { + uci->err = MC_IGNORED; + uci->cksum = mc_header->rev; + } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev) + uci->cksum = mc_header->rev; } else if (mc_header->rev == uci->rev) { - /* notify the caller of success on this cpu */ - uci->err = MC_SUCCESS; - goto out; + if (uci->err < MC_MARKED) { + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + } + } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) { + pr_debug("microcode: CPU%d found a matching microcode update with " + " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + uci->cksum = cksum; + uci->pf = pf; /* keep the original mc pf for cksum calculation */ + uci->err = MC_MARKED; /* found the match */ + for_each_online_cpu(cpu_num) { + if (ucode_cpu_info + cpu_num != uci + && ucode_cpu_info[cpu_num].mc == uci->mc) { + uci->mc = NULL; + break; + } + } + if (uci->mc != NULL) { + vfree(uci->mc); + uci->mc = NULL; + } } - - pr_debug("microcode: CPU%d found a matching microcode update with " - " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); - uci->cksum = cksum; - uci->pf = pf; /* keep the original mc pf for cksum calculation */ - uci->err = MC_MARKED; /* found the match */ -out: return; } @@ -253,10 +271,8 @@ static int find_matching_ucodes (void) for_each_online_cpu(cpu_num) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ - continue; - if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf)) + if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); } @@ -295,9 +311,8 @@ static int find_matching_ucodes (void) } for_each_online_cpu(cpu_num) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ - continue; - if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) { + + if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) { mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); } } @@ -368,6 +383,13 @@ static void do_update_one (void * unused) struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; if (uci->mc == NULL) { + if (verbose) { + if (uci->err == MC_SUCCESS) + printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", + cpu_num, uci->rev); + else + printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); + } return; } @@ -426,6 +448,9 @@ out_free: ucode_cpu_info[j].mc = NULL; } } + if (ucode_cpu_info[i].err == MC_IGNORED && verbose) + printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision" + " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev); } out: return error; -- cgit v1.2.3 From b88d4f1d390a6a232938d27d551f24cf08a2c7e0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 23 Jun 2006 02:04:20 -0700 Subject: [PATCH] i386: break out of recursion in stackframe walk If CONFIG_FRAME_POINTERS is enabled, and one does a dump_stack() during early SMP init, an infinite stackdump and a bootup hang happens: [] show_trace+0xd/0xf [] dump_stack+0x15/0x17 [] save_trace+0xc3/0xce [] mark_lock+0x8c/0x4fe [] __lockdep_acquire+0x44e/0xaa5 [] lockdep_acquire+0x68/0x84 [] _spin_lock+0x21/0x2f [] prepare_set+0xd/0x5d [] generic_set_all+0x1d/0x201 [] mtrr_ap_init+0x23/0x3b [] identify_cpu+0x2a7/0x2af [] smp_store_cpu_info+0x2f/0xb4 [] start_secondary+0xb5/0x3ec [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [] end_of_stack_stop_unwind_function+0x1/0x4 [...] Due to "end_of_stack_stop_unwind_function" recursing back to itself in the EBP stackframe-walker. So avoid this type of recursion when walking the stack . Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 0e498369f35e..df9d210626ac 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -149,6 +149,12 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, while (valid_stack_ptr(tinfo, (void *)ebp)) { addr = *(unsigned long *)(ebp + 4); printed = print_addr_and_symbol(addr, log_lvl, printed); + /* + * break out of recursive entries (such as + * end_of_stack_stop_unwind_function): + */ + if (ebp == *(unsigned long *)ebp) + break; ebp = *(unsigned long *)ebp; } #else -- cgit v1.2.3 From a03a3e287b119c7bcbcff1d68f81864ce33b1ad2 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 23 Jun 2006 02:04:20 -0700 Subject: [PATCH] Don't trigger full rebuild via CONFIG_X86_MCE Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/common.c | 1 + arch/i386/power/cpu.c | 1 + include/asm-i386/mce.h | 5 +++++ include/asm-i386/processor.h | 6 ------ 4 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 include/asm-i386/mce.h (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index f2a2b0ac9a18..44f2c5f2dda1 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #include diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 63d25ca6306f..e6517915fe3e 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c @@ -11,6 +11,7 @@ #include #include #include +#include static struct saved_context saved_context; diff --git a/include/asm-i386/mce.h b/include/asm-i386/mce.h new file mode 100644 index 000000000000..7cc1a973bf00 --- /dev/null +++ b/include/asm-i386/mce.h @@ -0,0 +1,5 @@ +#ifdef CONFIG_X86_MCE +extern void mcheck_init(struct cpuinfo_x86 *c); +#else +#define mcheck_init(c) do {} while(0) +#endif diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 5116465272ec..0c83cf12eec9 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -728,10 +728,4 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -#ifdef CONFIG_X86_MCE -extern void mcheck_init(struct cpuinfo_x86 *c); -#else -#define mcheck_init(c) do {} while(0) -#endif - #endif /* __ASM_I386_PROCESSOR_H */ -- cgit v1.2.3 From 1b61b910e99059abdd54c93aa70e84e076e33d16 Mon Sep 17 00:00:00 2001 From: Zhang Yanmin Date: Fri, 23 Jun 2006 02:04:22 -0700 Subject: [PATCH] x86: kernel irq balance doesn't work On i386, kernel irq balance doesn't work. 1) In function do_irq_balance, after kernel finds the min_loaded cpu but before calling set_pending_irq to really pin the selected_irq to the target cpu, kernel does a cpus_and with irq_affinity[selected_irq]. Later on, when the irq is acked, kernel would calls move_native_irq=>desc->handler->set_affinity to change the irq affinity. However, every function pointed by hw_interrupt_type->set_affinity(unsigned int irq, cpumask_t cpumask) always changes irq_affinity[irq] to cpumask. Next time when recalling do_irq_balance, it has to do cpu_ands again with irq_affinity[selected_irq], but irq_affinity[selected_irq] already becomes one cpu selected by the first irq balance. 2) Function balance_irq in file arch/i386/kernel/io_apic.c has the same issue. [akpm@osdl.org: cleanups] Signed-off-by: Zhang Yanmin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 31 ++++++++++++++++++++----------- include/linux/irq.h | 8 ++++++++ kernel/irq/proc.c | 3 +++ 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d70f2ade5cde..a62df3e764c5 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -267,7 +267,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) # include /* kmalloc() */ # include /* time_after() */ -# ifdef CONFIG_BALANCED_IRQ_DEBUG +#ifdef CONFIG_BALANCED_IRQ_DEBUG # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) # define Dprintk(x...) do { TDprintk(x); } while (0) # else @@ -275,10 +275,15 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) # define Dprintk(x...) # endif - #define IRQBALANCE_CHECK_ARCH -999 -static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; -static int physical_balance = 0; +#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) +#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) +#define BALANCED_IRQ_MORE_DELTA (HZ/10) +#define BALANCED_IRQ_LESS_DELTA (HZ) + +static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH; +static int physical_balance __read_mostly; +static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; static struct irq_cpu_info { unsigned long * last_irq; @@ -297,12 +302,14 @@ static struct irq_cpu_info { #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) -#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) -#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) -#define BALANCED_IRQ_MORE_DELTA (HZ/10) -#define BALANCED_IRQ_LESS_DELTA (HZ) +static cpumask_t balance_irq_affinity[NR_IRQS] = { + [0 ... NR_IRQS-1] = CPU_MASK_ALL +}; -static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; +void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) +{ + balance_irq_affinity[irq] = mask; +} static unsigned long move(int curr_cpu, cpumask_t allowed_mask, unsigned long now, int direction) @@ -340,7 +347,7 @@ static inline void balance_irq(int cpu, int irq) if (irqbalance_disabled) return; - cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); + cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); new_cpu = move(cpu, allowed_mask, now, 1); if (cpu != new_cpu) { set_pending_irq(irq, cpumask_of_cpu(new_cpu)); @@ -529,7 +536,9 @@ tryanotherirq: } } - cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); + cpus_and(allowed_mask, + cpu_online_map, + balance_irq_affinity[selected_irq]); target_cpu_mask = cpumask_of_cpu(min_loaded); cpus_and(tmp, target_cpu_mask, allowed_mask); diff --git a/include/linux/irq.h b/include/linux/irq.h index 42c9cd562860..e8a07e75e4fb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -164,6 +164,14 @@ static inline void set_irq_info(int irq, cpumask_t mask) #endif // CONFIG_SMP +#ifdef CONFIG_IRQBALANCE +extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); +#else +static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) +{ +} +#endif + extern int no_irq_affinity; extern int noirqdebug_setup(char *str); diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index d03b5eef8ce0..afacd6f585fa 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -24,6 +24,8 @@ static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; #ifdef CONFIG_GENERIC_PENDING_IRQ void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) { + set_balance_irq_affinity(irq, mask_val); + /* * Save these away for later use. Re-progam when the * interrupt is pending @@ -33,6 +35,7 @@ void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) #else void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) { + set_balance_irq_affinity(irq, mask_val); irq_affinity[irq] = mask_val; irq_desc[irq].handler->set_affinity(irq, mask_val); } -- cgit v1.2.3 From acae9d32436122959667470b84da517d7b1b9c2d Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 23 Jun 2006 02:04:25 -0700 Subject: [PATCH] x86: make using_apic_timer __read_mostly Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apic.c | 2 +- arch/x86_64/kernel/apic.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 261796ff83c3..5ab59c12335b 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -113,7 +113,7 @@ void __init apic_intr_init(void) } /* Using APIC to generate smp_local_timer_interrupt? */ -int using_apic_timer = 0; +int using_apic_timer __read_mostly = 0; static int enabled_via_apicbase; diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 100a30c40044..29ef99001e05 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -51,7 +51,7 @@ int disable_apic_timer __initdata; static cpumask_t timer_interrupt_broadcast_ipi_mask; /* Using APIC to generate smp_local_timer_interrupt? */ -int using_apic_timer = 0; +int using_apic_timer __read_mostly = 0; static void apic_pm_activate(void); -- cgit v1.2.3 From cefc01130ba2bb0a81abda14b3f00fcc2e70dd43 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 23 Jun 2006 02:04:26 -0700 Subject: [PATCH] x86: cyrix code CONFIG_PCI fix / add __initdata PCI code was outside of CONFIG_PCI, add __initdata at cyrix_55x0 (since accessed within __init function only). Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/cyrix.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index 00f2e058797c..fc32c8028e24 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c @@ -184,7 +184,7 @@ static void __init geode_configure(void) #ifdef CONFIG_PCI -static struct pci_device_id cyrix_55x0[] = { +static struct pci_device_id __initdata cyrix_55x0[] = { { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, { }, @@ -272,14 +272,15 @@ static void __init init_cyrix(struct cpuinfo_x86 *c) printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); isa_dma_bridge_buggy = 2; -#endif - c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ - + + /* * The 5510/5520 companion chips have a funky PIT. */ if (pci_dev_present(cyrix_55x0)) pit_latch_buggy = 1; +#endif + c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ /* GXm supports extended cpuid levels 'ala' AMD */ if (c->cpuid_level == 2) { -- cgit v1.2.3 From 7b0c2d92180dbd9c7cd0c4b9bd38b06bb0f12843 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 23 Jun 2006 02:04:26 -0700 Subject: [PATCH] x86: make i387 mxcsr_feature_mask __read_mostly Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/i387.c | 2 +- arch/x86_64/kernel/i387.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index d75524758daf..c4351972d9af 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -25,7 +25,7 @@ #define HAVE_HWFP 1 #endif -static unsigned long mxcsr_feature_mask = 0xffffffff; +static unsigned long mxcsr_feature_mask __read_mostly = 0xffffffff; void mxcsr_feature_mask_init(void) { diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c index a5d7e16b928e..44ddb1ec808d 100644 --- a/arch/x86_64/kernel/i387.c +++ b/arch/x86_64/kernel/i387.c @@ -24,7 +24,7 @@ #include #include -unsigned int mxcsr_feature_mask = 0xffffffff; +unsigned int mxcsr_feature_mask __read_mostly = 0xffffffff; void mxcsr_feature_mask_init(void) { -- cgit v1.2.3 From 110cb1d2e343443c4a4b5f7e081928aa4da90f93 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 23 Jun 2006 02:04:28 -0700 Subject: [PATCH] x86: use proper defines for i8259A I/O Use proper defines instead of open-coded values. Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/i8259.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 323ef8ab3244..b7636b96e104 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -271,8 +271,8 @@ static int i8259A_shutdown(struct sys_device *dev) * the kernel initialization code can get it * out of. */ - outb(0xff, 0x21); /* mask all of 8259A-1 */ - outb(0xff, 0xA1); /* mask all of 8259A-1 */ + outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ return 0; } -- cgit v1.2.3 From 6444541671bd821b950dbaafee70d65188198aa6 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 23 Jun 2006 02:04:30 -0700 Subject: [PATCH] i386: don't try kprobes for v8086 mode Never allow int3 traps from V8086 mode to enter the kprobes handler. Signed-off-by: Zachary Amsden Cc: Prasanna S Panchamukhi Cc: Ananth N Mavinakayanahalli Cc: Anil S Keshavamurthy Cc: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 38806f427849..395a9a6dff88 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -607,7 +607,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; - if (args->regs && user_mode(args->regs)) + if (args->regs && user_mode_vm(args->regs)) return ret; switch (val) { -- cgit v1.2.3 From 7e04a1183eac3e6b3570a154c8677fd9184b51e7 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Fri, 23 Jun 2006 02:04:31 -0700 Subject: [PATCH] i386: extra checks in show_registers() Sometimes thread_info and task_struct get out-of-sync with each other. Printing task.thread_info in show_registers() can help spot this. And when task_struct is corrupt then task.comm can contain garbage, so only print as many characters as it can hold. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index df9d210626ac..dcc14477af1f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -274,8 +274,9 @@ void show_registers(struct pt_regs *regs) regs->esi, regs->edi, regs->ebp, esp); printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, ss); - printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", - current->comm, current->pid, current_thread_info(), current); + printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", + TASK_COMM_LEN, current->comm, current->pid, + current_thread_info(), current, current->thread_info); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. -- cgit v1.2.3 From 224f611c1639cb6c134a934dae7f7b9f0ac3b540 Mon Sep 17 00:00:00 2001 From: Michal Ludvig Date: Fri, 23 Jun 2006 02:04:32 -0700 Subject: [PATCH] x86: VIA C7 CPU flags New CPU flags for next generation of crypto engine as found in VIA C7 processors. Signed-off-by: Michal Ludvig Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/proc.c | 2 +- include/asm-i386/cpufeature.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index f94cdb7aca50..a19fcb262dbb 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -52,7 +52,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* VIA/Cyrix/Centaur-defined */ NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index b44bfc6239cb..3ecedbafa8ce 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -88,6 +88,12 @@ #define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ #define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ +#define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */ +#define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */ +#define X86_FEATURE_PHE (5*32+ 10) /* PadLock Hash Engine */ +#define X86_FEATURE_PHE_EN (5*32+ 11) /* PHE enabled */ +#define X86_FEATURE_PMM (5*32+ 12) /* PadLock Montgomery Multiplier */ +#define X86_FEATURE_PMM_EN (5*32+ 13) /* PMM enabled */ /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ @@ -121,6 +127,12 @@ #define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) #define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) #define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) +#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) +#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) +#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) +#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) +#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) +#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) #endif /* __ASM_I386_CPUFEATURE_H */ -- cgit v1.2.3 From b6370d96e09944c6e3ae8d5743ca8a8ab1f79f6c Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 23 Jun 2006 02:04:45 -0700 Subject: [PATCH] swsusp: i386 mark special saveable/unsaveable pages Pages (Reserved/ACPI NVS/ACPI Data) below max_low_pfn will be saved/restored by S4 currently. We should mark 'Reserved' pages not saveable. Pages (Reserved/ACPI NVS/ACPI Data) above max_low_pfn will not be saved/restored by S4 currently. We should save the 'ACPI NVS/ACPI Data' pages. Signed-off-by: Shaohua Li Cc: Pavel Machek Cc: "Rafael J. Wysocki" Cc: Nigel Cunningham Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/setup.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'arch/i386/kernel') diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index dd6b0e3386ce..e6023970aa40 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -48,6 +48,7 @@ #include #include #include +#include #include