qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v6 07/24] hw/arm: add Faraday FTWDT010 watchdog


From: Kuo-Jung Su
Subject: Re: [Qemu-devel] [PATCH v6 07/24] hw/arm: add Faraday FTWDT010 watchdog timer support
Date: Thu, 7 Mar 2013 10:44:14 +0800

2013/3/6 Paolo Bonzini <address@hidden>:
>> > > It doesn't work while running under ROM mode. ( no -kernel )
>> > > Because Faraday SoC Platform usually designed to boot from ROM and
>> > > followed by an AHB remapping process (i.e. remap ROM/RAM address).
>> >
>> > What doesn't work exactly?  Why aren't these called?  Or are
>> > you forcing a particular reset order?
>> >
>> > Paolo
>>
>> While booting from ROM, the faraday soc usually remap the ROM / RAM
>> before jumping into linux.
>>
>> In other words,  the system mapping is:
>>
>> 1. Power-On:
>>
>>     ROM: 0x00000000
>>     RAM: N/A
>>     SRAM: 0xA0000000
>>
>> 2. AHB Remap (u-boot/linux)
>>
>>     ROM: 0x20000000
>>     RAM: 0x00000000
>>
>> So I have to register my own reset handler to
>>
>> 1. Undo the ROM/RAM remap (i.e. device_reset(s->ahbc))
>> 2. Reset CPU
>
> ----- Messaggio originale -----
>> Da: "Kuo-Jung Su" <address@hidden>
>> A: "Paolo Bonzini" <address@hidden>
>> Inviato: Mercoledì, 6 marzo 2013 11:00:49
>> Oggetto: Re: [PATCH v6 07/24] hw/arm: add Faraday FTWDT010 watchdog timer 
>> support
>>
>> 2013/3/6 Paolo Bonzini <address@hidden>:
>> >
>> >> 2013/3/6 Paolo Bonzini <address@hidden>:
>> >> > Il 06/03/2013 08:27, Kuo-Jung Su ha scritto:
>> >> >> The FTWDT010 is used to prevent system from infinite loop
>> >> >> while software gets trapped in the deadlock.
>> >> >>
>> >> >> Under the normal operation, users should restart FTWDT010
>> >> >> at the regular intervals before counter counts down to 0.
>> >> >>
>> >> >> If the counter does reach 0, FTWDT010 will try to reset
>> >> >> the system by generating one or a combination of signals,
>> >> >> system reset, system interrupt, and external interrupt.
>> >> >>
>> >> >> Signed-off-by: Kuo-Jung Su <address@hidden>
>> >> >> ---
>> >> >>  hw/arm/Makefile.objs      |    1 +
>> >> >>  hw/arm/faraday_a369_soc.c |   23 +++++
>> >> >>  hw/arm/ftwdt010.c         |  212
>> >> >>  +++++++++++++++++++++++++++++++++++++++++++++
>> >> >>  hw/arm/ftwdt010.h         |   35 ++++++++
>> >> >>  4 files changed, 271 insertions(+)
>> >> >>  create mode 100644 hw/arm/ftwdt010.c
>> >> >>  create mode 100644 hw/arm/ftwdt010.h
>> >> >>
>> >> >> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
>> >> >> index 2190edd..bc8e2de 100644
>> >> >> --- a/hw/arm/Makefile.objs
>> >> >> +++ b/hw/arm/Makefile.objs
>> >> >> @@ -41,3 +41,4 @@ obj-y += ftintc020.o
>> >> >>  obj-y += ftahbc020.o
>> >> >>  obj-y += ftddrii030.o
>> >> >>  obj-y += ftpwmtmr010.o
>> >> >> +obj-y += ftwdt010.o
>> >> >> diff --git a/hw/arm/faraday_a369_soc.c
>> >> >> b/hw/arm/faraday_a369_soc.c
>> >> >> index 66d9891..1bf64d4 100644
>> >> >> --- a/hw/arm/faraday_a369_soc.c
>> >> >> +++ b/hw/arm/faraday_a369_soc.c
>> >> >> @@ -68,6 +68,25 @@ static void a369soc_reset(DeviceState *ds)
>> >> >>  }
>> >> >>
>> >> >>  static void
>> >> >> +a369soc_system_reset(void *opaque)
>> >> >> +{
>> >> >> +    FaradaySoCState *s = FARADAY_SOC(opaque);
>> >> >> +
>> >> >> +    if (s->scu) {
>> >> >> +        device_reset(s->scu);
>> >> >> +    }
>> >> >> +    if (s->ddrc) {
>> >> >> +        device_reset(s->ddrc);
>> >> >> +    }
>> >> >> +    if (s->ahbc) {
>> >> >> +        device_reset(s->ahbc);
>> >> >> +    }
>> >> >> +    if (s->cpu) {
>> >> >> +        cpu_reset(CPU(s->cpu));
>> >> >> +    }
>> >> >> +}
>> >> >
>> >> > Why is this needed?  Aren't they called already by
>> >> >
>> >> >     qemu_register_reset(qbus_reset_all_fn,
>> >> >     sysbus_get_default());
>> >> >
>> >> > ?
>> >> >
>> >>
>> >> It doesn't work while running under ROM mode. ( no -kernel )
>> >> Because Faraday SoC Platform usually designed to boot from ROM and
>> >> followed by an AHB remapping process (i.e. remap ROM/RAM address).
>> >
>> > What doesn't work exactly?  Why aren't these called?  Or are
>> > you forcing a particular reset order?
>> >
>> > Paolo
>>
>> While booting from ROM, the faraday soc usually remap the ROM / RAM
>> before jumping into linux.
>>
>> In other words,  the system mapping is:
>>
>> 1. Power-On:
>>
>>     ROM: 0x00000000
>>     RAM: N/A
>>     SRAM: 0xA0000000
>>
>> 2. AHB Remap (u-boot/linux)
>>
>>     ROM: 0x20000000
>>     RAM: 0x00000000
>>
>> So I have to register my own reset handler to
>>
>> 1. Undo the ROM/RAM remap (i.e. device_reset(s->ahbc))
>> 2. Reset CPU
>
> I understand that.  What I'm missing is, why these reset handlers aren't
> called anyway when QEMU does qemu_devices_reset(), for example from
> qemu_system_reset().
>

1. arm_cpu_reset() is never be invoked from the default reset handler.

2. Undo ROM/RAM remap would make bus become unstable there is no
    guaranty when the bus would be stabilized.
    (It looks to me that it's true for both QEMU and real hardware)

3. In QEMU, my guess is without arm_cpu_reset(), when the AHB remap process
    activated upon watchdog counts down to zero.
    The PC (r15) could be anywhere, and so does the stack & bss.
    Which means the CPU would likely suffers from UNKNOWN INSTRUCTION,
    DATA ABORT... etc.

> Also, I do not understand who performs this again:
>

It's performed at my ROM code:

https://github.com/dantesu1218/virgil/blob/master/arch/mach-a369/board.c

line 200 ~ 220

#ifndef CONFIG_SKIP_SYSINIT
/* Skip AHB remap if the jump address is not inside SDRAM address space */
"ldr r4, =0x10000000\n"
"cmp %2, r4\n"
"movhs pc, %2\n" /* jump without AHB remapped */
/* AHB remap
* REG32(CONFIG_IOBASE_DDR + 0x10) &= 0x00FFFFFF
* REG32(CONFIG_IOBASE_AHB + 0x88)  = 0x00100F01
*/
"ldr r4, [%0, #0x10]\n"
"bic r4, #0xff000000\n"
"ldr r5, =0x00100f01\n"
".ALIGN 5\n" /* Make sure all the following codes to be fetched in a
single 32-bytes cache line */
"str r4, [%0, #0x10]\n" /* REG32(CONFIG_IOBASE_DDR + 0x10) &= 0x00FFFFFF */
"str r5, [%1, #0x88]\n" /* REG32(CONFIG_IOBASE_AHB + 0x88)  = 0x00100F01 */
"5:\n"
"ldr r4, [%2, #0]\n" /* while(magic != REG32(addr)) */
"teq r4, %3\n"
"bne 5b\n"
#endif
"mov pc, %2\n" /* jump */


> +        /* Remap AHB slave 4 (ROM) & slave 6 (RAM) */
> +        /* 1. Remap RAM to base of ROM */
> +        s->ram_base = s->ahb_slave[4] & 0xfff00000;
> +        s->ahb_slave[6] = s->ram_base | (s->ahb_slave[6] & 0x000f0000);
> +        /* 2. Remap ROM to base of ROM + size of RAM */
> +        s->rom_base = s->ram_base
> +                    + ((1 << extract32(s->ahb_slave[6], 16, 4)) << 20);
> +        s->ahb_slave[4] = s->rom_base | (s->ahb_slave[4] & 0x000f0000);
>
> when you do a system_reset and the board was started in kernel mode.
>

The problem is not about the kernel mode. In my words, I call them:

1. RAM Mode Emulation (Launching QEMU with -kernel) :
    The emulator would assume that the SDRAM has been remapped to
    0x00000000.

2. ROM Mode Emulation (Without -kernel):
    The emulator would map the 6KB ROM (pflash) to 0x00000000, 32KB SRAM
    to 0xA0000000, but no SDRAM

P.S:

In A369, the the boot sequence of ROM mode is:

1. Power-on
2. ROM code execution on ROM @ 0x00000000
3. 2nd bootstrap on SRAM @ 0xA0000000
4. General software (Linux/U-boot) execution on SDRAM @ 0x00000000

In newer design, (from 2010, after my referenced ROM code is reay)
the the boot sequence of ROM mode becomes:

1. Power-on
2. ROM code execution on ROM @ 0x00000000
3. General software (Linux/U-boot) execution on SDRAM @ 0x00000000

Currently I have a kw9505 QEMU model ready for this,  and since it's a
customer ASIC,
it shall never be merged into open source.
But if you want, I could provide the kw9505.c with lots of coding style issues
for function test.

> Paolo



--
Best wishes,
Kuo-Jung Su



reply via email to

[Prev in Thread] Current Thread [Next in Thread]