coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smihandler.c
Go to the documentation of this file.
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3
/*
4
* SMI handler -- mostly takes care of SMIs from the EC
5
*/
6
7
#include <arch/io.h>
8
#include <
console/console.h
>
9
#include <
cpu/x86/smm.h
>
10
#include <
ec/compal/ene932/ec.h
>
11
#include <
southbridge/amd/agesa/hudson/hudson.h
>
12
#include <
southbridge/amd/agesa/hudson/smi.h
>
13
14
#include "
ec.h
"
15
16
#define ACPI_PM1_CNT_SLEEP(state) ((1 << 13) | (state & 0x7) << 10)
17
18
enum
sleep_states
{
19
S0
= 0,
20
S1
= 1,
21
S3
= 3,
22
S4
= 4,
23
S5
= 5,
24
};
25
26
enum
ec_smi_event
{
27
EC_SMI_EVENT_IDLE
= 0x80,
28
EC_SMI_BATTERY_LOW
= 0xb3,
29
};
30
31
/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
32
static
void
ec_enter_apm_mode
(
void
)
33
{
34
ec_kbc_write_cmd
(0x59);
35
ec_kbc_write_ib
(0xE9);
36
}
37
/* Tell EC to operate in ACPI mode, thus generating SCIs on events, not SMIs */
38
static
void
ec_enter_acpi_mode
(
void
)
39
{
40
ec_kbc_write_cmd
(0x59);
41
ec_kbc_write_ib
(0xE8);
42
}
43
44
static
uint8_t
ec_get_smi_event
(
void
)
45
{
46
ec_kbc_write_cmd
(0x56);
47
return
ec_kbc_read_ob
();
48
}
49
50
static
void
ec_process_smi
(
uint8_t
src)
51
{
52
/* Reading the SMI source satisfies the EC in terms of responding to
53
* the event, regardless of whether we take an action or not.
54
*/
55
56
switch
(src) {
57
case
EC_SMI_BATTERY_LOW
:
58
printk
(
BIOS_DEBUG
,
"Battery low. Shutting down\n"
);
59
outl
(
ACPI_PM1_CNT_SLEEP
(
S5
),
ACPI_PM1_CNT_BLK
);
60
break
;
61
default
:
62
printk
(
BIOS_DEBUG
,
"EC_SMI event 0x%x\n"
, src);
63
}
64
}
65
66
static
void
handle_ec_smi
(
void
)
67
{
68
uint8_t
src;
69
70
while
((src =
ec_get_smi_event
()) !=
EC_SMI_EVENT_IDLE
)
71
ec_process_smi
(src);
72
}
73
74
static
void
handle_lid_smi
(
void
)
75
{
76
/* Only triggered in non-ACPI mode on lid close. */
77
outl
(
ACPI_PM1_CNT_SLEEP
(
S4
),
ACPI_PM1_CNT_BLK
);
78
}
79
80
int
mainboard_smi_apmc
(
uint8_t
data)
81
{
82
switch
(data) {
83
case
ACPI_SMI_CMD_ENABLE
:
84
printk
(
BIOS_DEBUG
,
"Enable ACPI mode\n"
);
85
ec_enter_acpi_mode
();
86
hudson_disable_gevent_smi
(
EC_LID_GEVENT
);
87
break
;
88
case
ACPI_SMI_CMD_DISABLE
:
89
printk
(
BIOS_DEBUG
,
"Disable ACPI mode\n"
);
90
ec_enter_apm_mode
();
91
hudson_configure_gevent_smi
(
EC_LID_GEVENT
,
SMI_MODE_SMI
,
92
SMI_LVL_LOW
);
93
break
;
94
default
:
95
printk
(
BIOS_DEBUG
,
"Unhandled ACPI command: 0x%x\n"
, data);
96
}
97
return
0;
98
}
99
100
void
mainboard_smi_gpi
(
uint32_t
gpi_sts)
101
{
102
if
(gpi_sts & (1 <<
EC_SMI_GEVENT
))
103
handle_ec_smi
();
104
if
(gpi_sts & (1 <<
EC_LID_GEVENT
))
105
handle_lid_smi
();
106
}
hudson.h
ACPI_SMI_CMD_ENABLE
#define ACPI_SMI_CMD_ENABLE
Definition:
hudson.h:29
ACPI_SMI_CMD_DISABLE
#define ACPI_SMI_CMD_DISABLE
Definition:
hudson.h:28
ACPI_PM1_CNT_BLK
#define ACPI_PM1_CNT_BLK
Definition:
iomap.h:43
printk
#define printk(level,...)
Definition:
stdlib.h:16
console.h
mainboard_smi_apmc
int __weak mainboard_smi_apmc(u8 data)
Definition:
smihandler.c:209
mainboard_smi_gpi
void __weak mainboard_smi_gpi(u32 gpi_sts)
Definition:
smihandler.c:208
outl
void outl(u32 val, u16 port)
ec_kbc_read_ob
u8 ec_kbc_read_ob(void)
Definition:
ec.c:71
ec_kbc_write_ib
void ec_kbc_write_ib(u8 data)
Definition:
ec.c:83
ec_kbc_write_cmd
void ec_kbc_write_cmd(u8 cmd)
Definition:
ec.c:77
ec.h
EC_SMI_GEVENT
#define EC_SMI_GEVENT
Definition:
mainboard.h:13
EC_LID_GEVENT
#define EC_LID_GEVENT
Definition:
mainboard.h:12
smm.h
BIOS_DEBUG
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition:
loglevel.h:128
handle_lid_smi
static void handle_lid_smi(void)
Definition:
smihandler.c:74
ACPI_PM1_CNT_SLEEP
#define ACPI_PM1_CNT_SLEEP(state)
Definition:
smihandler.c:16
ec_smi_event
ec_smi_event
Definition:
smihandler.c:26
EC_SMI_EVENT_IDLE
@ EC_SMI_EVENT_IDLE
Definition:
smihandler.c:27
EC_SMI_BATTERY_LOW
@ EC_SMI_BATTERY_LOW
Definition:
smihandler.c:28
ec_enter_apm_mode
static void ec_enter_apm_mode(void)
Definition:
smihandler.c:32
handle_ec_smi
static void handle_ec_smi(void)
Definition:
smihandler.c:66
sleep_states
sleep_states
Definition:
smihandler.c:18
S3
@ S3
Definition:
smihandler.c:21
S1
@ S1
Definition:
smihandler.c:20
S5
@ S5
Definition:
smihandler.c:23
S4
@ S4
Definition:
smihandler.c:22
S0
@ S0
Definition:
smihandler.c:19
ec_get_smi_event
static uint8_t ec_get_smi_event(void)
Definition:
smihandler.c:44
ec_enter_acpi_mode
static void ec_enter_acpi_mode(void)
Definition:
smihandler.c:38
ec_process_smi
static void ec_process_smi(uint8_t src)
Definition:
smihandler.c:50
ec.h
SMI_MODE_SMI
@ SMI_MODE_SMI
Definition:
smi.h:10
smi.h
hudson_disable_gevent_smi
void hudson_disable_gevent_smi(uint8_t gevent)
Disable events from given GEVENT pin.
Definition:
smi_util.c:63
hudson_configure_gevent_smi
void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
Configure generation of interrupts for given GEVENT pin.
Definition:
smi_util.c:43
SMI_LVL_LOW
@ SMI_LVL_LOW
Definition:
smi.h:32
uint32_t
unsigned int uint32_t
Definition:
stdint.h:14
uint8_t
unsigned char uint8_t
Definition:
stdint.h:8
src
mainboard
hp
pavilion_m6_1035dx
smihandler.c
Generated by
1.9.1