/* * Older OF's require that when claiming a specific range of addresses, * we claim the physical space in the /memory node and the virtual * space in the chosen mmu node, and then do a map operation to * map virtual to physical. */ static int check_of_version(void) { phandle oprom; char version[20]; oprom = of1275_finddevice("/openprom"); if (oprom == (phandle) (-1)) return 0; if (of1275_getprop(oprom, "model", version, sizeof(version)) <= 0) return 0; if (!string_match(version, "Open Firmware, 1.") && !string_match(version, "FirmWorks,3.")) return 0; memory = (ihandle) call_prom("open", 1, 1, "/memory"); if (memory == (ihandle) (-1)) { memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); if (memory == (ihandle) (-1)) return 0; } return 1; }
static void *claim(unsigned long virt, unsigned long size, unsigned long align) { int ret; unsigned int result; if (need_map < 0) need_map = check_of_version(); if (align || !need_map) return (void *) call_prom("claim", 3, 1, virt, size, align); ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, align, size, virt); if (ret != 0 || result == -1) return (void *) -1; ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, align, size, virt); /* 0x12 == coherent + read/write */ ret = call_prom("call-method", 6, 1, "map", chosen_mmu, 0x12, size, virt, virt); return (void *) virt; }
static int check_of_version(void) { phandle oprom, chosen; char version[64]; oprom = finddevice("/openprom"); if (oprom == (phandle) -1) return 0; if (getprop(oprom, "model", version, sizeof(version)) <= 0) return 0; version[sizeof(version)-1] = 0; printf("OF version = '%s'\r\n", version); if (!string_match(version, "Open Firmware, 1.") && !string_match(version, "FirmWorks,3.")) return 0; chosen = finddevice("/chosen"); if (chosen == (phandle) -1) { chosen = finddevice("/chosen@0"); if (chosen == (phandle) -1) { printf("no chosen\n"); return 0; } } if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) { printf("no mmu\n"); return 0; } memory = (ihandle) call_prom("open", 1, 1, "/memory"); if (memory == (ihandle) -1) { memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); if (memory == (ihandle) -1) { printf("no memory node\n"); return 0; } } printf("old OF detected\r\n"); return 1; }
int of1275_write(phandle node, void *buf, int buflen) { return call_prom("write", 3, 1, node, buf, buflen); }
int of1275_map(unsigned int phys, unsigned int virt, unsigned int size) { return call_prom("call-method", 6, 1, "map", mmu, 0, size, virt, phys); }
static void of_console_write(char *buf, int len) { call_prom("write", 3, 1, of_stdout_handle, buf, len); }
static int of_setprop(const void *phandle, const char *name, const void *buf, const int buflen) { return call_prom("setprop", 4, 1, phandle, name, buf, buflen); }
/* * OF device tree routines */ static void *of_finddevice(const char *name) { return (phandle) call_prom("finddevice", 1, 1, name); }
static void of_exit(void) { call_prom("exit", 0, 0); }
int of1275_read(phandle node, void *buf, int buflen) { return call_prom("read", 3, 1, node, buf, buflen); }