oflib-0git20070620/0000775000175000017500000000000010636273125013200 5ustar julienjulienoflib-0git20070620/example/0000775000175000017500000000000010636266014014632 5ustar julienjulienoflib-0git20070620/example/example.c0000664000175000017500000000255110571625472016441 0ustar julienjulien#include int main(void) { struct device_node *node; struct device_node *tree; struct device_node *tmp; int x=0; void *property=NULL; int plen; of_init(); if((node=of_find_node_by_name("pci", 0))) { printf("node name is %s, node path is %s\n", node->name, node->path); tmp=of_get_parent(node); if(tmp) { printf("tmp name is %s, tmp path is %s\n", tmp->name, tmp->path); } property=of_find_property(node, "reg", &plen); of_free_node(tmp); of_free_node(node); free(property); } node=of_find_node_by_phandle(4287171720); if(node) { printf("FOUND NODE\n"); printf("node path is %s\n", node->path); printf("node type is %s\n", node->type); of_free_node(node); } while((node = of_find_node_by_name("pci", 1))!=NULL) { printf("node path is %s\n", node->path); of_free_node(node); } while((node = of_find_node_by_type("pci", 1))!=NULL) { printf("node path is %s\n", node->path); of_free_node(node); } if((node=of_find_node_by_path("/"))){ printf("node path is %s\n", node->path); printf("node type is %s\n", node->type); of_free_node(node); } /* needs a tree_next(thing) */ tree=of_find_type_devices("pci"); if(tree) { tmp=tree->next; while(tmp) { printf("(%s) %d - tmp name is %s\n", tmp->type, x++, tmp->name); tmp=tmp->next; } } of_find_type_devices_free(tree); return EXIT_SUCCESS; } oflib-0git20070620/example/ramtest.c0000664000175000017500000000300010571625472016453 0ustar julienjulien#include uint64_t total_ram; uint32_t cells_addr; uint32_t cells_size; void calculate_ram(uint8_t * ptr, uint32_t size) { int i = 1; int num = 0; int status = 1; uint64_t size64; uint32_t size32; uint8_t *p = ptr; while(status) { if((cells_addr == 2) && (cells_size == 1)) i+=2; else i++; if(cells_size == 2) { status=of_property_to_n_uint64(&size64, p, size, i++); if(!status) break; total_ram+=size64; } else { status=of_property_to_n_uint32(&size32, p, size, i++); if(!status) break; total_ram+=size32; } } } int main(int argc, char **argv) { struct device_node *node; struct device_node *parent; int plen = 0; void *property; if(argc == 1) of_init(); else of_init_root(argv[1]); while ((node = of_find_node_by_name("memory", 1)) != NULL) { if((parent=of_get_parent(node))) { if((property = of_find_property(parent,"#address-cells", &plen))) { of_property_to_uint32(&cells_addr, property, plen); free(property); } if((property = of_find_property(parent,"#size-cells", &plen))) { of_property_to_uint32(&cells_size, property, plen); free(property); } property = of_find_property(node, "reg", &plen); calculate_ram(property, plen); free(property); of_free_node(parent); } of_free_node(node); } printf("Total bytes %lld\n", total_ram); printf("Total MB %lld\n", total_ram >> 20); printf("Total GB %lld\n", total_ram >> 30); return EXIT_SUCCESS; } oflib-0git20070620/example/soundbus.c0000664000175000017500000000361410571625472016651 0ustar julienjulien#include void print_resources(struct device_node *node) { void *property; int plen; int ranges = 0; int x = 0; uint32_t start, end; int rsrc = 0; property = of_find_property(node, "reg", &plen); if(!property) return; ranges = plen/4; puts("Resources: "); for(x = 1; x <= ranges;x+=2 ) { of_property_to_n_uint32(&start, property, plen, x); of_property_to_n_uint32(&end, property, plen, x+1); end += start + 0x80000000; start += 0x80000000; printf(" rsrc[%d] 0x%08x - 0x%08x\n", rsrc++, start, end); } free(property); } void print_model(struct device_node *node) { void *property; char *str; int plen; property = of_find_property(node, "model", &plen); if(!property) return; str = property; str[plen-1] = '\0'; printf("Model: %s\n", str); free(property); } void print_sound(struct device_node *node) { void *property; char *str; int plen; uint32_t layout_id; property = of_find_property(node, "compatible", &plen); if(!property) return; str = property; str[plen-1]='\0'; printf("Compatible: %s\n", str); free(property); property = of_find_property(node, "layout-id", &plen); if(!property) return; of_property_to_int(&layout_id, property, plen); printf("Layout ID: %d\n", layout_id); free(property); } int main(int argc, char **argv) { struct device_node *root; struct device_node *sound; struct device_node *soundbus; if(argc == 1) of_init(); else of_init_root(argv[1]); if((root = of_find_node_by_path("/")) == NULL) of_error("Could not find node"); if((sound = of_find_node_by_name("sound", 0)) == NULL) of_error("Could not find sound"); if((soundbus = of_get_parent(sound)) == NULL) of_error("Could not find soundbus"); print_model(root); print_sound(sound); print_resources(soundbus); of_free_node(root); of_free_node(sound); of_free_node(soundbus); return EXIT_SUCCESS; } oflib-0git20070620/example/Makefile0000664000175000017500000000020410636266014016266 0ustar julienjuliendefault: gcc -std=c99 -lofapi example.c -o example gcc -std=c99 -lofapi ramtest.c -o ramtest clean: rm -f ramtest rm -f example oflib-0git20070620/lib/0000775000175000017500000000000010636266015013746 5ustar julienjulienoflib-0git20070620/lib/of_api.h0000664000175000017500000000224510636266014015356 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef __OF_USERSPACE__ #define __OF_USERSPACE__ #define _GNU_SOURCE #include #include #include #include #include #include #include #include char *OF_ROOT; struct node_property_t { uint8_t *data; uint32_t len; }; struct device_node { char *name; char *path; char *full_path; char *type; struct node_property_t linux_phandle; struct device_node *next; void *data; uint32_t len; }; #include "of_standard.h" #include "of_internals.h" #include "of_externals.h" #endif oflib-0git20070620/lib/of_externals.c0000664000175000017500000001101310636266015016577 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "of_api.h" void of_init(void) { OF_ROOT="/proc/device-tree"; } void of_init_root(char *path) { uint32_t len; if(!path) of_error("of_init_root() NULL path"); len = strlen(path); if(!len) of_error("of_init_root() Invalid path"); if(path[len-1] == '/') path[len-1] = '\0'; OF_ROOT=path; } int of_test_property(struct device_node *node, const char *name) { struct stat fstats; char buf[PATH_MAX]={0}; strcat(strcat(buf, node->full_path), name); if(stat(buf, &fstats) < 0) return 0; else return 1; } void *of_find_property(struct device_node *node, const char *name, int *plen) { char buf[PATH_MAX]={0}; uint8_t *property; uint32_t size; struct stat fstats; int fd; strcat(strcat(buf, node->full_path), name); if (stat(buf, &fstats) < 0) return NULL; size = fstats.st_size; property = malloc(size); if(!property) of_error("malloc()"); if ((fd = open(buf, O_RDONLY)) < 0) of_error("open()"); if ((*plen = read(fd, property, size)) != size) of_error("read()"); close(fd); return property; } int of_property_to_n_uint64(uint64_t *val, void *prop, uint32_t len, int n) { *val = 0; int i=0; uint8_t *data = prop; if((n*8 > len) || (n == 0)) return 0; for(i=0; i < (n*8)-1; i++); *val = ((uint64_t) data[i - 7] << 56) + ((uint64_t) data[i - 6] << 48) + ((uint64_t) data[i - 5] << 40) + ((uint64_t) data[i - 4] << 32) + ((uint64_t) data[i - 3] << 24) + ((uint64_t) data[i - 2] << 16) + ((uint64_t) data[i - 1] << 8) + (uint64_t) data[i]; return 1; } int of_property_to_n_uint32(uint32_t *val, void *prop, uint32_t len, int n) { *val = 0; int i=0; uint8_t *data = prop; if((n*4 > len) || (n == 0)) return 0; for(i=0; i < (n*4)-1; i++); *val = (data[i-3] << 24) + (data[i-2] << 16) + (data[i-1] << 8) + (data[i]); return 1; } int of_property_to_uint32(uint32_t *val, void *prop, uint32_t len) { *val=0; uint8_t *data = prop; if(len != 4) return 0; *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; return 1; } struct device_node *of_get_parent(struct device_node *node) { struct device_node *tmp; char *p; char *ptr; if((!node->path) || (!node) || (strlen(node->path)==1)) return NULL; ptr=strdup(node->path); p=strrchr(ptr, '/'); *p=0; p=strrchr(ptr, '/'); *p=0; tmp=of_find_node_by_path(ptr); free(ptr); return tmp; } struct device_node *of_find_node_by_name(const char *name, int type) { if (!_n_sem) _of_find_node_by_parse(OF_ROOT, name, OF_SEARCH_NAME, type); return _of_return_nodes(_n_array, &_n_idx, &_n_sem, type); } struct device_node *of_find_type_devices(const char *device_type) { struct device_node *list = calloc(1, sizeof(struct device_node)); struct device_node *tmp = NULL; struct device_node *ptr = list; while ((tmp = of_find_node_by_type(device_type, 1)) != NULL) { ptr->next = tmp; ptr = ptr->next; ptr->next = NULL; } return list; } void of_find_type_devices_free(struct device_node *root) { struct device_node *cursor = root; struct device_node *fwd; while (cursor) { fwd = cursor->next; of_free_node(cursor); cursor = fwd; } } struct device_node *of_find_node_by_path(const char *path) { struct device_node *tmp = NULL; char buf[PATH_MAX]; struct stat fstats; _of_make_compat_path(path, buf); if (stat(buf, &fstats) < 0) return NULL; tmp = _of_populate_node(buf, NULL); return tmp; } struct device_node *of_find_node_by_phandle(uint32_t phandle) { uint32_t *ptr = malloc(4); if(!ptr) of_error("malloc()"); *ptr = phandle; _of_find_node_by_parse(OF_ROOT, (void *)ptr, OF_SEARCH_PHDL, 0); free(ptr); return _of_return_nodes(_p_array, &_p_idx, &_t_sem, 0); } struct device_node *of_find_node_by_type(const char *device_type, int type) { if (!_t_sem) _of_find_node_by_parse(OF_ROOT, device_type, OF_SEARCH_TYPE, type); return _of_return_nodes(_t_array, &_t_idx, &_t_sem, type); } oflib-0git20070620/lib/of_externals.h0000664000175000017500000000343210636266015016612 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef __OF_DEVICE_BY__ #define __OF_DEVICE_BY__ #define OF_SEARCH_NAME 0x01 #define OF_SEARCH_TYPE 0x02 #define OF_SEARCH_PHDL 0x03 struct device_node *_n_array[256]; int _n_idx; int _n_sem; struct device_node *_t_array[256]; int _t_idx; int _t_sem; struct device_node *_p_array[2]; int _p_sem; int _p_idx; void of_init(void); void of_init_root(char *path); struct device_node *of_find_node_by_type(const char *device_type, int type); struct device_node *of_find_node_by_name(const char *name, int type); struct device_node *of_find_node_by_path(const char *path); struct device_node *of_find_node_by_phandle(uint32_t phandle); struct device_node *of_get_parent(struct device_node *node); void *of_find_property(struct device_node *node, const char *name, int *plen); int of_test_property(struct device_node *node, const char *name); int of_property_to_uint32(uint32_t *val, void *prop, uint32_t len); int of_property_to_n_uint32(uint32_t *val, void *prop, uint32_t len, int n); int of_property_to_n_uint64(uint64_t *val, void *prop, uint32_t len, int n); struct device_node *of_find_type_devices(const char *device_type); void of_find_type_devices_free(struct device_node *root); #endif oflib-0git20070620/lib/of_internals.c0000664000175000017500000001652410636266015016605 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "of_api.h" #include struct device_node *_of_return_nodes(struct device_node **array, int *idx, int *sem, int type) { while (*idx >= 0) { if (*idx == 0 || type == 0) *sem = 0; return *idx > 0 ? array[(*idx)--] : NULL; } return NULL; } char *_of_read_name(const char *path, struct device_node *node) { int fd; char *tmp; char buf[PATH_MAX]; struct stat fstats; uint32_t size; snprintf(buf, sizeof(buf), "%s%s", path, "name"); if (stat(buf, &fstats) < 0) return NULL; size = fstats.st_size; if ((fd = open(buf, O_RDONLY)) < 0) return NULL; if (node) { node->name = calloc(1, size); if(!node->name) of_error("calloc()"); tmp = node->name; } else { tmp = calloc(1, size); if(!tmp) of_error("calloc()"); } if (read(fd, tmp, size) != size) of_error("read()"); close(fd); return tmp; } void _of_read_type(const char *path, struct device_node *node) { int fd; char buf[PATH_MAX]; struct stat fstats; uint32_t size; snprintf(buf, sizeof(buf),"%s%s", path, "device_type"); if (stat(buf, &fstats) < 0) return; size = fstats.st_size; if ((fd = open(buf, O_RDONLY)) < 0) return; node->type = calloc(1, size); if(!node->type) of_error("calloc()"); if (read(fd, node->type, size) != size) of_error("read()"); close(fd); } void _of_read_linux_phandle(const char *path, struct device_node *node) { int fd; char buf[PATH_MAX]; struct stat fstats; uint32_t size; snprintf(buf, sizeof(buf), "%s%s", path, "linux,phandle"); if (stat(buf, &fstats) < 0) return; size = fstats.st_size; if(!size) return; if ((fd = open(buf, O_RDONLY)) < 0) return; node->linux_phandle.len = size; node->linux_phandle.data = calloc(1, size); if (read(fd, node->linux_phandle.data, size) != size) of_error("read()"); close(fd); } void _of_get_path(char *path) { char *ptr; char *p; int i; i = strlen(OF_ROOT); ptr = strdup(path); p = &ptr[i]; sprintf(path, "%s", p); free(ptr); } struct device_node *_of_populate_node(const char *path, const char *name) { struct device_node *tmp = calloc(1, sizeof(struct device_node)); char *p = strdup(path); _of_remove_filename(p); tmp->full_path = strdup(p); if (name) tmp->name = strdup(name); else _of_read_name(path, tmp); _of_get_path(p); tmp->path = strdup(p); free(p); _of_read_linux_phandle(tmp->full_path, tmp); _of_read_type(tmp->full_path, tmp); return tmp; } struct device_node *_of_get_type(const char *path, const char *type) { int fd; char buf[PATH_MAX]; char *name; char *ptr; struct device_node *tmp = NULL; struct stat fstats; uint32_t size; if (stat(path, &fstats) < 0) { exit(EXIT_FAILURE); } size = fstats.st_size; if(!size) return NULL; if ((fd = open(path, O_RDONLY)) < 0) of_error("open()"); if (read(fd, buf, size) != size) of_error("read()"); if (memcmp(buf, type, size)) goto out; ptr = strdup(path); _of_remove_filename(ptr); name = _of_read_name(ptr, NULL); tmp = _of_populate_node(path, name); free(ptr); free(name); out: close(fd); return tmp; } void _of_remove_filename(char *path) { char *ptr; ptr = strrchr(path, '/'); *(ptr + 1) = '\0'; } uint32_t _of_phandle_to_int(struct node_property_t phandle) { uint32_t tmp = 0; if (phandle.len == 4) tmp = (phandle.data[0] << 24) + (phandle.data[1] << 16) + (phandle.data[2] << 8) + phandle.data[3]; return tmp; } void _of_make_compat_path(const char *path, char *buf) { size_t slen = strlen(path); int changed = 0; if (*path != '/') changed = 1; if(!strlen(path)) { snprintf(buf, PATH_MAX, "%s/", OF_ROOT); return; } if (path[slen - 1] != '/') { if (changed) snprintf(buf, PATH_MAX, "%s/%s/", OF_ROOT, path); else snprintf(buf, PATH_MAX, "%s%s/", OF_ROOT, path); } else snprintf(buf, PATH_MAX, "%s%s", OF_ROOT, path); } struct device_node *_of_get_phandle(const char *path, const uint32_t * phandle) { struct node_property_t props; struct device_node *tmp = NULL; uint32_t size, val = 0; struct stat fstats; int fd; char *ptr; char *name; if (stat(path, &fstats) < 0) return NULL; size = fstats.st_size; if(!size) return NULL; props.data = malloc(size); if(!props.data) of_error("calloc()"); props.len = size; if ((fd = open(path, O_RDONLY)) < 0) of_error("open()"); if (read(fd, props.data, size) != size) of_error("read()"); close(fd); val = _of_phandle_to_int(props); free(props.data); if (val == *phandle) { ptr = strdup(path); _of_remove_filename(ptr); name = _of_read_name(ptr, NULL); tmp = _of_populate_node(path, name); free(ptr); free(name); } return tmp; } struct device_node *_of_get_name(const char *path, const char *name) { int fd; uint32_t size; char buf[PATH_MAX]; struct device_node *tmp = NULL; struct stat fstats; if (stat(path, &fstats) < 0) return NULL; size = fstats.st_size; if(!size) return NULL; if ((fd = open(path, O_RDONLY)) < 0) of_error("open()"); if (read(fd, buf, size) != size) of_error("read()"); if (memcmp(buf, name, size)) goto out; tmp = _of_populate_node(path, name); out: close(fd); return tmp; } void _of_find_node_by_parse(char *path, const void *search, uint16_t type, int full) { DIR *dir; struct dirent *tmp = NULL; char *directories[8192] = { NULL }; char fullpath[PATH_MAX]; int x = 0; struct stat fstats; struct device_node *node = NULL; lstat(path, &fstats); if (S_ISLNK(fstats.st_mode)) return; if ((dir = opendir(path)) == NULL) return; while ((tmp = readdir(dir)) != NULL) { if ((strcmp(tmp->d_name, ".")) && (strcmp(tmp->d_name, ".."))) { if (!strcmp(path, "/")) strcat(strcpy(fullpath, "/"), tmp->d_name); else strcat(strcat(strcpy(fullpath, path), "/"), tmp->d_name); if (type == OF_SEARCH_NAME) { if (!strcmp(tmp->d_name, "name")) { if ((node = _of_get_name(fullpath, search)) != NULL) { _n_array[++_n_idx] = node; _n_sem = 1; if(full==0) goto out; } } } if (type == OF_SEARCH_TYPE) { if (!strcmp(tmp->d_name, "device_type")) { if ((node = _of_get_type(fullpath, search)) != NULL) { _t_array[++_t_idx] = node; _t_sem = 1; if(full==0) goto out; } } } if (type == OF_SEARCH_PHDL) { if (!strcmp(tmp->d_name, "linux,phandle")) { if ((node = _of_get_phandle(fullpath, search)) != NULL) { _p_array[++_p_idx] = node; _p_sem = 1; goto out; } } } lstat(fullpath, &fstats); if (S_ISDIR(fstats.st_mode)) directories[x++] = strdup(fullpath); } } x = 0; while (directories[x] != NULL) { _of_find_node_by_parse(directories[x], search, type, full); out: free(directories[x++]); } closedir(dir); } oflib-0git20070620/lib/of_internals.h0000664000175000017500000000266010636266015016606 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef __OF_INTERNALS__ #define __OF_INTERNALS__ #include "of_api.h" void _of_find_node_by_parse(char *path, const void *search, uint16_t type, int full); struct device_node *_of_return_nodes(struct device_node **array, int *idx, int *sem, int type); struct device_node *_of_get_name(const char *path, const char *name); struct device_node *_of_get_type(const char *path, const char *type); struct device_node *_of_populate_node(const char *path, const char *name); struct device_node *_of_get_phandle(const char *path, const uint32_t * phandle); void _of_read_linux_phandle(const char *path, struct device_node *node); void _of_read_type(const char *path, struct device_node *node); void _of_remove_filename(char *path); void _of_get_path(char *path); void _of_make_compat_path(const char *path, char *buf); #endif oflib-0git20070620/lib/of_standard.c0000664000175000017500000000205210636266015016375 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "of_api.h" void of_error(char *error) { fprintf(stderr, "Error: %s\n", error); exit(EXIT_FAILURE); } void of_free_node(struct device_node *node) { if (node->name) free(node->name); if (node->path) free(node->path); if (node->full_path) free(node->full_path); if (node->type) free(node->type); if (node->linux_phandle.data) free(node->linux_phandle.data); if (node->data) free(node->data); if (node) free(node); } oflib-0git20070620/lib/of_standard.h0000664000175000017500000000135510636266015016407 0ustar julienjulien/*************************************************************************** * (C) Copyright 2006, 2007 Alastair Poole. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef __OF_STANDARD__ #define __OF_STANDARD__ void of_error(char *error); void of_free_node(struct device_node *node); #endif oflib-0git20070620/Makefile0000664000175000017500000000111510636266014014635 0ustar julienjulieninclude_dir=/usr/local/include/ofapi LIBNAME = libofapi.so SONAME = $(LIBNAME).0 SOVERSION = $(SONAME).0.0 default: gcc -g -Wall -D_REENTRANT -DPIC -fpic -Wl,-soname -Wl,$(SONAME) lib/*.c -shared -o $(SOVERSION) install: cp $(SOVERSION) /usr/local/lib ln -s /usr/local/lib/$(SOVERSION) /usr/local/lib/$(SONAME) ln -s /usr/local/lib/$(SOVERSION) /usr/local/lib/$(LIBNAME) test -d "$(include_dir)" || mkdir "$(include_dir)" cp lib/*.h $(include_dir) all: make default make install make examples examples: make -C example/ clean: make -C example/ clean rm -f libofapi.so.*