void pcr_or32(uint8_t pid, uint16_t offset, uint32_t ordata) { uint32_t data32; data32 = pcr_read32(pid, offset); data32 |= ordata; pcr_write32(pid, offset, data32); }
/* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *pei_data) { char *spd_file; size_t spd_file_len; int spd_index; int spd_gpio[4]; /************************************************************* * FIXME: Remove when real GPIO support is ready. */ GPIO_PAD gpio_set[4] = { GPIO_LP_GPP_C12, /* PCH_MEM_CONFIG[0] */ GPIO_LP_GPP_C13, /* PCH_MEM_CONFIG[1] */ GPIO_LP_GPP_C14, /* PCH_MEM_CONFIG[2] */ GPIO_LP_GPP_C15, /* PCH_MEM_CONFIG[3] */ }; int index; for (index = 0; index < ARRAY_SIZE(gpio_set); index++) { u32 number = GPIO_GET_PAD_NUMBER(gpio_set[index]); u32 cfgreg = 8 * number + R_PCH_PCR_GPIO_GPP_C_PADCFG_OFFSET; /* * Set GPIO mode and enable input * Clear PMODE0 | PMODE1 | GPIORXDIS */ u32 dw0mask = (1 << 10) | (1 << 11) | (1 << 9); u32 dw0reg = 0; pcr_andthenor32(PID_GPIOCOM1, cfgreg, ~dw0mask, dw0reg); /* Read current input value */ pcr_read32(PID_GPIOCOM1, cfgreg, &dw0reg); spd_gpio[index] = !!(dw0reg & (1 << 1)); } /*************************************************************/ spd_index = (spd_gpio[3] << 3) | (spd_gpio[2] << 2) | (spd_gpio[1] << 1) | spd_gpio[0]; printk(BIOS_DEBUG, "SPD: index %d (GPP_C15=%d GPP_C14=%d GPP_C13=%d GPP_C12=%d)\n", spd_index, spd_gpio[3], spd_gpio[2], spd_gpio[1], spd_gpio[0]); /* Load SPD data from CBFS */ spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); /* make sure we have at least one SPD in the file. */ if (spd_file_len < SPD_LEN) die("Missing SPD data."); /* Make sure we did not overrun the buffer */ if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n"); spd_index = 1; } /* Assume same memory in both channels */ spd_index *= SPD_LEN; memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN); memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN); /* Make sure a valid SPD was found */ if (pei_data->spd_data[0][0][0] == 0) die("Invalid SPD data."); mainboard_print_spd_info(pei_data->spd_data[0][0]); }
void smihandler_southbridge_monitor( const struct smm_save_state_ops *save_state_ops) { #define IOTRAP(x) (trap_sts & (1 << x)) u32 trap_cycle; u32 data, mask = 0; u8 trap_sts; int i; global_nvs_t *gnvs = smm_get_gnvs(); /* TRSR - Trap Status Register */ trap_sts = pcr_read8(PID_PSTH, PCR_PSTH_TRPST); /* Clear trap(s) in TRSR */ pcr_write8(PID_PSTH, PCR_PSTH_TRPST, trap_sts); /* TRPC - Trapped cycle */ trap_cycle = pcr_read32(PID_PSTH, PCR_PSTH_TRPC); for (i = 16; i < 20; i++) { if (trap_cycle & (1 << i)) mask |= (0xff << ((i - 16) << 2)); } /* IOTRAP(3) SMI function call */ if (IOTRAP(3)) { if (gnvs && gnvs->smif) io_trap_handler(gnvs->smif); return; } /* * IOTRAP(2) currently unused * IOTRAP(1) currently unused */ /* IOTRAP(0) SMIC */ if (IOTRAP(0)) { if (!(trap_cycle & (1 << 24))) { /* It's a write */ printk(BIOS_DEBUG, "SMI1 command\n"); /* Trapped write data */ data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD); data &= mask; } } printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc); for (i = 0; i < 4; i++) if (IOTRAP(i)) printk(BIOS_DEBUG, " TRAP = %d\n", i); printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf); printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask); printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write"); if (!(trap_cycle & (1 << 24))) { /* Write Cycle */ data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD); printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data); } #undef IOTRAP }