Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - names_are_hard

#76
Probably all you need to try is low-level format card in cam, and choose to keep ML.

All the other steps, you don't care about.  You're not trying to make comparable benchmarks each time.
#77
Quote from: gabriielangel on January 08, 2024, 06:44:11 PM
If there is a module enabling the logging of everything  available, let me know. I would then be able to zero in on the issue.

Can you define "everything available"?  I might be able to add logging if I knew what you wanted to be logged.
#78
Quote from: Teamsleepkid on January 07, 2024, 03:16:05 AM
if it's easy simple for someone..any way to make the preview when using dual iso just normal preview?

Likely possible, will not be easy.  The preview is showing the lines, because the sensor is recording the lines.  Fixing this in software is too slow.  Fixing it in hardware is likely to be difficult.
#79
Reverse Engineering / Re: EDMAC in Digic 7 / 8 world
January 05, 2024, 09:52:39 AM
I can now read some kind of intermediate LV data from 200D using edmac.  Format is 1620*1080, YUV 422, with an offset of -0x80 applied to all UV values.

In theory I could turn this into a "half-raw" video capture mode.  I don't think I'll bother unless there's a compelling reason given from others.  It would be a not very useful format I think.  Uncompressed (apart from the YUV encoding of the colour data), but limited to 10-bit 16:10, 1080 (p, I guess?  Haven't checked).

Since finding code that would display the slightly weird format was annoying, here's a complete script to do so:

#!/usr/bin/env python3
import os
import argparse

import cv2
import numpy as np

def main():
    args = parse_args()

    buf = np.fromfile(args.filename, dtype=np.uint8)
    width = 1620

    # Reshape to allow easy swapping / manipulation of each byte of each u32
    buf = buf.reshape(-1, 4) # 4 cols
    buf = buf.swapaxes(0, 1) # 4 rows, each all one byte from the u32s

    # conditionally modify the UV rows only
    uv_selector = np.array([True, False, True, False])
    uv_only = buf[uv_selector]
    uv_only = (uv_only - 128) # Canon uses a diffent bias on UV than openCV / standards

    # replace original UV rows with modified
    buf[[0, 2]] = uv_only[[0, 1]]

    # Reshape for display
    buf = buf.swapaxes(0, 1)
    buf = buf.reshape(-1, width, 2) # 1080 rows

    bgr = cv2.cvtColor(buf, cv2.COLOR_YUV2BGR_UYVY)

    cv2.imshow("frame", bgr)
    cv2.waitKey()

def parse_args():
    description = """ """
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument("filename",
                        help="raw yuv data file")

    args = parser.parse_args()
    if not os.path.isfile(args.filename):
        print("yuv file didn't exist: '%s'" % args.filename)
        exit()

    return args


if __name__ == "__main__":
    main()


If somebody who is less of a noob with numpy and/or opencv can simplify that, I'd be interested in learning :)
#80
Some (fairly reliable) people have also reported low-level format in cam restoring a slow card back to fast.  Possibly, this is better if done at the overclock you intend to run the card at.  I'm not convinced by that last part, but it might be worth testing.  The low-level format restoring a slow card I've seen multiple people report good results with.

I'm not sure why a low-level format should help.  Possibly, because writing to erased blocks is fast, but erasing blocks is slow?  If the drive controller knows which blocks are erased, this might avoid the need for erases during recording.
#81
Quote from: csg2 on January 03, 2024, 10:13:51 AM
Nightly.2018.Jul03.550D.109

Nightly build doesn't have sleep(), so this is expected behaviour.  Use msleep(), with a correspondingly longer time, or use lua_fix build, which does have sleep() (and other improvements).
#82
What build of ML are you using?

If you reduce your script so it only does a sleep(2) in main, do you still see an error?
If you replace sleep(2) with msleep(2000), do you see an error?
#83
Sadly, ChatGPT is also drunk, and a liar.
#84
It can be good to have an end goal in mind when learning to program, but from experience teaching people, you don't want to start with a challenge.  Learning to program is enough challenge on its own, initially.

Start with standard boring tutorials (text, not video).  Learn how to use python first, write a range of simple but functioning programs, then consider starting on your actual goal.  If you're confused by python *and* your goal, it's much harder to learn.  Keep the problems simple so you're sure you understand them, while you're still getting over the confusion around programming itself.
#85
Reverse Engineering / Re: ResLock stuff
December 28, 2023, 01:49:59 PM
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.
#86
Camera-specific Development / Re: Canon 750D
December 27, 2023, 04:38:33 AM
It hasn't stopped.  There are no significant updates.  Progress is slow because there are very few devs (I am most of the dev effort).  Recently heder has also started looking at a modern cam, which is much appreciated and is likely to indirectly help with 750d (same digic gen).
#87
Camera-specific Development / Re: Canon 7D Mark II
December 20, 2023, 07:42:17 PM
Both 7D2 master and slave have their own Omar.  I've done a little investigation, I have suspicions that it might be a true dual-core part, if so, this is "dual-socket dual-core", with four R4 cores in total.  Hard to prove fully without a nice x-ray machine I suppose :)
#88
Camera-specific Development / Re: Canon 7D Mark II
December 19, 2023, 01:29:26 PM
Ah, okay, so not a confirmed Omar RPC function.  Oh well :)  Yes, I've seen that msg send function.  I haven't tried logging it to see what it sends, don't know if it allows RPC.

Something I hadn't noticed before from that wiki page, they claim Omar is also R4.  I thought it was a Digic 5 chip, but if it's R4 I'm wrong.  Could use cpu ID registers to check.  If it is, then we at least know the Omar firmware blob is compatible with ICU (we still don't know if it all makes sense to run from ICU context).
#89
Camera-specific Development / Re: Canon 7D Mark II
December 19, 2023, 12:48:13 PM
Ah, that RPC handler.  Isn't that the one for doing master-slave comms?  7D2 has master, slave *and* Omar.
#90
Camera-specific Development / Re: Canon 7D Mark II
December 19, 2023, 11:15:46 AM
I have no problem with hacks while exploring :)  Only if we give stuff to other people do we need to make sure it's doing things in a sensible way.

Which old RPC stubs are these?  Omar is a new core with digic 6.  Something like Eeko, but not the same.
#91
Camera-specific Development / Re: Canon 7D Mark II
December 18, 2023, 11:34:17 PM
Can't trust anything you read :D  Nothing beats testing.  I would expect 0x8XXXYYYY to be separate (different address space?) comparing Omar and ICU.  But I'm guessing 0xdfXXYYYY is mirrored, so it doesn't matter.  If Omar instead copies from that range into 0x8XXXYYYY, then it may be harder to mess with.
#92
Camera-specific Development / Re: Canon 7D Mark II
December 17, 2023, 10:08:37 PM
It may not be safe to run the Omar code from ICU.  These cores are similar but different ARM architectures.  The code may not be compatible with ICU.  I also don't know if this code is truly PIC.  Arm code tends to be mostly PIC by default, but this is no guarantee it all is.  And, calling shamem_read() from ICU may well give incorrect results - assuming it's intended to be read from Omar, the masking may be the reverse of what you expect.

Some of the EDMAC routines obtain kernel locks before proceeding.  Since the Omar core is running an entirely different instance of the OS, I wouldn't expect these to be shared locks with the ICU.  This is untested.  And, since the kernel locks probably aren't shared between different OS instances, the cam will crash if you contest for resources on different cores.

The Omar 0x8000_6XXX code is populated by a copy from fe6X_YYYY rom region.  See the struct created in fe0ad874().  After the copy, the memory is visible at 0xdfXXXXXX on 7D2, or 0x8000_XXXX on Omar - I haven't tested writing the 7D2 side so I don't know if this is a mirror (my guess) or a copy.

Triggering arbitrary code from Omar looks easy, so this may be the safer route.  That way we know code is running in the intended context.  If you can prove all the code is appropriate and safe to run from ICU context that's fine too.  Feels like more work to me.  It also seems fairly likely there is an existing RPC mechanism.

The shamem info is useful to me, thanks.  I've not worked with this before, it doesn't seem to exist on D7 and above.
#93
Camera-specific Development / Re: Canon 7D Mark II
December 15, 2023, 01:45:20 PM
fe0ad874 is load_Omar().  This copies (somehow, indirectly) Omar firmware from 7D2 master, and does some other region setup.

I would guess 0xdff0_0000 is mirrored to 0x8000_0000, 0xdff4_0800 to 0x8000_0800.  However, my quick tests on phys cam don't make sense.  Maybe I did something wrong, maybe my assumptions are wrong.  Either way, it seemed potentially useful enough that I wanted to share before fully understanding it.

Bear in mind, we think the Omar core is Digic 5: ARMv5t.  D6 is ARMv7-R.  I know that's not forward compatible: -R has hardware division ops.  Can't remember if it's backwards compatible.  I think so?  Running Omar code from ICU may be dumb for a bunch of other reasons too, but you know that :D

EDIT: mistake identified.  I'd got two comments in the wrong places in a struct.


omar_dst_01 0xdff00000        // this is mapped as Omar atcm at 0x0
icu_src_01  code at 0xfe6afd04
len_01      0x6c80
omar_dst_02 0xdff40800        // this is mapped as Omar btcm at 8000_0800
icu_src_02  code at 0xfe6b698c
len_02      0xa0f0
omar_dst_03 0x1ac0000
icu_src_03  0xfe6c0a84
len_03      0x95c8
omar_dst_04 0x1ae0000
icu_src_04  0xfe6ca054
len_04      0x1f2ea8


So, all the Omar EDMAC func code should be readable (and writable!) in the dff40800 region.  Good luck flushing Omar's icache, I guess.
#94
Camera-specific Development / Re: Canon 7D Mark II
December 15, 2023, 01:17:52 PM
Nice, glad it's useful to you!  I've been looking for these for ages (more the 200D ones really), and now I know how to do it, it's not even that hard to find.  But the docs for what anything means are so fragmentary :(

The EDMAC stuff you're talking about helps me, it's easier to understand the wiki page now: https://magiclantern.fandom.com/wiki/Register_Map#EDMAC

It would make sense to me if you could read back the edmac_info region values, I'll try that.  I want to map out usage, I assume channels get remapped when in different modes / purposes.  I'm reading up on EDMAC (again) and intend to run tests on 200D - Digic 7 doesn't have Omar, and we can patch rom via MMU, so it's easier.  The code in edmac-memcpy.c has a lot of very ugly hard-coded values, as does the module.  I will look at making these general, should help me understand how things work, and it would be good to have these working on modern cams.

Re running code on Omar, I can think of a few ways.  The cleanest would be finding an existing Canon RPC mechanism.  It feels likely this exists (probably the code near fe0a30b2 is doing RPC with Omar).  If it doesn't, or we can't find it, since Omar is running DryOS, and ICU supplies the firmware it runs, it wouldn't be that hard to create our own RPC.  Bilal pointed me at some experiments on Eeko RPC here: https://www.magiclantern.fm/forum/index.php?topic=13408.msg175842#msg175842  Might be useful?  It's not clear how it triggers code in shared mem to run, presumably via the 0xc0XX_YYYY registers, but it's not explained.

So, we have options.  Since I don't know how to use EDMAC yet perhaps it makes sense for you to get it working however you want, and I can try and make a cleaner RPC method if needed.  Presumably 5D4 is similar, would be nice to have it somewhat general.

lv_save_raw is new to me.  The function just sets a flag, and indeed forum search suggests "There's a debug flag (lv_save_raw) that enables this".  I see that CONFIG_EDMAC_RAW_SLURP is supposed to be "better" than lv_save_raw.  Trying to understand this from reading forum posts is so incredibly slow.  I'm glad you're still around to keep the old knowledge alive :)

Possibly related...  take a look at 7d2 master rom1, fe25570a.  This is clearly Omar init related and looks to be doing something EDMAC.

I believe 13dfe() is send_msg_to_Omar(), there's a similar ComForOmar on the other side.  No idea on the message contents (refs Postman, so probably the same system, whatever that is).
#95
Reverse Engineering / Re: EDMAC in Digic 7 / 8 world
December 14, 2023, 10:54:48 PM
I have identified the following stubs for 200D, 1.0.1:

35392 StartEDmac
35486 edmac_set_addr
35506 edmac_set_size
3649c ConnectWriteEDmac
364f0 ConnectReadEDmac
3678e RegisterEDmacCompleteCBR

The EngDrv functions don't seem to exist here, instead registers are written to directly.  shamem_read() also appears missing, probably for similar reason.
#96
Camera-specific Development / Re: Canon 7D Mark II
December 14, 2023, 09:36:57 PM
After a lot of reading very old forum posts, and much messing about in Ghidra, I now have some important stubs found for 7D2 1.1.2.  These are all on Omar:

8000626a EngDrvOut
800062a4 EngDrvBits
800062ba EngDrvOuts
80006298 shamem_read
800063c2 StartEDmac
80006498 edmac_set_addr
800064c2 edmac_set_size
80006bfe ConnectWriteEDmac
80006c10 ConnectReadEDmac
80006c42 RegisterEDmacCompleteCBR

Alex's notes say edmac_set_addr() and edmac_set_size() together act like SetEDmac, I haven't checked that.  If true, we can wrap these together to provide that function.

As is, we cannot call these functions from ICU.  The 0x8000_XXXX address space does not contain the same content if you read it from ICU vs Omar.

Heder - are any other stubs required to attempt reading from e.g. the sensor?  To be safe, we need to find unused channels - anything else?
#97
Reverse Engineering / Re: EDMAC internals
December 14, 2023, 07:17:08 PM
After further testing on real cam to confirm I understand it, here's an illustrative copy example.


    // Region size 128kB == 0x20000, we can factor to:
    // 0x4 * 0x10 grid, each tile 0x80 * 0x10;
    // 0x4 * 0x10 * 0x80 * 0x10 == 0x20000
    struct edmac_info region = {
        .off1a = 0,
        .off1b = 0,
        .off2a = 0,
        .off2b = 0,
        .off3 = 0,
        .xa = 0x80, // "regular" col width
        .xb = 0x80, // "irregular" col width
        .ya = 0xf, // implies 0x10 high
        .yb = 0xf, // 0x10 high
        .xn = 0xf, // 0xf regular cols + 1 xb col
        .yn = 0x3 // 3 normal rows + 1 yb row
    };


It might seem more obvious to not use xb or yb at all; just have 10 normal columns and 4 normal rows.  I agree, but the hardware doesn't.

If you have xb == 0, your copy will silently fail.

yb is more tricky.  In general, ya and yb are treated as holding a number 1 higher than their values, but if yn is 0, ya is not used. Yb is always used, meaning if you keep it 0, you get a single row added to the end of your copy, of length (xa * xn) * (xb).
#98
Reverse Engineering / Re: EDMAC internals
December 13, 2023, 08:36:43 PM
I am exploring EDMAC on modern cams.  I found this thread useful, but hard to understand.   Here's my attempt for a useful diagram:



xa and ya specify "regular" tiles, which can be repeated, with the number of repeats controlled by xn and yn.

xb and yb specify "irregular" / "remainder" tiles, only appearing in one column or row, or none if the respective xb or yb is 0.

Memory is linear, accessed left-to-right, top-to-bottom.

I would assume this design was chosen as it allows specifying regions of arbitrary size, while also allowing most of the transfers to occur using tiles of a convenient width for the underlying copy mechanism (which is presumably aligned to some power of two).

Note that I'm ignoring the offsets.  You don't need them if you're copying a contiguous region of memory, and they complicate the diagram significantly.  Check the patent for details, should you need this.  In broad terms, you can specify an offset between any of the rows or columns, and that offset can be positive (you are now copying a grid of disconnected regions), or negative (you are copying a grid of partially overlapping regions).

Because you can provide a different edmac_info struct for the dst and src, this allows some kinds of transforms to happen very efficiently (likely bottle-necked only by ram speed).  The example given in the patent is for handling data from a unit that produces RGB data as three separate channels (each at a different memory location), which can be combined together using such a copy operation.  For the source, specify 3 rows or columns, with offsets meaning you're reading from each channel, for the destination, choose a different geometry.

Further complicating things, there are various restrictions on what edmac_info configs are valid.  I don't know all of these.  Alex implies some in his comments, but also talks about some configs that aren't valid on my test cam, a 200D.

Some examples:
You can specify a single rectangle with only xb and yb, and if so, xa and ya can be 0.  But yb must be at least 1, and this implies 2 rows: there's an implicit first row, so 0 => 1, but this doesn't work if xb is the only non-zero value.
If you have xa and xn non-zero, but everything else zero - your copy will silently fail.
If you have xa, ya, xn, yn all non-zero, but everything else zero - your copy will silently fail.
If you have xa, xn, xb non-zero, all else zero, this works!
Possibly this means you must have a non-zero xb.

There are limits on the maximums for each variable, which can be quite low, perhaps somewhere around 4000.  But it depends on which variable, and I haven't checked this thoroughly.  xb works up to at least 65536.  But in essence, each tile should be somewhat small.
#99
Camera-specific Development / Re: Canon 7D Mark II
December 13, 2023, 03:26:31 PM
I played around with this and now understand it more.  I haven't been able to do direct comparison between EDMAC on modern digic and fast dma_memcpy(), for complicated reasons.

Heder isn't using dma_memcpy() the *function*, he's using the underlying physical DMA controller in a similar manner to how the code tries to do it, but via direct access.  I suspect the reason you're doing that is because dma_memcpy() doesn't work on 7D2?  At least, that's what I find: it always fails for me, taking the "Nothing DMA ch now!" path, which I think means it fails to find a free DMA channel, possibly because they haven't been initialised.

7D2 has EDMAC, and it lives on Omar core.  https://www.magiclantern.fm/forum/index.php?topic=26249.msg245605#msg245605

If we want to use EDMAC resources that are sometimes used by *any* DryOS instance, we may have to go through Omar, or we're going to get into trouble with races / contention of physical resources.  If we can find channels / ports that are never used by DryOS then we can probably do stuff direct from ICU.  Or if there's some signalling method, RPC or interrupts etc to synchronise across cores.

D7 has a very different dma_memcpy() to older gens.  The functionality is the same, but the code is doing things in a very different way, no use of digic registers are easily found.  Might exist deeper into the code, I haven't spent a lot of time on it (EDMAC works for memory copies here).

Given that dma_memcpy() looks deliberately not working on 7D2 ICU, but does work on Digic 7, maybe this functionality is supposed to happen via Omar on D6?  It's not clear to me.
#100
Reverse Engineering / Re: EDMAC in Digic 7 / 8 world
December 13, 2023, 03:19:52 PM
7D2 has the same EDMAC code for mem_to_mem_edmac_copy(), but it lives on the Omar core.  Specifically, at 0x1b0e150.  I don't currently know how to run code on Omar, so I haven't tested this in the same way as 200D.  Possibly, since they're both ARM cores, I can just run the code from ICU...  but I'm not sure how memory mapping interacts here.  The code tries to get kernel locks at various points, and Omar is running a different instance of DryOS.  Feels like avoiding races on the locks is a pain, as well as avoiding contention accessing the physical resources - unless there's some RPC layer to synchronise the different OS instances.