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; |