2013/3/7 Kuo-Jung Su <dant...@gmail.com>: > 2013/3/6 Paolo Bonzini <pbonz...@redhat.com>: >>> > > 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" <dant...@gmail.com> >>> A: "Paolo Bonzini" <pbonz...@redhat.com> >>> 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 <pbonz...@redhat.com>: >>> > >>> >> 2013/3/6 Paolo Bonzini <pbonz...@redhat.com>: >>> >> > 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 <dant...@gmail.com> >>> >> >> --- >>> >> >> 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