Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit a113b517eb022487a9c4023a69b83c388b7946fc @iainb committed Jun 19, 2012
Showing with 258 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +15 −0 Makefile
  3. +20 −0 README
  4. +176 −0 cdxalloc.c
  5. +45 −0 cdxalloc.h
2 .gitignore
@@ -0,0 +1,2 @@
+*.o
+*.a
15 Makefile
@@ -0,0 +1,15 @@
+PROJECT = libcedarxalloc.a
+OBJECTS = cdxalloc.o
+CFLAGS = -Wall
+
+all: $(PROJECT)
+
+.c.o:
+ gcc -c $(CFLAGS) $<
+
+$(PROJECT): $(OBJECTS)
+ ar rcs $(PROJECT) $(OBJECTS)
+
+clean:
+ @rm -f $(PROJECT)
+ @rm -f $(OBJECTS)
20 README
@@ -0,0 +1,20 @@
+open cdxalloc
+=============
+
+This is a work in progress reverse engineering effort of libcederxalloc.a library which is used to manage memory allocated to the cedarx video decoder chip found in Allwinner A10 devices.
+
+This library also aims to help in reverse engineering the cedarx video video decoder chip.
+
+Status
+------
+
+Currently this library is not quality code, there are many things missing. It is the bare minimum required for the sample code from the [allwinner-a10-video] (https://github.com/amery/allwinner-a10-video) repository to work (at least as well as the bundled libcedarxalloc.a).
+
+I have developed and tested this code on an Mele A1000 A10 device running 3.0.31 linux kernel with Debian squeeze as per the [instructions here] (http://rhombus-tech.net/allwinner_a10/hacking_the_mele_a1000/Building_Debian_From_Source_Code_for_Mele/)
+
+Todo
+----
+
+* proper management of memory (rather than just working through the available memory).
+* free/ close down
+* locking to allow for multi-threaded use
176 cdxalloc.c
@@ -0,0 +1,176 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include "cdxalloc.h"
+
+#define cdxalloc_simple_debug 1
+#define cdxalloc_verbose_debug 0
+
+int fd;
+
+cedar_env_info_t *cedar_env;
+void *pos;
+mapping_t **mappings;
+int num_mappings = 100;
+
+/*
+ cdxalloc_open sets up the cdxalloc library, it is required
+ to be called before the library is used.
+*/
+int cdxalloc_open(void)
+{
+ int i;
+ // alloc cedar_env_info_t structure
+ cedar_env = (cedar_env_info_t*)malloc(sizeof(cedar_env_info_t));
+ if (!cedar_env) {
+ return -1;
+ }
+ memset(cedar_env, 0,sizeof(cedar_env_info_t));
+
+ // allocate memory mappings
+ mappings = (mapping_t **) malloc(sizeof(mapping_t *) * num_mappings);
+ for(i = 0; i < num_mappings; i++)
+ {
+ mappings[i] = (mapping_t *) malloc(sizeof(mapping_t));
+ memset(mappings[i],0,sizeof(mapping_t));
+ }
+
+ // open cedar_dev device
+ fd = open(cedar_dev_name,O_RDWR);
+ if (fd == -1) {
+ return -1;
+ }
+
+ // load cedar environment info into user land
+ ioctl(fd,IOCTL_GET_ENV_INFO,cedar_env);
+
+ #ifdef cdxalloc_simple_debug
+ printf("phymem_start:0x%08x\n",cedar_env->phymem_start);
+ #endif
+
+ pos = (void *)cedar_env->phymem_start;
+ return 0;
+}
+
+/*
+ cdxalloc_close closes down the driver, freeing memory etc.
+ TODO: implement this.
+*/
+int cdxalloc_close(void)
+{
+ // close fd
+ close(fd);
+ // free cedar memory
+ // free cedar_env
+ return 0;
+}
+
+/*
+ cdxalloc_alloc creates a memory mapping into the cedarx video
+ decoder of a specified size.
+
+ in the mmapcall the offset (defined by the integer pos) is the
+ physical address at which the mapping should start at.
+
+ Observations of libceaderxalloc has shown mappings all being created
+ on 4096 byte boundries - so this works in the same way.
+
+*/
+void* cdxalloc_alloc(int size)
+{
+ void *ret;
+ ret = mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(int) pos);
+ if (ret == MAP_FAILED) {
+ printf("Error allocating %d bytes\n",size);
+ return ret;
+ }
+ cdxalloc_createmapping(ret,pos,size);
+ pos = pos + size;
+ // align to 4kb boundry
+ pos = pos + 4096 - ((unsigned int)pos % 4096);
+ return ret;
+}
+/*
+ * cdxalloc_free frees memory allocated at a particular address
+ * TODO: implement this.
+ *
+ */
+void cdxalloc_free(void *address)
+{
+ //munmap(address,size)
+}
+
+/*
+ cdxalloc_vir2phy takes a virtual user space address which
+ maps to physical memory owned by the cedarx video decoder.
+ This address is then converted from a virtual to a phyical
+ address.
+*/
+unsigned int cdxalloc_vir2phy(void *address)
+{
+ int i;
+ unsigned int ret = 0;
+
+ for(i=0;i<num_mappings;i++) {
+ #ifdef cdxalloc_verbose_debug
+ printf("cmp: 0x%08x == 0x%08x\n",(unsigned int) mappings[i]->start_virt, (unsigned int) address);
+ #endif
+ if (mappings[i]->start_virt == address) {
+ ret = (unsigned int) mappings[i]->start_phys;
+ break;
+ } else if (address > mappings[i]->start_virt && address < (mappings[i]->start_virt + mappings[i]->size)) {
+ ret = (unsigned int) mappings[i]->start_phys + (address - mappings[i]->start_virt);
+ break;
+ }
+ }
+ if (ret == 0) {
+ printf("couldn't find address! 0x%08x\n",(unsigned int) address);
+ exit(1);
+ } else {
+ #ifdef cdxalloc_verbose_debug
+ printf("found: 0x%08x\n",(unsigned int) address);
+ #endif
+ }
+ ret = ret & 0x0fffffff;
+ return ret;
+}
+
+/*
+ cdxalloc_allocregs returns a pointer to 2048bytes of memory which
+ contain the registers for the cedarx video decoder.
+*/
+void* cdxalloc_allocregs()
+{
+ return mmap(NULL, 2048, PROT_READ | PROT_WRITE, MAP_SHARED,fd,(int)cedar_env->address_macc);
+}
+
+/*
+ cdxalloc_createmapping creates an entry in the mapping array for
+ the given arguments. Used for cdxalloc_vir2phy.
+*/
+void cdxalloc_createmapping(void *virt,void *phys,int size)
+{
+ // find first unallocated mapping
+ int i;
+ for (i=0;i<num_mappings;i++) {
+ if (mappings[i]->start_phys == 0) {
+ #ifdef cdxalloc_verbose_debug
+ printf("creating mapping at %d\n",i);
+ #endif
+ mappings[i]->start_phys = phys;
+ mappings[i]->start_virt = virt;
+ mappings[i]->size = size;
+ break;
+ }
+ }
+}
45 cdxalloc.h
@@ -0,0 +1,45 @@
+
+enum IOCTL_CMD {
+ IOCTL_UNKOWN = 0x100,
+ IOCTL_GET_ENV_INFO,
+ IOCTL_WAIT_VE,
+ IOCTL_RESET_VE,
+ IOCTL_ENABLE_VE,
+ IOCTL_DISABLE_VE,
+ IOCTL_SET_VE_FREQ,
+
+ IOCTL_CONFIG_AVS2 = 0x200,
+ IOCTL_GETVALUE_AVS2 ,
+ IOCTL_PAUSE_AVS2 ,
+ IOCTL_START_AVS2 ,
+ IOCTL_RESET_AVS2 ,
+ IOCTL_ADJUST_AVS2,
+ IOCTL_ENGINE_REQ,
+ IOCTL_ENGINE_REL,
+ IOCTL_ENGINE_CHECK_DELAY,
+ IOCTL_GET_IC_VER,
+
+ IOCTL_ADJUST_AVS2_ABS,
+ IOCTL_FLUSH_CACHE,
+};
+
+typedef struct CEDAR_ENV_INFORMATION {
+ unsigned int phymem_start;
+ int phymem_total_size;
+ unsigned int address_macc;
+}cedar_env_info_t;
+
+typedef struct {
+ void *start_virt;
+ void *start_phys;
+ int size;
+}mapping_t;
+
+int cdxalloc_open(void);
+int cdxalloc_close(void);
+void* cdxalloc_alloc(int size);
+void* cdxalloc_allocregs();
+void cdxalloc_free(void *address);
+unsigned int cdxalloc_vir2phy(void *address);
+void cdxalloc_createmapping(void *virt,void *phys,int size);
+#define cedar_dev_name "/dev/cedar_dev"

0 comments on commit a113b51

Please sign in to comment.