ResLock stuff

Started by g3gg0, June 24, 2013, 11:33:56 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

g3gg0

i digged a bit into ResLock stuff and will describe how i think it works.


struct struc_LockEntry
{
  char *name;
  int status;
  int semaphore;
  int some_prev;
  int some_next;
  unsigned int *pResource;
  int resourceEntries;
  void (*cbr)(struct struc_LockEntry *lockEntry, void *cbr_priv);
  void *cbr_priv;
};

struct struc_LockEntry *CreateResLockEntry(uint32_t *resIds, resIdCount);
unsigned int LockEngineResources(struct struc_LockEntry *lockEntry);
unsigned int UnLockEngineResources(struct struc_LockEntry *lockEntry);
unsigned int AsyncLockEngineResources(struct struc_LockEntry *lockEntry, void (*cbr)(struct struc_LockEntry *lockEntry, void *cbr_priv), void *cbr_priv);


LockEngineResources:
Lock a previously allocated LockEntry and its associated devices

UnLockEngineResources:
Unlock a previously allocated LockEntry and its associated devices

CreateResLockEntry:
register a lock that will use semaphores to lock all the resources specified in a list.
when registering your lock, the resIds[] is a list of resources to be locked.
the number of entries in this list is passed as second parameter.
initial state of the lock is unlocked.

resId format:
resId = (block << 16) | (entry)

entry specifies the exact "device" in the given block, if any.
blocks are one of those:
0x00 = EDMAC[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x20, 0x21]
0x01 = EDMAC[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x28, 0x29, 0x2A, 0x2B]
0x04 = HEAD
0x36 = encdrwrap
0x37 (max)
(...to be continued)

e.g. resId 0x1000C is block 0x01 and entry 0x0C. This is EDMAC 0x28 being locked whenever LockEngineResources is called with the LockEntry.
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

a1ex

around hCopyLumaLockKey: 00010001 00000000 00030006 00020006

code around this uses EDMAC 9, 0 and connection 6 for both read and write. Therefore, blocks 2 and 3 can be read/write connections or viceversa?

LV_ResUnLockTripleRamClearPass seems to confirm that block 2 is for write connections and 3 is for read:
00030006 00030007 00030003 00020006 00020007 00020004 and others
connect calls: r/w for connections 6 and 7, r for 3 and w for 4.

g3gg0

updated with information about AsyncLockEngineResources from maqs
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

a1ex

ResLock entries used by ProcessPathForFurikake:


5D3 113:
*** LockEngineResources(65d8c8) x8 from ff3c3728:
     1)        1 (write channel 0x1)
     2)    1000c (read channel 0x28)
     3)    50002 (?)
     4)    50005 (?)
     5)    5001d (?)
     6)    5001f (?)
     7)    20010 (write connection 0x10)
     8)    30001 (read connection 0x1)

60D:
*** CreateResLockEntry(2cd58, 8) from ff3c1008:
     1)        3 (write channel 0x3)
     2)    10002 (read channel 0xa)
     3)    50002 (?)
     4)    50005 (?)
     5)    5001d (?)
     6)    5001f (?)
     7)    20010 (write connection 0x10)
     8)    30001 (read connection 0x1)


so, block 5 must cover PACK16, DSUNPACK, DEF(C) and WDMAC16 modules?

My current hypothesis:

    50002 (DSUNPACK?)
    50003 (ADUNPACK?)
    50005 (DEFC?)
    50006 (DARK?)
    5001d (PACK16/WDMAC16)
    5001f (PACK16/WDMAC16)

names_are_hard

Quote from: g3gg0 on June 24, 2013, 11:33:56 PM
entry specifies the exact "device" in the given block, if any.
blocks are one of those:
0x00 = EDMAC[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x20, 0x21]
0x01 = EDMAC[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x28, 0x29, 0x2A, 0x2B]
0x04 = HEAD
0x36 = encdrwrap
0x37 (max)
(...to be continued)

e.g. resId 0x1000C is block 0x01 and entry 0x0C. This is EDMAC 0x28 being locked whenever LockEngineResources is called with the LockEntry.

Some notes when working on newer cams.  The above information was always wrong.  The LockEntry struct seems to be the same at least up to Digic 7, which is good.  The implication that 0x1000c is the c-th entry in the list I can't understand and believe is wrong (and yet, ML code works, so possibly I'm not fully understanding something).  I'm fairly confident that 0x1000c says "block 1, device ID c", *not* "block 1, device ID index c".

Canon has a linked-list structure that holds information about Resources.  If you walk this list, you get values similar to those listed (I don't have a 5D3 to check this on, but 70D has similar lists).  But the ordering is not the same as in g3gg0's list.  Also, I *think* that when g3gg0 says "read only" resources, he's combining blocks 1 and 3 (same with write and blocks 0 and 2).  So it's not even possible to use one index to obtain one result.

I'm fairly sure the "entry" part of a Resource is not an index, but more like a device ID.  I confirmed the code for creating and locking resources never checks the index, but always compares the "entry" value to items already in the array.  Code is very similar on D5 vs D7.

Further to the above, something has changed significantly moving to D7.  Here's a dump from 70D:


Run: 0, block: 0
0x00  0x08  0x03  0x06
0x0e  0x01  0x07  0x02
0x0a  0x0b  0x0c  0x0d
0x04  0x09  0x05 
Run: 0, block: 1
0x06  0x03  0x0d  0x0c
0x01  0x04  0x02  0x08
0x09  0x00  0x07  0x05
0x0a 
Run: 0, block: 2
0x02  0x12  0x1c  0x00
0x10  0x01  0x17  0x06
0x2d  0x16  0x05  0x03
0x07  0x04  0x13  0x0d
0x1a  0x11  0x15  0x1f
0x20  0x23  0x1b  0x27
0x29  0x0f 
Run: 0, block: 3
0x08  0x0f  0x01  0x02
0x00  0x34  0x0e  0x35
0x06  0x21  0x07  0x03
0x05  0x12  0x0a  0x0c
0x0b  0x18  0x19  0x1e
0x27  0x28


Broadly comparable with 5D3 listed above, although more complete.  I'm walking the OS list, prior work was I guess via hooking LockEngineResources(), which would miss things.

Here's 200D:

Run: 0, block: 0
0x1d  0x1e  0x1f  0x20
0x21  0x22  0x23  0x25
0x00  0x01  0x05  0x09
0x0a  0x49  0x4e  0x4f
0x0d  0x10  0x11  0x12
0x13  0x46  0x4a  0x44
0x08  0x16  0x17  0x18
0x1a  0x1b  0x1c  0x38
0x24  0x34  0x35  0x36
0x0e  0x0f  0x0b  0x04
0x02  0x33  0x03  0x06
0x07  0x26  0x28  0x29
0x2a  0x2b  0x2c  0x2d

Run: 0, block: 1
0x00 
Run: 0, block: 2

Run: 0, block: 3
0x0f  0x10  0x09  0x0b


Almost everything is in block 0!  Block 2 doesn't contain anything.  Block 1 only has a single entry, 0x0, which at least used to be the sensor.  That could still make sense, it's supposed to be a read block, but it seems strange if there are no other read devices!

I don't currently know the reason for this change.  Possibly, the purpose of a given block has changed, and things have moved elsewhere (there are 55 blocks on 200D).

Here's the code used for dumping, which I attached to Don't Click Me:


void dump_resource_info(void)
{
    static int test_run = 0;

    struct ResInfo_entry
    {
        struct ResInfo_entry *prev_entry;
        struct ResInfo_entry *next_entry;
        uint32_t Resource;
        uint32_t unk_01;
    };

    struct block
    {
        struct ResInfo_entry *prev_entry;
        struct ResInfo_entry *next_entry;
    };

// 200D
    // 0x10998 is the global that stores address of ResInfo_blocks[55]
    struct block *blocks = (struct block *)(*(uint32_t *)0x10998);

// 70D
//    // 0x949b0 is the global that stores address of ResInfo_blocks[]
//    struct block *blocks = (struct block *)(*(uint32_t *)0x949b0);
    DryosDebugMsg(0, 15, "\nBlocks start: 0x%x\n", blocks);

    char filename[64] = {0};
    for (uint32_t i = 0; i < 4; i++)
    {
        snprintf(filename, sizeof(filename),
                 "ML/LOGS/b_%d_%d.log", test_run, i);

        FILE *f = FIO_CreateFile(filename);
        my_fprintf(f, "Run: %d, block: %d\n", test_run, i);

        struct ResInfo_entry *entry = blocks[i].next_entry;
        DryosDebugMsg(0, 15, "\nEntry start: 0x%x\n", entry);
        int tab_count = 0;
        while(entry != (struct ResInfo_entry *)(&blocks[i]))
        {
            // We expect low half of Resource to probably fit in
            // a single byte (old cams have max 48 channels),
            // and we expect high half to always be equal to
            // blockNum.
            //
            // Print only the deviceID if expectations are met,
            // otherwise print everything to see what went wrong.
            uint32_t out = entry->Resource;
            if ((out >> 0x10 == i)
                && ((out & 0xffff) < 0xff))
            {
                out = out & 0xffff;
                my_fprintf(f, "0x%02x", out);
            }
            else
            {
                my_fprintf(f, "0x%08x", out);
            }

            if (tab_count < 3)
            {
                my_fprintf(f, "  ");
                tab_count ++;
            }
            else
            {
                my_fprintf(f, "\n");
                tab_count = 0;
            }
            entry = entry->next_entry;
        }

        my_fprintf(f, "\n");
        FIO_CloseFile(f);
    }

    test_run++;
}



Please let me know if you have any memories of how this is supposed to work, or can show I'm right / wrong on anything.  This area of code is especially lacking in comments, and quite hard to understand.

reddeercity

This sound like the same issue with the 5D2/D4 , it would crash on the ResLock stuff
I can get a compressed image in Liveview (Photo or Video) but lock's up on saving.
I always thought that there something not right on D4 ResLock, at the time even a1ex was or still stumped .

Anyway good to see some work here,  its starting to help me understand where the problems are.
I'm digging around the information and see if i can finish compressed 14bit raw on 5D2 & maybe 50D too since there so closely related.
I do have so old research in to ResLock stuff i think may still have some logs , I had a trace capture log for the first minute or two
so i could took a CR2 & or shot H264 .mov file and trace the events on the log.
I see if i still have them , thou no sure if it will help from D4 .

Edit: Found 2 trace logs 5D2 (CR2 Photo & H264 .mov compression ResLocks)
dm-0001_cr2_2018_2_12.log
5D2_Trace_log_h264_compression_ResLocks.txt