/* * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc. */ #include #include #include #include #include #include #include #include size_t mmap_region_granluarity(void) { if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) /* Align to TSEG size when SMM is in use */ if (CONFIG_SMM_TSEG_SIZE != 0) return CONFIG_SMM_TSEG_SIZE; /* Make it 8MiB by default. */ return 8*MiB; } /* Returns base of requested region encoded in the system agent. */ static inline uintptr_t system_agent_region_base(size_t reg) { /* All regions concerned for have 1 MiB alignment. */ return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB); } static inline uintptr_t smm_region_start(void) { return system_agent_region_base(TSEG); } static inline size_t smm_region_size(void) { return system_agent_region_base(BGSM) - smm_region_start(); } void smm_region(void **start, size_t *size) { *start = (void *)smm_region_start(); *size = smm_region_size(); } void *cbmem_top(void) { /* * +-------------------------+ Top of RAM (aligned) * | System Management Mode | * | code and data | Length: CONFIG_TSEG_SIZE * | (TSEG) | * +-------------------------+ SMM base (aligned) * | | * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE * | | * +-------------------------+ top_of_ram (aligned) * | | * | CBMEM Root | * | | * +-------------------------+ * | | * | FSP Reserved Memory | * | | * +-------------------------+ * | | * | Various CBMEM Entries | * | | * +-------------------------+ top_of_stack (8 byte aligned) * | | * | stack (CBMEM Entry) | * | | * +-------------------------+ */ uintptr_t top_of_ram = smm_region_start(); /* * Subtract DMA Protected Range size if enabled and align to a multiple * of TSEG size. */ u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR); if (dpr & DPR_EPM) { top_of_ram -= (dpr & DPR_SIZE_MASK) << 16; top_of_ram = ALIGN_DOWN(top_of_ram, mmap_region_granluarity()); } return (void *)top_of_ram; }