diff mbox

[RFC,v5,2/5] hw/arm/digic: prepare DIGIC-based boards support

Message ID 1378537467-13471-3-git-send-email-antonynpavlov@gmail.com
State New
Headers show

Commit Message

Antony Pavlov Sept. 7, 2013, 7:04 a.m. UTC
Also this patch adds initial support for Canon
PowerShot A1100 IS compact camera.

Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
 hw/arm/Makefile.objs  |  1 +
 hw/arm/digic_boards.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 hw/arm/digic_boards.c

Comments

Peter Maydell Oct. 17, 2013, 6:01 p.m. UTC | #1
On 7 September 2013 08:04, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> +
> +static void digic4_board_init(DigicBoard *board)
> +{
> +    Error *err = NULL;
> +
> +    DigicBoardState *s = g_new(DigicBoardState, 1);
> +
> +    s->digic = DIGIC(object_new(TYPE_DIGIC));
> +    object_property_set_bool(OBJECT(s->digic), true, "realized", &err);
> +    if (err != NULL) {
> +        fprintf(stderr, "Couldn't realize DIGIC SoC: %s\n",
> +                error_get_pretty(err));
> +        exit(1);
> +    }
> +
> +    digic4_board_setup_ram(s, board->ram_size);
> +
> +    s->digic->cpu.env.regs[15] = board->start_addr;

I still think this is wrong. Real hardware can't possibly
start at this address; we should boot the same way the
hardware does.

> +}
> +
> +static DigicBoard digic4_board_canon_a1100 = {
> +    .ram_size = 64 * 1024 * 1024,
> +    /* CHDK recommends this address for ROM disassembly */
> +    .start_addr = 0xffc00000,
> +};

thanks
-- PMM
Georg Hofstetter Oct. 17, 2013, 6:51 p.m. UTC | #2
Hello,

just for the record.

flash (ROM1) on these cameras starts at 0xF8000000 and is either
0x00800000, 0x01000000 ox 0x02000000 large. just like with every
chip-selected memory, where the CS/EN line is selected by address masks,
addressing beyond the size memory repeats the content over and over.

ROM0 (0xF0000000) is rarely used.

The ARM in DIGIC has the high vectors selected by hardware and so the
reset vector is 0xFFFF0000. There you will find a bootloader.
Due to the memories repeating over and over starting from 0xF8000000,
the CPU will read from 0xF87F0000, 0xF8FF0000 or 0xF9FF0000, depending
on flash size (see above).

This kind of addressing beyond real flash end and wrapping over is
intentionally used by canon in multiple places - even in the main
firmware and when reflashing.
Some blocks are reflashed on a regular basis. They are used for
properties, which are the configuration area.

If you want to make the emulator behave like the real hardware, then you
have to:

 - reset to 0xFFFF0000
 - place ROM0 at 0xF0000000
 - place ROM1 at 0xF8000000
 - make the memory subsystem address correctly: (pseudocode)
     if((virt_addr & 0xF8000000) == 0xF0000000)
     {
         real_addr = 0xF0000000 | (virt_addr & (rom0_size - 1));
     }
     if((virt_addr & 0xF8000000) == 0xF8000000)
     {
         real_addr = 0xF8000000 | (virt_addr & (rom1_size - 1));
     }
 - make sure the flash emulation supports reflashing (properties)
 - change qemu memory subsystem to support execution from a flash that
   can be reprogrammed (properties are rewritten during startup)
   (maybe this is already possible, but it wasn't so 6 months ago)

OR
 - make workarounds so the system gets close to that behavior ;)


BR,
Georg

Am 17.10.2013 20:01, schrieb Peter Maydell:
> On 7 September 2013 08:04, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> 
> I still think this is wrong. Real hardware can't possibly
> start at this address; we should boot the same way the
> hardware does.
> 
>> +}
>> +
>> +static DigicBoard digic4_board_canon_a1100 = {
>> +    .ram_size = 64 * 1024 * 1024,
>> +    /* CHDK recommends this address for ROM disassembly */
>> +    .start_addr = 0xffc00000,
>> +};
> 
> thanks
> -- PMM
>
Peter Maydell Oct. 17, 2013, 7:17 p.m. UTC | #3
On 17 October 2013 19:51, Georg Hofstetter <qemu@g3gg0.de> wrote:
> flash (ROM1) on these cameras starts at 0xF8000000 and is either
> 0x00800000, 0x01000000 ox 0x02000000 large. just like with every
> chip-selected memory, where the CS/EN line is selected by address masks,
> addressing beyond the size memory repeats the content over and over.
>
> ROM0 (0xF0000000) is rarely used.
>
> The ARM in DIGIC has the high vectors selected by hardware and so the
> reset vector is 0xFFFF0000. There you will find a bootloader.
> Due to the memories repeating over and over starting from 0xF8000000,
> the CPU will read from 0xF87F0000, 0xF8FF0000 or 0xF9FF0000, depending
> on flash size (see above).
>
> This kind of addressing beyond real flash end and wrapping over is
> intentionally used by canon in multiple places - even in the main
> firmware and when reflashing.
> Some blocks are reflashed on a regular basis. They are used for
> properties, which are the configuration area.

Thanks for this explanation of the hardware.

> If you want to make the emulator behave like the real hardware, then you
> have to:
>
>  - reset to 0xFFFF0000

Yep. This implies having a cpu property corresponding to "enable
hivecs from bootup" (matching the h/w config signal), and making
sure cpu reset honours it; that's fairly easy.

>  - place ROM0 at 0xF0000000
>  - place ROM1 at 0xF8000000
>  - make the memory subsystem address correctly: (pseudocode)
>      if((virt_addr & 0xF8000000) == 0xF0000000)
>      {
>          real_addr = 0xF0000000 | (virt_addr & (rom0_size - 1));
>      }
>      if((virt_addr & 0xF8000000) == 0xF8000000)
>      {
>          real_addr = 0xF8000000 | (virt_addr & (rom1_size - 1));
>      }

The easy way to do this is just to use memory region aliases
to repeat the ROM through the whole area; you can do that
in the board model without having to mess with the memory
subsystem itself.

>  - make sure the flash emulation supports reflashing (properties)
>  - change qemu memory subsystem to support execution from a flash that
>    can be reprogrammed (properties are rewritten during startup)
>    (maybe this is already possible, but it wasn't so 6 months ago)

I agree that these are probably missing features in our flash
emulation, but aren't they orthogonal to the question of how
we handle CPU reset and what the starting PC should be?

-- PMM
Georg Hofstetter Oct. 20, 2013, 12:13 a.m. UTC | #4
Am 17.10.2013 21:17, schrieb Peter Maydell:
> 
>>  - make sure the flash emulation supports reflashing (properties)
>>  - change qemu memory subsystem to support execution from a flash that
>>    can be reprogrammed (properties are rewritten during startup)
>>    (maybe this is already possible, but it wasn't so 6 months ago)
> 
> I agree that these are probably missing features in our flash
> emulation, but aren't they orthogonal to the question of how
> we handle CPU reset and what the starting PC should be?
> 

Hi Peter,

absolutely - this was just the whole list of behavior to be implemented
and/or emulated to get the emulator close to real hardware.
Its just something that would prevent a clean firmware boot and came to
my mind while writing about system startup.

So yeah, its a bit off topic :)

Regards,
Georg
Antony Pavlov Oct. 22, 2013, 11:26 a.m. UTC | #5
On Thu, 17 Oct 2013 20:17:15 +0100
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 17 October 2013 19:51, Georg Hofstetter <qemu@g3gg0.de> wrote:
> > flash (ROM1) on these cameras starts at 0xF8000000 and is either
> > 0x00800000, 0x01000000 ox 0x02000000 large. just like with every
> > chip-selected memory, where the CS/EN line is selected by address masks,
> > addressing beyond the size memory repeats the content over and over.
> >
> > ROM0 (0xF0000000) is rarely used.
> >
> > The ARM in DIGIC has the high vectors selected by hardware and so the
> > reset vector is 0xFFFF0000. There you will find a bootloader.
> > Due to the memories repeating over and over starting from 0xF8000000,
> > the CPU will read from 0xF87F0000, 0xF8FF0000 or 0xF9FF0000, depending
> > on flash size (see above).
> >
> > This kind of addressing beyond real flash end and wrapping over is
> > intentionally used by canon in multiple places - even in the main
> > firmware and when reflashing.
> > Some blocks are reflashed on a regular basis. They are used for
> > properties, which are the configuration area.
> 
> Thanks for this explanation of the hardware.
> 
> > If you want to make the emulator behave like the real hardware, then you
> > have to:
> >
> >  - reset to 0xFFFF0000
> 
> Yep. This implies having a cpu property corresponding to "enable
> hivecs from bootup" (matching the h/w config signal), and making
> sure cpu reset honours it; that's fairly easy.
> 
> >  - place ROM0 at 0xF0000000
> >  - place ROM1 at 0xF8000000
> >  - make the memory subsystem address correctly: (pseudocode)
> >      if((virt_addr & 0xF8000000) == 0xF0000000)
> >      {
> >          real_addr = 0xF0000000 | (virt_addr & (rom0_size - 1));
> >      }
> >      if((virt_addr & 0xF8000000) == 0xF8000000)
> >      {
> >          real_addr = 0xF8000000 | (virt_addr & (rom1_size - 1));
> >      }
> 
> The easy way to do this is just to use memory region aliases
> to repeat the ROM through the whole area; you can do that
> in the board model without having to mess with the memory
> subsystem itself.

Hmm. The current DIGIC patchseries already has the functionality like this!
Here is my console log:

$ xxd -g 1 -l 0x40 ./canon-a1100-rom1.bin 
0000000: 12 00 00 ea fe ff ff ea fe ff ff ea fe ff ff ea  ................
0000010: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea  ................
0000020: 62 61 72 65 62 6f 78 00 00 00 10 00 84 5e 01 00  barebox......^..
0000030: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU

$ ./arm-softmmu/qemu-system-arm -M canon-a1100 -bios ./canon-a1100-rom1.bin -serial stdio

Switch to console [cs0]


barebox 2013.08.0-00267-g85b83fb #125 Thu Aug 29 07:58:57 MSK 2013


Board: Canon PowerShot A1100 IS
digic-gpio c0220000.gpio: probed gpiochip-1 with base 0
cfi_flash f8000000.flash: found cfi flash at f8000000, size 4194304
malloc space: 0x00100000 -> 0x002fffff (size 2 MiB)
Open /dev/env0 No such file or directory
no valid environment found on /dev/env0. Using default environment
running /env/bin/init...
canon> /
canon> / md -b 0xf8000000+0x40
f8000000: 12 00 00 ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f8000010: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f8000020: 62 61 72 65 62 6f 78 00 00 00 10 00 84 5e 01 00    barebox......^..
f8000030: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55    UUUUUUUUUUUUUUUU
canon> / md -b 0xf8400000+0x40
f8400000: 12 00 00 ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f8400010: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f8400020: 62 61 72 65 62 6f 78 00 00 00 10 00 84 5e 01 00    barebox......^..
f8400030: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55    UUUUUUUUUUUUUUUU
canon> / md -b 0xf9000000+0x40
f9000000: 12 00 00 ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f9000010: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea    ................
f9000020: 62 61 72 65 62 6f 78 00 00 00 10 00 84 5e 01 00    barebox......^..
f9000030: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55    UUUUUUUUUUUUUUUU
canon> / 

-- 
Best regards,
  Antony Pavlov
Antony Pavlov Dec. 4, 2013, 8:22 p.m. UTC | #6
On Thu, 17 Oct 2013 20:17:15 +0100
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 17 October 2013 19:51, Georg Hofstetter <qemu@g3gg0.de> wrote:
> > flash (ROM1) on these cameras starts at 0xF8000000 and is either
> > 0x00800000, 0x01000000 ox 0x02000000 large. just like with every
> > chip-selected memory, where the CS/EN line is selected by address masks,
> > addressing beyond the size memory repeats the content over and over.
> >
> > ROM0 (0xF0000000) is rarely used.
> >
> > The ARM in DIGIC has the high vectors selected by hardware and so the
> > reset vector is 0xFFFF0000. There you will find a bootloader.
> > Due to the memories repeating over and over starting from 0xF8000000,
> > the CPU will read from 0xF87F0000, 0xF8FF0000 or 0xF9FF0000, depending
> > on flash size (see above).
> >
> > This kind of addressing beyond real flash end and wrapping over is
> > intentionally used by canon in multiple places - even in the main
> > firmware and when reflashing.
> > Some blocks are reflashed on a regular basis. They are used for
> > properties, which are the configuration area.
> 
> Thanks for this explanation of the hardware.
> 
> > If you want to make the emulator behave like the real hardware, then you
> > have to:
> >
> >  - reset to 0xFFFF0000
> 
> Yep. This implies having a cpu property corresponding to "enable
> hivecs from bootup" (matching the h/w config signal), and making
> sure cpu reset honours it; that's fairly easy.
> 
> >  - place ROM0 at 0xF0000000
> >  - place ROM1 at 0xF8000000
> >  - make the memory subsystem address correctly: (pseudocode)
> >      if((virt_addr & 0xF8000000) == 0xF0000000)
> >      {
> >          real_addr = 0xF0000000 | (virt_addr & (rom0_size - 1));
> >      }
> >      if((virt_addr & 0xF8000000) == 0xF8000000)
> >      {
> >          real_addr = 0xF8000000 | (virt_addr & (rom1_size - 1));
> >      }
> 
> The easy way to do this is just to use memory region aliases
> to repeat the ROM through the whole area; you can do that
> in the board model without having to mess with the memory
> subsystem itself.
> 
> >  - make sure the flash emulation supports reflashing (properties)
> >  - change qemu memory subsystem to support execution from a flash that
> >    can be reprogrammed (properties are rewritten during startup)
> >    (maybe this is already possible, but it wasn't so 6 months ago)
> 
> I agree that these are probably missing features in our flash
> emulation, but aren't they orthogonal to the question of how
> we handle CPU reset and what the starting PC should be?

Here is my proposition:

1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
on DIGIC chips)

2. we need somehow put a 'jump-to-beginning-of-ROM' instruction to 0xffff0000.
(We can't put barebox to 0xffff0000 as barebox image is bigger that 64K.)

There is at least two possibilities to do so:
 * we can use specially prepared ROM image;
 * qemu board code can insert by itself a 'jump-to-beginning-of-ROM' instruction
after loading ROM image (as qemu MIPS Malta board code does).

3. CPU starts as usual. Branching to barebox code in ROM happends in a natural way!

Please comment my proposition.

-- 
Best regards,
  Antony Pavlov
Peter Maydell Dec. 4, 2013, 8:29 p.m. UTC | #7
On 4 December 2013 20:22, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> Here is my proposition:
>
> 1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
> on DIGIC chips)

Sort of. What we need is:
 1a. Add a "hivecs" property to the ARM CPU object (which
just sets env->cp15.c1_sys bit 13)

(this is about half a dozen lines of code max)

 1b DIGIC board init code creates the CPU and sets the hivecs property on it

(another handful of lines of code)

> 2. we need somehow put a 'jump-to-beginning-of-ROM' instruction to 0xffff0000.
> (We can't put barebox to 0xffff0000 as barebox image is bigger that 64K.)
>
> There is at least two possibilities to do so:
>  * we can use specially prepared ROM image;
>  * qemu board code can insert by itself a 'jump-to-beginning-of-ROM' instruction
> after loading ROM image (as qemu MIPS Malta board code does).

The board code should definitely not be writing random instructions into
memory. You need to provide a ROM image which will do the work.

> 3. CPU starts as usual. Branching to barebox code in ROM happends in a natural way!

This bit's OK :-)

thanks
-- PMM
Antony Pavlov Dec. 4, 2013, 9:20 p.m. UTC | #8
On Wed, 4 Dec 2013 20:29:05 +0000
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 4 December 2013 20:22, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> > Here is my proposition:
> >
> > 1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
> > on DIGIC chips)
> 
> Sort of. What we need is:
>  1a. Add a "hivecs" property to the ARM CPU object (which
> just sets env->cp15.c1_sys bit 13)
> 
> (this is about half a dozen lines of code max)
> 
>  1b DIGIC board init code creates the CPU and sets the hivecs property on it
> 
> (another handful of lines of code)

Ok, I'll try to make the work at the weekend.

> > 2. we need somehow put a 'jump-to-beginning-of-ROM' instruction to 0xffff0000.
> > (We can't put barebox to 0xffff0000 as barebox image is bigger that 64K.)
> >
> > There is at least two possibilities to do so:
> >  * we can use specially prepared ROM image;
> >  * qemu board code can insert by itself a 'jump-to-beginning-of-ROM' instruction
> > after loading ROM image (as qemu MIPS Malta board code does).
> 
> The board code should definitely not be writing random instructions into
> memory. You need to provide a ROM image which will do the work.
> 
> > 3. CPU starts as usual. Branching to barebox code in ROM happends in a natural way!
> 
> This bit's OK :-)
> 
> thanks
> -- PMM
Peter Maydell Dec. 4, 2013, 9:34 p.m. UTC | #9
On 4 December 2013 21:20, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> On Wed, 4 Dec 2013 20:29:05 +0000
> Peter Maydell <peter.maydell@linaro.org> wrote:
>
>> On 4 December 2013 20:22, Antony Pavlov <antonynpavlov@gmail.com> wrote:
>> > Here is my proposition:
>> >
>> > 1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
>> > on DIGIC chips)
>>
>> Sort of. What we need is:
>>  1a. Add a "hivecs" property to the ARM CPU object (which
>> just sets env->cp15.c1_sys bit 13)
>>
>> (this is about half a dozen lines of code max)
>>
>>  1b DIGIC board init code creates the CPU and sets the hivecs property on it
>>
>> (another handful of lines of code)
>
> Ok, I'll try to make the work at the weekend.

The recent (not yet applied) patchset adding a property for the CBAR
register value is probably a good model to look at.

-- PMM
Peter Crosthwaite Dec. 5, 2013, 12:20 a.m. UTC | #10
On Thu, Dec 5, 2013 at 7:34 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 4 December 2013 21:20, Antony Pavlov <antonynpavlov@gmail.com> wrote:
>> On Wed, 4 Dec 2013 20:29:05 +0000
>> Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>>> On 4 December 2013 20:22, Antony Pavlov <antonynpavlov@gmail.com> wrote:
>>> > Here is my proposition:
>>> >
>>> > 1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
>>> > on DIGIC chips)
>>>
>>> Sort of. What we need is:
>>>  1a. Add a "hivecs" property to the ARM CPU object (which
>>> just sets env->cp15.c1_sys bit 13)
>>>
>>> (this is about half a dozen lines of code max)
>>>
>>>  1b DIGIC board init code creates the CPU and sets the hivecs property on it
>>>
>>> (another handful of lines of code)
>>
>> Ok, I'll try to make the work at the weekend.
>
> The recent (not yet applied) patchset adding a property for the CBAR
> register value is probably a good model to look at.
>

Is hivecs-on-reset ideally a new ARM_FEATURE or is there a simpler
conditional we can use as post_init time?

Regards,
Peter

> -- PMM
>
Peter Crosthwaite Dec. 5, 2013, 12:25 a.m. UTC | #11
On Thu, Dec 5, 2013 at 7:20 AM, Antony Pavlov <antonynpavlov@gmail.com> wrote:
> On Wed, 4 Dec 2013 20:29:05 +0000
> Peter Maydell <peter.maydell@linaro.org> wrote:
>
>> On 4 December 2013 20:22, Antony Pavlov <antonynpavlov@gmail.com> wrote:
>> > Here is my proposition:
>> >
>> > 1. qemu board code setup CPU to start from 0xFFFF0000. (0xffff0000 is a ROM address
>> > on DIGIC chips)
>>
>> Sort of. What we need is:
>>  1a. Add a "hivecs" property to the ARM CPU object (which
>> just sets env->cp15.c1_sys bit 13)
>>
>> (this is about half a dozen lines of code max)
>>
>>  1b DIGIC board init code creates the CPU and sets the hivecs property on it
>>
>> (another handful of lines of code)
>
> Ok, I'll try to make the work at the weekend.
>
>> > 2. we need somehow put a 'jump-to-beginning-of-ROM' instruction to 0xffff0000.
>> > (We can't put barebox to 0xffff0000 as barebox image is bigger that 64K.)
>> >
>> > There is at least two possibilities to do so:
>> >  * we can use specially prepared ROM image;
>> >  * qemu board code can insert by itself a 'jump-to-beginning-of-ROM' instruction
>> > after loading ROM image (as qemu MIPS Malta board code does).
>>
>> The board code should definitely not be writing random instructions into
>> memory. You need to provide a ROM image which will do the work.
>>

But the bootloader does this already. We have support for board
configurable secondary bootloops. Is this as simple as supporting
board configurable primary boot fragments?

arm_boot needs to be patched to do its bootstrap magic with no -kernel
arg I guess. I have something of that nature in my own tree, where I
have a command line argument that forces arm-boot to use the linux
bootstrap stuff (primary and secondary bootloops and all that)
regardless of image type.

Regards,
Peter

>> > 3. CPU starts as usual. Branching to barebox code in ROM happends in a natural way!
>>
>> This bit's OK :-)
>>
>> thanks
>> -- PMM
>
>
> --
> --
> Best regards,
>   Antony Pavlov
>
Peter Maydell Dec. 5, 2013, 7:59 a.m. UTC | #12
On 5 December 2013 00:25, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> But the bootloader does this already. We have support for board
> configurable secondary bootloops. Is this as simple as supporting
> board configurable primary boot fragments?
>
> arm_boot needs to be patched to do its bootstrap magic with no -kernel
> arg I guess.

I'd really rather not extend the arm_boot code to more usage cases
if I can avoid it. It's really intended for loading kernels. In this case
the thing being loaded really is a ROM image, and the correct way
to handle this is to make the board model behave the same way
the hardware does and make the ROM image sit at the same place
in the memory map that the real ROM image does.

thanks
-- PMM
Peter Maydell Dec. 5, 2013, 8:02 a.m. UTC | #13
On 5 December 2013 00:20, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> Is hivecs-on-reset ideally a new ARM_FEATURE or is there a simpler
> conditional we can use as post_init time?

I think we want the property if (!arm_feature(ARM_FEATURE_M)).

-- PMM
Antony Pavlov Dec. 7, 2013, 12:55 a.m. UTC | #14
[RFC 1/2] ARM: cpu: add "hivecs" property (high vectors on reset)
[RFC 2/2] ARM: arm_cpu_reset: make possible to use high vectors for
diff mbox

Patch

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index eb548dd..69a8de5 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,4 +1,5 @@ 
 obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
+obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
new file mode 100644
index 0000000..77cfc81
--- /dev/null
+++ b/hw/arm/digic_boards.c
@@ -0,0 +1,88 @@ 
+/*
+ * QEMU model of the Canon DIGIC boards (cameras indeed :).
+ *
+ * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This model is based on reverse engineering efforts
+ * made by CHDK (http://chdk.wikia.com) and
+ * Magic Lantern (http://www.magiclantern.fm) projects
+ * contributors.
+ *
+ * See docs here:
+ *   http://magiclantern.wikia.com/wiki/Register_Map
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/digic.h"
+
+typedef struct DigicBoardState {
+    DigicState *digic;
+    MemoryRegion ram;
+} DigicBoardState;
+
+typedef struct DigicBoard {
+    hwaddr ram_size;
+    hwaddr start_addr;
+} DigicBoard;
+
+static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
+{
+    memory_region_init_ram(&s->ram, NULL, "ram", ram_size);
+    memory_region_add_subregion(get_system_memory(), 0, &s->ram);
+    vmstate_register_ram_global(&s->ram);
+}
+
+static void digic4_board_init(DigicBoard *board)
+{
+    Error *err = NULL;
+
+    DigicBoardState *s = g_new(DigicBoardState, 1);
+
+    s->digic = DIGIC(object_new(TYPE_DIGIC));
+    object_property_set_bool(OBJECT(s->digic), true, "realized", &err);
+    if (err != NULL) {
+        fprintf(stderr, "Couldn't realize DIGIC SoC: %s\n",
+                error_get_pretty(err));
+        exit(1);
+    }
+
+    digic4_board_setup_ram(s, board->ram_size);
+
+    s->digic->cpu.env.regs[15] = board->start_addr;
+}
+
+static DigicBoard digic4_board_canon_a1100 = {
+    .ram_size = 64 * 1024 * 1024,
+    /* CHDK recommends this address for ROM disassembly */
+    .start_addr = 0xffc00000,
+};
+
+static void canon_a1100_init(QEMUMachineInitArgs *args)
+{
+    digic4_board_init(&digic4_board_canon_a1100);
+}
+
+static QEMUMachine canon_a1100 = {
+    .name = "canon-a1100",
+    .desc = "Canon PowerShot A1100 IS",
+    .init = &canon_a1100_init,
+};
+
+static void digic_register_machines(void)
+{
+    qemu_register_machine(&canon_a1100);
+}
+
+machine_init(digic_register_machines)