Rev 1787 | Rev 1790 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1787 | Rev 1789 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | #include "ofw.h" |
29 | #include <ofw.h> |
- | 30 | #include <ofwarch.h> |
|
30 | #include <printf.h> |
31 | #include <printf.h> |
31 | #include <asm.h> |
32 | #include <asm.h> |
32 | #include <types.h> |
33 | #include <types.h> |
33 | 34 | ||
34 | uintptr_t ofw_cif; |
35 | uintptr_t ofw_cif; |
Line 38... | Line 39... | ||
38 | phandle ofw_root; |
39 | phandle ofw_root; |
39 | ihandle ofw_mmu; |
40 | ihandle ofw_mmu; |
40 | phandle ofw_memory; |
41 | phandle ofw_memory; |
41 | phandle ofw_aliases; |
42 | phandle ofw_aliases; |
42 | 43 | ||
- | 44 | void ofw_init(void) |
|
- | 45 | { |
|
- | 46 | ofw_chosen = ofw_find_device("/chosen"); |
|
- | 47 | if (ofw_chosen == -1) |
|
- | 48 | halt(); |
|
- | 49 | ||
- | 50 | if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
|
- | 51 | ofw_stdout = 0; |
|
- | 52 | ||
- | 53 | ofw_root = ofw_find_device("/"); |
|
- | 54 | if (ofw_root == -1) { |
|
- | 55 | puts("\r\nError: Unable to find / device, halted.\r\n"); |
|
- | 56 | halt(); |
|
- | 57 | } |
|
- | 58 | ||
- | 59 | if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) { |
|
- | 60 | puts("\r\nError: Unable to get mmu property, halted.\r\n"); |
|
- | 61 | halt(); |
|
- | 62 | } |
|
- | 63 | ||
- | 64 | ofw_memory = ofw_find_device("/memory"); |
|
- | 65 | if (ofw_memory == -1) { |
|
- | 66 | puts("\r\nError: Unable to find /memory device, halted.\r\n"); |
|
- | 67 | halt(); |
|
- | 68 | } |
|
- | 69 | ||
- | 70 | ofw_aliases = ofw_find_device("/aliases"); |
|
- | 71 | if (ofw_aliases == -1) { |
|
- | 72 | puts("\r\nError: Unable to find /aliases device, halted.\r\n"); |
|
- | 73 | halt(); |
|
- | 74 | } |
|
- | 75 | } |
|
- | 76 | ||
- | 77 | ||
43 | static unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
78 | static unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
44 | { |
79 | { |
45 | va_list list; |
80 | va_list list; |
46 | ofw_args_t args; |
81 | ofw_args_t args; |
47 | int i; |
82 | int i; |
Line 77... | Line 112... | ||
77 | { |
112 | { |
78 | return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
113 | return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
79 | } |
114 | } |
80 | 115 | ||
81 | 116 | ||
82 | static unsigned int ofw_get_address_cells(const phandle device) |
117 | unsigned int ofw_get_address_cells(const phandle device) |
83 | { |
118 | { |
84 | unsigned int ret; |
119 | unsigned int ret = 1; |
85 | 120 | ||
86 | if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0) |
121 | if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0) |
87 | if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0) |
122 | if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0) |
88 | ret = 1; |
123 | ret = OFW_ADDRESS_CELLS; |
89 | 124 | ||
90 | return ret; |
125 | return ret; |
91 | } |
126 | } |
92 | 127 | ||
93 | 128 | ||
94 | static unsigned int ofw_get_size_cells(const phandle device) |
129 | unsigned int ofw_get_size_cells(const phandle device) |
95 | { |
130 | { |
96 | unsigned int ret; |
131 | unsigned int ret; |
97 | 132 | ||
98 | if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0) |
133 | if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0) |
99 | if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0) |
134 | if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0) |
100 | ret = 1; |
135 | ret = OFW_SIZE_CELLS; |
101 | 136 | ||
102 | return ret; |
137 | return ret; |
103 | } |
138 | } |
104 | 139 | ||
105 | 140 | ||
Line 107... | Line 142... | ||
107 | { |
142 | { |
108 | return ofw_call("open", 1, 1, NULL, name); |
143 | return ofw_call("open", 1, 1, NULL, name); |
109 | } |
144 | } |
110 | 145 | ||
111 | 146 | ||
112 | void init(void) |
- | |
113 | { |
- | |
114 | ofw_chosen = ofw_find_device("/chosen"); |
- | |
115 | if (ofw_chosen == -1) |
- | |
116 | halt(); |
- | |
117 | - | ||
118 | if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
- | |
119 | ofw_stdout = 0; |
- | |
120 | - | ||
121 | ofw_root = ofw_find_device("/"); |
- | |
122 | if (ofw_root == -1) { |
- | |
123 | puts("\r\nError: Unable to find / device, halted.\r\n"); |
- | |
124 | halt(); |
- | |
125 | } |
- | |
126 | - | ||
127 | if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) { |
- | |
128 | puts("\r\nError: Unable to get mmu property, halted.\r\n"); |
- | |
129 | halt(); |
- | |
130 | } |
- | |
131 | - | ||
132 | ofw_memory = ofw_find_device("/memory"); |
- | |
133 | if (ofw_memory == -1) { |
- | |
134 | puts("\r\nError: Unable to find /memory device, halted.\r\n"); |
- | |
135 | halt(); |
- | |
136 | } |
- | |
137 | - | ||
138 | ofw_aliases = ofw_find_device("/aliases"); |
- | |
139 | if (ofw_aliases == -1) { |
- | |
140 | puts("\r\nError: Unable to find /aliases device, halted.\r\n"); |
- | |
141 | halt(); |
- | |
142 | } |
- | |
143 | } |
- | |
144 | - | ||
145 | - | ||
146 | void ofw_write(const char *str, const int len) |
147 | void ofw_write(const char *str, const int len) |
147 | { |
148 | { |
148 | if (ofw_stdout == 0) |
149 | if (ofw_stdout == 0) |
149 | return; |
150 | return; |
150 | 151 | ||
Line 167... | Line 168... | ||
167 | 168 | ||
168 | if (sizeof(unative_t) == 8) |
169 | if (sizeof(unative_t) == 8) |
169 | shift = 32; |
170 | shift = 32; |
170 | else |
171 | else |
171 | shift = 0; |
172 | shift = 0; |
172 | 173 | ||
173 | return (void *) ((result[2]<<shift)|result[3]); |
174 | return (void *) ((result[2]<<shift)|result[3]); |
174 | } |
175 | } |
175 | 176 | ||
176 | void *ofw_claim(const void *virt, const int len) |
177 | void *ofw_claim(const void *virt, const int len) |
177 | { |
178 | { |
Line 204... | Line 205... | ||
204 | } |
205 | } |
205 | 206 | ||
206 | 207 | ||
207 | int ofw_memmap(memmap_t *map) |
208 | int ofw_memmap(memmap_t *map) |
208 | { |
209 | { |
209 | unsigned long buf[BUF_SIZE]; |
- | |
210 | int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf)); |
- | |
211 | if (ret <= 0) |
- | |
212 | return false; |
- | |
213 | - | ||
214 | unsigned int ac = ofw_get_address_cells(ofw_memory); |
210 | unsigned int ac = ofw_get_address_cells(ofw_memory); |
215 | unsigned int sc = ofw_get_size_cells(ofw_memory); |
211 | unsigned int sc = ofw_get_size_cells(ofw_memory); |
216 | 212 | ||
- | 213 | uint32_t buf[((ac+sc)*MEMMAP_MAX_RECORDS)]; |
|
- | 214 | int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf)); |
|
- | 215 | if (ret <= 0) /* ret is the number of written bytes */ |
|
- | 216 | return false; |
|
- | 217 | ||
217 | int pos; |
218 | int pos; |
218 | map->total = 0; |
219 | map->total = 0; |
219 | map->count = 0; |
220 | map->count = 0; |
220 | for (pos = 0; (pos < ret / sizeof(unsigned long)) && (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
221 | for (pos = 0; (pos < ret / sizeof(uint32_t)) && (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
221 | void * start = (void *) buf[pos + ac - 1]; |
222 | void * start = (void *) ((uintptr_t) buf[pos + ac - 1]); |
222 | unsigned int size = buf[pos + ac + sc - 1]; |
223 | unsigned int size = buf[pos + ac + sc - 1]; |
223 | 224 | ||
224 | if (size > 0) { |
225 | if (size > 0) { |
225 | map->zones[map->count].start = start; |
226 | map->zones[map->count].start = start; |
226 | map->zones[map->count].size = size; |
227 | map->zones[map->count].size = size; |
227 | map->count++; |
228 | map->count++; |
228 | map->total += size; |
229 | map->total += size; |
229 | } |
230 | } |
230 | } |
231 | } |
- | 232 | ||
- | 233 | return true; |
|
231 | } |
234 | } |
232 | 235 | ||
233 | 236 | ||
234 | int ofw_screen(screen_t *screen) |
237 | int ofw_screen(screen_t *screen) |
235 | { |
238 | { |
236 | char device_name[BUF_SIZE]; |
239 | char device_name[BUF_SIZE]; |
- | 240 | uint32_t virtaddr; |
|
237 | 241 | ||
238 | if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0) |
242 | if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0) |
239 | return false; |
243 | return false; |
240 | 244 | ||
241 | phandle device = ofw_find_device(device_name); |
245 | phandle device = ofw_find_device(device_name); |
242 | if (device == -1) |
246 | if (device == -1) |
243 | return false; |
247 | return false; |
244 | 248 | ||
245 | if (ofw_get_property(device, "address", &screen->addr, sizeof(screen->addr)) <= 0) |
249 | if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0) |
246 | return false; |
250 | return false; |
- | 251 | ||
- | 252 | screen->addr = (void *) ((uintptr_t) virtaddr); |
|
247 | 253 | ||
248 | if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0) |
254 | if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0) |
249 | return false; |
255 | return false; |
250 | 256 | ||
251 | if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0) |
257 | if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0) |
252 | return false; |
258 | return false; |