coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
memmap.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <assert.h>
6 #include <console/console.h>
7 #include <cpu/x86/smm.h>
8 #include <device/pci_ops.h>
11 #include <cpu/intel/smm_reloc.h>
12 
13 #include "q35.h"
14 
16 {
17  switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) {
18  case 256: return 0 << 1;
19  case 128: return 1 << 1;
20  case 64: return 2 << 1;
21  default: return dead_code_t(uint32_t);
22  }
23 }
24 
26 {
27  return CONFIG_ECAM_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1;
28 }
29 
30 /* Check that MCFG is active. If it's not, QEMU was started for machine PC */
32 {
34  die("You must run qemu for machine Q35 (-M q35)");
35 }
36 
37 /* QEMU-specific register */
38 #define EXT_TSEG_MBYTES 0x50
39 #define SMRAMC 0x9d
40 #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
41 #define G_SMRAME (1 << 3)
42 #define D_LCK (1 << 4)
43 #define D_CLS (1 << 5)
44 #define D_OPEN (1 << 6)
45 #define ESMRAMC 0x9e
46 #define T_EN (1 << 0)
47 #define TSEG_SZ_MASK (3 << 1)
48 #define H_SMRAME (1 << 7)
49 
50 void smm_region(uintptr_t *start, size_t *size)
51 {
53 
54  switch ((esmramc & TSEG_SZ_MASK) >> 1) {
55  case 0:
56  *size = 1 * MiB;
57  break;
58  case 1:
59  *size = 2 * MiB;
60  break;
61  case 2:
62  *size = 8 * MiB;
63  break;
64  default:
66  }
67 
68  *start = qemu_get_memory_size() * KiB - *size;
69  printk(BIOS_SPEW, "SMM_BASE: 0x%08lx, SMM_SIZE: %zu MiB\n", *start, *size / MiB);
70 }
71 
72 void smm_lock(void)
73 {
74  /*
75  * LOCK the SMM memory window and enable normal SMM.
76  * After running this function, only a full reset can
77  * make the SMM registers writable again.
78  */
79  printk(BIOS_DEBUG, "Locking SMM.\n");
80 
81  pci_or_config8(PCI_DEV(0, 0, 0), ESMRAMC, T_EN);
83 }
#define dead_code_t(type)
Definition: assert.h:92
#define MiB
Definition: helpers.h:76
#define KiB
Definition: helpers.h:75
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
Definition: pci_ops.h:169
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
unsigned long qemu_get_memory_size(void)
Definition: memmap.c:33
#define G_SMRAME
Definition: memmap.c:41
#define T_EN
Definition: memmap.c:46
void mainboard_machine_check(void)
Definition: memmap.c:31
uint32_t make_pciexbar(void)
Definition: memmap.c:25
void smm_region(uintptr_t *start, size_t *size)
Definition: memmap.c:50
void smm_lock(void)
Definition: memmap.c:72
#define EXT_TSEG_MBYTES
Definition: memmap.c:38
static uint32_t encode_pciexbar_length(void)
Definition: memmap.c:15
#define C_BASE_SEG
Definition: memmap.c:40
#define SMRAMC
Definition: memmap.c:39
#define D_LCK
Definition: memmap.c:42
#define TSEG_SZ_MASK
Definition: memmap.c:47
#define ESMRAMC
Definition: memmap.c:45
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
#define D0F0_PCIEXBAR_LO
Definition: q35.h:11
@ HOST_BRIDGE
Definition: reg_access.h:23
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8