static uint32_t mtrr_index_to_host_bridge_register_offset(unsigned long index) { uint32_t offset; /* Convert from MTRR index to host brigde offset (Datasheet 12.7.2) */ if (index == MTRR_CAP_MSR) offset = QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP; else if (index == MTRR_DEF_TYPE_MSR) offset = QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE; else if (index == MTRR_FIX_64K_00000) offset = QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000; else if ((index >= MTRR_FIX_16K_80000) && (index <= MTRR_FIX_16K_A0000)) offset = ((index - MTRR_FIX_16K_80000) << 1) + QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000; else if ((index >= MTRR_FIX_4K_C0000) && (index <= MTRR_FIX_4K_F8000)) offset = ((index - MTRR_FIX_4K_C0000) << 1) + QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0; else if ((index >= MTRR_PHYS_BASE(0)) && (index <= MTRR_PHYS_MASK(7))) offset = (index - MTRR_PHYS_BASE(0)) + QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0; else { printk(BIOS_DEBUG, "index: 0x%08lx\n", index); die("Invalid MTRR index specified!\n"); } return offset; }
static void set_init_ecc_mtrrs(void) { msr_t msr; int i; disable_cache(); /* First clear all of the msrs to be safe */ for (i = 0; i < MTRR_COUNT; i++) { msr_t zero; zero.lo = zero.hi = 0; wrmsr(MTRR_PHYS_BASE(i), zero); wrmsr(MTRR_PHYS_MASK(i), zero); } /* Write back cache the first 1MB */ msr.hi = 0x00000000; msr.lo = 0x00000000 | MTRR_TYPE_WRBACK; wrmsr(MTRR_PHYS_BASE(0), msr); msr.hi = 0x000000ff; msr.lo = ~((CONFIG_RAMTOP) - 1) | 0x800; wrmsr(MTRR_PHYS_MASK(0), msr); /* Set the default type to write combining */ msr.hi = 0x00000000; msr.lo = 0xc00 | MTRR_TYPE_WRCOMB; wrmsr(MTRR_DEF_TYPE_MSR, msr); /* Set TOP_MEM to 4G */ msr.hi = 0x00000001; msr.lo = 0x00000000; wrmsr(TOP_MEM, msr); enable_cache(); }
static void set_var_mtrr(int reg, uint32_t base, uint32_t size, int type) { msr_t basem, maskm; basem.lo = base | type; basem.hi = 0; wrmsr(MTRR_PHYS_BASE(reg), basem); maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1; wrmsr(MTRR_PHYS_MASK(reg), maskm); }
static void save_mtrr_state(struct mtrr_state *state) { int i; for (i = 0; i < MTRR_COUNT; i++) { state->mtrrs[i].base = rdmsr(MTRR_PHYS_BASE(i)); state->mtrrs[i].mask = rdmsr(MTRR_PHYS_MASK(i)); } state->top_mem = rdmsr(TOP_MEM); state->top_mem2 = rdmsr(TOP_MEM2); state->def_type = rdmsr(MTRR_DEF_TYPE_MSR); }
static void restore_mtrr_state(struct mtrr_state *state) { int i; disable_cache(); for (i = 0; i < MTRR_COUNT; i++) { wrmsr(MTRR_PHYS_BASE(i), state->mtrrs[i].base); wrmsr(MTRR_PHYS_MASK(i), state->mtrrs[i].mask); } wrmsr(TOP_MEM, state->top_mem); wrmsr(TOP_MEM2, state->top_mem2); wrmsr(MTRR_DEF_TYPE_MSR, state->def_type); enable_cache(); }
static void set_resume_cache(void) { msr_t msr; /* disable fixed mtrr for now, it will be enabled by mtrr restore */ msr = rdmsr(SYSCFG_MSR); msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn); wrmsr(SYSCFG_MSR, msr); /* Enable cached access to RAM in the range 0M to CACHE_TMP_RAMTOP */ msr.lo = 0 | MTRR_TYPE_WRBACK; msr.hi = 0; wrmsr(MTRR_PHYS_BASE(0), msr); msr.lo = ~(CACHE_TMP_RAMTOP - 1) | MTRR_PHYS_MASK_VALID; msr.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1; wrmsr(MTRR_PHYS_MASK(0), msr); /* Set the default memory type and disable fixed and enable variable MTRRs */ msr.hi = 0; msr.lo = (1 << 11); wrmsr(MTRR_DEF_TYPE_MSR, msr); enable_cache(); }
/* Enable the HSUART */ REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, UART_BASE_ADDRESS), REG_PCI_OR8(PCI_COMMAND, PCI_COMMAND_MEMORY), REG_SCRIPT_END }; static const struct reg_script mtrr_init[] = { /* Use write-through caching, for FSP 2.0 the cache will be invalidated * postchar (arch/x86/exit_car.S). */ /* Enable the cache */ REG_CPU_CR_AND(0, ~(CR0_CD | CR0_NW)), /* Cache the SPI flash */ REG_MSR_WRITE(MTRR_PHYS_BASE(0), (uint32_t)((-CONFIG_ROM_SIZE) | MTRR_TYPE_WRTHROUGH)), REG_MSR_WRITE(MTRR_PHYS_MASK(0), (uint32_t)((-CONFIG_ROM_SIZE) | MTRR_PHYS_MASK_VALID)), /* Cache ESRAM */ REG_MSR_WRITE(MTRR_PHYS_BASE(1), (uint32_t)(0x80000000 | MTRR_TYPE_WRTHROUGH)), REG_MSR_WRITE(MTRR_PHYS_MASK(1), (uint32_t)((~0x7ffff) | MTRR_PHYS_MASK_VALID)), /* Enable the variable MTRRs */ REG_MSR_WRITE(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_EN | MTRR_TYPE_UNCACHEABLE), REG_SCRIPT_END