Rockbox.org home
release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Rockbox mail archive

Subject: bootloader hanging early on 80G G5.5 iPod - debugging attempt

bootloader hanging early on 80G G5.5 iPod - debugging attempt

From: Paul Collins <paul_at_briny.ondioline.org>
Date: Wed, 11 Oct 2006 21:39:24 +1300

A number of people have succeeded in running Rockbox on their 30G G5.5
iPods with some trickery: a regular bootloader and rockbox build,
modified ipod_fw, a fresh 512bps filesystem, and an extra partition
table entry for Rockbox's benefit, with the start and count multiplied
by four. However, when I try the same technique on my 80G iPod, I
find that the bootloader hangs while trying to read the MBR.

amiconn suggested that I try to debug ATA init somehow, but there
doesn't seem to be much to it. The value of the IDE control register
is 0x20150020 - does that sound right?

ata_device_init() (see firmware/target/arm/ata-pp5020.c) does

    outl(inl(0xc3000028) | (1 << 5), 0xc3000028);
    outl(inl(0xc3000028) & ~0x10000000, 0xc3000028);

but that just writes back the register twice, unchanged, because
neither of the bitwise operations alter any of the register's bits.

This next bit is probably a waste of time if the ATA init is indeed
the problem, but I got a nice tour through the Rockbox code on the
way, so I don't mind.

By adding a bunch of debugging messages, I traced the hang through the
following call chain:

[bootloader] main()
        -> disk_init()
                -> ata_read_sectors() (it's reading the MBR)
                        -> copy_read_sectors
                        status & STATUS_ERR is true
                        -> perform_soft_reset() - which hangs

perform_soft_reset() hangs here:

  static int perform_soft_reset(void)
  {
      int ret;
      int retry_count;

      SET_REG(ATA_SELECT, SELECT_LBA | ata_device );
      SET_REG(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST );
      sleep(1); /* >= 5us */ <-- *** HANGS HERE ***

      SET_REG(ATA_CONTROL, CONTROL_nIEN);
      sleep(1); /* >2ms */
      lcd_log("sleep #2 done");

      /* This little sucker can take up to 30 seconds */
      retry_count = 8;
      do
      {
          lcd_log("boing");
          ret = wait_for_rdy();
      } while(!ret && retry_count--);

      /* Massage the return code so it is 0 on success and -1 on failure */
      ret = ret?0:-1;

      return ret;
  }

So that's a bit odd.

I removed all of my LCD-writing calls from ata_read_sectors() on down,
leaving just two: one before and one after that first sleep(1) call,
and that seems to definitely be where it hangs - I see the before
message, and not the after message.

Suggestions for more stuff to try are welcome.

-- 
Paul Collins
Wellington, New Zealand
Dag vijandelijk luchtschip de huismeester is dood
Received on 2006-10-11

Page was last modified "Jan 10 2012" The Rockbox Crew
aaa