/branches/dynload/kernel/genarch/src/ofw/ebus.c |
---|
44,7 → 44,8 |
#include <macros.h> |
/** Apply EBUS ranges to EBUS register. */ |
bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) |
bool |
ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) |
{ |
ofw_tree_property_t *prop; |
ofw_ebus_range_t *range; |
62,11 → 63,13 |
for (i = 0; i < ranges; i++) { |
if (reg->space != range[i].child_space) |
continue; |
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { |
if (overlaps(reg->addr, reg->size, range[i].child_base, |
range[i].size)) { |
ofw_pci_reg_t pci_reg; |
pci_reg.space = range[i].parent_space; |
pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base); |
pci_reg.addr = range[i].parent_base + |
(reg->addr - range[i].child_base); |
pci_reg.size = reg->size; |
return ofw_pci_apply_ranges(node->parent, &pci_reg, pa); |
76,7 → 79,9 |
return false; |
} |
bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr) |
bool |
ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, |
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) |
{ |
ofw_tree_property_t *prop; |
ofw_tree_node_t *controller; |
104,8 → 109,8 |
unsigned int i; |
for (i = 0; i < count; i++) { |
if ((intr_map[i].space == space) && (intr_map[i].addr == addr) |
&& (intr_map[i].intr == intr)) |
if ((intr_map[i].space == space) && |
(intr_map[i].addr == addr) && (intr_map[i].intr == intr)) |
goto found; |
} |
return false; |
113,10 → 118,12 |
found: |
/* |
* We found the device that functions as an interrupt controller |
* for the interrupt. We also found partial mapping from interrupt to INO. |
* for the interrupt. We also found partial mapping from interrupt to |
* INO. |
*/ |
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle); |
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), |
intr_map[i].controller_handle); |
if (!controller) |
return false; |
130,7 → 137,8 |
/* |
* Let the PCI do the next step in mapping the interrupt. |
*/ |
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr)) |
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, |
inr, cir, cir_arg)) |
return false; |
return true; |
/branches/dynload/kernel/genarch/src/ofw/fhc.c |
---|
109,7 → 109,9 |
return false; |
} |
bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr) |
bool |
ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, |
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) |
{ |
fhc_t *fhc = NULL; |
if (!node->device) { |
126,6 → 128,8 |
fhc_enable_interrupt(fhc, interrupt); |
*inr = interrupt; |
*cir = fhc_clear_interrupt; |
*cir_arg = fhc; |
return true; |
} |
/branches/dynload/kernel/genarch/src/ofw/ofw_tree.c |
---|
57,9 → 57,11 |
* @param node Node in which to lookup the property. |
* @param name Name of the property. |
* |
* @return Pointer to the property structure or NULL if no such property. |
* @return Pointer to the property structure or NULL if no such |
* property. |
*/ |
ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) |
ofw_tree_property_t * |
ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) |
{ |
unsigned int i; |
96,7 → 98,8 |
* @param node Node whose child is being looked up. |
* @param name Name of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the matching child node. |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
*/ |
ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name) |
{ |
130,9 → 133,11 |
* @param node Node whose child is being looked up. |
* @param name Device type of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the matching child node. |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
*/ |
ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name) |
ofw_tree_node_t * |
ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
156,9 → 161,11 |
* @param root Root of the searched subtree. |
* @param handle OpenFirmware handle. |
* |
* @return NULL if there is no such node or pointer to the matching node. |
* @return NULL if there is no such node or pointer to the matching |
* node. |
*/ |
ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) |
ofw_tree_node_t * |
ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) |
{ |
ofw_tree_node_t *cur; |
183,9 → 190,11 |
* @param node Node whose peer is being looked up. |
* @param name Device type of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the matching child node. |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
*/ |
ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name) |
ofw_tree_node_t * |
ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
202,11 → 211,37 |
} |
/** Lookup first peer of given name. |
* |
* @param node Node whose peer is being looked up. |
* @param name Name of the child being looked up. |
* |
* @return NULL if there is no such peer or pointer to the matching |
* peer node. |
*/ |
ofw_tree_node_t * |
ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
for (cur = node->peer; cur; cur = cur->peer) { |
prop = ofw_tree_getprop(cur, "name"); |
if (!prop || !prop->value) |
continue; |
if (strcmp(prop->value, name) == 0) |
return cur; |
} |
return NULL; |
} |
/** Lookup OpenFirmware node by its path. |
* |
* @param path Path to the node. |
* |
* @return NULL if there is no such node or pointer to the leaf node. |
* @return NULL if there is no such node or pointer to the leaf |
* node. |
*/ |
ofw_tree_node_t *ofw_tree_lookup(const char *path) |
{ |
/branches/dynload/kernel/genarch/src/ofw/pci.c |
---|
49,7 → 49,8 |
#define PCI_IGN 0x1f |
bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) |
bool |
ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) |
{ |
ofw_tree_property_t *prop; |
ofw_pci_range_t *range; |
68,10 → 69,13 |
unsigned int i; |
for (i = 0; i < ranges; i++) { |
if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK)) |
if ((reg->space & PCI_SPACE_MASK) != |
(range[i].space & PCI_SPACE_MASK)) |
continue; |
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { |
*pa = range[i].parent_base + (reg->addr - range[i].child_base); |
if (overlaps(reg->addr, reg->size, range[i].child_base, |
range[i].size)) { |
*pa = range[i].parent_base + |
(reg->addr - range[i].child_base); |
return true; |
} |
} |
79,7 → 83,9 |
return false; |
} |
bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out) |
bool |
ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, |
ofw_pci_reg_t *out) |
{ |
if (reg->space & PCI_ABS_MASK) { |
/* already absolute */ |
103,7 → 109,8 |
unsigned int i; |
for (i = 0; i < assigned_addresses; i++) { |
if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) { |
if ((assigned_address[i].space & PCI_REG_MASK) == |
(reg->space & PCI_REG_MASK)) { |
out->space = assigned_address[i].space; |
out->addr = reg->addr + assigned_address[i].addr; |
out->size = reg->size; |
119,7 → 126,9 |
* So far, we only know how to map interrupts of non-PCI devices connected |
* to a PCI bridge. |
*/ |
bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr) |
bool |
ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, |
int *inr, cir_t *cir, void **cir_arg) |
{ |
pci_t *pci = node->device; |
if (!pci) { |
132,6 → 141,8 |
pci_enable_interrupt(pci, ino); |
*inr = (PCI_IGN << IGN_SHIFT) | ino; |
*cir = pci_clear_interrupt; |
*cir_arg = pci; |
return true; |
} |