Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions common/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ bool_cmd("qemu_console", opt_qemu_console);
bool opt_poweroff = true;
bool_cmd("poweroff", opt_poweroff);

bool opt_power_button = false;
bool_cmd("power_button", opt_power_button);

static char opt_com1[20];
string_cmd("com1", opt_com1);

Expand Down
1 change: 1 addition & 0 deletions common/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static void init_cpu(cpu_t *cpu, unsigned int id, bool is_bsp, bool enabled) {

cpu->percpu = get_percpu_page(id);
BUG_ON(!cpu->percpu);
cpu->percpu->cpu = cpu;

cpu->lock = SPINLOCK_INIT;
list_init(&cpu->task_queue);
Expand Down
4 changes: 4 additions & 0 deletions common/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <drivers/hpet.h>
#include <drivers/pic.h>
#include <drivers/pit.h>
#include <drivers/power_button.h>
#include <drivers/serial.h>
#include <drivers/vga.h>

Expand Down Expand Up @@ -283,6 +284,9 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic, unsigned long
enable_fpu();
}

if (opt_power_button)
init_power_button();

#ifdef KTF_PMU
printk("Initializing PFM library\n");

Expand Down
68 changes: 68 additions & 0 deletions drivers/power_button.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <acpi_ktf.h>
#include <drivers/power_button.h>

static void default_handler(void *);

/** power button press handler */
static pb_handler_t pb_handler = default_handler;
/** context passed to the power button press handler */
static void *pb_context = NULL;

#ifdef KTF_ACPICA
static UINT32 button_handler(void *Context) {
if (ACPI_FAILURE(AcpiClearEvent(ACPI_EVENT_POWER_BUTTON)))
panic("PWRB: Failed to clear power button event");

if (pb_handler)
pb_handler(pb_context);

return ACPI_INTERRUPT_HANDLED;
}
#endif

static void default_handler(void *notused) {
#ifdef KTF_ACPICA
acpi_power_off();
#endif
}

void pb_set_handler(pb_handler_t handler, void *context) {
// check that we are on the bsp. Assumes that there is no task migration
ASSERT(is_cpu_bsp(get_this_cpu()));

unsigned long flags = interrupts_disable_save();
pb_handler = handler;
pb_context = context;
interrupts_restore(flags);
}

bool init_power_button() {
#ifdef KTF_ACPICA
ACPI_TABLE_FADT *fadt = acpi_find_table(ACPI_SIG_FADT);

if (!(fadt->Flags & ACPI_FADT_POWER_BUTTON)) {
printk("PWRB: Configuring ACPI 'fixed' power button handling\n");

if (ACPI_FAILURE(AcpiClearEvent(ACPI_EVENT_POWER_BUTTON))) {
warning("PWRB: Failed to clear power button event");
return false;
}

if (ACPI_FAILURE(AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
button_handler, NULL))) {
warning("PWRB: Failed to install power button handler");
return false;
}
}
else {
warning("PWRB: Non-fixed power button not implemented\n");
return false;
}

return true;
#else
warning("PWRB: Power button without ACPICA not implemented\n");

return false;
#endif
}
1 change: 1 addition & 0 deletions include/cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extern bool opt_hpet;
extern bool opt_fpu;
extern bool opt_qemu_console;
extern bool opt_poweroff;
extern bool opt_power_button;
extern bool opt_fb_scroll;
extern unsigned long opt_reboot_timeout;
extern bool opt_tlb_global;
Expand Down
4 changes: 4 additions & 0 deletions include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ extern void wait_for_all_cpus(void);

/* Static declarations */

static inline cpu_t *get_this_cpu() {
return PERCPU_GET(cpu);
}

static inline bool is_cpu_bsp(cpu_t *cpu) {
return cpu->flags.bsp;
}
Expand Down
18 changes: 18 additions & 0 deletions include/drivers/power_button.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef KTF_POWER_BUTTON_H
#define KTF_POWER_BUTTON_H

typedef void (*pb_handler_t)(void *);

/**
* Set a handler for the power button. Useful to control experiments.
*
* Note: This function MUST be called from the bsp to ensure consistency!
*/
void pb_set_handler(pb_handler_t handler, void *context);

/**
* Initialize power button handling. Requires ACPICA library.
*/
extern bool init_power_button();

#endif /* KTF_POWER_BUTTON_H */
2 changes: 2 additions & 0 deletions include/percpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <list.h>
#include <page.h>

struct cpu;
struct percpu {
list_head_t list;

Expand Down Expand Up @@ -60,6 +61,7 @@ struct percpu {
unsigned long usermode_private;
volatile unsigned long apic_ticks;
bool apic_timer_enabled;
struct cpu *cpu;
} __aligned(PAGE_SIZE);
typedef struct percpu percpu_t;

Expand Down