[OpenBIOS] [commit] r784 - trunk/openbios-devel/drivers
repository service
svn at openbios.org
Thu May 27 22:12:03 CEST 2010
Author: blueswirl
Date: Thu May 27 22:12:02 2010
New Revision: 784
URL: http://tracker.coreboot.org/trac/openbios/changeset/784
Log:
pci: property encoding helpers
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>
Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
Modified:
trunk/openbios-devel/drivers/pci.c
Modified: trunk/openbios-devel/drivers/pci.c
==============================================================================
--- trunk/openbios-devel/drivers/pci.c Thu May 27 22:11:59 2010 (r783)
+++ trunk/openbios-devel/drivers/pci.c Thu May 27 22:12:02 2010 (r784)
@@ -52,7 +52,21 @@
MEMORY_SPACE_64 = 3,
};
-static inline void pci_encode_phys_addr(u32 *phys, int flags, int space_code,
+static int encode_int32_cells(int num_cells, u32 *prop, ucell val)
+{
+ int i = 0;
+
+ /* hi ... lo */
+ for (i=0; i < num_cells; ++i) {
+ prop[num_cells - i - 1] = val;
+ val >>= 16;
+ val >>= 16;
+ }
+
+ return num_cells;
+}
+
+static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code,
pci_addr dev, uint8_t reg, uint64_t addr)
{
@@ -67,8 +81,44 @@
/* phys.lo */
phys[2] = addr;
+
+ return 3;
}
+static inline int pci_encode_size(u32 *prop, uint64_t size)
+{
+ return encode_int32_cells(2, prop, size);
+}
+
+static int host_address_cells(void)
+{
+ return get_int_property(find_dev("/"), "#address-cells", NULL);
+}
+
+static int host_encode_phys_addr(u32 *prop, ucell addr)
+{
+ return encode_int32_cells(host_address_cells(), prop, addr);
+}
+
+static int host_size_cells(void)
+{
+ return get_int_property(find_dev("/"), "#size-cells", NULL);
+}
+
+/*
+static int parent_address_cells(void)
+{
+ phandle_t parent_ph = ih_to_phandle(my_parent());
+ return get_int_property(parent_ph, "#address-cells", NULL);
+}
+
+static int parent_size_cells(void)
+{
+ phandle_t parent_ph = ih_to_phandle(my_parent());
+ return get_int_property(parent_ph, "#size-cells", NULL);
+}
+*/
+
static void
ob_pci_open(int *idx)
{
@@ -318,14 +368,23 @@
static void pci_host_set_reg(const pci_config_t *config)
{
- phandle_t dev = get_cur_dev();
- u32 props[2];
+ phandle_t dev = get_cur_dev();
+ /* at most 2 integers for address and size */
+ u32 props[4];
+ int ncells = 0;
+
+ ncells += encode_int32_cells(host_address_cells(), props + ncells,
+ arch->cfg_base);
+
+ ncells += encode_int32_cells(host_size_cells(), props + ncells,
+ arch->cfg_len);
- props[0] = arch->cfg_base;
- props[1] = arch->cfg_len;
- set_property(dev, "reg", (char *)props, 2 * sizeof(props[0]));
+ set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
}
+/* child-phys : parent-phys : size */
+/* 3 cells for PCI : 2 cells for 64bit parent : 2 cells for PCI */
+
static void pci_host_set_ranges(const pci_config_t *config)
{
phandle_t dev = get_cur_dev();
@@ -333,29 +392,31 @@
int ncells;
ncells = 0;
+ /* first encode PCI configuration space */
+ {
+ ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
+ config->dev, 0, 0);
+ ncells += host_encode_phys_addr(props + ncells, arch->cfg_addr);
+ ncells += pci_encode_size(props + ncells, arch->cfg_len);
+ }
+
if (arch->io_base) {
- pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
+ ncells += pci_encode_phys_addr(props + ncells, 0, IO_SPACE,
config->dev, 0, 0);
- ncells += 3;
- props[ncells++] = arch->io_base;
- props[ncells++] = 0x00000000;
- props[ncells++] = arch->io_len;
+ ncells += host_encode_phys_addr(props + ncells, arch->io_base);
+ ncells += pci_encode_size(props + ncells, arch->io_len);
}
if (arch->rbase) {
- pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
+ ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
config->dev, 0, 0);
- ncells += 3;
- props[ncells++] = arch->rbase;
- props[ncells++] = 0x00000000;
- props[ncells++] = arch->rlen;
+ ncells += host_encode_phys_addr(props + ncells, arch->rbase);
+ ncells += pci_encode_size(props + ncells, arch->rlen);
}
if (arch->mem_base) {
- pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
+ ncells += pci_encode_phys_addr(props + ncells, 0, MEMORY_SPACE_32,
config->dev, 0, arch->mem_base);
- ncells += 3;
- props[ncells++] = arch->mem_base;
- props[ncells++] = 0x00000000;
- props[ncells++] = arch->mem_len;
+ ncells += host_encode_phys_addr(props + ncells, arch->mem_base);
+ ncells += pci_encode_size(props + ncells, arch->mem_len);
}
set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0]));
}
@@ -548,11 +609,10 @@
pci_decode_pci_addr(config->assigned[i],
&flags, &space_code, &mask);
- pci_encode_phys_addr(props + ncells,
+ ncells += pci_encode_phys_addr(props + ncells,
flags, space_code, config->dev,
PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
config->assigned[i] & ~mask);
- ncells += 3;
props[ncells++] = 0x00000000;
props[ncells++] = config->sizes[i];
@@ -571,13 +631,13 @@
uint32_t mask;
int space_code, flags;
- ncells = 0;
- pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
+ ncells = 0;
+
+ /* first (addr, size) pair is the beginning of configuration address space */
+ ncells += pci_encode_phys_addr(props + ncells, 0, CONFIGURATION_SPACE,
config->dev, 0, 0);
- ncells += 3;
- props[ncells++] = 0x00000000;
- props[ncells++] = 0x00000000;
+ ncells += pci_encode_size(props + ncells, 0);
for (i = 0; i < num_bars; i++) {
if (!config->assigned[i] || !config->sizes[i])
@@ -586,17 +646,15 @@
pci_decode_pci_addr(config->regions[i],
&flags, &space_code, &mask);
- pci_encode_phys_addr(props + ncells,
+ ncells += pci_encode_phys_addr(props + ncells,
flags, space_code, config->dev,
PCI_BASE_ADDR_0 + (i * sizeof(uint32_t)),
config->regions[i] & ~mask);
- ncells += 3;
/* set size */
-
- props[ncells++] = 0x00000000;
- props[ncells++] = config->sizes[i];
+ ncells += pci_encode_size(props + ncells, config->sizes[i]);
}
+
set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
}
@@ -624,10 +682,9 @@
pci_decode_pci_addr(config->assigned[i],
&flags, &space_code, &mask);
- pci_encode_phys_addr(props + ncells, flags, space_code,
+ ncells += pci_encode_phys_addr(props + ncells, flags, space_code,
config->dev, 0x10 + i * 4,
config->assigned[i] & ~mask);
- ncells += 3;
/* size */
More information about the OpenBIOS
mailing list