[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 13:53:39 +0800 |
2013/3/7 Kuo-Jung Su <address@hidden>:
> 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 */
>
>
Sorry, if I get you wrong, and what you're actually asking is:
Where or which module is responsible for SDRAM init and AHB remap?
The answer is:
1. ftahbc020: It's responsible for AHB remap, please check this:
static void ftahbc020_mem_write()
{
......
if (!soc->ahb_remapped && (s->cr & CR_REMAP)) {
/* Remap AHB slave 4 (ROM) & slave 6 (RAM) */
/* 1. Remap RAM to base of ROM */
soc->ram_base = soc->ahb_slave[4] & 0xfff00000;
/* 2. Remap ROM to base of ROM + size of RAM */
soc->rom_base = soc->ram_base
+ ((1 << extract32(soc->ahb_slave[6], 16, 4)) << 20);
/* 3. Update ROM memory map */
sysbus_mmio_map(SYS_BUS_DEVICE(soc->rom), 0, soc->rom_base);
/* 4. Update RAM memory map if it has been initialized. */
if (soc->ddr_inited) {
memory_region_del_subregion(soc->as, soc->ram);
memory_region_add_subregion(soc->as, soc->ram_base, soc->ram);
}
soc->ahb_remapped = true;
}
......
}
2. ftddrii030: It's responsible for SDRAM init, please check this:
static void ftddrii030_mem_write()
{
......
if (!soc->ddr_inited && (val & MSR_CMD_MRS)) {
val &= ~MSR_CMD_MRS;
val |= MSR_INIT_OK;
memory_region_add_subregion(soc->as, soc->ram_base, soc->ram);
soc->ddr_inited = true;
}
......
}
>> + /* 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
--
Best wishes,
Kuo-Jung Su
- [Qemu-devel] [PATCH v6 02/24] hw/arm: add Faraday a369 SoC platform support, (continued)
- [Qemu-devel] [PATCH v6 02/24] hw/arm: add Faraday a369 SoC platform support, Kuo-Jung Su, 2013/03/06
- [Qemu-devel] [PATCH v6 03/24] hw/arm: add Faraday FTINTC020 interrupt controller support, Kuo-Jung Su, 2013/03/06
- [Qemu-devel] [PATCH v6 04/24] hw/arm: add Faraday FTAHBC020 support, Kuo-Jung Su, 2013/03/06
- [Qemu-devel] [PATCH v6 05/24] hw/arm: add Faraday FTDDRII030 support, Kuo-Jung Su, 2013/03/06
- [Qemu-devel] [PATCH v6 06/24] hw/arm: add Faraday FTPWMTMR010 timer support, Kuo-Jung Su, 2013/03/06
- [Qemu-devel] [PATCH v6 07/24] hw/arm: add Faraday FTWDT010 watchdog timer support, Kuo-Jung Su, 2013/03/06
[Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Kuo-Jung Su, 2013/03/06
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Paolo Bonzini, 2013/03/06
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Kuo-Jung Su, 2013/03/07
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Paolo Bonzini, 2013/03/07
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Wei-Ren Chen, 2013/03/07
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Paolo Bonzini, 2013/03/07
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Wei-Ren Chen, 2013/03/07
- Re: [Qemu-devel] [PATCH v6 08/24] hw/arm: add Faraday FTRTC011 RTC timer support, Kuo-Jung Su, 2013/03/07
[Qemu-devel] [PATCH v6 09/24] hw/arm: add Faraday FTDMAC020 AHB DMA support, Kuo-Jung Su, 2013/03/06
[Qemu-devel] [PATCH v6 10/24] hw/arm: add Faraday FTAPBBRG020 APB DMA support, Kuo-Jung Su, 2013/03/06