aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2015-08-10 12:51:41 -0400
committerKevin O'Connor <kevin@koconnor.net>2015-08-24 11:02:13 -0400
commit9f7b2362ef9d6f8e7de54c9d245778c575bd1b23 (patch)
treefd7ea082f72568c89a41c00ad0c54fde5fd9151e
parent5ddce09ab45ec87a61723c6b100e13294b5d7757 (diff)
downloadseabios-9f7b2362ef9d6f8e7de54c9d245778c575bd1b23.zip
seabios-9f7b2362ef9d6f8e7de54c9d245778c575bd1b23.tar.gz
seabios-9f7b2362ef9d6f8e7de54c9d245778c575bd1b23.tar.bz2
sdcard: Allow sdcard addresses to be specified in CBFS files
Allow a hardcoded address to be specified in cbfs files with a prefix of "etc/sdcard". Some real-world devices have valid SDHCI controllers that do not show up as PCI devices. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--docs/Runtime_config.md1
-rw-r--r--src/hw/sdcard.c48
2 files changed, 37 insertions, 12 deletions
diff --git a/docs/Runtime_config.md b/docs/Runtime_config.md
index 4ac0eae..d6fea28 100644
--- a/docs/Runtime_config.md
+++ b/docs/Runtime_config.md
@@ -188,3 +188,4 @@ There are several additional configuration options available in the
| floppy0 | Set this to the type of the first floppy drive in the system (only type 4 for 3.5 inch drives is supported).
| floppy1 | The type of the second floppy drive in the system. See the description of **floppy0** for more info.
| threads | By default, SeaBIOS will parallelize hardware initialization during bootup to reduce boot time. Multiple hardware devices can be initialized in parallel between vga initialization and option rom initialization. One can set this file to a value of zero to force hardware initialization to run serially. Alternatively, one can set this file to 2 to enable early hardware initialization that runs in parallel with vga, option rom initialization, and the boot menu.
+| sdcard* | One may create one or more files with an "sdcard" prefix (eg, "etc/sdcard0") with the physical memory address of an SDHCI controller (one memory address per file). This may be useful for SDHCI controllers that do not appear as PCI devices, but are mapped to a consistent memory address.
diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c
index 540e97c..8e7e954 100644
--- a/src/hw/sdcard.c
+++ b/src/hw/sdcard.c
@@ -10,6 +10,7 @@
#include "pci.h" // pci_config_readl
#include "pci_ids.h" // PCI_CLASS_SYSTEM_SDHCI
#include "pci_regs.h" // PCI_BASE_ADDRESS_0
+#include "romfile.h" // romfile_findprefix
#include "stacks.h" // wait_preempt
#include "std/disk.h" // DISK_RET_SUCCESS
#include "string.h" // memset
@@ -416,15 +417,8 @@ sdcard_set_frequency(struct sdhci_s *regs, u32 khz)
// Setup and configure an SD card controller
static void
-sdcard_controller_setup(void *data)
+sdcard_controller_setup(struct sdhci_s *regs, int prio)
{
- struct pci_device *pci = data;
- u16 bdf = pci->bdf;
- wait_preempt(); // Avoid pci_config_readl when preempting
- struct sdhci_s *regs = (void*)pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
- pci_config_maskw(bdf, PCI_COMMAND, 0,
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-
// Initialize controller
u32 present_state = readl(&regs->present_state);
if (!(present_state & SP_CARD_INSERTED))
@@ -470,27 +464,57 @@ sdcard_controller_setup(void *data)
drive->regs = regs;
drive->card_type = card_type;
- dprintf(1, "Found SD Card at %02x:%02x.%x\n"
- , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
+ dprintf(1, "Found SD Card at %p\n", regs);
char *desc = znprintf(MAXDESCSIZE, "SD Card"); // XXX
- boot_add_hd(&drive->drive, desc, bootprio_find_pci_device(pci));
+ boot_add_hd(&drive->drive, desc, prio);
return;
fail:
writeb(&regs->power_control, 0);
writew(&regs->clock_control, 0);
}
+static void
+sdcard_pci_setup(void *data)
+{
+ struct pci_device *pci = data;
+ wait_preempt(); // Avoid pci_config_readl when preempting
+ // XXX - bars dependent on slot index register in pci config space
+ u32 regs = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0);
+ pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ int prio = bootprio_find_pci_device(pci);
+ sdcard_controller_setup((void*)regs, prio);
+}
+
+static void
+sdcard_romfile_setup(void *data)
+{
+ struct romfile_s *file = data;
+ int prio = bootprio_find_named_rom(file->name, 0);
+ u32 addr = romfile_loadint(file->name, 0);
+ dprintf(1, "Starting sdcard controller check at addr %x\n", addr);
+ sdcard_controller_setup((void*)addr, prio);
+}
+
void
sdcard_setup(void)
{
if (!CONFIG_SDCARD)
return;
+ struct romfile_s *file = NULL;
+ for (;;) {
+ file = romfile_findprefix("etc/sdcard", file);
+ if (!file)
+ break;
+ run_thread(sdcard_romfile_setup, file);
+ }
+
struct pci_device *pci;
foreachpci(pci) {
if (pci->class != PCI_CLASS_SYSTEM_SDHCI || pci->prog_if >= 2)
// Not an SDHCI controller following SDHCI spec
continue;
- run_thread(sdcard_controller_setup, pci);
+ run_thread(sdcard_pci_setup, pci);
}
}