Re: [Openocd-development] Good Way to Determine Block Size
On Wednesday 18 November 2009, Dean Glazeski wrote: The thing is that the first time I tried to do this: nand erase 0 0 2048 I got presented with command usage and had no idea why it was failing. I looked into it a bit more and found out what the block size was. For my NAND chip it is 128KB. Now, when I tried again with nand erase 0 0 0x2 It failed in the same way. Looking at how the NAND struct was used, the erase block size is defined as 0. There is a check in the nand erase command handler that checks for length % nand-erase_size != 0 and this fails for my chip when I specify length. I thought that was filled in via nand probe. Did you probe? Or did probing not collect that data? I certainly see code in the probe routine to fill in erase_size... You're not allowed to acess any kind of flash chip before it's been probed. Normally, a reset-init event handler probes. The issue is that the erase block size is wrong and this could be retrieved from the Samsung NAND chip. I'm wondering if it would be good to parse this field out when probed or to just set the value in the device_id array as opposed to leaving it as 0. Long story short, nand probe works. I'm just not sure if specifying 128k erase blocks for all 512MiB, 8-bit NAND chips is correct. I'm still not following. If it works, what's the issue?? This leads me to another question. Should there be more descriptive error output? It's sort of confusing to get presented with the command syntax when the syntax is correct, but the underlying command handler errors over an invalid parameter value. Sounds like some bad diagnostics, on the order of you didn't probe this yet. - Dave // Dean Glazeski On Thu, Nov 19, 2009 at 1:04 AM, David Brownell davi...@pacbell.net wrote: On Wednesday 18 November 2009, Dean Glazeski wrote: Hi all, Is there a good way for me to determine the erase block size for a NAND chip? Right now, the device ID array in nand.c has 0 as the erase block size for my NAND device. I believe this should be 128k. Is this not always the case for 512MiB, 8-bit NAND devices? Is this just a case of no one has filled in the table? I know my Samsung chip gives out additional data bytes in addition to manufacturer and device ID that specify block and page sizes. Can this be leveraged to dynamically populate the NAND devices? I'm not following. Not that I've done this with very many NAND chips ... but nand probe bank# has so far been good at finding out block sizes. Including 1GiB parts filled out like the 512Mib ones... Are you saying that nand probe fails for your chip? Or just wondering if the table should be filled in differently? ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] OOCD V0.x.y doesn't work with STM32 low density devices?
Hi, I've tried alot to bring up my board with the OOCD and Olimex JTAG, but it doesn't work. Can somebody explane the problem and help me to solve it? I installed the OOCD in it works with the Olimex Dev-Board STM32-P103. It also works on my board with an medium density chip but on my new one it doesn't work I got follow messages: Open On-Chip Debugger 0.3.1 (2009-11-13-16:13) $URL$ For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html 10 kHz jtag_nsrst_delay: 1000 jtag_ntrst_delay: 1000 trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain force hard breakpoints Info : clock speed 10 kHz Info : JTAG tap: stm32.cpu tap/device found: 0x9de00477 (mfg: 0x23b, part: 0xde00, ver: 0x9) Warn : JTAG tap: stm32.cpu UNEXPECTED: 0x9de00477 (mfg: 0x23b, part: 0xde00, ver: 0x9) Error: JTAG tap: stm32.cpu expected 1 of 1: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3) Warn : TAP stm32.bs does not have IDCODE Warn : JTAG tap: stm32.bs UNEXPECTED: 0x (mfg: 0x000, part: 0x, ver: 0x0) Error: JTAG tap: stm32.bs expected 1 of 5: 0x06412041 (mfg: 0x020, part: 0x6412, ver: 0x0) Error: JTAG tap: stm32.bs expected 2 of 5: 0x06410041 (mfg: 0x020, part: 0x6410, ver: 0x0) Error: JTAG tap: stm32.bs expected 3 of 5: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1) Error: JTAG tap: stm32.bs expected 4 of 5: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0) Error: JTAG tap: stm32.bs expected 5 of 5: 0x06418041 (mfg: 0x020, part: 0x6418, ver: 0x0) Warn : Unexpected idcode after end of chain: 33 0xe2d04010 Warn : Unexpected idcode after end of chain: 65 0xc01f Warn : Unexpected idcode after end of chain: 97 0x803f Warn : Unexpected idcode after end of chain: 129 0xc03f Warn : Unexpected idcode after end of chain: 161 0x803f Warn : Unexpected idcode after end of chain: 193 0x807f Warn : Unexpected idcode after end of chain: 225 0xc03f Warn : Unexpected idcode after end of chain: 257 0x803f Warn : Unexpected idcode after end of chain: 289 0x807f Warn : Unexpected idcode after end of chain: 321 0x807f Warn : Unexpected idcode after end of chain: 353 0xc03f Warn : Unexpected idcode after end of chain: 385 0x803f Warn : Unexpected idcode after end of chain: 417 0x807f Warn : Unexpected idcode after end of chain: 449 0xc03f Warn : Unexpected idcode after end of chain: 481 0x803f Warn : Unexpected idcode after end of chain: 513 0xc03f Warn : Unexpected idcode after end of chain: 545 0xc01f Warn : Unexpected idcode after end of chain: 577 0x803f Error: double-check your JTAG setup (interface, speed, missing TAPs, ...) Info : JTAG tap: stm32.cpu tap/device found: 0x9de00477 (mfg: 0x23b, part: 0xde00, ver: 0x9) Warn : JTAG tap: stm32.cpu UNEXPECTED: 0x9de00477 (mfg: 0x23b, part: 0xde00, ver: 0x9) Error: JTAG tap: stm32.cpu expected 1 of 1: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3) Warn : TAP stm32.bs does not have IDCODE Warn : JTAG tap: stm32.bs UNEXPECTED: 0x (mfg: 0x000, part: 0x, ver: 0x0) Error: JTAG tap: stm32.bs expected 1 of 5: 0x06412041 (mfg: 0x020, part: 0x6412, ver: 0x0) Error: JTAG tap: stm32.bs expected 2 of 5: 0x06410041 (mfg: 0x020, part: 0x6410, ver: 0x0) Error: JTAG tap: stm32.bs expected 3 of 5: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1) Error: JTAG tap: stm32.bs expected 4 of 5: 0x06414041 (mfg: 0x020, part: 0x6414, ver: 0x0) Error: JTAG tap: stm32.bs expected 5 of 5: 0x06418041 (mfg: 0x020, part: 0x6418, ver: 0x0) Warn : Unexpected idcode after end of chain: 33 0xf9642008 Warn : Unexpected idcode after end of chain: 65 0xe007 Warn : Unexpected idcode after end of chain: 97 0x801f Warn : Unexpected idcode after end of chain: 129 0xc03f Warn : Unexpected idcode after end of chain: 161 0x803f Warn : Unexpected idcode after end of chain: 193 0x807f Warn : Unexpected idcode after end of chain: 225 0xc03f Warn : Unexpected idcode after end of chain: 257 0x803f Warn : Unexpected idcode after end of chain: 289 0xc03f Warn : Unexpected idcode after end of chain: 321 0x803f Warn : Unexpected idcode after end of chain: 353 0x807f Warn : Unexpected idcode after end of chain: 385 0x807f Warn : Unexpected idcode after end of chain: 417 0x807f Warn : Unexpected idcode after end of chain: 449 0x807f Warn : Unexpected idcode after end of chain: 481 0x807f Warn : Unexpected idcode after end of chain: 513 0x807f Warn : Unexpected idcode after end of chain: 545 0xc03f Warn : Unexpected idcode after end of chain: 577 0xc01f Error: double-check your JTAG setup (interface, speed, missing TAPs, ...) The hardware should be ok because I've test the connection with the Hitex JTAG and also with Peedi from Ronetix, currently I switch to this tool but it is no way I want to use the OOCD. Cheers, Christian -- GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT! Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
Re: [Openocd-development] NAND File I/O parses wrong argument
On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] Slowly moving from 8 to 32 bit words in jtag_add_xxx API
On Thu, Nov 19, 2009 at 1:03 PM, Øyvind Harboe oyvind.har...@zylin.com wrote: Was this for the list? Yeah it was, that Reply-to-all button seems to be hard to find sometimes. On Thu, Nov 19, 2009 at 12:34 AM, Andreas Fritiofson andreas.fritiof...@gmail.com wrote: On Wed, Nov 18, 2009 at 9:40 AM, Øyvind Harboe oyvind.har...@zylin.com wrote: On Wed, Nov 18, 2009 at 9:38 AM, Laurent Gauch laurent.ga...@amontec.com wrote: I'm pondering how we could gently in a series of non-breaking patches prepare the ground for switching from 8 to 32 bit words in the jtag_add_xxx API. The attached patch gets rid of buf_set_u32() when setting the value of a byte. This achieves two things: the code is less obtuse and it is more evident how we could introduce a new type that is *currently* uint8_t and later on could be increased to uint32_t or wider, for the out_value/in_value bit vectors. Comments? Protests? JTAG serial link itself has a notion of bits and not bytes nor dwords ... I do not understand what is the advantage to work on 32bit buffers instead 8bit buffers for out_value and in_value. Why the code will be less obtuse use 32bit buffer instead 8 bit buffers ? Look at all the buf_set_u32()'s sprinkled around the code. They are essentially unnecessary. The drivers probably wouldn't change. I don't see the point in deciding on a specific width of the storage unit. The JTAG layer (should?) handle bit strings of arbitrary lenghts, so why not abstract away how the bit strings are stored internally? Some time ago someone (David?) suggested we borrow/build on the bitmap facility from Linux. I remember someone had strong opinions against it, don't remember why. I myself think it's a good idea to migrate towards a similar solution rather than switching from one arbitrary, fixed width to another. As a side note, the Linux' bitmap implementation actually uses 'unsigned long' as storage, so if using 32 bits is your design requirement you'll get it on at least some platforms. :) ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch] Cortex-A8: parts of examine() run just once
The examine() method has some conceptual breakage. Cope with it by manually splitting out the run-once parts from the after-each-reset parts ... this gets rid of memory leaks and speeds up resets after the first one. --- This passes in light testing, and it looks like the after-each-reset logic is still prepared to reinit the debug port. But ... please keep an eye out for more subtle problems that might crop up. src/target/cortex_a8.c | 19 +++ 1 file changed, 15 insertions(+), 4 deletions(-) --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -1362,7 +1362,7 @@ static int cortex_a8_handle_target_reque * Cortex-A8 target information and configuration */ -static int cortex_a8_examine(struct target *target) +static int cortex_a8_examine_first(struct target *target) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = cortex_a8-armv7a_common; @@ -1447,10 +1447,21 @@ static int cortex_a8_examine(struct targ LOG_DEBUG(Configured %i hw breakpoint pairs and %i hw watchpoint pairs, cortex_a8-brp_num , cortex_a8-wrp_num); - /* Configure core debug access */ - cortex_a8_init_debug_access(target); - target_set_examined(target); + return ERROR_OK; +} + +static int cortex_a8_examine(struct target *target) +{ + int retval = ERROR_OK; + + /* don't re-probe hardware after each reset */ + if (!target_was_examined(target)) + retval = cortex_a8_examine_first(target); + + /* Configure core debug access */ + if (retval == ERROR_OK) + retval = cortex_a8_init_debug_access(target); return retval; } ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] Slowly moving from 8 to 32 bit words in jtag_add_xxx API
On Wednesday 18 November 2009, Laurent Gauch wrote: I do not understand what is the advantage to work on 32bit buffers instead 8bit buffers for out_value and in_value. For starters, in some contexts it's faster by a factor of more than four ... one instruction moving N bits, not four (and then there are second-order effects too. :) For another thing, it's a clean way to help get rid of warnings like this: arm_jtag.h: In function 'arm7flip32': arm_jtag.h:48: error: cast increases required alignment of target type arm_jtag.h: In function 'arm_le_to_h_u32': arm_jtag.h:54: error: cast increases required alignment of target type ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] Slowly moving from 8 to 32 bit words in jtag_add_xxx API
On Wednesday 18 November 2009, Michael Bruck wrote: I would actually prefer an API that is tightly linked to an independent data structure that that builds up a jtag sequence in the target driver and then executes it. All the commands would then work on building up that structure and in the end it is handed over directly to the jtag interface driver for execution. That presumes there *is* a target. We have SVF and XSVF today, and there can be other tools that work more at the JTAG level. Plus, it's a bit awkward to be coupling address space access (memory read/write) to targets, considering that newer ARMs decouple them (via ADIv5) and so does, ISTR, Nexus. I'm not entirely sure what you mean to describe though. I'd like to see less baroque structures for the JTAG messages, and one part of that is clearly a need for more efficient bit vector handling. Along those lines, $SUBJECT is the wrong model too. When we want to work with 64 bit or 128 bit words -- or even just the 40-bit words common with older ARM stuff -- then we should be able to just pass those down. Thinking 8 or 32 focusses on the wrong stuff ... implementation details, not the concepts that will produce a better interface. The current model does the same but essentially uses a global variable. But presumably due to ownership issues the field data is cloned for that global variable. If the jtag sequence structure is owned by the target this (second) copy operation can be avoided as well. I think I agree with what you're saying there. JTAG layer gets delivered a queue, which it processes and modifies in place (if required). For extra credit: some way to package queues with a bit of intelligence, so they could be downloaded into smarter controllers. Example, the polling loops which run in the background ... or between key steps of high level operations. - Dave ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 1/2] ARM: streamline register init
Combine register names with other per-register data into a single template structure. This saves space, and makes it easier to change how registers get handled (by shrinking the number of places that care about cache indices). --- It happens that the ARM11 register code uses init templates that looks something like this, though obviously it's not integrated with the rest of the ARM support. src/target/armv4_5.c | 148 ++--- 1 file changed, 81 insertions(+), 67 deletions(-) --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -36,26 +36,6 @@ #include register.h -static const char *armv4_5_core_reg_list[] = -{ - r0, r1, r2, r3, r4, r5, r6, r7, - r8, r9, r10, r11, r12, sp_usr, lr_usr, pc, - - r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq, sp_fiq, lr_fiq, - - sp_irq, lr_irq, - - sp_svc, lr_svc, - - sp_abt, lr_abt, - - sp_und, lr_und, - - cpsr, spsr_fiq, spsr_irq, spsr_svc, spsr_abt, spsr_und, - - sp_mon, lr_mon, spsr_mon, -}; - static const uint8_t arm_usr_indices[17] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR, }; @@ -230,58 +210,90 @@ char* armv4_5_state_strings[] = ARM, Thumb, Jazelle, ThumbEE, }; -static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] = -{ - {0, ARMV4_5_MODE_ANY, NULL, NULL}, - {1, ARMV4_5_MODE_ANY, NULL, NULL}, - {2, ARMV4_5_MODE_ANY, NULL, NULL}, - {3, ARMV4_5_MODE_ANY, NULL, NULL}, - {4, ARMV4_5_MODE_ANY, NULL, NULL}, - {5, ARMV4_5_MODE_ANY, NULL, NULL}, - {6, ARMV4_5_MODE_ANY, NULL, NULL}, - {7, ARMV4_5_MODE_ANY, NULL, NULL}, - {8, ARMV4_5_MODE_ANY, NULL, NULL}, - {9, ARMV4_5_MODE_ANY, NULL, NULL}, - {10, ARMV4_5_MODE_ANY, NULL, NULL}, - {11, ARMV4_5_MODE_ANY, NULL, NULL}, - {12, ARMV4_5_MODE_ANY, NULL, NULL}, - {13, ARMV4_5_MODE_USR, NULL, NULL}, - {14, ARMV4_5_MODE_USR, NULL, NULL}, - {15, ARMV4_5_MODE_ANY, NULL, NULL}, +/* Templates for ARM core registers. + * + * NOTE: offsets in this table are coupled to the arm_mode_data + * table above, the armv4_5_core_reg_map array below, and also to + * the ARMV4_5_*PSR* symols. + */ +static const struct { + /* The name is used for e.g. the regs command. */ + const char *name; - {8, ARMV4_5_MODE_FIQ, NULL, NULL}, - {9, ARMV4_5_MODE_FIQ, NULL, NULL}, - {10, ARMV4_5_MODE_FIQ, NULL, NULL}, - {11, ARMV4_5_MODE_FIQ, NULL, NULL}, - {12, ARMV4_5_MODE_FIQ, NULL, NULL}, - {13, ARMV4_5_MODE_FIQ, NULL, NULL}, - {14, ARMV4_5_MODE_FIQ, NULL, NULL}, + /* The {cookie, mode} tuple uniquely identifies one register. +* In a given mode, cookies 0..15 map to registers R0..R15, +* with R13..R15 usually called SP, LR, PC. +* +* MODE_ANY is used as *input* to the mapping, and indicates +* various special cases (sigh) and errors. +* +* Cookie 16 is (currently) confusing, since it indicates +* CPSR -or- SPSR depending on whether 'mode' is MODE_ANY. +* (Exception modes have both CPSR and SPSR registers ...) +*/ + unsigned cookie; + enum armv4_5_mode mode; +} arm_core_regs[] = { + { .name = r0, .cookie = 0, .mode = ARMV4_5_MODE_ANY, }, + { .name = r1, .cookie = 1, .mode = ARMV4_5_MODE_ANY, }, + { .name = r2, .cookie = 2, .mode = ARMV4_5_MODE_ANY, }, + { .name = r3, .cookie = 3, .mode = ARMV4_5_MODE_ANY, }, + { .name = r4, .cookie = 4, .mode = ARMV4_5_MODE_ANY, }, + { .name = r5, .cookie = 5, .mode = ARMV4_5_MODE_ANY, }, + { .name = r6, .cookie = 6, .mode = ARMV4_5_MODE_ANY, }, + { .name = r7, .cookie = 7, .mode = ARMV4_5_MODE_ANY, }, - {13, ARMV4_5_MODE_IRQ, NULL, NULL}, - {14, ARMV4_5_MODE_IRQ, NULL, NULL}, + /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging +* them as MODE_ANY creates special cases. +*/ + { .name = r8, .cookie = 8, .mode = ARMV4_5_MODE_ANY, }, + { .name = r9, .cookie = 9, .mode = ARMV4_5_MODE_ANY, }, + { .name = r10, .cookie = 10, .mode = ARMV4_5_MODE_ANY, }, + { .name = r11, .cookie = 11, .mode = ARMV4_5_MODE_ANY, }, + { .name = r12, .cookie = 12, .mode = ARMV4_5_MODE_ANY, }, - {13, ARMV4_5_MODE_SVC, NULL, NULL}, - {14, ARMV4_5_MODE_SVC, NULL, NULL}, + /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */ + { .name = sp_usr, .cookie = 13, .mode = ARMV4_5_MODE_USR, }, + { .name = lr_usr, .cookie = 14, .mode = ARMV4_5_MODE_USR, }, - {13, ARMV4_5_MODE_ABT, NULL, NULL}, - {14, ARMV4_5_MODE_ABT, NULL, NULL}, + { .name = pc, .cookie = 15, .mode = ARMV4_5_MODE_ANY, }, - {13, ARMV4_5_MODE_UND, NULL, NULL}, - {14, ARMV4_5_MODE_UND, NULL, NULL}, + { .name = r8_fiq, .cookie = 8, .mode = ARMV4_5_MODE_FIQ, }, + { .name = r9_fiq, .cookie =
[Openocd-development] [patch 2/2] ARM: remove per-register malloc
Just pre-allocate memory for the cached register value. Shrinks heap overhead; increases locality-of-reference. --- src/target/armv4_5.c |2 +- src/target/armv4_5.h |1 + 2 files changed, 2 insertions(+), 1 deletion(-) --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -489,7 +489,7 @@ struct reg_cache* armv4_5_build_reg_cach reg_list[i].name = (char *) arm_core_regs[i].name; reg_list[i].size = 32; - reg_list[i].value = calloc(1, 4); + reg_list[i].value = arch_info[i].value; reg_list[i].type = arm_reg_type; reg_list[i].arch_info = arch_info[i]; --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -143,6 +143,7 @@ struct armv4_5_core_reg enum armv4_5_mode mode; struct target *target; struct arm *armv4_5_common; + uint32_t value; }; struct reg_cache* armv4_5_build_reg_cache(struct target *target, ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] OOCD V0.x.y doesn't work with STM32 low density devices?
On Thursday 19 November 2009, Christian Dumhart wrote: I've tried alot to bring up my board with the OOCD and Olimex JTAG, but it doesn't work. Can somebody explane the problem and help me to solve it? My first reaction was that this looks like your JTAG clock is too fast ... since a number of the bit patterns show your values are shifted by a bit or two from what they should be. Once you get the clocking right, it'll work better. How fast are you clocking the STM32? ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] Good Way to Determine Block Size
I think this is just me being stupid. I looked up the nand probe function and it appears to have the correct detection mechanism in place. In fact, I rebuilt after the daily pull from the repo and it seems to be working fine. I must have just mistyped something somewhere along the line. // Dean Glazeski On Thu, Nov 19, 2009 at 2:40 AM, David Brownell davi...@pacbell.net wrote: On Wednesday 18 November 2009, Dean Glazeski wrote: The thing is that the first time I tried to do this: nand erase 0 0 2048 I got presented with command usage and had no idea why it was failing. I looked into it a bit more and found out what the block size was. For my NAND chip it is 128KB. Now, when I tried again with nand erase 0 0 0x2 It failed in the same way. Looking at how the NAND struct was used, the erase block size is defined as 0. There is a check in the nand erase command handler that checks for length % nand-erase_size != 0 and this fails for my chip when I specify length. I thought that was filled in via nand probe. Did you probe? Or did probing not collect that data? I certainly see code in the probe routine to fill in erase_size... You're not allowed to acess any kind of flash chip before it's been probed. Normally, a reset-init event handler probes. The issue is that the erase block size is wrong and this could be retrieved from the Samsung NAND chip. I'm wondering if it would be good to parse this field out when probed or to just set the value in the device_id array as opposed to leaving it as 0. Long story short, nand probe works. I'm just not sure if specifying 128k erase blocks for all 512MiB, 8-bit NAND chips is correct. I'm still not following. If it works, what's the issue?? This leads me to another question. Should there be more descriptive error output? It's sort of confusing to get presented with the command syntax when the syntax is correct, but the underlying command handler errors over an invalid parameter value. Sounds like some bad diagnostics, on the order of you didn't probe this yet. - Dave // Dean Glazeski On Thu, Nov 19, 2009 at 1:04 AM, David Brownell davi...@pacbell.net wrote: On Wednesday 18 November 2009, Dean Glazeski wrote: Hi all, Is there a good way for me to determine the erase block size for a NAND chip? Right now, the device ID array in nand.c has 0 as the erase block size for my NAND device. I believe this should be 128k. Is this not always the case for 512MiB, 8-bit NAND devices? Is this just a case of no one has filled in the table? I know my Samsung chip gives out additional data bytes in addition to manufacturer and device ID that specify block and page sizes. Can this be leveraged to dynamically populate the NAND devices? I'm not following. Not that I've done this with very many NAND chips ... but nand probe bank# has so far been good at finding out block sizes. Including 1GiB parts filled out like the 512Mib ones... Are you saying that nand probe fails for your chip? Or just wondering if the table should be filled in differently? ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] STM32: flash write_image has an alignment issue and flash protect/erase is broken
Hiya, I've found a few issues in OpenOCD and thought that I'd share before hacking a solution together. The following revision is used: commit 8f446fcf676e9cd13cf53d9946f0cae5d29a10ec Date: Thu Nov 19 13:23:49 2009 -0800 When doing flash write_image erase unlock image.bin 0x800 bin on an STM32, the following error is generated: auto erase enabled auto unlock enabled Info : device id = 0x20036410 Info : flash size = 128kbytes Warn : Error: start and end sectors must be on a 4 sector boundary Error: failed setting protection for areas 0 to 21 (-901) So it seems we need write_image to be a bit smarter and do some boundary aligning before doing the unprotect / erase . The way I was thinking to do this is to add a configuration parameter to OpenOCD which tells it to be smart ( or not ) when encountering alignment issues like this one. For example smartalign on and smartalign off. smartalign on will make OpenOCD adjust alignment automatically to be valid. Anyone go a better idea? Also I've noticed that the following two commands have stopped working, at least on STM32: - flash protect 0 0 last off - flash erase_sector 0 0 last OpenOCD just exits and the -d parameter only yields this: User : 208 1276 command.c:608 jim_echo(): ---Removing write protection--- Debug: 210 1279 command.c:64 script_debug(): command - protect Debug: 211 1279 command.c:74 script_debug(): protect - argv[0]=ocd_flash_protect Debug: 212 1279 command.c:74 script_debug(): protect - argv[1]=0 Debug: 213 1279 command.c:74 script_debug(): protect - argv[2]=0 Debug: 214 1279 command.c:74 script_debug(): protect - argv[3]=last Debug: 215 1279 command.c:74 script_debug(): protect - argv[4]=off User : 217 1282 command.c:675 openocd_jim_vfprintf(): User : 219 1282 command.c:675 openocd_jim_vfprintf(): User : 221 1282 command.c:675 openocd_jim_vfprintf(): User : 223 1282 command.c:675 openocd_jim_vfprintf(): User : 224 1283 command.c:675 openocd_jim_vfprintf(): User : 227 1283 command.c:675 openocd_jim_vfprintf(): User : 229 1283 command.c:675 openocd_jim_vfprintf(): User : 231 1283 command.c:675 openocd_jim_vfprintf(): User : 233 1283 command.c:675 openocd_jim_vfprintf(): User : 235 1283 command.c:675 openocd_jim_vfprintf(): User : 237 1283 command.c:675 openocd_jim_vfprintf(): make: *** [flash] Error 1 and User : 207 1027 command.c:608 jim_echo(): ---Erasing--- Debug: 209 1029 command.c:64 script_debug(): command - erase_sector Debug: 210 1029 command.c:74 script_debug(): erase_sector - argv[0]=ocd_flash_erase_sector Debug: 211 1029 command.c:74 script_debug(): erase_sector - argv[1]=0 Debug: 212 1029 command.c:74 script_debug(): erase_sector - argv[2]=0 Debug: 213 1029 command.c:74 script_debug(): erase_sector - argv[3]=last User : 215 1032 command.c:675 openocd_jim_vfprintf(): User : 216 1032 command.c:675 openocd_jim_vfprintf(): User : 219 1032 command.c:675 openocd_jim_vfprintf(): User : 221 1032 command.c:675 openocd_jim_vfprintf(): User : 223 1032 command.c:675 openocd_jim_vfprintf(): User : 225 1032 command.c:675 openocd_jim_vfprintf(): User : 227 1032 command.c:675 openocd_jim_vfprintf(): User : 229 1032 command.c:675 openocd_jim_vfprintf(): make: *** [flash] Error 1 OpenOCD apparently exits with an error, but why; I don't know. The mass_erase command, on the other hand, does work as it should. I've yet do dig in to this, but for lack of time, haven't done so yet. Perhaps somebody already knows the answer. If not, I'll try and find the cause some time next week. Cheers, Johnny ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 0/8] unify usb device opening
Hi all, Add jtag/usb_common.[ch] to hold routines shared between the USB JTAG interface drivers. This series adds the first helper, jtag_usb_open that unifies the steps required to probe the USB busses and devices, matching vid/pids, and opening the selected device in the jtag_usb_open helper. All of the driver open routines look much cleaner as a result. This paves the road for more jtag_usb_* helpers and abstraction, which should pave the way for switching to libusb-1.0 when completed. Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 2/8] arm-jtag-ew: use jtag_usb_open
Rewrite armjtagwe_usb_open to use jtag_usb_open. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/arm-jtag-ew.c | 53 +++ 1 files changed, 17 insertions(+), 36 deletions(-) diff --git a/src/jtag/arm-jtag-ew.c b/src/jtag/arm-jtag-ew.c index 18b353a..68fcb34 100644 --- a/src/jtag/arm-jtag-ew.c +++ b/src/jtag/arm-jtag-ew.c @@ -25,6 +25,7 @@ #include interface.h #include commands.h #include usb.h +#include usb_common.h #define USB_VID0x15ba @@ -724,50 +725,30 @@ static int armjtagew_tap_execute(void) static struct armjtagew* armjtagew_usb_open() { - struct usb_bus *busses; - struct usb_bus *bus; - struct usb_device *dev; - - struct armjtagew *result; - - result = (struct armjtagew*) malloc(sizeof(struct armjtagew)); - usb_init(); - usb_find_busses(); - usb_find_devices(); - - busses = usb_get_busses(); - /* find armjtagew device in usb bus */ + const uint16_t vids[] = { USB_VID, 0 }; + const uint16_t pids[] = { USB_PID, 0 }; + struct usb_dev_handle *dev; + if (jtag_usb_open(vids, pids, dev) != ERROR_OK) + return NULL; - for (bus = busses; bus; bus = bus-next) - { - for (dev = bus-devices; dev; dev = dev-next) - { - if ((dev-descriptor.idVendor == USB_VID) (dev-descriptor.idProduct == USB_PID)) - { - result-usb_handle = usb_open(dev); + struct armjtagew *result = malloc(sizeof(struct armjtagew)); + result-usb_handle = dev; #if 0 - /* usb_set_configuration required under win32 */ - usb_set_configuration(result-usb_handle, dev-config[0].bConfigurationValue); + /* usb_set_configuration required under win32 */ + usb_set_configuration(dev, dev-config[0].bConfigurationValue); #endif - usb_claim_interface(result-usb_handle, 0); - + usb_claim_interface(dev, 0); #if 0 - /* -* This makes problems under Mac OS X. And is not needed -* under Windows. Hopefully this will not break a linux build -*/ - usb_set_altinterface(result-usb_handle, 0); + /* +* This makes problems under Mac OS X. And is not needed +* under Windows. Hopefully this will not break a linux build +*/ + usb_set_altinterface(dev, 0); #endif - return result; - } - } - } - - free(result); - return NULL; + return result; } static void armjtagew_usb_close(struct armjtagew *armjtagew) -- 1.6.4.4 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 3/8] usbprog: use jtag_usb_open
Rewrite usbprob_jtag_open to use jtag_usb_open helper. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/usbprog.c | 43 +-- 1 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/jtag/usbprog.c b/src/jtag/usbprog.c index 10dfe06..d6b45d1 100644 --- a/src/jtag/usbprog.c +++ b/src/jtag/usbprog.c @@ -36,8 +36,7 @@ #include interface.h #include commands.h - -#include usb.h +#include usb_common.h #define VID 0x1781 @@ -404,39 +403,23 @@ struct usb_bus *busses; struct usbprog_jtag* usbprog_jtag_open(void) { - struct usb_bus *bus; - struct usb_device *dev; - - struct usbprog_jtag *tmp; - - tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag)); - usb_set_debug(10); usb_init(); - usb_find_busses(); - usb_find_devices(); - busses = usb_get_busses(); + const uint16_t vids[] = { VID, 0 }; + const uint16_t pids[] = { PID, 0 }; + struct usb_dev_handle *dev; + if (jtag_usb_open(vids, pids, dev) != ERROR_OK) + return NULL; - /* find usbprog_jtag device in usb bus */ + struct usbprog_jtag *tmp = malloc(sizeof(struct usbprog_jtag)); + tmp-usb_handle = dev; - for (bus = busses; bus; bus = bus-next) - { - for (dev = bus-devices; dev; dev = dev-next) - { - /* condition for sucessfully hit (too bad, I only check the vendor id)*/ - if (dev-descriptor.idVendor == VID dev-descriptor.idProduct == PID) - { - tmp-usb_handle = usb_open(dev); - usb_set_configuration(tmp-usb_handle, 1); - usb_claim_interface(tmp-usb_handle, 0); - usb_set_altinterface(tmp-usb_handle, 0); - return tmp; - } - } - } - free(tmp); - return 0; + usb_set_configuration(dev, 1); + usb_claim_interface(dev, 0); + usb_set_altinterface(dev, 0); + + return tmp; } #if 0 -- 1.6.4.4 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 5/8] rlink: eliminate spurious indentation
Rework rlink_init to use less indentation. Best viewed with diff -w. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/rlink/rlink.c | 109 1 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/jtag/rlink/rlink.c b/src/jtag/rlink/rlink.c index c88067c..2cdc70a 100644 --- a/src/jtag/rlink/rlink.c +++ b/src/jtag/rlink/rlink.c @@ -1635,66 +1635,65 @@ int rlink_init(void) for (dev = bus-devices; dev; dev = dev-next) { - if ((dev-descriptor.idVendor == USB_IDVENDOR) (dev-descriptor.idProduct == USB_IDPRODUCT)) + if ((dev-descriptor.idVendor != USB_IDVENDOR) || + (dev-descriptor.idProduct != USB_IDPRODUCT)) { - found = 1; - LOG_DEBUG(Found device on bus.\n); + continue; + } + found = 1; + LOG_DEBUG(Found device on bus.\n); - do - { - if (dev-descriptor.bNumConfigurations 1) - { - LOG_ERROR(Whoops! NumConfigurations is not 1, don't know what to do...\n); - break; - } - if (dev-config-bNumInterfaces 1) - { - LOG_ERROR(Whoops! NumInterfaces is not 1, don't know what to do...\n); - break; - } + if (dev-descriptor.bNumConfigurations 1) + { + LOG_ERROR(Whoops! NumConfigurations is not 1, don't know what to do...\n); + break; + } + if (dev-config-bNumInterfaces 1) + { + LOG_ERROR(Whoops! NumInterfaces is not 1, don't know what to do...\n); + break; + } + + pHDev = usb_open(dev); + if (!pHDev) + { + LOG_ERROR (Failed to open device.\n); + break; + } + LOG_DEBUG(Opened device, pHDev = %p\n,pHDev); + + /* usb_set_configuration required under win32 */ + usb_set_configuration(pHDev, dev-config[0].bConfigurationValue); - pHDev = usb_open(dev); - if (!pHDev) - LOG_ERROR (Failed to open device.\n); - else - { - LOG_DEBUG(Opened device, pHDev = %p\n,pHDev); - - /* usb_set_configuration required under win32 */ - usb_set_configuration(pHDev, dev-config[0].bConfigurationValue); - - retries = 3; - do - { - i = usb_claim_interface(pHDev,0); - if (i) - { - LOG_ERROR(usb_claim_interface: %s, usb_strerror()); + retries = 3; + do + { + i = usb_claim_interface(pHDev,0); + if (i) + { + LOG_ERROR(usb_claim_interface: %s, usb_strerror()); #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - j = usb_detach_kernel_driver_np(pHDev, 0); - if (j) - LOG_ERROR(detach kernel driver: %s, usb_strerror()); + j = usb_detach_kernel_driver_np(pHDev, 0); + if (j) + LOG_ERROR(detach kernel driver: %s, usb_strerror()); #endif - } - else -
[Openocd-development] [PATCH 4/8] vsllink: rewrite to use jtag_usb_open
Rewrite vsllink_usb_open to use jtag_usb_open helper. Eliminates spurious calls to exit(). Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/vsllink.c | 84 ++- 1 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/jtag/vsllink.c b/src/jtag/vsllink.c index 7962249..d28854d 100644 --- a/src/jtag/vsllink.c +++ b/src/jtag/vsllink.c @@ -28,9 +28,7 @@ #include interface.h #include commands.h - -#include usb.h - +#include usb_common.h //#define _VSLLINK_IN_DEBUG_MODE_ @@ -1703,64 +1701,42 @@ static int vsllink_tap_execute_dma(void) static struct vsllink* vsllink_usb_open(void) { - struct usb_bus *busses; - struct usb_bus *bus; - struct usb_device *dev; - int ret; - - struct vsllink *result; - - result = (struct vsllink*) malloc(sizeof(struct vsllink)); - usb_init(); - usb_find_busses(); - usb_find_devices(); - busses = usb_get_busses(); + const uint16_t vids[] = { vsllink_usb_vid, 0 }; + const uint16_t pids[] = { vsllink_usb_pid, 0 }; + struct usb_dev_handle *dev; + if (jtag_usb_open(vids, pids, dev) != ERROR_OK) + return NULL; - /* find vsllink device in usb bus */ - - for (bus = busses; bus; bus = bus-next) + /* usb_set_configuration required under win32 */ + struct usb_device *udev = usb_device(dev); + int ret = usb_set_configuration(dev, udev-config[0].bConfigurationValue); + if (ret != 0) { - for (dev = bus-devices; dev; dev = dev-next) - { - if ((dev-descriptor.idVendor == vsllink_usb_vid) (dev-descriptor.idProduct == vsllink_usb_pid)) - { - result-usb_handle = usb_open(dev); - if (NULL == result-usb_handle) - { - LOG_ERROR(failed to open %04X:%04X, not enough permissions?, vsllink_usb_vid, vsllink_usb_pid); - exit(-1); - } - - /* usb_set_configuration required under win32 */ - ret = usb_set_configuration(result-usb_handle, dev-config[0].bConfigurationValue); - if (ret != 0) - { - LOG_ERROR(fail to set configuration to %d, %d returned, not enough permissions?, dev-config[0].bConfigurationValue, ret); - exit(-1); - } - ret = usb_claim_interface(result-usb_handle, vsllink_usb_interface); - if (ret != 0) - { - LOG_ERROR(fail to claim interface %d, %d returned, vsllink_usb_interface, ret); - exit(-1); - } - + LOG_ERROR(fail to set configuration to %d (error %d). + Not enough permissions for the device?, + udev-config[0].bConfigurationValue, ret); + return NULL; + } + ret = usb_claim_interface(dev, vsllink_usb_interface); + if (ret != 0) + { + LOG_ERROR(fail to claim interface %d, %d returned, + vsllink_usb_interface, ret); + return NULL; + } #if 0 - /* -* This makes problems under Mac OS X. And is not needed -* under Windows. Hopefully this will not break a linux build -*/ - usb_set_altinterface(result-usb_handle, 0); + /* + * This makes problems under Mac OS X. And is not needed + * under Windows. Hopefully this will not break a linux build + */ + usb_set_altinterface(dev, 0); #endif - return result; - } - } - } - free(result); - return NULL; + struct vsllink *result = malloc(sizeof(struct vsllink)); + result-usb_handle = dev; + return result; } static void vsllink_usb_close(struct vsllink *vsllink) -- 1.6.4.4 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 7/8] jlink: remove superfluous indentation
Rewrite logic to remove indentation in jlink_usb_open, in prep for further surgery. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/jlink.c | 107 -- 1 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c index dbbddb8..a69f09e 100644 --- a/src/jtag/jlink.c +++ b/src/jtag/jlink.c @@ -874,78 +874,81 @@ static struct jlink* jlink_usb_open() result-usb_handle = usb_open(dev); - if (result-usb_handle) - { + if (NULL == result-usb_handle) + return NULL; - /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS AREA!!! -* The behavior of libusb is not completely consistent across Windows, Linux, and Mac OS X platforms. The actions taken -* in the following compiler conditionals may not agree with published documentation for libusb, but were found -* to be necessary through trials and tribulations. Even little tweaks can break one or more platforms, so if you do make changes -* test them carefully on all platforms before committing them! -*/ + /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS +* AREA!!! The behavior of libusb is not completely +* consistent across Windows, Linux, and Mac OS X platforms. +* The actions taken in the following compiler conditionals may +* not agree with published documentation for libusb, but were +* found to be necessary through trials and tribulations. Even +* little tweaks can break one or more platforms, so if you do +* make changes test them carefully on all platforms before +* committing them! +*/ #if IS_WIN32 == 0 - usb_reset(result-usb_handle); + usb_reset(result-usb_handle); #if IS_DARWIN == 0 - int timeout = 5; + int timeout = 5; - /* reopen jlink after usb_reset -* on win32 this may take a second or two to re-enumerate */ - while ((dev = find_jlink_device()) == NULL) - { - usleep(1000); - timeout--; - if (!timeout) { - break; - } + /* reopen jlink after usb_reset +* on win32 this may take a second or two to re-enumerate */ + while ((dev = find_jlink_device()) == NULL) + { + usleep(1000); + timeout--; + if (!timeout) { + break; } + } - if (dev == NULL) - { - free(result); - return NULL; - } + if (dev == NULL) + { + free(result); + return NULL; + } - result-usb_handle = usb_open(dev); + result-usb_handle = usb_open(dev); #endif #endif - if (result-usb_handle) - { - /* usb_set_configuration required under win32 */ - usb_set_configuration(result-usb_handle, dev-config[0].bConfigurationValue); - usb_claim_interface(result-usb_handle, 0); + if (NULL == result-usb_handle) + { + free(result); + return NULL; + } + + /* usb_set_configuration required under win32 */ + usb_set_configuration(result-usb_handle, dev-config[0].bConfigurationValue); + usb_claim_interface(result-usb_handle, 0); #if 0 - /* -* This makes problems under Mac OS X. And is not needed -* under Windows. Hopefully this will not break a linux build -*/ - usb_set_altinterface(result-usb_handle, 0); + /* +* This makes problems under Mac OS X. And is not needed +* under Windows. Hopefully this will not break a linux build +*/ + usb_set_altinterface(result-usb_handle, 0); #endif - struct usb_interface *iface = dev-config-interface; - struct usb_interface_descriptor *desc = iface-altsetting; - for (int i = 0; i desc-bNumEndpoints; i++) - { - uint8_t epnum = desc-endpoint[i].bEndpointAddress; - bool is_input = epnum 0x80; - LOG_DEBUG(usb ep %s %02x, is_input ? in : out, epnum); - if (is_input) - jlink_read_ep = epnum; - else - jlink_write_ep = epnum; - } - - return result; - } + struct
[Openocd-development] [PATCH 8/8] jlink: rewrite to use jtag_usb_open
Rewrite jlink_usb_open to use jtag_usb_open helper. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/jlink.c | 76 ++--- 1 files changed, 15 insertions(+), 61 deletions(-) diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c index a69f09e..cf3f251 100644 --- a/src/jtag/jlink.c +++ b/src/jtag/jlink.c @@ -27,8 +27,7 @@ #include interface.h #include commands.h - -#include usb.h +#include usb_common.h #define VID 0x1366 @@ -828,53 +827,17 @@ static int jlink_tap_execute(void) return ERROR_OK; } -static struct usb_device* find_jlink_device(void) -{ - struct usb_bus *busses; - struct usb_bus *bus; - struct usb_device *dev; - - usb_find_busses(); - usb_find_devices(); - - busses = usb_get_busses(); - - /* find jlink device in usb bus */ - - for (bus = busses; bus; bus = bus-next) - { - for (dev = bus-devices; dev; dev = dev-next) - { - if ((dev-descriptor.idVendor == VID) (dev-descriptor.idProduct == PID)) { - return dev; - } - } - } - - return NULL; -} - /*/ /* JLink USB low-level functions */ static struct jlink* jlink_usb_open() { - struct usb_device *dev; - - struct jlink *result; - - result = (struct jlink*) malloc(sizeof(struct jlink)); - usb_init(); - if ((dev = find_jlink_device()) == NULL) { - free(result); - return NULL; - } - - result-usb_handle = usb_open(dev); - - if (NULL == result-usb_handle) + const uint16_t vids[] = { VID, 0 }; + const uint16_t pids[] = { PID, 0 }; + struct usb_dev_handle *dev; + if (jtag_usb_open(vids, pids, dev) != ERROR_OK) return NULL; /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS @@ -890,15 +853,15 @@ static struct jlink* jlink_usb_open() #if IS_WIN32 == 0 - usb_reset(result-usb_handle); + usb_reset(dev); #if IS_DARWIN == 0 int timeout = 5; - /* reopen jlink after usb_reset * on win32 this may take a second or two to re-enumerate */ - while ((dev = find_jlink_device()) == NULL) + int retval; + while ((retval = jtag_usb_open(vids, pids, dev)) != ERROR_OK) { usleep(1000); timeout--; @@ -906,27 +869,16 @@ static struct jlink* jlink_usb_open() break; } } - - if (dev == NULL) - { - free(result); + if (ERROR_OK != retval) return NULL; - } - - result-usb_handle = usb_open(dev); #endif #endif - if (NULL == result-usb_handle) - { - free(result); - return NULL; - } - /* usb_set_configuration required under win32 */ - usb_set_configuration(result-usb_handle, dev-config[0].bConfigurationValue); - usb_claim_interface(result-usb_handle, 0); + struct usb_device *udev = usb_device(dev); + usb_set_configuration(dev, udev-config[0].bConfigurationValue); + usb_claim_interface(dev, 0); #if 0 /* @@ -935,7 +887,7 @@ static struct jlink* jlink_usb_open() */ usb_set_altinterface(result-usb_handle, 0); #endif - struct usb_interface *iface = dev-config-interface; + struct usb_interface *iface = udev-config-interface; struct usb_interface_descriptor *desc = iface-altsetting; for (int i = 0; i desc-bNumEndpoints; i++) { @@ -948,6 +900,8 @@ static struct jlink* jlink_usb_open() jlink_write_ep = epnum; } + struct jlink *result = malloc(sizeof(struct jlink)); + result-usb_handle = dev; return result; } -- 1.6.4.4 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 6/8] rlink: use jtag_usb_open helper
Rewrite rlink_init routine to use jtag_usb_open helper. Eliminates some spurious calls to exit(). Wraps a tremendously long line of comment to fit 80 columns too. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/jtag/rlink/rlink.c | 131 ++-- 1 files changed, 49 insertions(+), 82 deletions(-) diff --git a/src/jtag/rlink/rlink.c b/src/jtag/rlink/rlink.c index 2cdc70a..6fb721d 100644 --- a/src/jtag/rlink/rlink.c +++ b/src/jtag/rlink/rlink.c @@ -34,9 +34,7 @@ #include st7.h #include ep1_cmd.h #include dtc_cmd.h - -/* system includes */ -#include usb.h +#include usb_common.h /* This feature is made useless by running the DTC all the time. When automatic, the LED is on whenever the DTC is running. Otherwise, USB messages are sent to turn it on and off. */ @@ -1616,103 +1614,72 @@ int rlink_register_commands(struct command_context *cmd_ctx) static int rlink_init(void) { - struct usb_bus *busses; - struct usb_bus *bus; int i, j, retries; - int found = 0; - int success = 0; uint8_t reply_buffer[USB_EP1IN_SIZE]; usb_init(); - usb_find_busses(); - usb_find_devices(); - - busses = usb_get_busses(); + const uint16_t vids[] = { USB_IDVENDOR, 0 }; + const uint16_t pids[] = { USB_IDPRODUCT, 0 }; + if (jtag_usb_open(vids, pids, pHDev) != ERROR_OK) + return ERROR_FAIL; - for (bus = busses; bus; bus = bus-next) + struct usb_device *dev = usb_device(pHDev); + if (dev-descriptor.bNumConfigurations 1) { - struct usb_device *dev; - - for (dev = bus-devices; dev; dev = dev-next) - { - if ((dev-descriptor.idVendor != USB_IDVENDOR) || - (dev-descriptor.idProduct != USB_IDPRODUCT)) - { - continue; - } - found = 1; - LOG_DEBUG(Found device on bus.\n); - - if (dev-descriptor.bNumConfigurations 1) - { - LOG_ERROR(Whoops! NumConfigurations is not 1, don't know what to do...\n); - break; - } - if (dev-config-bNumInterfaces 1) - { - LOG_ERROR(Whoops! NumInterfaces is not 1, don't know what to do...\n); - break; - } + LOG_ERROR(Whoops! NumConfigurations is not 1, don't know what to do...\n); + return ERROR_FAIL; + } + if (dev-config-bNumInterfaces 1) + { + LOG_ERROR(Whoops! NumInterfaces is not 1, don't know what to do...\n); + return ERROR_FAIL; + } - pHDev = usb_open(dev); - if (!pHDev) - { - LOG_ERROR (Failed to open device.\n); - break; - } - LOG_DEBUG(Opened device, pHDev = %p\n,pHDev); + LOG_DEBUG(Opened device, pHDev = %p\n, pHDev); - /* usb_set_configuration required under win32 */ - usb_set_configuration(pHDev, dev-config[0].bConfigurationValue); + /* usb_set_configuration required under win32 */ + usb_set_configuration(pHDev, dev-config[0].bConfigurationValue); - retries = 3; - do - { - i = usb_claim_interface(pHDev,0); - if (i) - { - LOG_ERROR(usb_claim_interface: %s, usb_strerror()); + retries = 3; + do + { + i = usb_claim_interface(pHDev,0); + if (i) + { + LOG_ERROR(usb_claim_interface: %s, usb_strerror()); #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - j = usb_detach_kernel_driver_np(pHDev, 0); - if (j) - LOG_ERROR(detach kernel driver: %s, usb_strerror()); + j = usb_detach_kernel_driver_np(pHDev, 0); + if (j) + LOG_ERROR(detach kernel driver: %s, usb_strerror()); #endif - } - else - { - LOG_DEBUG(interface claimed!\n); - break; - } - } while (--retries); - - if (!i) - { - if
[Openocd-development] [PATCH 1/8] add jtag/usb_common.[ch] files
Begins to consolidate code used by several USB JTAG interfaces. This first patch provides the required build system changes and a common jtag_usb_open routine, which will replace the guts for probing the busses and devices for possible VID/PID matches. The following patches convert each driver to use it. Signed-off-by: Zachary T Welch z...@superlucidity.net --- configure.in |2 + src/jtag/Makefile.am |7 +- src/jtag/usb_common.c | 61 + src/jtag/usb_common.h | 30 4 files changed, 99 insertions(+), 1 deletions(-) create mode 100644 src/jtag/usb_common.c create mode 100644 src/jtag/usb_common.h diff --git a/configure.in b/configure.in index 8ba8951..81e4326 100644 --- a/configure.in +++ b/configure.in @@ -996,6 +996,7 @@ if test $build_jlink = yes -o $build_vsllink = yes -o $build_usbprog = yes -o \ then AC_CHECK_HEADERS([usb.h],[], [AC_MSG_ERROR([usb.h is required to build some OpenOCD driver(s)])]) + build_usb=yes fi AM_CONDITIONAL(RELEASE, test $build_release = yes) @@ -1021,6 +1022,7 @@ AM_CONDITIONAL(JLINK, test $build_jlink = yes) AM_CONDITIONAL(VSLLINK, test $build_vsllink = yes) AM_CONDITIONAL(RLINK, test $build_rlink = yes) AM_CONDITIONAL(ARMJTAGEW, test $build_armjtagew = yes) +AM_CONDITIONAL(USB, test $build_usb = yes) AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes) AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes) AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes) diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index 85d98c0..5254a2b 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -23,6 +23,10 @@ else # Standard Driver: common files DRIVERFILES += driver.c commands.c +if USB +DRIVERFILES += usb_common.c +endif + if BITBANG DRIVERFILES += bitbang.c endif @@ -92,7 +96,8 @@ noinst_HEADERS = \ rlink/ep1_cmd.h \ rlink/rlink.h \ rlink/st7.h \ - minidummy/jtag_minidriver.h + minidummy/jtag_minidriver.h \ + usb_common.h EXTRA_DIST = startup.tcl diff --git a/src/jtag/usb_common.c b/src/jtag/usb_common.c new file mode 100644 index 000..463f1af --- /dev/null +++ b/src/jtag/usb_common.c @@ -0,0 +1,61 @@ +/*** + * Copyright (C) 2009 by Zachary T Welch z...@superlucidity.net * + * * + * 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***/ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif +#include usb_common.h + + +static bool jtag_usb_match(struct usb_device *dev, + const uint16_t vids[], const uint16_t pids[]) +{ + for (unsigned i = 0; vids[i] pids[i]; i++) + { + if (dev-descriptor.idVendor == vids[i] + dev-descriptor.idProduct == pids[i]) + { + return true; + } + } + return false; +} + +int jtag_usb_open(const uint16_t vids[], const uint16_t pids[], + struct usb_dev_handle **out) +{ + usb_find_busses(); + usb_find_devices(); + + struct usb_bus *busses = usb_get_busses(); + for (struct usb_bus *bus = busses; bus; bus = bus-next) + { + for (struct usb_device *dev = bus-devices; dev; dev = dev-next) + { + if (!jtag_usb_match(dev, vids, pids)) + continue; + + *out = usb_open(dev); + if (NULL == *out) + return -errno; + return 0; + } + } + return -ENODEV; +} diff --git a/src/jtag/usb_common.h b/src/jtag/usb_common.h new file mode 100644 index 000..da395ad --- /dev/null +++ b/src/jtag/usb_common.h @@
Re: [Openocd-development] NAND File I/O parses wrong argument
nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
On Wed, 2009-11-18 at 02:56 -0800, Zachary T Welch wrote: Hi all, This series improves on the patch sent previously to add bank names. It adds a 'name' field to the flash and nand bank structures. This name must be passed as the first argument to the 'flash bank' and 'nand device' commands, so the last two patches update all scripts to add 'set FLASHBANK $_CHIPNAME.flash' and use the improved syntax. I have pushed this series. Anyone with their own script that uses flash or nand bank (most of them!) will notice the breakage. The 'nand device' and 'flash bank' commands now take the desired name as their first argument, which has been updated using the convention above. So, flash bank ... effectively becomes flash bank $_CHIPNAME.flash and similarly for the 'nand device' command. You should now be able to refer to it by this name instead of using its bank number, if you want to update your scripts (or those in the tree). Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] NAND File I/O parses wrong argument
After writing this email, I came across the bug. There are a few ways to fix it and I'll leave it to you to decide. The dev.address needs to be advanced with the file.address in the main verify loop. This might be replaceable by just advancing dev and not file, or moving both, etc. As another note, would it be better to have a for loop iterate through data as opposed to using memcmp? memcmp is faster, but you can provide more information if things are in a for loop. // Dean Glazeski On Thu, Nov 19, 2009 at 4:58 PM, Dean Glazeski dngl...@gmail.com wrote: nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] NAND File I/O parses wrong argument
Thanks for the feedback. I will take a closer look at the code. I am not entirely surprised by this bug in the new function (given the way that I implemented it), but it's great to hear that I didn't cause any other regressions with the existing commands. --Z On Thu, 2009-11-19 at 16:58 -0600, Dean Glazeski wrote: nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] NAND File I/O parses wrong argument
On Thu, 2009-11-19 at 15:08 -0800, Zach Welch wrote: At the moment, I just want correctness. Thanks for doing the detective work, but you're also welcom. Whoops... that one slipped away from me you're also welcome to put together an initial patch for it. Similarly, you are welcome to submit a patch to improve the output, but I think the memcmps are good for the first check. A for-loop (in a static helper function) could then do a slower check to produce good output. -- On Thu, 2009-11-19 at 17:04 -0600, Dean Glazeski wrote: After writing this email, I came across the bug. There are a few ways to fix it and I'll leave it to you to decide. The dev.address needs to be advanced with the file.address in the main verify loop. This might be replaceable by just advancing dev and not file, or moving both, etc. As another note, would it be better to have a for loop iterate through data as opposed to using memcmp? memcmp is faster, but you can provide more information if things are in a for loop. // Dean Glazeski On Thu, Nov 19, 2009 at 4:58 PM, Dean Glazeski dngl...@gmail.com wrote: nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] NAND File I/O parses wrong argument
Here's a patch to fix the increment. I'll mess around with error output later. There are a lot of areas that I would like to visit to update error output. So many errors don't present proper fault output. It makes it hard to trace problems when regressions happen :) I'll spend some time with that once I have the AT91SAM9 NAND working and get a start with the dataflash. // Dean Glazeski On Thu, Nov 19, 2009 at 5:12 PM, Zach Welch z...@superlucidity.net wrote: On Thu, 2009-11-19 at 15:08 -0800, Zach Welch wrote: At the moment, I just want correctness. Thanks for doing the detective work, but you're also welcom. Whoops... that one slipped away from me you're also welcome to put together an initial patch for it. Similarly, you are welcome to submit a patch to improve the output, but I think the memcmps are good for the first check. A for-loop (in a static helper function) could then do a slower check to produce good output. -- On Thu, 2009-11-19 at 17:04 -0600, Dean Glazeski wrote: After writing this email, I came across the bug. There are a few ways to fix it and I'll leave it to you to decide. The dev.address needs to be advanced with the file.address in the main verify loop. This might be replaceable by just advancing dev and not file, or moving both, etc. As another note, would it be better to have a for loop iterate through data as opposed to using memcmp? memcmp is faster, but you can provide more information if things are in a for loop. // Dean Glazeski On Thu, Nov 19, 2009 at 4:58 PM, Dean Glazeski dngl...@gmail.com wrote: nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z From d2eaf8b518512af71660e9593cc84d24479dc3ae Mon Sep 17 00:00:00 2001 From: Dean Glazeski dngl...@gmail.com Date: Thu, 19 Nov 2009 17:12:23 -0600 Subject: [PATCH] NAND verify doesn't advance. Fix to move the device address up as the contents are verified. --- src/flash/nand.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/flash/nand.c b/src/flash/nand.c index ccc3f46..ec46bc4 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -1593,7 +1593,7 @@ COMMAND_HANDLER(handle_nand_verify_command) } file.size -= bytes_read; - file.address += nand-page_size; + dev.address += nand-page_size; } if (nand_fileio_finish(file) == ERROR_OK) -- 1.6.2.5 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] NAND File I/O parses wrong argument
Thanks. I think David and I have both been improving the error handling in places that we touch, but we need a more systematic approach to it. I have been thinking about starting an automated test suite for 0.4.0, as such might have prevented a few of the minor issues that we've seen. Any contributions that you feel like making... send the patches. :) On Thu, 2009-11-19 at 17:15 -0600, Dean Glazeski wrote: Here's a patch to fix the increment. I'll mess around with error output later. There are a lot of areas that I would like to visit to update error output. So many errors don't present proper fault output. It makes it hard to trace problems when regressions happen :) I'll spend some time with that once I have the AT91SAM9 NAND working and get a start with the dataflash. // Dean Glazeski On Thu, Nov 19, 2009 at 5:12 PM, Zach Welch z...@superlucidity.net wrote: On Thu, 2009-11-19 at 15:08 -0800, Zach Welch wrote: At the moment, I just want correctness. Thanks for doing the detective work, but you're also welcom. Whoops... that one slipped away from me you're also welcome to put together an initial patch for it. Similarly, you are welcome to submit a patch to improve the output, but I think the memcmps are good for the first check. A for-loop (in a static helper function) could then do a slower check to produce good output. -- On Thu, 2009-11-19 at 17:04 -0600, Dean Glazeski wrote: After writing this email, I came across the bug. There are a few ways to fix it and I'll leave it to you to decide. The dev.address needs to be advanced with the file.address in the main verify loop. This might be replaceable by just advancing dev and not file, or moving both, etc. As another note, would it be better to have a for loop iterate through data as opposed to using memcmp? memcmp is faster, but you can provide more information if things are in a for loop. // Dean Glazeski On Thu, Nov 19, 2009 at 4:58 PM, Dean Glazeski dngl...@gmail.com wrote: nand verify is not working. I'm trying to trace it to the problem, but it appears there is something wrong with the file struct that's reading the file. Somehow the data read from the file doesn't match the actual data in the file. The odd ball thing is that nand erase, followed by nand write, followed by nand dump produces matching bin files to the original written bin file. It also appears that the file struct is used in the same way in the nand write handler, so I'm a bit confused. I'm going to keep poking until I figure it out or some one posts something here. As another curveball, it reads 0x1B when not verifying oob and 0x05 when I tell it to at location 0. The correct value in the file is 0x1E for that location and the NAND device does return this value when read. // Dean Glazeski On Thu, Nov 19, 2009 at 9:15 AM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 23:25 -0600, Dean Glazeski wrote: Hi all, Recent NAND file I/O changes are parsing the wrong argument for the size. Should be third argument, not second. Pushed. Let me know if you find any other problems. Incidentally, does the 'new verify' command work for you (after this fix)? :) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] OpenOCD bites on OpenRD board :/
i tried several versions of openocd, incl. latest from git. serveral machines (x86 amd64), as well as different usb cables .. I am out of ideas and any hint ist appreciated: sudo ./src/openocd -f /usr/local/share/openocd/scripts/board/openrd.cfg -s /usr/local/share/openocd/scripts/ -c init -c openrd_reflash_uboot the nand probe 0 is always getting an uknown NAND flash device .. if more debug output is neccessary let me know! kind regards, phaidros Open On-Chip Debugger 0.4.0-dev-00465-g9b1f981 (2009-11-19-13:25) For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html 3000 kHz trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain jtag_nsrst_delay: 200 jtag_ntrst_delay: 200 dcc downloads are enabled Warn : use 'feroceon.cpu' as target identifier, not '0' Info : clock speed 3000 kHz Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2) Info : Embedded ICE version 0 target state: halted target halted in ARM state due to debug-request, current mode: Undefined cpsr: 0x209b pc: 0xec6c MMU: disabled, D-Cache: disabled, I-Cache: disabled 0 0 1 0: 00052078 Error: unknown NAND flash device found, manufacturer id: 0x00 device id: 0x00 probing failed for NAND flash device Floating point exception signature.asc Description: This is a digitally signed message part ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
This series seems to make command.c spew errors about invalid command argument. I traced it back to the parse##type macro or whatver that is that is called from flash/common.c in the get_flash_name_index function that is called from pretty much every nand * command. For my NAND devices, they don't have an integer after the '.'. I'm not really sure why this is there or how to fix it. // Dean Glazeski On Thu, Nov 19, 2009 at 5:00 PM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 02:56 -0800, Zachary T Welch wrote: Hi all, This series improves on the patch sent previously to add bank names. It adds a 'name' field to the flash and nand bank structures. This name must be passed as the first argument to the 'flash bank' and 'nand device' commands, so the last two patches update all scripts to add 'set FLASHBANK $_CHIPNAME.flash' and use the improved syntax. I have pushed this series. Anyone with their own script that uses flash or nand bank (most of them!) will notice the breakage. The 'nand device' and 'flash bank' commands now take the desired name as their first argument, which has been updated using the convention above. So, flash bank ... effectively becomes flash bank $_CHIPNAME.flash and similarly for the 'nand device' command. You should now be able to refer to it by this name instead of using its bank number, if you want to update your scripts (or those in the tree). Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] OpenOCD bites on OpenRD board :/
By '-c init' did you mean '-c openrd_init'? // Dean Glazeski On Thu, Nov 19, 2009 at 5:28 PM, :k klos...@subsignal.org wrote: i tried several versions of openocd, incl. latest from git. serveral machines (x86 amd64), as well as different usb cables .. I am out of ideas and any hint ist appreciated: sudo ./src/openocd -f /usr/local/share/openocd/scripts/board/openrd.cfg -s /usr/local/share/openocd/scripts/ -c init -c openrd_reflash_uboot the nand probe 0 is always getting an uknown NAND flash device .. if more debug output is neccessary let me know! kind regards, phaidros Open On-Chip Debugger 0.4.0-dev-00465-g9b1f981 (2009-11-19-13:25) For bug reports, read http://openocd.berlios.de/doc/doxygen/bugs.html 3000 kHz trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain jtag_nsrst_delay: 200 jtag_ntrst_delay: 200 dcc downloads are enabled Warn : use 'feroceon.cpu' as target identifier, not '0' Info : clock speed 3000 kHz Info : JTAG tap: feroceon.cpu tap/device found: 0x20a023d3 (mfg: 0x1e9, part: 0x0a02, ver: 0x2) Info : Embedded ICE version 0 target state: halted target halted in ARM state due to debug-request, current mode: Undefined cpsr: 0x209b pc: 0xec6c MMU: disabled, D-Cache: disabled, I-Cache: disabled 0 0 1 0: 00052078 Error: unknown NAND flash device found, manufacturer id: 0x00 device id: 0x00 probing failed for NAND flash device Floating point exception ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
Another whoops. The changes to use '$_CHIPNAME.flash' were added after I wrote that code, and I didn't consider the consequences thoroughly. The attached patch should fix the issue. Let me know, and I'll push it. --Z On Thu, 2009-11-19 at 18:01 -0600, Dean Glazeski wrote: This series seems to make command.c spew errors about invalid command argument. I traced it back to the parse##type macro or whatver that is that is called from flash/common.c in the get_flash_name_index function that is called from pretty much every nand * command. For my NAND devices, they don't have an integer after the '.'. I'm not really sure why this is there or how to fix it. // Dean Glazeski On Thu, Nov 19, 2009 at 5:00 PM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 02:56 -0800, Zachary T Welch wrote: Hi all, This series improves on the patch sent previously to add bank names. It adds a 'name' field to the flash and nand bank structures. This name must be passed as the first argument to the 'flash bank' and 'nand device' commands, so the last two patches update all scripts to add 'set FLASHBANK $_CHIPNAME.flash' and use the improved syntax. I have pushed this series. Anyone with their own script that uses flash or nand bank (most of them!) will notice the breakage. The 'nand device' and 'flash bank' commands now take the desired name as their first argument, which has been updated using the convention above. So, flash bank ... effectively becomes flash bank $_CHIPNAME.flash and similarly for the 'nand device' command. You should now be able to refer to it by this name instead of using its bank number, if you want to update your scripts (or those in the tree). Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development From 360c25cf190cbd832028ddf42d4667b924b9efc7 Mon Sep 17 00:00:00 2001 From: Zachary T Welch z...@superlucidity.net Date: Thu, 19 Nov 2009 18:11:30 -0800 Subject: [PATCH] fix flash/nand name parsing Start driver.num check from end, and make sure the numeric part is actually a number. Fix problems trying to parse bank names. Signed-off-by: Zachary T Welch z...@superlucidity.net --- src/flash/common.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/src/flash/common.c b/src/flash/common.c index 253ed9d..072e691 100644 --- a/src/flash/common.c +++ b/src/flash/common.c @@ -25,9 +25,11 @@ unsigned get_flash_name_index(const char *name) { - const char *index = strchr(name, '.'); + const char *index = strrchr(name, '.'); if (NULL == index) return 0; + if (index[1] '0' || index[1] '9') + return ~0U; unsigned requested; int retval = parse_uint(index + 1, requested); // detect parsing error by forcing past end of bank list -- 1.6.4.4 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
Why is there even a number appended? Just let whoever defines the name define it however they want, and insist only that it be unique. That will get rid of lots of possible errors inthe code... ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
On Thu, 2009-11-19 at 19:47 -0700, David Brownell wrote: Why is there even a number appended? Just let whoever defines the name define it however they want, and insist only that it be unique. That will get rid of lots of possible errors inthe code... Well, the code in question supports '{driver/controller}_name[.num]' style names (which I added in my original patch). Arbitrary names (such as 'foo.flash') came after I added the required member to the bank/device structures, and I thought to myself: hey, look -- it will be easy to support both styles. It remains to be seen if I was right, or whether it's worth having both. --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 2/3] Cortex-A8: mode support
We *should* be able to read and write registers in any core mode, instead of being stuck with whatever mode the core was when we entered debug state. This patch makes them work. Note that the current restore_context() only handles the current mode; writing to other-mode registers is a NOP without a followup patch fixing that. Also, that SPSR access needed some bugfixes; it was confused with CPSR. Secure monitor mode also seems dubious; there's probably more to be done before that's sufficiently understood by the debugger. --- src/target/cortex_a8.c | 144 +-- 1 file changed, 115 insertions(+), 29 deletions(-) --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -237,7 +237,7 @@ static int cortex_a8_dap_read_coreregist struct armv7a_common *armv7a = target_to_armv7a(target); struct swjdp_common *swjdp = armv7a-swjdp_info; - if (reg 16) + if (reg 17) return retval; if (reg 15) @@ -251,10 +251,12 @@ static int cortex_a8_dap_read_coreregist cortex_a8_exec_opcode(target, 0xE1AF); cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0)); } - else if (reg == 16) + else { - /* MRS r0, CPSR; then move r0 to DCCTX */ - cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, 0)); + /* MRS r0, CPSR or MRS r0, SPSR +* then move r0 to DCCTX +*/ + cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg 1)); cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0)); } @@ -268,11 +270,13 @@ static int cortex_a8_dap_read_coreregist retval = mem_ap_read_atomic_u32(swjdp, armv7a-debug_base + CPUDBG_DTRTX, value); + LOG_DEBUG(read DCC 0x%08 PRIx32, *value); return retval; } -static int cortex_a8_dap_write_coreregister_u32(struct target *target, uint32_t value, int regnum) +static int cortex_a8_dap_write_coreregister_u32(struct target *target, + uint32_t value, int regnum) { int retval = ERROR_OK; uint8_t Rd = regnum0xFF; @@ -292,29 +296,39 @@ static int cortex_a8_dap_write_coreregis cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0)); } - if (Rd 16) + if (Rd 17) return retval; /* Write to DCCRX */ + LOG_DEBUG(write DCC 0x%08 PRIx32, value); retval = mem_ap_write_u32(swjdp, armv7a-debug_base + CPUDBG_DTRRX, value); if (Rd 15) { - /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */ + /* DCCRX to Rn, MCR p14, 0, Rn, c0, c5, 0, 0xEE00nE15 */ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0)); } else if (Rd == 15) { + /* DCCRX to R0, MCR p14, 0, R0, c0, c5, 0, 0xEE000E15 +* then mov r15, r0 +*/ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0)); cortex_a8_exec_opcode(target, 0xE1A0F000); } - else if (Rd == 16) + else { + /* DCCRX to R0, MCR p14, 0, R0, c0, c5, 0, 0xEE000E15 +* then MSR CPSR_cxsf, r0 or MSR SPSR_cxsf, r0 (all fields) +*/ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0)); - cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, 0)); - /* Execute a PrefetchFlush instruction through the ITR. */ - cortex_a8_exec_opcode(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 4)); + cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd 1)); + + /* Prefetch flush after modifying execution status in CPSR */ + if (Rd == 16) + cortex_a8_exec_opcode(target, + ARMV4_5_MCR(15, 0, 0, 7, 5, 4)); } return retval; @@ -950,28 +964,64 @@ static int cortex_a8_store_core_reg_u32( #endif +static int cortex_a8_write_core_reg(struct target *target, int num, + enum armv4_5_mode mode, uint32_t value); + static int cortex_a8_read_core_reg(struct target *target, int num, enum armv4_5_mode mode) { uint32_t value; int retval; struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target); + struct reg_cache *cache = armv4_5-core_cache; + uint32_t cpsr = 0; + unsigned cookie = num; - /* FIXME cortex may not be in mode ... */ + /* avoid some needless mode changes +* FIXME move some of these to shared ARM code... +*/ + if (mode != armv4_5-core_mode) { + if ((armv4_5-core_mode == ARMV4_5_MODE_SYS) +(mode == ARMV4_5_MODE_USR)) + mode = ARMV4_5_MODE_ANY; +
[Openocd-development] [patch 1/3] target: create/use register_cache_invalidate()
Create a generic register_cache_invalidate(), and use it to replace three all-but-identical core-specific routines: - armv4_5_invalidate_core_regs() - armv7m_invalidate_core_regs - mips32_invalidate_core_regs() too. Make cache-num_regs be unsigned, avoiding various errors. Net code shrink and simplification. --- src/target/arm7_9_common.c | 11 --- src/target/armv4_5.c | 16 src/target/armv4_5.h |2 -- src/target/armv7m.c| 15 --- src/target/cortex_a8.c |5 +++-- src/target/cortex_m3.c | 11 ++- src/target/etm.c |2 +- src/target/mips32.c| 15 --- src/target/mips32.h|1 - src/target/mips_m4k.c |6 +++--- src/target/register.c | 22 +- src/target/register.h |3 ++- src/target/target.c|8 src/target/xscale.c|7 +++ 14 files changed, 47 insertions(+), 77 deletions(-) --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -1040,7 +1040,7 @@ int arm7_9_assert_reset(struct target *t target-state = TARGET_RESET; jtag_add_sleep(5); - armv4_5_invalidate_core_regs(target); + register_cache_invalidate(arm7_9-armv4_5_common.core_cache); if ((target-reset_halt) ((jtag_reset_config RESET_SRST_PULLS_TRST) == 0)) { @@ -1224,10 +1224,7 @@ int arm7_9_soft_reset_halt(struct target } /* all register content is now invalid */ - if ((retval = armv4_5_invalidate_core_regs(target)) != ERROR_OK) - { - return retval; - } + register_cache_invalidate(armv4_5-core_cache); /* SVC, ARM state, IRQ and FIQ disabled */ buf_set_u32(armv4_5-core_cache-reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3); @@ -1921,7 +1918,7 @@ int arm7_9_resume(struct target *target, if (!debug_execution) { /* registers are now invalid */ - armv4_5_invalidate_core_regs(target); + register_cache_invalidate(armv4_5-core_cache); target-state = TARGET_RUNNING; if ((retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED)) != ERROR_OK) { @@ -2064,7 +2061,7 @@ int arm7_9_step(struct target *target, i arm7_9-disable_single_step(target); /* registers are now invalid */ - armv4_5_invalidate_core_regs(target); + register_cache_invalidate(armv4_5-core_cache); if (err != ERROR_OK) { --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -436,22 +436,6 @@ static const struct reg_arch_type arm_re .set = armv4_5_set_core_reg, }; -/** Marks the contents of the register cache as invalid (and clean). */ -int armv4_5_invalidate_core_regs(struct target *target) -{ - struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target); - unsigned num_regs = armv4_5-core_cache-num_regs; - struct reg *reg = armv4_5-core_cache-reg_list; - - for (unsigned i = 0; i num_regs; i++, reg++) { - reg-valid = 0; - reg-dirty = 0; - } - - /* FIXME don't bother returning a value then */ - return ERROR_OK; -} - struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common) { int num_regs = ARRAY_SIZE(arm_core_regs); --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -162,8 +162,6 @@ int armv4_5_run_algorithm(struct target uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info); -int armv4_5_invalidate_core_regs(struct target *target); - int arm_checksum_memory(struct target *target, uint32_t address, uint32_t count, uint32_t *checksum); int arm_blank_check_memory(struct target *target, --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -246,21 +246,6 @@ static int armv7m_write_core_reg(struct return ERROR_OK; } -/** Invalidates cache of core registers set up by armv7m_build_reg_cache(). */ -int armv7m_invalidate_core_regs(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - int i; - - for (i = 0; i armv7m-core_cache-num_regs; i++) - { - armv7m-core_cache-reg_list[i].valid = 0; - armv7m-core_cache-reg_list[i].dirty = 0; - } - - return ERROR_OK; -} - /** * Returns generic ARM userspace registers to GDB. * GDB doesn't quite understand that most ARMs don't have floating point --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -545,7 +545,7 @@ static int cortex_a8_resume(struct targe target-state = TARGET_RUNNING; /* registers are now invalid */ - armv4_5_invalidate_core_regs(target); + register_cache_invalidate(armv4_5-core_cache); if (!debug_execution) { @@ -1182,11 +1182,12 @@ static int
[Openocd-development] [patch 3/3] Cortex-A8: better context restore
The previous version never wrote dirty registers for non-current CPU modes ... fix that. --- And with this ... Cortex-A8 is fairly well supporting all the top level ARM operations, like ARM7 and ARM9 do. There are various performance optimizations that can be made, however. And it'd be nice if the reset logic used the vector catch hardware. :) src/target/cortex_a8.c | 80 +++ 1 file changed, 67 insertions(+), 13 deletions(-) --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -531,7 +531,7 @@ static int cortex_a8_resume(struct targe armv4_5-core_mode, 15).valid = 1; cortex_a8_restore_context(target); -// arm7_9_restore_context(target); TODO Context is currently NOT Properly restored + #if 0 /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) @@ -850,30 +850,84 @@ static int cortex_a8_step(struct target static int cortex_a8_restore_context(struct target *target) { - int i; uint32_t value; struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv4_5_common_s *armv4_5 = armv7a-armv4_5_common; + struct reg_cache *cache = armv7a-armv4_5_common.core_cache; + unsigned max = cache-num_regs; + struct reg *r; + bool flushed, flush_cpsr = false; LOG_DEBUG( ); if (armv7a-pre_restore_context) armv7a-pre_restore_context(target); - for (i = 15; i = 0; i--) - { - if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, - armv4_5-core_mode, i).dirty) - { - value = buf_get_u32(ARMV4_5_CORE_REG_MODE( - armv4_5-core_cache, - armv4_5-core_mode, i).value, - 0, 32); + /* Flush all dirty registers from the cache, one mode at a time so +* that we write CPSR as little as possible. Save CPSR and R0 for +* last; they're used to change modes and write other registers. +* +* REVISIT be smarter: save eventual mode for last loop, don't +* need to write CPSR an extra time. +*/ + do { + enum armv4_5_mode mode = ARMV4_5_MODE_ANY; + unsigned i; + + flushed = false; + + /* write dirty non-{R0,CPSR} registers sharing the same mode */ + for (i = max - 1, r = cache-reg_list + 1; i 0; i--, r++) { + struct armv4_5_core_reg *reg; + + if (!r-dirty || i == ARMV4_5_CPSR) + continue; + reg = r-arch_info; + /* TODO Check return values */ - cortex_a8_dap_write_coreregister_u32(target, value, i); + + /* Pick a mode and update CPSR; else ignore this +* register if it's for a different mode than what +* we're handling on this pass. +* +* REVISIT don't distinguish SYS and USR modes. +* +* FIXME if we restore from FIQ mode, R8..R12 will +* get wrongly flushed onto FIQ shadows... +*/ + if (mode == ARMV4_5_MODE_ANY) { + mode = reg-mode; + if (mode != ARMV4_5_MODE_ANY) { + cortex_a8_dap_write_coreregister_u32( + target, mode, 16); + flush_cpsr = true; + } + } else if (mode != reg-mode) + continue; + + /* Write this register */ + value = buf_get_u32(r-value, 0, 32); + cortex_a8_dap_write_coreregister_u32(target, value, + (reg-num == 16) ? 17 : reg-num); + r-dirty = false; + flushed = true; } + + } while (flushed); + + /* now flush CPSR if needed ... */ + r = cache-reg_list + ARMV4_5_CPSR; + if (flush_cpsr || r-dirty) { + value = buf_get_u32(r-value, 0, 32); + cortex_a8_dap_write_coreregister_u32(target, value, 16); + r-dirty = false; } + /* ... and R0 always (it was dirtied when we saved context) */ + r = cache-reg_list + 0; + value = buf_get_u32(r-value, 0, 32); + cortex_a8_dap_write_coreregister_u32(target, value, 0); + r-dirty = false; + if (armv7a-post_restore_context) armv7a-post_restore_context(target);
[Openocd-development] NEWS updates ...
Don't forget to put NEWS updates in for the user-visible changes you've made, like in the flash layer. Best to do such stuff while it's fresh in your memory! A bullet about improved error handling would make sense too; it might belong in a new generic scripting interface category. - Dave ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 9/8] add flash/nand name support
I can verify that this patch makes the fake errors go away. // Dean Glazeski On Thu, Nov 19, 2009 at 8:16 PM, Zach Welch z...@superlucidity.net wrote: Another whoops. The changes to use '$_CHIPNAME.flash' were added after I wrote that code, and I didn't consider the consequences thoroughly. The attached patch should fix the issue. Let me know, and I'll push it. --Z On Thu, 2009-11-19 at 18:01 -0600, Dean Glazeski wrote: This series seems to make command.c spew errors about invalid command argument. I traced it back to the parse##type macro or whatver that is that is called from flash/common.c in the get_flash_name_index function that is called from pretty much every nand * command. For my NAND devices, they don't have an integer after the '.'. I'm not really sure why this is there or how to fix it. // Dean Glazeski On Thu, Nov 19, 2009 at 5:00 PM, Zach Welch z...@superlucidity.net wrote: On Wed, 2009-11-18 at 02:56 -0800, Zachary T Welch wrote: Hi all, This series improves on the patch sent previously to add bank names. It adds a 'name' field to the flash and nand bank structures. This name must be passed as the first argument to the 'flash bank' and 'nand device' commands, so the last two patches update all scripts to add 'set FLASHBANK $_CHIPNAME.flash' and use the improved syntax. I have pushed this series. Anyone with their own script that uses flash or nand bank (most of them!) will notice the breakage. The 'nand device' and 'flash bank' commands now take the desired name as their first argument, which has been updated using the convention above. So, flash bank ... effectively becomes flash bank $_CHIPNAME.flash and similarly for the 'nand device' command. You should now be able to refer to it by this name instead of using its bank number, if you want to update your scripts (or those in the tree). Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] NAND Page Command Refactoring
Hi all, I found a chunk of code that was used by both the nand_[write|read]_page_raw and I thought it might be helpful to NAND devices that implement the read_page function. In my case, I don't want to copy the work like the davinci driver does :P. Let me know if this is good for committing. // Dean Glazeski From 0512447d983a6bf27db711148e30c3480683b5b0 Mon Sep 17 00:00:00 2001 From: Dean Glazeski dngl...@gmail.com Date: Fri, 20 Nov 2009 00:19:39 -0600 Subject: [PATCH] NAND page command refactoring. Created a new function that handles sending a command and the address information for pages to a NAND device. --- src/flash/nand.c | 91 +++-- src/flash/nand.h |3 ++ 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/flash/nand.c b/src/flash/nand.c index cac26d0..db2f314 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -839,20 +839,19 @@ static int nand_read_page(struct nand_device *nand, uint32_t page, uint8_t *data return nand-controller-read_page(nand, page, data, data_size, oob, oob_size); } -int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) +int nand_page_command(struct nand_device *nand, uint32_t page, uint8_t cmd, bool oob) { - uint32_t i; - if (!nand-device) return ERROR_NAND_DEVICE_NOT_PROBED; - if (nand-page_size = 512) - { + if (oob NAND_CMD_READ0 nand-page_size = 512) { + cmd = NAND_CMD_READOOB; + } + + nand-controller-command(nand, cmd); + + if (nand-page_size = 512) { /* small page device */ - if (data) - nand-controller-command(nand, NAND_CMD_READ0); - else - nand-controller-command(nand, NAND_CMD_READOOB); /* column (always 0, we start at the beginning of a page/OOB area) */ nand-controller-address(nand, 0x0); @@ -868,20 +867,17 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u /* 5th cycle only on devices with more than 8 GiB */ if (nand-address_cycles = 5) nand-controller-address(nand, (page 24) 0xff); - } - else - { + } else { /* large page device */ - nand-controller-command(nand, NAND_CMD_READ0); /* column (0 when we start at the beginning of a page, * or 2048 for the beginning of OOB area) */ nand-controller-address(nand, 0x0); - if (data) - nand-controller-address(nand, 0x0); - else + if (oob) nand-controller-address(nand, 0x8); + else + nand-controller-address(nand, 0x0); /* row */ nand-controller-address(nand, page 0xff); @@ -891,8 +887,10 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u if (nand-address_cycles = 5) nand-controller-address(nand, (page 16) 0xff); - /* large page devices need a start command */ - nand-controller-command(nand, NAND_CMD_READSTART); + if (NAND_CMD_READ0 == cmd) { + /* large page devices need a start command if reading */ + nand-controller-command(nand, NAND_CMD_READSTART); + } } if (nand-controller-nand_ready) { @@ -902,6 +900,20 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u alive_sleep(1); } + return ERROR_OK; +} + +int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) +{ + uint32_t i; + uint8_t command = NAND_CMD_READ0; + int retval; + + retval = nand_page_command(nand, page, command, !data); + if (ERROR_OK != retval) { + return retval; + } + if (data) { if (nand-controller-read_block_data != NULL) @@ -959,46 +971,9 @@ int nand_write_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, int retval; uint8_t status; - if (!nand-device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - nand-controller-command(nand, NAND_CMD_SEQIN); - - if (nand-page_size = 512) - { - /* column (always 0, we start at the beginning of a page/OOB area) */ - nand-controller-address(nand, 0x0); - - /* row */ - nand-controller-address(nand, page 0xff); - nand-controller-address(nand, (page 8) 0xff); - - /* 4th cycle only on devices with more than 32 MiB */ - if (nand-address_cycles = 4) - nand-controller-address(nand, (page 16) 0xff); - - /* 5th cycle only on devices with more than 8 GiB */ - if (nand-address_cycles = 5) - nand-controller-address(nand, (page 24) 0xff); - } - else - { - /* column (0 when we start at the beginning of a page, - * or 2048 for the beginning of OOB area) - */ - nand-controller-address(nand, 0x0); - if (data) - nand-controller-address(nand, 0x0); - else - nand-controller-address(nand, 0x8); - - /* row */ - nand-controller-address(nand, page 0xff); - nand-controller-address(nand, (page 8) 0xff); - - /* 5th cycle only on devices with more than 128 MiB */ - if (nand-address_cycles = 5) - nand-controller-address(nand, (page 16) 0xff); + retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); + if (ERROR_OK != retval) { +