Subversion Repositories HelenOS

Rev

Rev 3022 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3022 Rev 4055
Line 36... Line 36...
36
 */
36
 */
37
 
37
 
38
#include <genarch/ofw/ofw_tree.h>
38
#include <genarch/ofw/ofw_tree.h>
39
#include <arch/memstr.h>
39
#include <arch/memstr.h>
40
#include <arch/trap/interrupt.h>
40
#include <arch/trap/interrupt.h>
41
#include <func.h>
41
#include <string.h>
42
#include <panic.h>
42
#include <panic.h>
43
#include <debug.h>
43
#include <debug.h>
44
#include <macros.h>
44
#include <macros.h>
45
 
45
 
46
/** Apply EBUS ranges to EBUS register. */
46
/** Apply EBUS ranges to EBUS register. */
-
 
47
bool
47
bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
48
ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
48
{
49
{
49
    ofw_tree_property_t *prop;
50
    ofw_tree_property_t *prop;
50
    ofw_ebus_range_t *range;
51
    ofw_ebus_range_t *range;
51
    count_t ranges;
52
    count_t ranges;
52
 
53
 
Line 60... Line 61...
60
    unsigned int i;
61
    unsigned int i;
61
   
62
   
62
    for (i = 0; i < ranges; i++) {
63
    for (i = 0; i < ranges; i++) {
63
        if (reg->space != range[i].child_space)
64
        if (reg->space != range[i].child_space)
64
            continue;
65
            continue;
65
        if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
66
        if (overlaps(reg->addr, reg->size, range[i].child_base,
-
 
67
            range[i].size)) {
66
            ofw_pci_reg_t pci_reg;
68
            ofw_pci_reg_t pci_reg;
67
           
69
           
68
            pci_reg.space = range[i].parent_space;
70
            pci_reg.space = range[i].parent_space;
-
 
71
            pci_reg.addr = range[i].parent_base +
69
            pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base);
72
                (reg->addr - range[i].child_base);
70
            pci_reg.size = reg->size;
73
            pci_reg.size = reg->size;
71
           
74
           
72
            return ofw_pci_apply_ranges(node->parent, &pci_reg, pa);
75
            return ofw_pci_apply_ranges(node->parent, &pci_reg, pa);
73
        }
76
        }
74
    }
77
    }
75
 
78
 
76
    return false;
79
    return false;
77
}
80
}
78
 
81
 
-
 
82
bool
79
bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr)
83
ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg,
-
 
84
    uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
80
{
85
{
81
    ofw_tree_property_t *prop;
86
    ofw_tree_property_t *prop;
82
    ofw_tree_node_t *controller;
87
    ofw_tree_node_t *controller;
83
   
88
   
84
    prop = ofw_tree_getprop(node, "interrupt-map");
89
    prop = ofw_tree_getprop(node, "interrupt-map");
Line 102... Line 107...
102
    uint32_t addr = reg->addr & intr_mask->addr_mask;
107
    uint32_t addr = reg->addr & intr_mask->addr_mask;
103
    uint32_t intr = interrupt & intr_mask->intr_mask;
108
    uint32_t intr = interrupt & intr_mask->intr_mask;
104
   
109
   
105
    unsigned int i;
110
    unsigned int i;
106
    for (i = 0; i < count; i++) {
111
    for (i = 0; i < count; i++) {
107
        if ((intr_map[i].space == space) && (intr_map[i].addr == addr)
112
        if ((intr_map[i].space == space) &&
108
            && (intr_map[i].intr == intr))
113
            (intr_map[i].addr == addr) && (intr_map[i].intr == intr))
109
            goto found;
114
            goto found;
110
    }
115
    }
111
    return false;
116
    return false;
112
 
117
 
113
found:
118
found:
114
    /*
119
    /*
115
     * We found the device that functions as an interrupt controller
120
     * We found the device that functions as an interrupt controller
116
     * for the interrupt. We also found partial mapping from interrupt to INO.
121
     * for the interrupt. We also found partial mapping from interrupt to
-
 
122
     * INO.
117
     */
123
     */
118
 
124
 
119
    controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
125
    controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"),
-
 
126
        intr_map[i].controller_handle);
120
    if (!controller)
127
    if (!controller)
121
        return false;
128
        return false;
122
       
129
       
123
    if (strcmp(ofw_tree_node_name(controller), "pci") != 0) {
130
    if (strcmp(ofw_tree_node_name(controller), "pci") != 0) {
124
        /*
131
        /*
Line 128... Line 135...
128
    }
135
    }
129
 
136
 
130
    /*
137
    /*
131
     * Let the PCI do the next step in mapping the interrupt.
138
     * Let the PCI do the next step in mapping the interrupt.
132
     */
139
     */
133
    if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr))
140
    if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino,
-
 
141
        inr, cir, cir_arg))
134
        return false;
142
        return false;
135
 
143
 
136
    return true;
144
    return true;
137
}
145
}
138
 
146