coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
storage_test.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/pci_ops.h>
4 #include <assert.h>
5 #include <cbmem.h>
6 #include <commonlib/sdhci.h>
7 #include <commonlib/storage.h>
8 #include <console/console.h>
9 #include <lib.h>
10 #include <soc/iomap.h>
11 #include <soc/pci_devs.h>
12 #include <soc/storage_test.h>
13 #include <timer.h>
14 #include <string.h>
15 
16 #if CONFIG(STORAGE_LOG)
17 struct log_entry log[LOG_ENTRIES];
18 uint8_t log_index;
19 int log_full;
20 long log_start_time;
21 #endif
22 
24 
25 #define STORAGE_DEBUG BIOS_DEBUG
26 #define LOG_DEBUG (CONFIG(STORAGE_LOG) ? STORAGE_DEBUG : BIOS_NEVER)
27 
28 #ifdef __SIMPLE_DEVICE__
30  uint16_t *previous_command)
31 #else
32 uint32_t storage_test_init(struct device *dev, uint32_t *previous_bar,
33  uint16_t *previous_command)
34 #endif
35 {
36  uint32_t bar;
37 
38  /* Display the vendor/device IDs */
39  printk(LOG_DEBUG, "Vendor ID: 0x%04x, Device ID: 0x%04x\n",
42 
43  /* Set the temporary base address */
45  *previous_bar = bar;
47  if (!bar) {
48  bar = SD_BASE_ADDRESS;
50  }
51 
52  /* Enable the SD/MMC controller */
53  *previous_command = pci_read_config16(dev, PCI_COMMAND);
54  pci_write_config16(dev, PCI_COMMAND, *previous_command
56 
57  /* Return the controller address */
58  return bar;
59 }
60 
61 #ifdef __SIMPLE_DEVICE__
62 void storage_test_complete(pci_devfn_t dev, uint32_t previous_bar,
63  uint16_t previous_command)
64 #else
65 void storage_test_complete(struct device *dev, uint32_t previous_bar,
66  uint16_t previous_command)
67 #endif
68 {
69  pci_write_config16(dev, PCI_COMMAND, previous_command);
70  pci_write_config32(dev, PCI_BASE_ADDRESS_0, previous_bar);
71 }
72 
73 #if !ENV_BOOTBLOCK
74 static void display_log(void)
75 {
76  /* Determine the array bounds */
77  if (CONFIG(STORAGE_LOG)) {
78  long delta;
79  uint8_t end;
80  uint8_t index;
81  uint8_t start;
82 
83  end = log_index;
84  start = log_full ? log_index : 0;
85  for (index = start; (log_full || (index != end)); index++) {
86  log_full = 0;
87  delta = log[index].time.microseconds - log_start_time;
88  printk(BIOS_DEBUG, "%3ld.%03ld mSec, cmd: %2d 0x%08x%s",
89  delta / 1000, delta % 1000,
90  log[index].cmd.cmdidx,
91  log[index].cmd.cmdarg,
92  log[index].cmd_issued ? "" : "(not issued)");
93  if (log[index].response_entries == 1)
94  printk(BIOS_DEBUG, ", rsp: 0x%08x",
95  log[index].response[0]);
96  else if (log[index].response_entries == 4)
98  ", rsp: 0x%08x.%08x.%08x.%08x",
99  log[index].response[3],
100  log[index].response[2],
101  log[index].response[1],
102  log[index].response[0]);
103  printk(BIOS_DEBUG, ", ret: %d\n", log[index].ret);
104  }
105  }
106 }
107 
109 {
110  if (CONFIG(STORAGE_LOG)) {
111  timer_monotonic_get(&log[log_index].time);
112  log[log_index].cmd = *cmd;
113  log[log_index].cmd_issued = 0;
114  log[log_index].response_entries = 0;
115  if ((log_index == 0) && (!log_full))
116  log_start_time = log[0].time.microseconds;
117  }
118 }
119 
121 {
122  if (CONFIG(STORAGE_LOG)) {
123  log[log_index].cmd_issued = 1;
124  }
125 }
126 
128 {
129  unsigned int entry;
130 
131  if (CONFIG(STORAGE_LOG)) {
132  log[log_index].response_entries = entries;
133  for (entry = 0; entry < entries; entry++)
134  log[log_index].response[entry] = response[entry];
135  }
136 }
137 
138 void sdhc_log_ret(int ret)
139 {
140  if (CONFIG(STORAGE_LOG)) {
141  log[log_index].ret = ret;
142  if (++log_index == 0)
143  log_full = 1;
144  }
145 }
146 
147 void storage_test(uint32_t bar, int full_initialization)
148 {
149  uint64_t blocks_read;
150  uint8_t buffer[512];
151  int err;
152  struct storage_media *media;
153  const char *name;
154  unsigned int partition;
155  unsigned int previous_partition;
156  struct sdhci_ctrlr *sdhci_ctrlr;
157 
158  ASSERT(sizeof(struct sdhci_ctrlr) <= sizeof(drivers_storage));
159 
160  /* Get the structure addresses */
161  media = NULL;
162  if (ENV_ROMSTAGE)
163  media = (struct storage_media *)drivers_storage;
164  else
166  sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7);
167  media->ctrlr = (struct sd_mmc_ctrlr *)sdhci_ctrlr;
168  sdhci_ctrlr->ioaddr = (void *)bar;
169 
170  /* Initialize the controller */
171  if (!full_initialization) {
172  /* Perform fast initialization */
176  } else {
177  /* Initialize the log */
178  if (CONFIG(STORAGE_LOG)) {
179  log_index = 0;
180  log_full = 0;
181  }
182 
183  printk(LOG_DEBUG, "Initializing the SD/MMC controller\n");
184  err = sdhci_controller_init(sdhci_ctrlr, (void *)bar);
185  if (err) {
186  display_log();
187  printk(BIOS_ERR, "Controller failed to initialize, err = %d\n",
188  err);
189  return;
190  }
191 
192  /* Initialize the SD/MMC/eMMC card or device */
193  printk(LOG_DEBUG, "Initializing the device\n");
195  if (err) {
196  display_log();
197  printk(BIOS_ERR, "Device failed to initialize, err = %d\n",
198  err);
199  return;
200  }
201  display_log();
202  }
203 
204  /* Save the current partition */
205  previous_partition = storage_get_current_partition(media);
206 
207  /* Read block 0 from each partition */
208  for (partition = 0; partition < ARRAY_SIZE(media->capacity);
209  partition++) {
210  if (media->capacity[partition] == 0)
211  continue;
212  name = storage_partition_name(media, partition);
213  printk(STORAGE_DEBUG, "%s%sReading block 0\n", name,
214  name[0] ? ": " : "");
215  err = storage_set_partition(media, partition);
216  if (err)
217  continue;
218  blocks_read = storage_block_read(media, 0, 1, &buffer);
219  if (blocks_read)
220  hexdump(buffer, sizeof(buffer));
221  }
222 
223  /* Restore the previous partition */
224  storage_set_partition(media, previous_partition);
225 }
226 #endif
227 
228 #if ENV_ROMSTAGE
229 static void copy_storage_structures(int is_recovery)
230 {
231  struct storage_media *media;
232  struct sdhci_ctrlr *sdhci_ctrlr;
233  size_t size = sizeof(drivers_storage);
234 
235  /* Locate the data structures in CBMEM */
237  ASSERT(media != NULL);
238  sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7);
239 
240  /* Migrate the data into CBMEM */
241  memcpy(media, drivers_storage, size);
243 }
244 
245 ROMSTAGE_CBMEM_INIT_HOOK(copy_storage_structures);
246 #endif
const char * name
Definition: mmu.c:92
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void timer_monotonic_get(struct mono_time *mt)
Definition: arch_timer.c:6
#define ASSERT(x)
Definition: assert.h:44
#define ARRAY_SIZE(a)
Definition: helpers.h:12
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_)
Definition: cbmem.h:134
#define CBMEM_ID_STORAGE_DATA
Definition: cbmem_id.h:59
#define printk(level,...)
Definition: stdlib.h:16
@ CONFIG
Definition: dsi_common.h:201
int sdhci_controller_init(struct sdhci_ctrlr *sdhci_ctrlr, void *ioaddr)
Definition: pci_sdhci.c:13
void sdhci_update_pointers(struct sdhci_ctrlr *sdhci_ctrlr)
Definition: sdhci.c:744
void sdhci_display_setup(struct sdhci_ctrlr *sdhci_ctrlr)
Definition: sdhci_display.c:92
const char * storage_partition_name(struct storage_media *media, unsigned int partition_number)
Definition: storage.c:325
int storage_set_partition(struct storage_media *media, unsigned int partition_number)
Definition: storage.c:309
int storage_setup_media(struct storage_media *media, struct sd_mmc_ctrlr *ctrlr)
Definition: storage.c:188
unsigned int storage_get_current_partition(struct storage_media *media)
Definition: storage.c:339
void storage_display_setup(struct storage_media *media)
Definition: storage.c:88
uint64_t storage_block_read(struct storage_media *media, uint64_t start, uint64_t count, void *buffer)
Definition: storage.c:286
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
#define SD_BASE_ADDRESS
Definition: iomap.h:18
void hexdump(const void *memory, size_t length)
Definition: hexdump.c:7
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define PCI_BASE_ADDRESS_MEM_ATTR_MASK
Definition: pci_def.h:77
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_DEVICE_ID
Definition: pci_def.h:9
#define PCI_VENDOR_ID
Definition: pci_def.h:8
u32 pci_devfn_t
Definition: pci_type.h:8
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
#define ENV_ROMSTAGE
Definition: rules.h:149
static struct storage_media media
Definition: sd_media.c:21
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
static uint8_t drivers_storage[256]
Definition: storage_test.c:23
void sdhc_log_command(struct mmc_command *cmd)
Definition: storage_test.c:108
#define LOG_DEBUG
Definition: storage_test.c:26
static void display_log(void)
Definition: storage_test.c:74
#define STORAGE_DEBUG
Definition: storage_test.c:25
void storage_test(uint32_t bar, int full_initialization)
Definition: storage_test.c:147
void sdhc_log_command_issued(void)
Definition: storage_test.c:120
void storage_test_complete(struct device *dev, uint32_t previous_bar, uint16_t previous_command)
Definition: storage_test.c:65
uint32_t storage_test_init(struct device *dev, uint32_t *previous_bar, uint16_t *previous_command)
Definition: storage_test.c:32
void sdhc_log_response(uint32_t entries, uint32_t *response)
Definition: storage_test.c:127
void sdhc_log_ret(int ret)
Definition: storage_test.c:138
#define LOG_ENTRIES
Definition: storage_test.h:35
Definition: device.h:107
Definition: storage_test.h:26
int ret
Definition: storage_test.h:30
uint32_t response[4]
Definition: storage_test.h:32
uint32_t response_entries
Definition: storage_test.h:31
struct mono_time time
Definition: storage_test.h:27
struct mmc_command cmd
Definition: storage_test.h:28
uint16_t cmdidx
Definition: sd_mmc_ctrlr.h:25
void * ioaddr
Definition: sdhci.h:37
struct sd_mmc_ctrlr sd_mmc_ctrlr
Definition: sdhci.h:36
struct sd_mmc_ctrlr * ctrlr
Definition: storage.h:63
uint64_t capacity[8]
Definition: storage.h:62