Read about our upcoming Code of Conduct on this issue

Commit 253e3cd4 authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Merged unified into edmac

--HG--
branch : edmac
......@@ -56,10 +56,12 @@ On the 5D there are the following fonts added to the stubs.S file:
0xf00d1110: HCanonGothic 36 px, ascii only (0xFFE2)
0xf00d585c: CanonMonoSpace 40 px, ascii only (0xFFD8)
Alex, 16Mar2011
https://bitbucket.org/hudson/magic-lantern/changeset/cfba492ea84d
Daniel Fort, 05Jul2017
https://bitbucket.org/hudson/magic-lantern/pull-requests/844/find_fntpy-update/diff
"""
......@@ -105,6 +107,17 @@ def parseBitmap(m, off, base):
nb_byte = nb_byte + 1
print ' bitmap size = 0x%x' % ( nb_byte*height )
def guess_load_addr(rom, name):
if rom[4:12] == "gaonisoy":
return 0xFF010000 # assume old DIGIC 4 ROM dumped from 0xFF010000
if "ROM0" in name:
return 0xF0000000 # ROM0 from ML/LOGS/
if "ROM1" in name:
return 0xF8000000 # ROM1 from ML/LOGS/
# unknown, just report the offset inside the ROM.
return 0
f = open(sys.argv[1], 'rb')
m = f.read()
f.close()
......@@ -112,10 +125,11 @@ f.close()
if (len(sys.argv)>2):
base = int(sys.argv[2], 16)
else:
base = 0xff010000
base = guess_load_addr(m, sys.argv[1])
print 'Find bitmap fonts in Canon DSLR firmwares'
print 'Arm.Indy. based on work by Pel, Trammel Hudson and A1ex\n'
print 'Arm.Indy. based on work by Pel, Trammel Hudson and A1ex'
print 'Assume ROM file was dumped from 0x%08x \n' % base
off = 0
while off < len(m) and off <> -1:
......
MODEL=5D3
FW_VERSION=113
CFLAG_USER += -DCONFIG_5D3_113=1
x: clean_install_fir
......
MODEL=5D3
FW_VERSION=123
CFLAG_USER += -DCONFIG_5D3_123=1
x: clean_install_fir
include ../Makefile.minimal
MODEL=EOSM
include ../Makefile.minimal
......@@ -184,7 +184,7 @@ static void cmos16_log(breakpoint_t *bkpt)
void adtg_log_task()
{
adtg_buf_pos_max = 128 * 1024;
adtg_buf = fio_malloc(adtg_buf_pos_max * 4 + 0x100);
adtg_buf = malloc(adtg_buf_pos_max * 4 + 0x100);
if(!adtg_buf)
{
......@@ -253,7 +253,7 @@ void adtg_log_task()
/* free buffer */
void *buf = adtg_buf;
adtg_buf = NULL;
fio_free(buf);
free(buf);
}
static MENU_SELECT_FUNC(adtg_log_toggle)
......
......@@ -141,9 +141,11 @@ static void mem_test_bmp_fill(int arg0, int arg1, int arg2, int arg3)
static void mem_test_edmac_copy_rectangle(int arg0, int arg1, int arg2, int arg3)
{
uint8_t* real = bmp_vram_real();
uint8_t* idle = bmp_vram_idle();
edmac_copy_rectangle_adv(BMP_VRAM_START(idle), BMP_VRAM_START(real), 960, 0, 0, 960, 0, 0, 720, 480);
uint8_t* real = BMP_VRAM_START(bmp_vram_real());
uint8_t* idle = BMP_VRAM_START(bmp_vram_idle());
/* careful - do not mix cacheable and uncacheable pointers unless you know what you are doing */
edmac_copy_rectangle_adv(UNCACHEABLE(idle), UNCACHEABLE(real), 960, 0, 0, 960, 0, 0, 720, 480);
}
static uint64_t FAST DUMP_ASM mem_test_read64(uint64_t* buf, uint32_t n)
......@@ -197,8 +199,8 @@ static void mem_benchmark_task()
void* buf1 = 0;
void* buf2 = 0;
buf1 = tmp_malloc(bufsize);
buf2 = tmp_malloc(bufsize);
buf1 = fio_malloc(bufsize);
buf2 = fio_malloc(bufsize);
if (!buf1 || !buf2)
{
bmp_printf(FONT_LARGE, 0, 0, "malloc error :(");
......@@ -228,7 +230,7 @@ static void mem_benchmark_task()
if (HAS_EDMAC_MEMCPY)
{
mem_benchmark_run("edmac_memcpy ", &y, bufsize, (mem_bench_fun)edmac_memcpy, (intptr_t)buf1, (intptr_t)buf2, bufsize, 0, 1);
mem_benchmark_run("edmac_memcpy ", &y, bufsize, (mem_bench_fun)edmac_memcpy, (intptr_t)UNCACHEABLE(buf1), (intptr_t)UNCACHEABLE(buf2), bufsize, 0, 1);
mem_benchmark_run("edmac_copy_rectangle", &y, 720*480, (mem_bench_fun)mem_test_edmac_copy_rectangle, 0, 0, 0, 0, 0);
}
......@@ -250,6 +252,6 @@ static void mem_benchmark_task()
canon_gui_enable_front_buffer(0);
cleanup:
if (buf1) tmp_free(buf1);
if (buf2) tmp_free(buf2);
if (buf1) free(buf1);
if (buf2) free(buf2);
}
......@@ -7,7 +7,7 @@ CR2HDR_LDFLAGS=-lm -m32
CR2HDR_DEPS=$(SRC_DIR)/chdk-dng.c dcraw-bridge.c exiftool-bridge.c adobedng-bridge.c amaze_demosaic_RT.c dither.c timing.c kelvin.c
HOST=host
EXIFTOOL_VERS=10.33
EXIFTOOL_VERS=10.58
ifdef CROSS
HOSTCC=$(MINGW_GCC)
......
......@@ -53,10 +53,10 @@ static int is_bright[4];
#include "timing.h"
#include "kelvin.h"
#include "../../src/module.h"
#undef MODULE_STRINGS_SECTION
#define MODULE_STRINGS_SECTION
#define MODULE_STRINGS_PREFIX dual_iso_strings
#include "../module_strings_wrapper.h"
#include "module_strings.h"
MODULE_STRINGS()
/** Command-line interface */
......@@ -541,23 +541,6 @@ static void reverse_bytes_order(void* buf, int count)
}
}
const char* module_get_string(int module, const char* name)
{
module_strpair_t *strings = &__module_strings_MODULE_NAME[0];
if (strings)
{
for ( ; strings->name != NULL; strings++)
{
if (!strcmp(strings->name, name))
{
return strings->value;
}
}
}
return 0;
}
static void save_debug_dng(char* filename)
{
int black20 = raw_info.black_level;
......@@ -587,7 +570,7 @@ static int is_file(const char* filename)
int main(int argc, char** argv)
{
printf("cr2hdr: a post processing tool for Dual ISO images\n\n");
printf("Last update: %s\n", module_get_string(0, "Last update"));
printf("Last update: %s\n", module_get_string(dual_iso_strings, "Last update"));
fast_randn_init();
......
......@@ -157,7 +157,7 @@ void mlv_fill_idnt(mlv_idnt_hdr_t *hdr, uint64_t start_timestamp)
void mlv_build_vers(mlv_vers_hdr_t **hdr, uint64_t start_timestamp, const char *version_string)
{
int block_length = strlen(version_string) + sizeof(mlv_vers_hdr_t);
int block_length = (strlen(version_string) + sizeof(mlv_vers_hdr_t) + 3) & ~3;
mlv_vers_hdr_t *header = malloc(block_length);
/* prepare header */
......
......@@ -2639,6 +2639,16 @@ static void raw_prepare_chunk(FILE *f, mlv_file_hdr_t *hdr)
mlv_write_hdr(f, (mlv_hdr_t *)&styl_hdr);
write_mlv_vers_blocks(f);
}
/* insert a null block so the header size is multiple of 512 bytes */
int hdr_size = FIO_SeekSkipFile(f, 0, SEEK_CUR);
mlv_hdr_t nul_hdr;
memset(&nul_hdr, 0x00, sizeof(nul_hdr));
mlv_set_type(&nul_hdr, "NULL");
int padded_size = (hdr_size + sizeof(nul_hdr) + 511) & ~511;
nul_hdr.blockSize = padded_size - hdr_size;
FIO_WriteFile(f, &nul_hdr, nul_hdr.blockSize);
}
static void raw_writer_task(uint32_t writer)
......@@ -3051,8 +3061,8 @@ static uint32_t mlv_rec_precreate_del_empty(char *filename)
return 0;
}
/* if only the size of a file header, remove again */
if(size <= sizeof(mlv_file_hdr_t))
/* if only the size of a file header plus padding, remove again */
if(size <= 0x200)
{
trace_write(raw_rec_trace_ctx, "mlv_rec_precreate_del_empty: '%s' empty, deleting", filename);
FIO_RemoveFile(filename);
......
......@@ -34,7 +34,7 @@
#define MAX_WRITER_THREADS 2
/* pre-create that number of files befroe recording starts so that file catalog doesnt have to get updated while recording */
#define MAX_PRECREATE_FILES 10
#define MAX_PRECREATE_FILES 8
#define FRAMING_CENTER (dolly_mode == 0)
#define FRAMING_PANNING (dolly_mode == 1)
......
/* this struct supplies additional information like license, author etc - optional */
typedef struct
{
const char *name;
const char *value;
} module_strpair_t;
#define MODULE_STRINGS_SECTION
#define MODULE_STRINGS_START() MODULE_STRINGS_START_(MODULE_STRINGS_PREFIX)
#define MODULE_STRINGS_START_(varname) MODULE_STRINGS_START__(varname)
#define MODULE_STRINGS_START__(varname) module_strpair_t varname[] MODULE_STRINGS_SECTION = {
#define MODULE_STRING(field,value) { field, value },
#define MODULE_STRINGS_END() { (const char *)0, (const char *)0 }\
};
static const char* module_get_string(module_strpair_t *strings, const char* name)
{
if(strings)
{
for( ; strings->name != NULL; strings++)
{
if(!strcmp(strings->name, name))
{
return strings->value;
}
}
}
return NULL;
}
\ No newline at end of file
......@@ -14,6 +14,7 @@
#include <edmac-memcpy.h>
#include <screenshot.h>
#include <powersave.h>
#include <alloca.h>
/* optional routines */
extern WEAK_FUNC(ret_0) uint32_t ml_rpc_send(uint32_t command, uint32_t parm1, uint32_t parm2, uint32_t parm3, uint32_t wait);
......@@ -107,7 +108,7 @@ static void next_tick_cbr(int arg1, void* arg2)
SetHPTimerNextTick(arg1, 100000, timer_cbr, overrun_cbr, 0);
}
#define TEST_MSG(fmt, ...) { if (!stub_silence || !stub_ok) stub_log_len += snprintf(stub_log_buf + stub_log_len, stub_max_log_len - stub_log_len, fmt, ## __VA_ARGS__); printf(fmt, ## __VA_ARGS__); }
#define TEST_MSG(fmt, ...) { if (!stub_silence || !stub_ok) { stub_log_len += snprintf(stub_log_buf + stub_log_len, stub_max_log_len - stub_log_len, fmt, ## __VA_ARGS__); printf(fmt, ## __VA_ARGS__); } }
#define TEST_VOID(x) { x; stub_ok = 1; TEST_MSG(" %s\n", #x); }
#define TEST_FUNC(x) { int ans = (int)(x); stub_ok = 1; TEST_MSG(" %s => 0x%x\n", #x, ans); }
#define TEST_FUNC_CHECK(x, condition) { int ans = (int)(x); stub_ok = ans condition; TEST_MSG("[%s] %s => 0x%x\n", stub_ok ? "Pass" : "FAIL", #x, ans); if (stub_ok) stub_passed_tests++; else stub_failed_tests++; }
......@@ -196,6 +197,299 @@ static void stub_test_edmac()
TEST_VOID(free(dst));
}
/* delay with interrupts disabled */
static void busy_wait_ms(int ms)
{
int t0 = get_ms_clock_value();
while (get_ms_clock_value() - t0 < ms)
;
}
/* this checks whether clean_d_cache actually writes the data to physical memory
* so other devices (such as DMA controllers) will see the same memory contents as the CPU */
static void stub_test_cache_bmp()
{
TEST_MSG("Cache test A (EDMAC on BMP buffer)...\n");
void * bmp;
TEST_FUNC_CHECK(bmp = bmp_load("ML/CROPMKS/CINESCO2.BMP", 1), != 0);
if (!bmp) return;
uint8_t * const bvram_mirror = get_bvram_mirror();
if (!bvram_mirror) return;
/* perform the test twice:
* one without cache cleaning, expected to fail,
* and one with cache cleaning, expected to succeed */
for (int k = 0; k < 2; k++)
{
/* perform this test with interrupts disabled */
int old = cli();
int dis = cli();
TEST_FUNC_CHECK(old, != dis);
/* draw a cropmark */
clrscr();
bmp_draw_scaled_ex(bmp, os.x0, os.y0, os.x_ex, os.y_ex, bvram_mirror);
/* copy the image to idle buffer using EDMAC */
uint8_t * src = bmp_vram_real();
uint8_t * dst = bmp_vram_idle();
ASSERT(src == CACHEABLE(src));
ASSERT(dst == CACHEABLE(dst));
if (k == 0)
{
/* trick the copying routine so it doesn't handle caching issues.
* these pointers are actually cacheable (for speed reasons);
* flagging them as uncacheable has no effect on DMA behavior.
* this test should fail. */
src = UNCACHEABLE(src);
}
/* mark destination as uncacheable (the EDMAC routine expects it this way) */
/* this is generally incorrect; you should use fio_malloc instead. */
dst = UNCACHEABLE(dst);
edmac_copy_rectangle_adv_start(dst, src, 960, 0, 0, 960, 0, 0, 720, 480);
/* wait for EDMAC transfer to finish */
/* probably not needed, as take_semaphore will re-enable interrupts */
busy_wait_ms(1000);
/* cleanup EDMAC transfer */
edmac_copy_rectangle_finish();
/* interrupts are disabled again - from DryOS context switch */
/* now compare the image buffers */
int differences = 0;
for (int y = 0; y < 480; y++)
{
for (int x = 0; x < 720; x++)
{
int i = x + y * 960;
if (src[i] != dst[i])
{
differences++;
}
}
}
info_led_on();
busy_wait_ms(1000);
info_led_off();
/* do we still have interrupts disabled? */
int irq = cli();
TEST_FUNC_CHECK(irq, == dis);
if (k)
{
/* expect to succeed */
TEST_FUNC_CHECK(differences, == 0);
}
else
{
/* expect to fail */
TEST_FUNC_CHECK(differences, > 100);
}
/* interrupts no longer needed */
sei(old);
}
}
static int stub_test_cache_fio_do(int handle_cache)
{
/* prefer CF card if present */
char * test_file = is_dir("A:/") ? "A:/test.dat" : "test.dat";
FILE * f;
TEST_FUNC_CHECK(f = FIO_CreateFile(test_file), != 0);
/* result */
int fail = -1;
/* cacheable buffer that will fit the entire cache */
/* placed at some random stack offset */
/* note: we have 32K stack */
const int size = 8192;
uint8_t * pad = alloca(MOD(rand(), size));
uint8_t * buf = alloca(size);
/* make sure pad gets allocated above buf
* therefore moving "buf" on the stack at some random offset */
ASSERT(buf + 8192 <= pad);
/* fill the buffer (this should bring it into cache) */
for (int i = 0; i < size; i++)
{
buf[i] = i;
}
/* fill the buffer again; hoping some values won't reach the physical memory */
for (int i = 0; i < size; i++)
{
buf[i] = i + 1;
}
/* save it to card */
if (handle_cache & 1)
{
/* let the wrapper handle the cacheable buffer */
TEST_FUNC_CHECK(FIO_WriteFile(f, buf, size), == size);
}
else
{
/* Trick the wrapper into calling Canon stub directly,
* so it will no longer clean the cache before writing.
* This should fail - do not use it in practice.
* The uncacheable flag has no effect on DMA.
* You should either use fio_malloc (which returns uncacheable buffers)
* or pass regular (cacheable) pointers and let the wrapper handle them. */
TEST_FUNC_CHECK(FIO_WriteFile(f, UNCACHEABLE(buf), size), == size);
}
TEST_VOID(FIO_CloseFile(f));
/* reopen the file for reading */
TEST_FUNC_CHECK(f = FIO_OpenFile(test_file, O_RDONLY | O_SYNC), != 0);
/* read the file into uncacheable memory (this one will be read correctly) */
uint8_t * ubuf = fio_malloc(size);
TEST_FUNC_CHECK(ubuf, != 0);
if (!ubuf) goto cleanup;
TEST_FUNC_CHECK(FIO_ReadFile(f, ubuf, size), == size);
FIO_SeekSkipFile(f, 0, SEEK_SET);
/* alter the buffer contents; hoping some values will be only in cache */
for (int i = 0; i < size; i++)
{
buf[i] = i + 2;
}
/* read the file into regular (cacheable) memory */
if (handle_cache & 2)
{
/* let the wrapper handle the cacheable buffer */
TEST_FUNC_CHECK(FIO_ReadFile(f, buf, size), == size);
}
else
{
/* Trick the wrapper into calling Canon stub directly.
* This should fail (same as with FIO_WriteFile). */
TEST_FUNC_CHECK(FIO_ReadFile(f, UNCACHEABLE(buf), size), == size);
}
/* check the results */
int a = 0, b = 0, c = 0, r = 0;
for (int i = 0; i < size; i++)
{
a += (ubuf[i] == (uint8_t)(i));
b += (ubuf[i] == (uint8_t)(i + 1));
c += (ubuf[i] == (uint8_t)(i + 2));
r += (ubuf[i] == buf[i]);
}
free(ubuf);
/* don't report success/failure yet, as this test is not deterministic
* just log the values and return the status */
TEST_FUNC(a);
TEST_FUNC(b);
TEST_FUNC(c);
TEST_FUNC(a + b + c);
TEST_FUNC(r);
/* which part of the test failed? read or write? */
int fail_r = (r != size);
int fail_w = (a != 0) || (b != size) || (c != 0);
fail = (fail_r << 1) | fail_w;
cleanup:
/* cleanup */
TEST_VOID(FIO_CloseFile(f));
TEST_FUNC_CHECK(FIO_RemoveFile(test_file), == 0);
return fail;
}
static void stub_test_cache_fio()
{
TEST_MSG("Cache test B (FIO on 8K buffer)...\n");
/* non-deterministic test - run many times */
stub_silence = 1;
int tries[4] = {0};
int times[4] = {0};
int failr[4] = {0};
int failw[4] = {0};
for (int i = 0; i < 1000; i++)
{
/* select whether the FIO_WriteFile wrapper (1) and/or
* FIO_ReadFile (2) wrapper should handle caching issues */
int handle_cache = rand() & 3;
/* run one iteration and time it */
int t0 = get_ms_clock_value();
int fail = stub_test_cache_fio_do(handle_cache);
int t1 = get_ms_clock_value();
ASSERT(fail == (fail & 3));
/* count the stats */
tries[handle_cache]++;
times[handle_cache] += (t1 - t0);
if (fail & 1) failw[handle_cache]++;
if (fail & 2) failr[handle_cache]++;
/* progress indicator */
if (i % 100 == 0)
{
printf(".");
}
}
stub_silence = 0;
printf("\n");
/* report how many tests were performed in each case */
TEST_FUNC_CHECK(tries[0], > 100);
TEST_FUNC_CHECK(tries[1], > 100);
TEST_FUNC_CHECK(tries[2], > 100);
TEST_FUNC_CHECK(tries[3], > 100);
/* each test (read or write) should succeed only
* if the corresponding wrapper (FIO_WriteFile
* and FIO_ReadFile) is allowed to handle caching
* for regular buffers; it should fail otherwise,
* at least a few times. This also implies both tests
* (R and W) should succeed if and only if both routines
* are allowed to handle caching. */
TEST_FUNC_CHECK(failr[0], > 10);
TEST_FUNC_CHECK(failw[0], > 10);
TEST_FUNC_CHECK(failr[1], > 10);
TEST_FUNC_CHECK(failw[1], == 0);
TEST_FUNC_CHECK(failr[2], == 0);
TEST_FUNC_CHECK(failw[2], > 10);
TEST_FUNC_CHECK(failr[3], == 0);
TEST_FUNC_CHECK(failw[3], == 0);
/* check whether cache cleaning causes any slowdown */
TEST_FUNC(times[0] / tries[0]);
TEST_FUNC(times[1] / tries[1]);
TEST_FUNC(times[2] / tries[2]);
TEST_FUNC(times[3] / tries[3]);
}
static void stub_test_cache()
{
stub_test_cache_bmp();
stub_test_cache_fio();
TEST_MSG("Cache tests finished.\n\n");
}
static void stub_test_file_io()
{
/* File I/O */
......@@ -269,7 +563,9 @@ static void stub_test_file_io()
fio_free(buf);
}
TEST_FUNC_CHECK(is_file("test.dat"), != 0);
TEST_FUNC_CHECK(FIO_RemoveFile("test.dat"), == 0);
TEST_FUNC_CHECK(is_file("test.dat"), == 0);
}
static void stub_test_gui_timers()
......@@ -694,15 +990,27 @@ static void stub_test_dryos()
TEST_FUNC_CHECK(ReleaseRecursiveLock(rlock), != 0);
}
static void stub_test_save_log()
{
FILE* log = FIO_CreateFile( "stubtest.log" );
if (log)
{
FIO_WriteFile(log, stub_log_buf, stub_log_len);
FIO_CloseFile(log);
}
}
static void stub_test_task(void* arg)
{
if (stub_log_buf) return;
stub_log_buf = fio_malloc(stub_max_log_len);
if (!stub_log_buf) return;