Implemented basic raytracing and custom startup code.
authorethereal <ethereal@ethv.net>
Thu, 11 Jun 2015 19:30:50 +0000 (19:30 +0000)
committerethereal <ethereal@ethv.net>
Thu, 11 Jun 2015 19:30:50 +0000 (19:30 +0000)
src/CMakeLists.txt
src/ecommon.h
src/ecore/ecore.c
src/ecore/ecore.h
src/ecore/math.c
src/ecore/math.h
src/ecore/render.c
src/ecore/render.h
src/ecore/rreq.c
src/ecore/support.S [new file with mode: 0644]
src/ewrap/main.c

index d411a1d..553a246 100644 (file)
@@ -4,14 +4,15 @@ include_directories($ENV{EPIPHANY_HOME}/tools/host/include)
 link_directories($ENV{EPIPHANY_HOME}/tools/host/lib)
 
 if(${build_ecore})
-    #add_custom_command(OUTPUT ecore.o DEPENDS ecore/ecore.s COMMAND e-as ${CMAKE_CURRENT_LIST_DIR}/ecore/ecore.s -o ecore.o)
-    #add_custom_command(OUTPUT ecore.elf DEPENDS ecore.o COMMAND e-ld ecore.o -o ecore.elf)
-    #add_custom_command(OUTPUT ecore.srec DEPENDS ecore.elf COMMAND e-objcopy --srec-forceS3 --output-target srec ecore.elf ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ecore.srec)
-    #add_custom_target(ecore ALL DEPENDS ecore.srec)
+    set(base ${CMAKE_CURRENT_LIST_DIR}/ecore/)
 
-    aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/ecore/ sources)
+    add_custom_command(OUTPUT ecore.o DEPENDS ${base}/ecore.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/ecore.c -c -o ecore.o -ffreestanding -nostdlib)
+    add_custom_command(OUTPUT rreq.o DEPENDS ${base}/rreq.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/rreq.c -c -o rreq.o -ffreestanding -nostdlib)
+    add_custom_command(OUTPUT render.o DEPENDS ${base}/render.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/render.c -c -o render.o -ffreestanding -nostdlib)
+    add_custom_command(OUTPUT math.o DEPENDS ${base}/math.c COMMAND e-gcc -Wall -Wextra -std=c99 ${base}/math.c -c -o math.o -ffreestanding -nostdlib)
+    add_custom_command(OUTPUT support.o DEPENDS ${base}/support.S COMMAND e-as ${base}/support.S -o support.o)
 
-    add_custom_command(OUTPUT ecore.elf DEPENDS ${sources} COMMAND e-gcc -Wall -Wextra -std=c99 ${sources} -o ecore.elf -le-lib -T$ENV{EPIPHANY_HOME}/bsps/current/internal.ldf -ffreestanding)
+    add_custom_command(OUTPUT ecore.elf DEPENDS ecore.o rreq.o render.o math.o support.o COMMAND e-ld ecore.o rreq.o render.o math.o support.o -o ecore.elf -le-lib -lgcc -T$ENV{EPIPHANY_HOME}/bsps/current/internal.ldf -L$ENV{EPIPHANY_HOME}/tools/e-gnu/epiphany-elf/lib/ -L$ENV{EPIPHANY_HOME}/tools/e-gnu/lib/gcc/epiphany-elf/4.8.2/)
     add_custom_command(OUTPUT ecore.srec DEPENDS ecore.elf COMMAND e-objcopy --srec-forceS3 --output-target srec ecore.elf ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ecore.srec)
     add_custom_target(ecore ALL DEPENDS ecore.srec)
 endif(${build_ecore})
index 2e9daec..6b26346 100644 (file)
@@ -4,11 +4,22 @@
 #include <stdint.h>
 
 typedef struct __attribute__((packed)) {
-    
+    float x, y, z;
+    float r, g, b;
+    float a, d, s;
+} shm_light_t;
+
+typedef struct __attribute__((packed)) {
+    float r, g, b;
+    float sr, sg, sb;
+    float a, d, s;
+    float shininess;
+    float ref;
 } shm_mat_t;
 
 typedef struct __attribute__((packed)) {
     float x, y, z;
+    float r;
     uint32_t mat;
 } shm_sph_t;
 
@@ -22,6 +33,9 @@ typedef struct __attribute__((packed)) {
     uint32_t width, height;
     uint32_t fb_off;
 
+    uint32_t light_off;
+    uint32_t light_count;
+
     uint32_t mat_off;
     uint32_t mat_count;
 
@@ -33,6 +47,8 @@ typedef struct __attribute__((packed)) {
     uint32_t generation;
     uint32_t finished;
 
+    uint32_t msg[16];
+
     shm_cam_t cam;
 } shm_region_t;
 
index 0e940ed..562060c 100644 (file)
@@ -4,7 +4,30 @@
 #include "render.h"
 
 e_memseg_t shared_mem;
-shm_region_t *shm_region;
+volatile shm_region_t *shm_region;
+
+//int __errno;
+
+void *memcpy(void *dst, const void *src, size_t n) {
+    uint8_t *dst8 = dst;
+    const uint8_t *src8 = src;
+    while(n>0) {
+        *dst8 = *src8;
+        dst8++, src8++, n--;
+    }
+    return dst;
+}
+
+// stupidity
+float sinf(float x) { return x; }
+float cosf(float x) { return x; }
+float tanf(float x) { return x; }
+float sqrtf(float x) { return x; }
+float powf(float x, float y) { return x; }
+//float __divsf3(float x) { return x; }
+
+//uint32_t __umodsi3() { return 0; }
+//uint32_t __udivsi3() { return 0; }
 
 int main() {
     e_shm_attach(&shared_mem, "raytrace_shm");
@@ -22,15 +45,13 @@ int main() {
     e_irq_mask(E_MESSAGE_INT, E_FALSE);
 
     int id = y*e_group_config.group_rows + x;
+    int ind = 0;
     while(1) {
         request_new_range(id);
 
-        for(int i = 0; i < NUM_OUT_ELEMENTS; i ++) {
-            out_buffer_ptr[i] = i+1 + (id << 16);
-        }
+        //shm_region->msg[id] = ++ind;
 
-        // do rendering
-        render_finished();
+        //render_range();
     }
 
     return 0;
index 8b9ead6..fe193f2 100644 (file)
@@ -10,6 +10,6 @@
 
 extern e_memseg_t shared_mem;
 
-extern shm_region_t *shm_region;
+extern volatile shm_region_t *shm_region;
 
 #endif
index e79cedf..da0adca 100644 (file)
@@ -1,3 +1,5 @@
+#include <math.h>
+
 #include "math.h"
 
 void set_vector(vector_t *v, float x, float y, float z, float w) {
@@ -44,18 +46,20 @@ void cross_vectors(vector_t *v1, vector_t *v2, vector_t *result) {
 
 void project_vector(vector_t *onto, vector_t *v, vector_t *result) {
     /*
-            cos = v . onto
-            cos = adj/hyp
-
-            
+        cos = v . onto
+        cos = adj/hyp
     */
-    float c = dot_vectors(v, onto) / sqrt(dot_vectors(onto, onto));
+    float c = dot_vectors(v, onto) / sqrtf(dot_vectors(onto, onto));
     mul_vector(onto, c, result);
 }
 
+void norm_vector(vector_t *v) {
+    mul_vector(v, 1/sqrtf(dot_vectors(v, v)), v);
+}
+
 void set_quaternion(vector_t *q, float x, float y, float z, float angle) {
-    float s = sin(angle/2);
-    float c = cos(angle/2);
+    float s = sinf(angle/2);
+    float c = cosf(angle/2);
     q->c[0] = s*x;
     q->c[1] = s*y;
     q->c[2] = s*z;
@@ -63,8 +67,8 @@ void set_quaternion(vector_t *q, float x, float y, float z, float angle) {
 }
 
 void set_quaternion_aa(vector_t *q, vector_t *n, float angle) {
-    mul_vector(n, sin(angle/2), q);
-    q->c[3] = cos(angle/2);
+    mul_vector(n, sinf(angle/2), q);
+    q->c[3] = cosf(angle/2);
 }
 
 void mul_quaternions(vector_t *q1, vector_t *q2, vector_t *result) {
@@ -104,3 +108,73 @@ void rotate_vector(vector_t *q, vector_t *v, vector_t *result) {
 
     /* And we end up with result = q*v*q^{conjugate}. */
 }
+
+static const float HALF_PI = 1.570796326;
+static const float ONE_OVER_PI = 0.318309886;
+static const float r[] = { -0.1666665668,
+                            0.8333025139e-02,
+                           -0.1980741872e-03,
+                            0.2601903036e-5 };
+
+float fabsf(float x) {
+    if(x<0) return -x;
+    return x;
+}
+
+float sinef(float x, int cosine) {
+  int sgn, N;
+  float y, XN, g, R, res;
+
+  /* Use sin and cos properties to ease computations. */
+  if (cosine)
+    {
+      sgn = 1;
+      y = fabsf (x) + HALF_PI;
+    }
+  else
+    {
+      if (x < 0.0)
+        {
+          sgn = -1;
+          y = -x;
+        }
+      else
+        {
+          sgn = 1;
+          y = x;
+        }
+    }
+
+  /* Calculate the exponent. */
+  if (y < 0.0)
+    N = (int) (y * ONE_OVER_PI - 0.5);
+  else
+    N = (int) (y * ONE_OVER_PI + 0.5);
+  XN = (float) N;
+
+  if (N & 1)
+    sgn = -sgn;
+
+  if (cosine)
+    XN -= 0.5;
+
+  y = fabsf (x) - XN * M_PI;
+
+  if (-1e-5 < y && y < 1e-5)
+    res = y;
+
+  else
+    {
+      g = y * y;
+
+      /* Calculate the Taylor series. */
+      R = (((r[3] * g + r[2]) * g + r[1]) * g + r[0]) * g;
+
+      /* Finally, compute the result. */
+      res = y + y * R;
+    }
+  res *= sgn;
+
+  return (res);
+}
index 8985b14..fdb8454 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <math.h>
 
+#define M_PI 3.14159265358979323846
+
 /* Four-dimensional affine vector/point. */
 typedef struct vector_t vector_t;
 struct vector_t {
@@ -17,6 +19,7 @@ void mul_vector(vector_t *v, float s, vector_t *result);
 float dot_vectors(vector_t *v1, vector_t *v2);
 void cross_vectors(vector_t *v1, vector_t *v2, vector_t *result);
 void project_vector(vector_t *onto, vector_t *v, vector_t *result);
+void norm_vector(vector_t *v);
 
 /* Quaternion operations. */
 void set_quaternion(vector_t *q, float x, float y, float z, float angle);
index 5de99a4..4ac6e2e 100644 (file)
 #include "ecore.h"
-
 #include "render.h"
+#include "math.h"
 
 uint32_t render_start, render_end;
-uint8_t __attribute__((section(".data_bank2"))) in_buffer[0x2000];
-uint32_t __attribute__((section(".data_bank3"))) out_buffer[NUM_OUT_ELEMENTS];
-uint32_t *out_buffer_ptr = out_buffer;
+/*uint8_t __attribute__((section(".data_bank2"))) in_buffer[0x2000];*/
+uint8_t in_buffer[0x2000];
 void *in_buffer_ptr = in_buffer;
 
-void render_finished() {
-    // use DMA channel 1 to transfer results back
-    e_dma_desc_t desc;
-    e_dma_set_desc(E_DMA_1, E_DMA_ENABLE | E_DMA_WORD | E_DMA_MASTER, NULL,
-        4, 4, NUM_OUT_ELEMENTS, 1, 0, 0, out_buffer,
-        (uint8_t *)shared_mem.ephy_base + shm_region->fb_off + render_start*4,
-        &desc);
-    e_dma_start(&desc, E_DMA_1);
-    e_dma_wait(E_DMA_1);
+shm_region_t *buf_region;
+shm_sph_t *spheres;
+shm_mat_t *materials;
+shm_light_t *lights;
+
+static void write_render_result(uint32_t value) {
+    uint32_t target_address = shared_mem.ephy_base + buf_region->fb_off
+        + render_start*4;
+    *(uint32_t *)target_address = value;
+}
+
+int sphere_intersect(shm_sph_t *sph, vector_t *ray, vector_t *dir,
+    float *intersect) {
+
+    vector_t pos;
+    set_vector(&pos, sph->x, sph->y, sph->z, 1.0);
+    
+    float b = 2*(dot_vectors(ray, dir));
+    float c = dot_vectors(ray, ray) - 1.0;
+
+    float dis = b*b - 4*c;
+    if(dis < 0) return 0;
+
+    float ds = sqrtf(dis);
+
+    float i1 = (-b - ds)/2.0;
+    float i2 = (-b + ds)/2.0;
+
+    if(i1>i2) {
+        float t = i1;
+        i1 = i2; i2 = t;
+    }
+
+    if(i1 < 1e-5) {
+        // if it's only a glancing touch, ignore it
+        if(i2 <= 1e-5) return 0;
+        *intersect = i2;
+    }
+    else *intersect = i1;
+
+    return 1;
+}
+
+int find_closest(vector_t *ray, vector_t *dir, float *min_i, int *min_ind) {
+    for(int i = 0; i < buf_region->sph_count; i ++) {
+        float intersect = 0;
+        if(!sphere_intersect(spheres + i, ray, dir, &intersect)) continue;
+        if(*min_ind == -1 || *min_i > intersect) 
+            *min_i = intersect, *min_ind = i;
+    }
+    return *min_ind != -1;
+}
+
+vector_t trace(vector_t *ray, vector_t *dir, int depth) {
+    /* Find closest sphere intersection. */
+    float min_i; int min_ind = -1;
+
+    if(!find_closest(ray, dir, &min_i, &min_ind)) {
+        vector_t ret;
+        ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0;
+        return ret;
+    }
+
+    /* We have an intersection. */
+    vector_t intersection;
+    intersection.c[0] = ray->c[0] + dir->c[0]*min_i;
+    intersection.c[1] = ray->c[1] + dir->c[1]*min_i;
+    intersection.c[2] = ray->c[2] + dir->c[2]*min_i;
+
+    shm_mat_t *mat = materials + spheres[min_ind].mat;
+
+    /* Calculate normal. */
+    vector_t normal;
+    normal.c[0] = intersection.c[0] - spheres[min_ind].x;
+    normal.c[1] = intersection.c[1] - spheres[min_ind].y;
+    normal.c[2] = intersection.c[2] - spheres[min_ind].z;
+    norm_vector(&normal);
+
+    /* Do we need to do a recursive raycast? */
+    vector_t ret;
+    ret.c[0] = ret.c[1] = ret.c[2] = ret.c[3] = 0;
+    if(mat->ref > 0 && depth) {
+        vector_t r;
+        /* r = n*(2 * n.dot(-dir)) + dir */
+        mul_vector(&normal, -2 * dot_vectors(&normal, dir), &r);
+        add_vectors(&r, dir, &r);
+        
+        ret = trace(&intersection, &r, depth-1);
+    }
+
+    /* Do lighting calculations for each light. */
+
+    for(int i = 0; i < buf_region->light_count; i ++) {
+        vector_t ldir;
+        ldir.c[0] = lights[i].x - intersection.c[0];
+        ldir.c[1] = lights[i].y - intersection.c[1];
+        ldir.c[2] = lights[i].z - intersection.c[2];
+        norm_vector(&ldir);
+
+        /* apply ambient */
+        ret.c[0] += lights[i].a * mat->a * mat->r * lights[i].r;
+        ret.c[1] += lights[i].a * mat->a * mat->g * lights[i].g;
+        ret.c[2] += lights[i].a * mat->a * mat->b * lights[i].b;
+
+        if(!find_closest(&intersection, &ldir, &min_i, &min_ind)) {
+            /* apply diffuse */
+            float diffuse = dot_vectors(&ldir, &normal);
+            if(diffuse < 0) diffuse = -diffuse;
+
+            diffuse *= lights[i].d * mat->d;
+            ret.c[0] += diffuse * mat->r * lights[i].r;
+            ret.c[1] += diffuse * mat->g * lights[i].g;
+            ret.c[2] += diffuse * mat->b * lights[i].b;
+            
+            /* apply specular */
+
+            vector_t r;
+            mul_vector(&normal, -2 * dot_vectors(&normal, &ldir), &r);
+            add_vectors(&r, &ldir, &r);
+
+            float specular = powf(dot_vectors(&r, dir), mat->shininess);
+            specular *= lights[i].s * mat->s;
+
+            ret.c[0] += specular * mat->sr * lights[i].r;
+            ret.c[1] += specular * mat->sg * lights[i].g;
+            ret.c[2] += specular * mat->sb * lights[i].b;
+        }
+    }
+
+    if(ret.c[0] > 1) ret.c[0] = 1;
+    if(ret.c[1] > 1) ret.c[1] = 1;
+    if(ret.c[2] > 1) ret.c[2] = 1;
+
+    return ret;
+}
+
+void render_range() {
+    buf_region = in_buffer_ptr;
+    spheres = (void *)(in_buffer + buf_region->sph_off);
+    materials = (void *)(in_buffer + buf_region->mat_off);
+    lights = (void *)(in_buffer + buf_region->light_off);
+
+    vector_t cam_pos;
+    set_vector(&cam_pos, buf_region->cam.x, buf_region->cam.y,
+        buf_region->cam.z, 1.0);
+    vector_t cam_rot;
+    set_quaternion(&cam_rot, buf_region->cam.dx, buf_region->cam.dy,
+        buf_region->cam.dz, buf_region->cam.dw);
+
+    /* Calculate camera plane origin. */
+    vector_t cam_plane;
+    set_vector(&cam_plane, 0.0, 0.0, 1.0/tanf(buf_region->cam.fov/2), 0.0);
+    rotate_vector(&cam_rot, &cam_plane, &cam_plane);
+    add_vectors(&cam_plane, &cam_pos, &cam_plane);
+
+    /* Calculate camera plane basis vectors. */
+    vector_t cam_basisx, cam_basisy;
+    float aratio = (float)buf_region->width / (float)buf_region->height;
+    set_vector(&cam_basisx, -aratio, 0.0, 0.0, 0.0);
+    rotate_vector(&cam_rot, &cam_basisx, &cam_basisx);
+    set_vector(&cam_basisy, 0.0, -1.0, 0.0, 0.0);
+    rotate_vector(&cam_rot, &cam_basisy, &cam_basisy);
+
+    while(render_start != render_end) {
+        float x = (render_start % buf_region->width)
+            / (float)buf_region->width - 0.5;
+        float y = (render_start / buf_region->width)
+            / (float)buf_region->height - 0.5;
+        
+        /* Calculate ray direction. */
+        vector_t ray_dir, temp;
+        mul_vector(&cam_basisx, x, &ray_dir);
+        mul_vector(&cam_basisy, y, &temp);
+        add_vectors(&temp, &ray_dir, &ray_dir);
+        norm_vector(&ray_dir);
+
+        /* Begin trace */
+        vector_t col = trace(&cam_pos, &ray_dir, 1);
+
+        /* Write back result into framebuffer. */
+        uint32_t result = 0;
+        result |= (int)(col.c[0] * 255);
+        result |= (int)(col.c[1] * 255) << 8;
+        result |= (int)(col.c[2] * 255) << 16;
+
+        write_render_result(result);
+
+        /* Done, next pixel! */
+        render_start ++;
+    }
 }
index 339f594..1db873f 100644 (file)
@@ -1,12 +1,12 @@
 #ifndef RENDER_H
 #define RENDER_H
 
-#define NUM_OUT_ELEMENTS 0x800/4
-
-void render_finished();
+#include <stdint.h>
 
 extern uint32_t render_start, render_end;
 extern void *in_buffer_ptr;
 extern uint32_t *out_buffer_ptr;
 
+void render_range();
+
 #endif
index 50264ee..f32853e 100644 (file)
@@ -6,10 +6,11 @@ uint32_t idle_cores;
 uint32_t range_start, range_end;
 uint32_t current_generation;
 
-uint8_t message_intr;
+volatile uint8_t message_intr;
 
 e_dma_desc_t __attribute__((aligned(8))) dma_desc;
 
+#define NUM_OUT_ELEMENTS 0x100
 
 void handle_range_request(int id) {
     if(range_start >= range_end) {
@@ -29,6 +30,8 @@ void handle_range_request(int id) {
     uint32_t target_range_end = range_start + len;
     range_start += len;
 
+    shm_region->light_off = range_start | range_end << 16;
+
     e_write(&e_group_config, &target_range_start, target_r, target_c,
         &render_start, 4);
     e_write(&e_group_config, &target_range_end, target_r, target_c,
@@ -41,8 +44,8 @@ void handle_range_request(int id) {
 
     if(target_generation != shm_region->generation) {
         // first update generation ID
-        e_write(&e_group_config, &shm_region->generation, target_r, target_c,
-            &current_generation, 4);
+        e_write(&e_group_config, (void*)&shm_region->generation, target_r,
+            target_c, &current_generation, 4);
 
 #if 0
         // need to DMA in render data, using target core's DMA engine
@@ -59,10 +62,10 @@ void handle_range_request(int id) {
         uint32_t value = E_DMA_STARTUP | ((uint32_t)&dma_desc & 0xffff) << 16;
         e_write(&e_group_config, &value, target_r, target_c,
             (void *)E_REG_DMA1CONFIG, 4);
-#endif
-
-        // XXX: debug
+#else
+        shm_region->msg[id] |= 1<<16;
         e_irq_set(target_r, target_c, E_MESSAGE_INT);
+#endif
     }
     else {
         // render data already present, so just send a message IRQ
@@ -72,6 +75,10 @@ void handle_range_request(int id) {
 
 void __attribute((interrupt)) range_request_handler(
     int __attribute__((unused)) irq) {
+    static int call_index = 0;
+    call_index ++;
+
+    shm_region->light_count = call_index;
 
     // clear ILAT entry to accept other pending requests
     e_reg_write(E_REG_ILATCL, 1<<9);
@@ -85,6 +92,7 @@ void __attribute((interrupt)) range_request_handler(
     // are all cores idle?
     if(idle_cores == (1<<NCORES)-1) {
         shm_region->finished = 1;
+
         // if so, wait for next generation to be set up
         while(shm_region->generation == current_generation) {}
         // mark all cores as non-idle
@@ -99,6 +107,7 @@ void __attribute((interrupt)) range_request_handler(
 
 void __attribute((interrupt)) message_handler() {
     message_intr = 1;
+    shm_region->sph_count = 0x1234;
 }
 
 void setup_range_request() {
@@ -114,6 +123,8 @@ void request_new_range(int id) {
     e_write(&e_group_config, &one, 0, 0, range_requests + id, 1);
 
     message_intr = 0;
+    shm_region->msg[id] |= 1;
     e_irq_set(0, 0, E_USER_INT);
     while(!message_intr) {}
+    shm_region->msg[id] |= 2;
 }
diff --git a/src/ecore/support.S b/src/ecore/support.S
new file mode 100644 (file)
index 0000000..f96e980
--- /dev/null
@@ -0,0 +1,60 @@
+.section IVT_RESET,"a",@progbits     ;
+.global _start;
+.type   _start, %function;
+_start:
+.balign 4 ;
+       b _epiphany_start
+
+.size  _start, .-_start
+
+.section .text
+.org 0
+.extern init
+.global _epiphany_start
+.type _epiphany_start, %function
+
+_epiphany_start:
+       ; Set up stack
+       mov     sp, %low(___stack)
+       movt    sp, %high(___stack)
+       mov     fp, #0
+
+       ; Zero out data
+       mov     r0, %low(___bss_start)
+       movt    r0, %high(___bss_start)
+       mov     r1, %low(_end)
+       movt    r1, %high(_end)
+       mov     r2, #0
+       mov     r3, #0
+zero_loop:
+       strd    r2, [r0], +#1
+       sub     r5, r1, r0
+       bne     zero_loop
+
+       ; Call global constructors
+       ;mov    r0, %low(init)
+       ;movt   r0, %high(init)
+       ;jalr   r0
+
+       ; Mask all interrupts
+       mov     r0, #0xffff
+       movts   imask, r0
+
+       ; Return from the reset ISR
+       mov     r0, %low(epiphany_continue)
+       movt    r0, %high(epiphany_continue)
+       movts   iret, r0
+       rti
+epiphany_continue:
+       ; call main()
+       mov     r0, #0
+       mov     r1, #0
+       mov     r2, #0
+       mov     r3, %low(_main)
+       mov     r4, %high(_main)
+       jalr    r3
+
+       ; shouldn't be reached
+inf_loop:
+       idle
+       b       inf_loop
index 7d35164..b056c16 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "../ecommon.h"
 
-shm_region_t *shm_region;
+volatile shm_region_t *shm_region;
 
 int main() {
     e_platform_t platform;
@@ -28,15 +28,11 @@ int main() {
     shm_region = mem.base;
 
     shm_region->generation = 0;
+    shm_region->finished = 0;
 
     e_open(&dev, 0, 0, platform.rows, platform.cols);
     printf("rows, cols: %i, %i\n", platform.rows, platform.cols);
 
-    uint8_t finished[platform.rows * platform.cols];
-    for(int i = 0; i < platform.rows * platform.cols; i ++) finished[i] = 0;
-    r = e_write(&mem, 0,0, 0, finished, platform.rows * platform.cols);
-    if(r == E_ERR) { printf("Failed to write\n"); }
-
     /* ensure that core (0,0) is loaded first; it needs to finish initialization
         strictly before the others do.
 
@@ -61,22 +57,15 @@ int main() {
     shm_region->width = 0x40;
     shm_region->height = 0x40;
     shm_region->data_end = 0x100;
-    shm_region->generation = 1;
     shm_region->fb_off = 0x200;
-    //for(int i = 0; i < 30; i ++) printf("finished: %lx\n", shm_region->finished);
-    /*for(int i = 0; i < 30; i ++) {
-        printf("state: [%lx, %2lx, %2lx, %lx]", shm_region->finished, shm_region->interrupts_fired, shm_region->range_end, shm_region->messages_received);
-        for(int j = 0; j < 16; j ++) printf(" %lx", shm_region->msg[j]);
-        printf("\n");
-    }*/
-    //while(shm_region->finished == 1) {}
-    //while(shm_region->finished == 0) {}
-
-    /*printf("fb: ");
+    shm_region->generation = 1;
+    while(shm_region->finished == 0) {}
+
+    printf("fb: ");
     for(int i = 0; i < 0x1000; i ++) {
         printf("%lx ", *((uint32_t *)shm_region + 0x200/4 + i));
     }
-    printf("\n");*/
+    printf("\n");
 
     e_close(&dev);
     e_shm_release("raytrace_shm");