/** * Update the UPD data based on values from devicetree.cb * * @param UpdData Pointer to the UPD Data structure */ static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData) { /* * Serial Port */ if (IS_ENABLED(CONFIG_INTEGRATED_UART)) UpdData->SerialPortConfigure = 1; /* * Memory Down */ if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN)) { UpdData->MemDownEnable = 1; if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM0_SPD_PRESENT)) UpdData->MemDownCh0Dimm0SpdPtr = (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm0.bin", CBFS_TYPE_RAW, NULL); if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH0DIMM1_SPD_PRESENT)) UpdData->MemDownCh0Dimm1SpdPtr = (UINT32)cbfs_boot_map_with_leak("spd_ch0_dimm1.bin", CBFS_TYPE_RAW, NULL); if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM0_SPD_PRESENT)) UpdData->MemDownCh1Dimm0SpdPtr = (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm0.bin", CBFS_TYPE_RAW, NULL); if (IS_ENABLED(CONFIG_FSP_MEMORY_DOWN_CH1DIMM1_SPD_PRESENT)) UpdData->MemDownCh1Dimm1SpdPtr = (UINT32)cbfs_boot_map_with_leak("spd_ch1_dimm1.bin", CBFS_TYPE_RAW, NULL); } else { UpdData->MemDownEnable = 0; } printk(FSP_INFO_LEVEL, "Memory Down Support: %s\n", UpdData->MemDownEnable ? "Enabled" : "Disabled"); /* * Fast Boot */ if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) UpdData->MemFastBoot = 1; else UpdData->MemFastBoot = 0; /* * Hyper-Threading */ if (IS_ENABLED(CONFIG_FSP_HYPERTHREADING)) UpdData->HyperThreading = 1; else UpdData->HyperThreading = 0; }
static uint8_t retrieve_board_id(void) { const char *board_id_file_name = CBFS_BOARD_ID_FILE_NAME; char *file_contents; int i; size_t length; file_contents = cbfs_boot_map_with_leak(board_id_file_name, CBFS_TYPE_RAW, &length); if (!file_contents) { printk(BIOS_WARNING, "board_id: failed to locate file '%s'\n", board_id_file_name); return 0; } for (i = 0; i < ARRAY_SIZE(board_id_map); i++) { const struct bid_map *entry = board_id_map + i; if ((strlen(entry->board_name) == length) && !strncmp(entry->board_name, file_contents, length)) { printk(BIOS_INFO, "board_id: name '%s', ID %d\n", entry->board_name, entry->board_id); return entry->board_id; } } printk(BIOS_WARNING, "board_id: no match for board name '%.*s'\n", length, file_contents); printk(BIOS_WARNING, "board_id: will use default board ID 0\n"); return 0; }
/* Get SPD data for on-board memory */ uint8_t *mainboard_find_spd_data() { uint8_t *spd_data; int spd_index; size_t spd_file_len; char *spd_file; spd_index = 0; spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 0 due to incorrect SPD index.\n"); spd_index = 0; } if (spd_file_len < SPD_LEN) die("Missing SPD data."); /* Assume same memory in both channels */ spd_index *= SPD_LEN; spd_data = (uint8_t *)(spd_file + spd_index); /* Make sure a valid SPD was found */ if (spd_data[0] == 0) die("Invalid SPD data."); return spd_data; }
void mainboard_romstage_entry(struct romstage_params *rp) { void *spd_content; int dual_channel = 0; void *spd_file; size_t spd_fsize; struct mrc_params mp = { .mainboard = { .dram_type = DRAM_DDR3L, .dram_info_location = DRAM_INFO_SPD_MEM, .weaker_odt_settings = 1, }, }; spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_fsize); if (!spd_file) die("SPD data not found."); /* Both channels are always present. */ spd_content = get_spd_pointer(spd_file, spd_fsize / SPD_SIZE, &dual_channel); mp.mainboard.dram_data[0] = spd_content; if (dual_channel) mp.mainboard.dram_data[1] = spd_content; rp->mrc_params = ∓ romstage_common(rp); }
unsigned long mainboard_write_acpi_tables(device_t dev, unsigned long start, acpi_rsdp_t *rsdp) { unsigned long current; acpi_header_t *ssdtx; const void *p; size_t p_size; int i; get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */ /* Align ACPI tables to 16 bytes */ start = ALIGN(start, 16); current = start; /* same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table */ for(i = 1; i < sysconf.hc_possible_num; i++) { /* 0: is hc sblink */ const char *file_name; if((sysconf.pci1234[i] & 1) != 1 ) continue; u8 c; if(i < 7) { c = (u8) ('4' + i - 1); } else { c = (u8) ('A' + i - 1 - 6); } current = ALIGN(current, 8); printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); /* pci0 and pci1 are in dsdt */ ssdtx = (acpi_header_t *)current; switch(sysconf.hcid[i]) { case 1: /* 8132 */ file_name = CONFIG_CBFS_PREFIX "/ssdt2.aml"; break; case 2: /* 8151 */ file_name = CONFIG_CBFS_PREFIX "/ssdt3.aml"; break; case 3: /* 8131 */ file_name = CONFIG_CBFS_PREFIX "/ssdt4.aml"; break; default: continue; } p = cbfs_boot_map_with_leak( file_name, CBFS_TYPE_RAW, &p_size); if (!p || p_size < sizeof(acpi_header_t)) continue; memcpy(ssdtx, p, sizeof(acpi_header_t)); current += ssdtx->length; memcpy(ssdtx, p, ssdtx->length); update_ssdtx((void *)ssdtx, i); ssdtx->checksum = 0; ssdtx->checksum = acpi_checksum((u8 *)ssdtx, ssdtx->length); acpi_add_table(rsdp, ssdtx); } return current; }
/* Copy SPD data for on-board memory */ static void copy_spd(struct pei_data *peid) { const int gpio_vector[] = {13, 9, 47, -1}; int spd_index = get_gpios(gpio_vector); char *spd_file; size_t spd_file_len; printk(BIOS_DEBUG, "SPD index %d\n", spd_index); spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * sizeof(peid->spd_data[0]))) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < sizeof(peid->spd_data[0])) die("Missing SPD data."); /* Index 0-2, are 4GB config with both CH0 and CH1 * Index 3-5, are 2GB config with CH0 only */ switch (spd_index) { case 3: case 4: case 5: peid->dimm_channel1_disabled = 3; } memcpy(peid->spd_data[0], spd_file + spd_index * sizeof(peid->spd_data[0]), sizeof(peid->spd_data[0])); }
uintptr_t mainboard_get_spd_data(void) { char *spd_file; size_t spd_file_len; int spd_index; spd_index = mainboard_get_spd_index(); printk(BIOS_INFO, "SPD index %d\n", spd_index); /* 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; } spd_index *= SPD_LEN; mainboard_print_spd_info((uint8_t *)(spd_file + spd_index)); return (uintptr_t)(spd_file + spd_index); }
/* Copy SPD data for on-board memory */ static void copy_spd(struct pei_data *peid) { const int gpio_vector[] = {13, 9, 47, -1}; int spd_index = get_gpios(gpio_vector); char *spd_file; size_t spd_file_len; printk(BIOS_DEBUG, "SPD index %d\n", spd_index); spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * sizeof(peid->spd_data[0]))) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < sizeof(peid->spd_data[0])) die("Missing SPD data."); memcpy(peid->spd_data[0], spd_file + spd_index * sizeof(peid->spd_data[0]), sizeof(peid->spd_data[0])); }
/* Copy SPD data for on-board memory */ static void copy_spd(struct pei_data *peid) { char *spd_file; size_t spd_file_len; int spd_index = 0; /* No GPIO selection, force index 0 for now */ printk(BIOS_DEBUG, "SPD index %d\n", spd_index); spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * sizeof(peid->spd_data[0]))) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < sizeof(peid->spd_data[0])) die("Missing SPD data."); memcpy(peid->spd_data[0], spd_file + spd_index * sizeof(peid->spd_data[0]), sizeof(peid->spd_data[0])); }
unsigned long mainboard_write_acpi_tables(struct device *device, unsigned long current, acpi_rsdp_t *rsdp) { acpi_header_t *ssdtx; const void *p; size_t p_size; int i; /* same htio, but different possition? We may have to copy, * change HCIN, and recalculate the checknum and add_table */ for (i = 1; i < sysconf.hc_possible_num; i++) { /* 0: is hc sblink */ const char *file_name; if ((sysconf.pci1234[i] & 1) != 1) continue; u8 c; if (i < 7) { c = (u8) ('4' + i - 1); } else { c = (u8) ('A' + i - 1 - 6); } current = ALIGN(current, 8); printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c at %lx\n", c, current); /* pci0 and pci1 are in dsdt */ ssdtx = (acpi_header_t *)current; switch (sysconf.hcid[i]) { case 1: file_name = CONFIG_CBFS_PREFIX "/ssdt2.aml"; break; case 2: file_name = CONFIG_CBFS_PREFIX "/ssdt3.aml"; break; case 3: /* 8131 */ file_name = CONFIG_CBFS_PREFIX "/ssdt4.aml"; break; default: /* HTX no io apic */ file_name = CONFIG_CBFS_PREFIX "/ssdt5.aml"; } p = cbfs_boot_map_with_leak( file_name, CBFS_TYPE_RAW, &p_size); if (!p || p_size < sizeof(acpi_header_t)) continue; memcpy(ssdtx, p, sizeof(acpi_header_t)); current += ssdtx->length; memcpy(ssdtx, p, ssdtx->length); update_ssdtx((void *)ssdtx, i); ssdtx->checksum = 0; ssdtx->checksum = acpi_checksum((u8 *)ssdtx, ssdtx->length); acpi_add_table(rsdp, ssdtx); } return current; }
AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt) { GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt; pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak( "pci"CONFIG_VGA_BIOS_ID".rom", CBFS_TYPE_OPTIONROM, NULL); printk(BIOS_DEBUG, "agesa_GfxGetVbiosImage: IMGptr=%p\n", pVbiosImageInfo->ImagePtr); return (pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING); }
static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { size_t region_size; *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", CBFS_TYPE_MRC_CACHE, ®ion_size); return region_size; }
/* 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, sku_id; gpio_t spd_gpios[] = { GPIO_MEM_CONFIG_0, GPIO_MEM_CONFIG_1, GPIO_MEM_CONFIG_2, GPIO_MEM_CONFIG_3, }; spd_index = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); /* * XXX: This is incorrect usage.The Board ID should be the revision ID * and not SKU ID but on SCRD it indicates SKU. */ sku_id = board_id(); printk(BIOS_INFO, "SPD index %d\n", spd_index); printk(BIOS_INFO, "Board ID %d\n", sku_id); /* 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 0 - old hardware?\n"); spd_index = 0; } /* Assume same memory in both channels */ spd_index *= SPD_LEN; memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN); /* * XXX: This is incorrect usage. mem_cfg should be used here instead of * SKU ID. The current implementation of mem_config does not * support channel population. */ if (sku_id != SCRD_SKU1) 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]); }
/* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *pei_data) { int spd_bits[3] = { SPD_GPIO_BIT0, SPD_GPIO_BIT1, SPD_GPIO_BIT2 }; int spd_gpio[3]; int spd_index; size_t spd_file_len; char *spd_file; spd_gpio[0] = get_gpio(SPD_GPIO_BIT0); spd_gpio[1] = get_gpio(SPD_GPIO_BIT1); spd_gpio[2] = get_gpio(SPD_GPIO_BIT2); spd_index = spd_gpio[2] << 2 | spd_gpio[1] << 1 | spd_gpio[0]; printk(BIOS_DEBUG, "SPD: index %d (GPIO%d=%d GPIO%d=%d GPIO%d=%d)\n", spd_index, spd_bits[2], spd_gpio[2], spd_bits[1], spd_gpio[1], spd_bits[0], spd_gpio[0]); spd_file = cbfs_boot_map_with_leak("spd.bin", 0xab, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < SPD_LEN) die("Missing SPD data."); memcpy(pei_data->spd_data[0][0], spd_file + (spd_index * SPD_LEN), SPD_LEN); /* Index 0-2 are 4GB config with both CH0 and CH1. * Index 4-6 are 2GB config with CH0 only. */ if (spd_index > 3) pei_data->dimm_channel1_disabled = 3; else memcpy(pei_data->spd_data[1][0], spd_file + (spd_index * SPD_LEN), 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]); }
AGESA_STATUS agesa_GfxGetVbiosImage(uint32_t Func, uintptr_t FchData, void *ConfigPrt) { GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo; pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt; pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak( "pci"CONFIG_VGA_BIOS_ID".rom", CBFS_TYPE_OPTIONROM, NULL); printk(BIOS_DEBUG, "%s: IMGptr=%p\n", __func__, pVbiosImageInfo->ImagePtr); return pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING; }
void mainboard_get_spd(spd_raw_data *spd, bool id_only) { /* C1S0 is a soldered RAM with no real SPD. Use stored SPD. */ size_t spd_file_len = 0; void *spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file || spd_file_len < sizeof(spd_raw_data)) die("SPD data for C1S0 not found."); read_spd(&spd[0], 0x50, id_only); memcpy(&spd[2], spd_file, spd_file_len); }
/* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *pei_data) { int spd_bits[4] = { SPD_GPIO_BIT0, SPD_GPIO_BIT1, SPD_GPIO_BIT2, SPD_GPIO_BIT3 }; int spd_gpio[4]; int spd_index; size_t spd_file_len; char *spd_file; spd_gpio[0] = get_gpio(spd_bits[0]); spd_gpio[1] = get_gpio(spd_bits[1]); spd_gpio[2] = get_gpio(spd_bits[2]); spd_gpio[3] = get_gpio(spd_bits[3]); spd_index = (spd_gpio[3] << 3) | (spd_gpio[2] << 2) | (spd_gpio[1] << 1) | spd_gpio[0]; printk(BIOS_DEBUG, "SPD: index %d (GPIO%d=%d GPIO%d=%d " "GPIO%d=%d GPIO%d=%d)\n", spd_index, spd_bits[3], spd_gpio[3], spd_bits[2], spd_gpio[2], spd_bits[1], spd_gpio[1], spd_bits[0], spd_gpio[0]); spd_file = cbfs_boot_map_with_leak("spd.bin", 0xab, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < SPD_LEN) die("Missing SPD data."); /* 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]); }
/* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *ps) { char *spd_file; size_t spd_file_len; void *spd_content; int dual_channel = 0; /* Find the SPD data in CBFS. */ spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < SPD_PAGE_LEN) die("Missing SPD data."); /* * Both channels are always present in SPD data. Always use matched * DIMMs so use the same SPD data for each DIMM. */ spd_content = get_spd_pointer(spd_file, spd_file_len / SPD_PAGE_LEN, &dual_channel); if (IS_ENABLED(CONFIG_DISPLAY_SPD_DATA) && spd_content != NULL) { printk(BIOS_DEBUG, "SPD Data:\n"); hexdump(spd_content, SPD_PAGE_LEN); printk(BIOS_DEBUG, "\n"); } /* * Set SPD and memory configuration: * Memory type: 0=DimmInstalled, * 1=SolderDownMemory, * 2=DimmDisabled */ if (spd_content != NULL) { ps->spd_data_ch0 = spd_content; ps->spd_ch0_config = 1; printk(BIOS_DEBUG, "Channel 0 DIMM soldered down\n"); if (dual_channel) { printk(BIOS_DEBUG, "Channel 1 DIMM soldered down\n"); ps->spd_data_ch1 = spd_content; ps->spd_ch1_config = 1; } else { printk(BIOS_DEBUG, "Channel 1 DIMM not installed\n"); ps->spd_ch1_config = 2; } } }
const void *agesawrapper_locate_module (const CHAR8 name[8]) { const void* agesa; const AMD_IMAGE_HEADER* image; const AMD_MODULE_HEADER* module; size_t file_size; agesa = cbfs_boot_map_with_leak((const char *)CONFIG_CBFS_AGESA_NAME, CBFS_TYPE_RAW, &file_size); if (!agesa) return NULL; image = LibAmdLocateImage(agesa, agesa + file_size - 1, 4096, name); module = (AMD_MODULE_HEADER*)image->ModuleInfoOffset; return module; }
/** * Find PEI executable in coreboot filesystem and execute it. * * @param pei_data: configuration data for UEFI PEI reference code */ void sdram_initialize(struct pei_data *pei_data) { unsigned long entry; printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n"); /* * Do not pass MRC data in for recovery mode boot, * Always pass it in for S3 resume. */ if (!vboot_recovery_mode_enabled() || pei_data->boot_mode == 2) prepare_mrc_cache(pei_data); /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == 2 && !pei_data->mrc_input) { post_code(POST_RESUME_FAILURE); printk(BIOS_DEBUG, "Giving up in sdram_initialize: " "No MRC data\n"); outb(0x6, 0xcf9); halt(); } /* Pass console handler in pei_data */ pei_data->tx_byte = do_putchar; /* Locate and call UEFI System Agent binary. */ entry = (unsigned long)cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); if (entry) { int rv; asm volatile ( "call *%%ecx\n\t" :"=a" (rv) : "c" (entry), "a" (pei_data)); if (rv) { switch (rv) { case -1: printk(BIOS_ERR, "PEI version mismatch.\n"); break; case -2: printk(BIOS_ERR, "Invalid memory frequency.\n"); break; default: printk(BIOS_ERR, "MRC returned %x.\n", rv); } die("Nonzero MRC return value.\n"); } } else {
static void vga_init(device_t dev) { printk(BIOS_INFO, "Starting Graphics Initialization\n"); size_t mbi_len; void *mbi = cbfs_boot_map_with_leak("mbi.bin", CBFS_TYPE_MBI, &mbi_len); if (mbi && mbi_len) { /* The GDT or coreboot table is going to live here. But * a long time after we relocated the GNVS, so this is * not troublesome. */ *(u32 *)0x500 = (u32)mbi; *(u32 *)0x504 = (u32)mbi_len; outb(0xeb, 0xb2); } pci_dev_init(dev); printk(BIOS_INFO, "Graphics Initialization Complete\n"); /* Enable TV-Out */ #if CONFIG_PCI_OPTION_ROM_RUN_YABEL #define PIPE_A_CRT (1 << 0) #define PIPE_A_LFP (1 << 1) #define PIPE_A_TV (1 << 3) #define PIPE_B_CRT (1 << 8) #define PIPE_B_TV (1 << 10) printk(BIOS_DEBUG, "Enabling TV-Out\n"); void runInt10(void); X86_AX = 0x5f64; X86_BX = 0x0001; // Set Display Device, force execution X86_CX = PIPE_A_CRT | PIPE_A_TV; // M.x86.R_CX = PIPE_B_TV; runInt10(); switch (X86_AX) { case 0x005f: printk(BIOS_DEBUG, "... failed.\n"); break; case 0x015f: printk(BIOS_DEBUG, "... ok.\n"); break; default: printk(BIOS_DEBUG, "... not supported.\n"); break; } #endif }
/* Copy SPD data for on-board memory */ static void copy_spd(struct pei_data *peid) { const int gpio_vector[] = {13, 9, 47, -1}; int spd_index = get_gpios(gpio_vector); char *spd_file; size_t spd_file_len; printk(BIOS_DEBUG, "SPD index %d\n", spd_index); spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); switch (google_chromeec_get_board_version()) { case PEPPY_BOARD_VERSION_PROTO: /* Index 0 is 2GB config with CH0 only. */ if (spd_index == 0) peid->dimm_channel1_disabled = 3; break; case PEPPY_BOARD_VERSION_EVT: default: /* Index 0-2 are 4GB config with both CH0 and CH1. * Index 4-6 are 2GB config with CH0 only. */ if (spd_index > 3) peid->dimm_channel1_disabled = 3; break; } if (spd_file_len < ((spd_index + 1) * sizeof(peid->spd_data[0]))) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < sizeof(peid->spd_data[0])) die("Missing SPD data."); memcpy(peid->spd_data[0], spd_file + spd_index * sizeof(peid->spd_data[0]), sizeof(peid->spd_data[0])); }
/* Right now, the offsets for the MRC cache area are hard-coded in the * northbridge Kconfig if CONFIG_CHROMEOS is not set. In order to make * this more flexible, there are two of options: * - Have each mainboard Kconfig supply a hard-coded offset * - Use CBFS */ static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { size_t region_size = 0; *mrc_region_ptr = NULL; if (IS_ENABLED(CONFIG_CHROMEOS)) { struct region_device rdev; if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev) == 0) { region_size = region_device_sz(&rdev); *mrc_region_ptr = rdev_mmap_full(&rdev); } } else { *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", CBFS_TYPE_MRC_CACHE, ®ion_size); } return region_size; }
static void program_mac_address(u16 io_base) { void *search_address = NULL; size_t search_length = -1; /* Default MAC Address of A0:00:BA:D0:0B:AD */ u32 high_dword = 0xD0BA00A0; /* high dword of mac address */ u32 low_dword = 0x0000AD0B; /* low word of mac address as a dword */ if (IS_ENABLED(CONFIG_CHROMEOS)) { struct region_device rdev; if (fmap_locate_area_as_rdev("RO_VPD", &rdev) == 0) { search_address = rdev_mmap_full(&rdev); if (search_address != NULL) search_length = region_device_sz(&rdev); } } else { search_address = cbfs_boot_map_with_leak("vpd.bin", CBFS_TYPE_RAW, &search_length); } if (search_address == NULL) printk(BIOS_ERR, "LAN: VPD not found.\n"); else get_mac_address(&high_dword, &low_dword, search_address, search_length); if (io_base) { printk(BIOS_DEBUG, "Realtek NIC io_base = 0x%04x\n", io_base); printk(BIOS_DEBUG, "Programming MAC Address\n"); /* Disable register protection */ outb(0xc0, io_base + 0x50); outl(high_dword, io_base); outl(low_dword, io_base + 0x04); outb(0x60, io_base + 54); /* Enable register protection again */ outb(0x00, io_base + 0x50); } }
/* 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; gpio_t spd_gpios[] = { GPIO_MEM_CONFIG_0, GPIO_MEM_CONFIG_1, GPIO_MEM_CONFIG_2, GPIO_MEM_CONFIG_3, }; spd_index = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); printk(BIOS_INFO, "SPD index %d\n", spd_index); /* 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 amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id) { const void *ucode; size_t ucode_len; uint32_t i; for (i = 0; i < ARRAY_SIZE(microcode_cbfs_file); i++) { if (equivalent_processor_rev_id == 0) { UCODE_DEBUG("rev id not found. Skipping microcode patch!\n"); return; } #ifdef __PRE_RAM__ #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) spin_lock(romstage_microcode_cbfs_lock()); #endif #endif ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i], CBFS_TYPE_MICROCODE, &ucode_len); if (!ucode) { UCODE_DEBUG("microcode file not found. Skipping updates.\n"); #ifdef __PRE_RAM__ #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) spin_unlock(romstage_microcode_cbfs_lock()); #endif #endif return; } amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id); #ifdef __PRE_RAM__ #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) spin_unlock(romstage_microcode_cbfs_lock()); #endif #endif } }
static uint8_t *locate_spd(void) { const int gpio_vector[] = {41, 42, 43, 10, -1}; uint8_t *spd_file; size_t spd_file_len; int spd_index = get_gpios(gpio_vector); printk(BIOS_DEBUG, "spd index %d\n", spd_index); spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); if (spd_file_len < ((spd_index + 1) * 256)) { printk(BIOS_ERR, "spd index override to 0 - old hardware?\n"); spd_index = 0; } if (spd_file_len < 256) die("Missing SPD data."); return spd_file + spd_index * 256; }
/* 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; /* Find the SPD data in 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."); /* Add board SKU detection here. Currently we only support one. */ spd_index = 0; /* Make sure we did not overrun the buffer */ if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); spd_index = 0; } /* 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]); }
/* Initialize the UPD parameters for MemoryInit */ void soc_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *upd) { const struct device *dev; const struct soc_intel_quark_config *config; struct chipset_power_state *ps = car_get_var_ptr(&power_state); char *rmu_file; size_t rmu_file_len; /* Locate the configuration data from devicetree.cb */ dev = dev_find_slot(0, LPC_DEV_FUNC); if (!dev) { printk(BIOS_ERR, "Error! Device (PCI:0:%02x.%01x) not found, " "soc_memory_init_params!\n", PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC); return; } config = dev->chip_info; /* Display the ROM shadow data */ hexdump((void *)0x000ffff0, 0x10); /* Clear SMI and wake events */ if (ps->prev_sleep_state != ACPI_S3) { printk(BIOS_SPEW, "Clearing SMI interrupts and wake events\n"); reg_script_run_on_dev(LPC_BDF, clear_smi_and_wake_events); } /* Locate the RMU data file in flash */ rmu_file = cbfs_boot_map_with_leak("rmu.bin", CBFS_TYPE_RAW, &rmu_file_len); if (!rmu_file) die("Microcode file (rmu.bin) not found."); /* Update the UPD data for MemoryInit */ printk(BIOS_DEBUG, "Updating UPD values for MemoryInit: 0x%p\n", upd); upd->AddrMode = config->AddrMode; upd->ChanMask = config->ChanMask; upd->ChanWidth = config->ChanWidth; upd->DramDensity = config->DramDensity; upd->DramRonVal = config->DramRonVal; upd->DramRttNomVal = config->DramRttNomVal; upd->DramRttWrVal = config->DramRttWrVal; upd->DramSpeed = config->DramSpeed; upd->DramType = config->DramType; upd->DramWidth = config->DramWidth; upd->EccScrubBlkSize = config->EccScrubBlkSize; upd->EccScrubInterval = config->EccScrubInterval; upd->Flags = config->Flags; upd->FspReservedMemoryLength = config->FspReservedMemoryLength; upd->RankMask = config->RankMask; upd->RmuBaseAddress = (uintptr_t)rmu_file; upd->RmuLength = rmu_file_len; upd->SerialPortBaseAddress = UART_BASE_ADDRESS; upd->SmmTsegSize = IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) ? config->SmmTsegSize : 0; upd->SocRdOdtVal = config->SocRdOdtVal; upd->SocWrRonVal = config->SocWrRonVal; upd->SocWrSlewRate = config->SocWrSlewRate; upd->SrInt = config->SrInt; upd->SrTemp = config->SrTemp; upd->tCL = config->tCL; upd->tFAW = config->tFAW; upd->tRAS = config->tRAS; upd->tRRD = config->tRRD; upd->tWTR = config->tWTR; }
unsigned long write_coreboot_table( unsigned long low_table_start, unsigned long low_table_end, unsigned long rom_table_start, unsigned long rom_table_end) { struct lb_header *head; if (low_table_start || low_table_end) { printk(BIOS_DEBUG, "Writing table forward entry at 0x%08lx\n", low_table_end); head = lb_table_init(low_table_end); lb_forward(head, (struct lb_header*)rom_table_end); low_table_end = (unsigned long) lb_table_fini(head); printk(BIOS_DEBUG, "Table forward entry ends at 0x%08lx.\n", low_table_end); low_table_end = ALIGN(low_table_end, 4096); printk(BIOS_DEBUG, "... aligned to 0x%08lx\n", low_table_end); } printk(BIOS_DEBUG, "Writing coreboot table at 0x%08lx\n", rom_table_end); head = lb_table_init(rom_table_end); rom_table_end = (unsigned long)head; printk(BIOS_DEBUG, "rom_table_end = 0x%08lx\n", rom_table_end); rom_table_end = ALIGN(rom_table_end, (64 * 1024)); printk(BIOS_DEBUG, "... aligned to 0x%08lx\n", rom_table_end); #if CONFIG_USE_OPTION_TABLE { struct cmos_option_table *option_table = cbfs_boot_map_with_leak("cmos_layout.bin", CBFS_COMPONENT_CMOS_LAYOUT, NULL); if (option_table) { struct lb_record *rec_dest = lb_new_record(head); /* Copy the option config table, it's already a lb_record... */ memcpy(rec_dest, option_table, option_table->size); /* Create cmos checksum entry in coreboot table */ lb_cmos_checksum(head); } else { printk(BIOS_ERR, "cmos_layout.bin could not be found!\n"); } } #endif /* Initialize the memory map at boot time. */ bootmem_init(); if (low_table_start || low_table_end) { uint64_t size = low_table_end - low_table_start; /* Record the mptable and the the lb_table. * (This will be adjusted later) */ bootmem_add_range(low_table_start, size, LB_MEM_TABLE); } /* Record the pirq table, acpi tables, and maybe the mptable. However, * these only need to be added when the rom_table is sitting below * 1MiB. If it isn't that means high tables are being written. * The code below handles high tables correctly. */ if (rom_table_end <= (1 << 20)) { uint64_t size = rom_table_end - rom_table_start; bootmem_add_range(rom_table_start, size, LB_MEM_TABLE); } /* No other memory areas can be added after the memory table has been * committed as the entries won't show up in the serialize mem table. */ bootmem_write_memory_table(lb_memory(head)); /* Record our motherboard */ lb_mainboard(head); /* Record the serial ports and consoles */ #if CONFIG_CONSOLE_SERIAL uart_fill_lb(head); #endif #if CONFIG_CONSOLE_USB lb_add_console(LB_TAG_CONSOLE_EHCI, head); #endif /* Record our various random string information */ lb_strings(head); lb_record_version_timestamp(head); /* Record our framebuffer */ lb_framebuffer(head); #if CONFIG_CHROMEOS /* Record our GPIO settings (ChromeOS specific) */ lb_gpios(head); /* pass along the VDAT buffer address */ lb_vdat(head); /* pass along VBNV offsets in CMOS */ lb_vbnv(head); /* pass along the vboot_handoff address. */ lb_vboot_handoff(head); #endif /* Add board ID if available */ lb_board_id(head); /* Add RAM config if available */ lb_ram_code(head); #if IS_ENABLED(CONFIG_SPI_FLASH) /* Add SPI flash description if available */ lb_spi_flash(head); #endif add_cbmem_pointers(head); /* Add board-specific table entries, if any. */ lb_board(head); #if IS_ENABLED(CONFIG_CHROMEOS_RAMOOPS) lb_ramoops(head); #endif lb_boot_media_params(head); /* Add all cbmem entries into the coreboot tables. */ cbmem_add_records_to_cbtable(head); /* Remember where my valid memory ranges are */ return lb_table_fini(head); }