예제 #1
0
void southbridge_smm_clear_state(void)
{
    u32 smi_en;

#if CONFIG_ELOG
    /* Log events from chipset before clearing */
    pch_log_state();
#endif
    printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
    printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", get_pmbase());

    smi_en = inl(get_pmbase() + SMI_EN);
    if (smi_en & APMC_EN) {
        printk(BIOS_INFO, "SMI# handler already enabled?\n");
        return;
    }

    printk(BIOS_DEBUG, "\n");

    /* Dump and clear status registers */
    clear_smi_status();
    clear_pm1_status();
    clear_tco_status();
    clear_gpe_status();
}
예제 #2
0
파일: elog.c 프로젝트: 0ida/coreboot
static void pch_log_gpio_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg, int start)
{
	/* GPE Bank 1 is GPIO 0-31 */
	u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
	u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;
	int i;

	for (i = 0; i <= 31; i++) {
		if (gpe0_sts & (1 << i))
			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start);
	}
}
예제 #3
0
static uint16_t reset_pm1_status(void)
{
	uint16_t pmbase = get_pmbase();
	uint16_t pm1_sts = inw(pmbase + PM1_STS);
	outw(pm1_sts, pmbase + PM1_STS);
	return pm1_sts;
}
예제 #4
0
static uint8_t mainboard_smi_ec(void)
{
	uint8_t cmd = google_chromeec_get_event();
	uint16_t pmbase = get_pmbase();
	uint32_t pm1_cnt;

#if IS_ENABLED(CONFIG_ELOG_GSMI)
	/* Log this event */
	if (cmd)
		elog_add_event_byte(ELOG_TYPE_EC_EVENT, cmd);
#endif

	switch (cmd) {
	case EC_HOST_EVENT_LID_CLOSED:
		printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n");

		/* Go to S5 */
		pm1_cnt = inl(pmbase + PM1_CNT);
		pm1_cnt |= SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT);
		outl(pm1_cnt, pmbase + PM1_CNT);
		break;
	}

	return cmd;
}
예제 #5
0
static uint32_t reset_alt_status(void)
{
	uint16_t pmbase = get_pmbase();
	uint32_t alt_gpio_smi = inl(pmbase + ALT_GPIO_SMI);
	outl(alt_gpio_smi, pmbase + ALT_GPIO_SMI);
	return alt_gpio_smi;
}
예제 #6
0
파일: acpi.c 프로젝트: 0ida/coreboot
void generate_cpu_entries(void)
{
	int len_pr, core;
	int pcontrol_blk = get_pmbase(), plen = 6;
	const struct pattrs *pattrs = pattrs_get();

	for (core=0; core<pattrs->num_cpus; core++) {
		if (core > 0) {
			pcontrol_blk = 0;
			plen = 0;
		}

		/* Generate processor \_PR.CPUx */
		len_pr = acpigen_write_processor(
			core, pcontrol_blk, plen);

		/* Generate  P-state tables */
		len_pr += generate_P_state_entries(
			core, pattrs->num_cpus);

		/* Generate C-state tables */
		len_pr += acpigen_write_CST_package(
			cstate_map, ARRAY_SIZE(cstate_map));

		/* Generate T-state tables */
		len_pr += generate_T_state_entries(
			core, pattrs->num_cpus);

		len_pr--;
		acpigen_patch_len(len_pr);
	}
}
예제 #7
0
void disable_gpe(uint32_t mask)
{
	uint16_t pmbase = get_pmbase();
	uint32_t gpe0_en = inl(pmbase + GPE0_EN);
	gpe0_en &= ~mask;
	outl(gpe0_en, pmbase + GPE0_EN);
}
예제 #8
0
static uint32_t reset_gpe_status(void)
{
	uint16_t pmbase = get_pmbase();
	uint32_t gpe_sts = inl(pmbase + GPE0_STS);
	outl(gpe_sts, pmbase + GPE0_STS);
	return gpe_sts;
}
예제 #9
0
void disable_pm1_control(uint32_t mask)
{
	uint16_t pmbase = get_pmbase();
	uint32_t pm1_cnt = inl(pmbase + PM1_CNT);
	pm1_cnt &= ~mask;
	outl(pm1_cnt, pmbase + PM1_CNT);
}
예제 #10
0
void disable_smi(uint32_t mask)
{
	uint16_t pmbase = get_pmbase();
	uint32_t smi_en = inl(pmbase + SMI_EN);
	smi_en &= ~mask;
	outl(smi_en, pmbase + SMI_EN);
}
예제 #11
0
static uint32_t reset_smi_status(void)
{
	uint16_t pmbase = get_pmbase();
	uint32_t smi_sts = inl(pmbase + SMI_STS);
	outl(smi_sts, pmbase + SMI_STS);
	return smi_sts;
}
예제 #12
0
파일: elog.c 프로젝트: 0ida/coreboot
static void pch_log_standard_gpe(u32 gpe0_sts_reg, u32 gpe0_en_reg)
{
	u32 gpe0_en = inl(get_pmbase() + gpe0_en_reg);
	u32 gpe0_sts = inl(get_pmbase() + gpe0_sts_reg) & gpe0_en;

	/* PME (TODO: determine wake device) */
	if (gpe0_sts & (1 << 11))
		elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);

	/* Internal PME (TODO: determine wake device) */
	if (gpe0_sts & (1 << 13))
		elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);

	/* SMBUS Wake */
	if (gpe0_sts & (1 << 7))
		elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
}
예제 #13
0
static uint32_t reset_tco_status(void)
{
	uint16_t pmbase = get_pmbase();
	uint32_t tco_sts = inl(pmbase + TCO_STS);
	uint32_t tco_en = inl(pmbase + TCO1_CNT);

	outl(tco_sts, pmbase + TCO_STS);
	return tco_sts & tco_en;
}
예제 #14
0
void southbridge_smm_init(void)
{
	u32 smi_en;

#if CONFIG_ELOG
	/* Log events from chipset before clearing */
	pch_log_state();
#endif
	printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
	printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", get_pmbase());

	smi_en = inl(get_pmbase() + SMI_EN);
	if (smi_en & APMC_EN) {
		printk(BIOS_INFO, "SMI# handler already enabled?\n");
		return;
	}

	printk(BIOS_DEBUG, "\n");

	/* Dump and clear status registers */
	clear_smi_status();
	clear_pm1_status();
	clear_tco_status();
	clear_gpe_status();

	/* Configure events */
	enable_pm1(PWRBTN_EN | GBL_EN);
	disable_gpe(PME_B0_EN);

	/* Enable SMI generation:
	 *  - on TCO events
	 *  - on APMC writes (io 0xb2)
	 *  - on writes to SLP_EN (sleep states)
	 *  - on writes to GBL_RLS (bios commands)
	 * No SMIs:
	 *  - on microcontroller writes (io 0x62/0x66)
	 */
	enable_smi(TCO_EN | APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
}
예제 #15
0
static u8 mainboard_smi_ec(void)
{
	u8 cmd = google_chromeec_get_event();
	u32 pm1_cnt;

#if CONFIG_ELOG_GSMI
	/* Log this event */
	if (cmd)
		elog_add_event_byte(ELOG_TYPE_EC_EVENT, cmd);
#endif

	switch (cmd) {
	case EC_HOST_EVENT_LID_CLOSED:
		printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n");

		/* Go to S5 */
		pm1_cnt = inl(get_pmbase() + PM1_CNT);
		pm1_cnt |= (0xf << 10);
		outl(pm1_cnt, get_pmbase() + PM1_CNT);
		break;
	}

	return cmd;
}
예제 #16
0
void southcluster_smm_clear_state(void)
{
	uint32_t smi_en;

	/* Log events from chipset before clearing */
	southcluster_log_state();

	printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
	printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());

	smi_en = inl(get_pmbase() + SMI_EN);
	if (smi_en & APMC_EN) {
		printk(BIOS_INFO, "SMI# handler already enabled?\n");
		return;
	}

	/* Dump and clear status registers */
	clear_smi_status();
	clear_pm1_status();
	clear_tco_status();
	clear_gpe_status();
	clear_alt_status();
	clear_pmc_status();
}
예제 #17
0
파일: elog.c 프로젝트: 0ida/coreboot
static void pch_log_gpe(void)
{
	int i;
	u16 pmbase = get_pmbase();
	u32 gpe0_sts, gpe0_en;
	int gpe0_high_gpios[] = {
		[0] = 27,
		[24] = 17,
		[25] = 19,
		[26] = 21,
		[27] = 22,
		[28] = 43,
		[29] = 56,
		[30] = 57,
		[31] = 60
	};

	pch_log_standard_gpe(GPE0_EN, GPE0_STS);

	/* GPIO 0-15 */
	gpe0_en = inw(pmbase + GPE0_EN + 2);
	gpe0_sts = inw(pmbase + GPE0_STS + 2) & gpe0_en;
	for (i = 0; i <= 15; i++) {
		if (gpe0_sts & (1 << i))
			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i);
	}

	/*
	 * Now check and log upper status bits
	 */

	gpe0_en = inl(pmbase + GPE0_EN_2);
	gpe0_sts = inl(pmbase + GPE0_STS_2) & gpe0_en;

	for (i = 0; i <= 31; i++) {
		if (!gpe0_high_gpios[i])
			continue;
		if (gpe0_sts & (1 << i))
			elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO,
					    gpe0_high_gpios[i]);
	}
}
예제 #18
0
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
{
	acpi_header_t *header = &(fadt->header);
	u16 pmbase = get_pmbase();

	memset((void *) fadt, 0, sizeof(acpi_fadt_t));
	memcpy(header->signature, "FACP", 4);
	header->length = sizeof(acpi_fadt_t);
	header->revision = 3;
	memcpy(header->oem_id, OEM_ID, 6);
	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
	memcpy(header->asl_compiler_id, ASLC, 4);
	header->asl_compiler_revision = 1;

	fadt->firmware_ctrl = (unsigned long) facs;
	fadt->dsdt = (unsigned long) dsdt;
	fadt->model = 1;
	fadt->preferred_pm_profile = PM_MOBILE;

	fadt->sci_int = 0x9;
	fadt->smi_cmd = APM_CNT;
	fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
	fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
	fadt->s4bios_req = 0x0;
	fadt->pstate_cnt = 0;

	fadt->pm1a_evt_blk = pmbase;
	fadt->pm1b_evt_blk = 0x0;
	fadt->pm1a_cnt_blk = pmbase + 0x4;
	fadt->pm1b_cnt_blk = 0x0;
	fadt->pm2_cnt_blk = pmbase + 0x50;
	fadt->pm_tmr_blk = pmbase + 0x8;
	fadt->gpe0_blk = pmbase + 0x80;
	fadt->gpe1_blk = 0;

	fadt->pm1_evt_len = 4;
	fadt->pm1_cnt_len = 2;
	fadt->pm2_cnt_len = 1;
	fadt->pm_tmr_len = 4;
	fadt->gpe0_blk_len = 32;
	fadt->gpe1_blk_len = 0;
	fadt->gpe1_base = 0;
	fadt->cst_cnt = 0;
	fadt->p_lvl2_lat = 1;
	fadt->p_lvl3_lat = 87;
	fadt->flush_size = 1024;
	fadt->flush_stride = 16;
	fadt->duty_offset = 1;
	fadt->duty_width = 0;
	fadt->day_alrm = 0xd;
	fadt->mon_alrm = 0x00;
	fadt->century = 0x00;
	fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;

	fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
			ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
			ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE |
			ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;

	fadt->reset_reg.space_id = 1;
	fadt->reset_reg.bit_width = 8;
	fadt->reset_reg.bit_offset = 0;
	fadt->reset_reg.resv = 0;
	fadt->reset_reg.addrl = 0xcf9;
	fadt->reset_reg.addrh = 0;

	fadt->reset_value = 6;
	fadt->x_firmware_ctl_l = (unsigned long)facs;
	fadt->x_firmware_ctl_h = 0;
	fadt->x_dsdt_l = (unsigned long)dsdt;
	fadt->x_dsdt_h = 0;

	fadt->x_pm1a_evt_blk.space_id = 1;
	fadt->x_pm1a_evt_blk.bit_width = 32;
	fadt->x_pm1a_evt_blk.bit_offset = 0;
	fadt->x_pm1a_evt_blk.resv = 0;
	fadt->x_pm1a_evt_blk.addrl = pmbase;
	fadt->x_pm1a_evt_blk.addrh = 0x0;

	fadt->x_pm1b_evt_blk.space_id = 1;
	fadt->x_pm1b_evt_blk.bit_width = 0;
	fadt->x_pm1b_evt_blk.bit_offset = 0;
	fadt->x_pm1b_evt_blk.resv = 0;
	fadt->x_pm1b_evt_blk.addrl = 0x0;
	fadt->x_pm1b_evt_blk.addrh = 0x0;

	fadt->x_pm1a_cnt_blk.space_id = 1;
	fadt->x_pm1a_cnt_blk.bit_width = 16;
	fadt->x_pm1a_cnt_blk.bit_offset = 0;
	fadt->x_pm1a_cnt_blk.resv = 0;
	fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
	fadt->x_pm1a_cnt_blk.addrh = 0x0;

	fadt->x_pm1b_cnt_blk.space_id = 1;
	fadt->x_pm1b_cnt_blk.bit_width = 0;
	fadt->x_pm1b_cnt_blk.bit_offset = 0;
	fadt->x_pm1b_cnt_blk.resv = 0;
	fadt->x_pm1b_cnt_blk.addrl = 0x0;
	fadt->x_pm1b_cnt_blk.addrh = 0x0;

	fadt->x_pm2_cnt_blk.space_id = 1;
	fadt->x_pm2_cnt_blk.bit_width = 8;
	fadt->x_pm2_cnt_blk.bit_offset = 0;
	fadt->x_pm2_cnt_blk.resv = 0;
	fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
	fadt->x_pm2_cnt_blk.addrh = 0x0;

	fadt->x_pm_tmr_blk.space_id = 1;
	fadt->x_pm_tmr_blk.bit_width = 32;
	fadt->x_pm_tmr_blk.bit_offset = 0;
	fadt->x_pm_tmr_blk.resv = 0;
	fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
	fadt->x_pm_tmr_blk.addrh = 0x0;

	fadt->x_gpe0_blk.space_id = 0;
	fadt->x_gpe0_blk.bit_width = 0;
	fadt->x_gpe0_blk.bit_offset = 0;
	fadt->x_gpe0_blk.resv = 0;
	fadt->x_gpe0_blk.addrl = 0;
	fadt->x_gpe0_blk.addrh = 0x0;

	fadt->x_gpe1_blk.space_id = 1;
	fadt->x_gpe1_blk.bit_width = 0;
	fadt->x_gpe1_blk.bit_offset = 0;
	fadt->x_gpe1_blk.resv = 0;
	fadt->x_gpe1_blk.addrl = 0x0;
	fadt->x_gpe1_blk.addrh = 0x0;

	header->checksum =
	    acpi_checksum((void *) fadt, header->length);
}
예제 #19
0
void enable_pm1(uint16_t events)
{
	outw(events, get_pmbase() + PM1_EN);
}
예제 #20
0
파일: elog.c 프로젝트: 0ida/coreboot
void pch_log_state(void)
{
	u16 pm1_sts, gen_pmcon_3, tco2_sts;
	u8 gen_pmcon_2;
	struct device *lpc = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
	if (!lpc)
		return;

	pm1_sts = inw(get_pmbase() + PM1_STS);
	tco2_sts = inw(get_pmbase() + TCO2_STS);
	gen_pmcon_2 = pci_read_config8(lpc, GEN_PMCON_2);
	gen_pmcon_3 = pci_read_config16(lpc, GEN_PMCON_3);

	/* PWR_FLR Power Failure */
	if (gen_pmcon_2 & (1 << 0))
		elog_add_event(ELOG_TYPE_POWER_FAIL);

	/* SUS Well Power Failure */
	if (gen_pmcon_3 & (1 << 14))
		elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);

	/* SYS_PWROK Failure */
	if (gen_pmcon_2 & (1 << 1))
		elog_add_event(ELOG_TYPE_SYS_PWROK_FAIL);

	/* PWROK Failure */
	if (gen_pmcon_2 & (1 << 0))
		elog_add_event(ELOG_TYPE_PWROK_FAIL);

	/* Second TCO Timeout */
	if (tco2_sts & (1 << 1))
		elog_add_event(ELOG_TYPE_TCO_RESET);

	/* Power Button Override */
	if (pm1_sts & (1 << 11))
		elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);

	/* System Reset Status (reset button pushed) */
	if (gen_pmcon_2 & (1 << 4))
		elog_add_event(ELOG_TYPE_RESET_BUTTON);

	/* General Reset Status */
	if (gen_pmcon_3 & (1 << 9))
		elog_add_event(ELOG_TYPE_SYSTEM_RESET);

	/* ACPI Wake */
	if (pm1_sts & (1 << 15))
		elog_add_event_byte(ELOG_TYPE_ACPI_WAKE,
				    acpi_is_wakeup_s3() ? 3 : 5);

	/*
	 * Wake sources
	 */

	/* Power Button */
	if (pm1_sts & (1 << 8))
		elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);

	/* RTC */
	if (pm1_sts & (1 << 10))
		elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);

	/* PCI Express (TODO: determine wake device) */
	if (pm1_sts & (1 << 14))
		elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);

	/* GPE */
	if (pch_is_lp())
		pch_lp_log_gpe();
	else
		pch_log_gpe();
}