Re: [U-Boot] [PATCH] ftsmc020: enhance for features and asm support.

Hi Wolfgnag
In message 1300965924-20508-1-git-send-email-macpaul@andestech.com you wrote:
- Enhance ftsmc020 according to datasheets.
- Add assembly register offsets for support lowlevel_init.S.
NAK. Such register offsets should be automatically generated from the respective C structs using make-asm-offsets; see the generic-asm-offsets.h / asm-offsets.s build rules in the top level Makefile.
Neither I ran the command
"tools/scripts/make-asm-offsets include/faraday/ftsmc020.h include/faraday/ftsmc020-genasm.h" nor I ran sed -ne "/^->/{s:->#(.*):/* \1 */:; \ s:^->([^ ]*) [$#]*([-0-9]*) (.*):#define \1 (\2) /* \3 */:; \ s:^->([^ ]*) [$#]*([^ ]*) (.*):#define \1 \2 /* \3 */:; \ s:->::; p;}" include/faraday/ftsmc020-genasm.h could be work.
I also tested file faraday/ftpmu010.h. It get the same output with output 'sed: -e expression #1, char 47: unknown command: `['.' Did I execute the script in wrong method? Is there a problem about this script?
Moreover, the structure of ftsmc020 was nested like struct ftsmc020 { struct { unsigned int cr; /* 0x00, 0x08, 0x10, 0x18 */ unsigned int tpr; /* 0x04, 0x0c, 0x14, 0x1c */ } bank[4]; unsigned int pad[8]; /* 0x20 - 0x3c */ unsigned int ssr; /* 0x40 */ };
I didn't see the sed script could support this kind of nested structure declaration. I guess the sed script could be applied to plain structure declareation. Maybe I have a diffcult here. If the script is needed to be rewrote to adapt nested declaration, It might need have some complicaticity about parse difference kind of nested structure and array.
It seems I need to rewrite the structure to be adaptable to the sed script.
Any suggestion?
Best regards, Macpaul Lin
CONFIDENTIALITY NOTICE:
This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.
Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

Dear macpaul@andestech.com,
In message 50FD90C65C53FB45BADEEBCD84FF07F202EC05C3@ATCPCS06.andestech.com you wrote:
Neither I ran the command
"tools/scripts/make-asm-offsets include/faraday/ftsmc020.h include/faraday/ftsmc020-genasm.h" nor I ran sed -ne "/^->/{s:->#(.*):/* \1 */:; \ s:^->([^ ]*) [$#]*([-0-9]*) (.*):#define \1 (\2) /* \3 */:; \ s:^->([^ ]*) [$#]*([^ ]*) (.*):#define \1 \2 /* \3 */:; \ s:->::; p;}" include/faraday/ftsmc020-genasm.h could be work.
I also tested file faraday/ftpmu010.h. It get the same output with output 'sed: -e expression #1, char 47: unknown command: `['.' Did I execute the script in wrong method? Is there a problem about this script?
There is no (known) problem with it, but you have to be careful about the context you are running in - the script as is is supposed to be run in "make" context, which means different $ expansion rules then when you try running directly under a shell.
Moreover, the structure of ftsmc020 was nested like struct ftsmc020 { struct { unsigned int cr; /* 0x00, 0x08, 0x10, 0x18 */ unsigned int tpr; /* 0x04, 0x0c, 0x14, 0x1c */ } bank[4]; unsigned int pad[8]; /* 0x20 - 0x3c */ unsigned int ssr; /* 0x40 */ };
I didn't see the sed script could support this kind of nested structure declaration. I guess the sed script could be applied to plain structure declareation. Maybe I have a diffcult here.
You could simply un-nest the structure declarations.
If the script is needed to be rewrote to adapt nested declaration, It might need have some complicaticity about parse difference kind of nested structure and array.
If I were in your situation I'd probably rather unnest the structs.
It seems I need to rewrite the structure to be adaptable to the sed script.
That seems straightforward to do, indeed.
Best regards,
Wolfgang Denk

Hi Wolfgang,
2011/3/25 Wolfgang Denk wd@denx.de:
Dear macpaul@andestech.com,
There is no (known) problem with it, but you have to be careful about the context you are running in - the script as is is supposed to be run in "make" context, which means different $ expansion rules then when you try running directly under a shell.
I'm not sure if this way I use make-asm-offset is correct.
First I add the OFFSET marco of ftsmc020 into "lib/asm-offsets.c". The file "lib/asm-offsets.c" becomes int main(void) { /* Round up to make sure size gives nice stack alignment */ DEFINE(GENERATED_GBL_DATA_SIZE, (sizeof(struct global_data) + 15) & ~15);
DEFINE(GENERATED_BD_INFO_SIZE, (sizeof(struct bd_info) + 15) & ~15);
OFFSET(FTSMC020_BANK0_CR, ftsmc020, bank[0].cr); OFFSET(FTSMC020_BANK0_TPR, ftsmc020, bank[0].tpr); OFFSET(FTSMC020_BANK1_CR, ftsmc020, bank[1].cr); OFFSET(FTSMC020_BANK1_TPR, ftsmc020, bank[1].tpr); OFFSET(FTSMC020_BANK2_CR, ftsmc020, bank[2].cr); OFFSET(FTSMC020_BANK2_TPR, ftsmc020, bank[2].tpr); OFFSET(FTSMC020_BANK3_CR, ftsmc020, bank[3].cr); OFFSET(FTSMC020_BANK3_TPR, ftsmc020, bank[3].tpr); OFFSET(FTSMC020_PAD0, ftsmc020, pad[0]); OFFSET(FTSMC020_PAD1, ftsmc020, pad[1]); OFFSET(FTSMC020_PAD2, ftsmc020, pad[2]); OFFSET(FTSMC020_PAD3, ftsmc020, pad[3]); OFFSET(FTSMC020_PAD4, ftsmc020, pad[4]); OFFSET(FTSMC020_PAD5, ftsmc020, pad[5]); OFFSET(FTSMC020_PAD6, ftsmc020, pad[6]); OFFSET(FTSMC020_PAD7, ftsmc020, pad[7]); OFFSET(FTSMC020_SSR, ftsmc020, ssr); }
Then I ran make process, the result of make-asm-offset goes into "include/generated/generic-asm-offsets.h" as #define GENERATED_GBL_DATA_SIZE (80) /* (sizeof(struct global_data) + 15) & ~15 */ #define GENERATED_BD_INFO_SIZE (64) /* (sizeof(struct bd_info) + 15) & ~15 */ #define FTSMC020_BANK0_CR (0) /* offsetof(struct ftsmc020, bank[0].cr) */ #define FTSMC020_BANK0_TPR (4) /* offsetof(struct ftsmc020, bank[0].tpr) */ #define FTSMC020_BANK1_CR (8) /* offsetof(struct ftsmc020, bank[1].cr) */ #define FTSMC020_BANK1_TPR (12) /* offsetof(struct ftsmc020, bank[1].tpr) */ #define FTSMC020_BANK2_CR (16) /* offsetof(struct ftsmc020, bank[2].cr) */ #define FTSMC020_BANK2_TPR (20) /* offsetof(struct ftsmc020, bank[2].tpr) */ #define FTSMC020_BANK3_CR (24) /* offsetof(struct ftsmc020, bank[3].cr) */ #define FTSMC020_BANK3_TPR (28) /* offsetof(struct ftsmc020, bank[3].tpr) */ #define FTSMC020_PAD0 (32) /* offsetof(struct ftsmc020, pad[0]) */ #define FTSMC020_PAD1 (36) /* offsetof(struct ftsmc020, pad[1]) */ #define FTSMC020_PAD2 (40) /* offsetof(struct ftsmc020, pad[2]) */ #define FTSMC020_PAD3 (44) /* offsetof(struct ftsmc020, pad[3]) */ #define FTSMC020_PAD4 (48) /* offsetof(struct ftsmc020, pad[4]) */ #define FTSMC020_PAD5 (52) /* offsetof(struct ftsmc020, pad[5]) */ #define FTSMC020_PAD6 (56) /* offsetof(struct ftsmc020, pad[6]) */ #define FTSMC020_PAD7 (60) /* offsetof(struct ftsmc020, pad[7]) */ #define FTSMC020_SSR (64) /* offsetof(struct ftsmc020, ssr) */
However, this looks weird. It doesn't look like the other automated generated code. And, how does the offset address in decimal could be generated in hex? Could I move the generated code into ftsmc020.h?
Moreover, the structure of ftsmc020 was nested like struct ftsmc020 { struct { unsigned int cr; /* 0x00, 0x08, 0x10, 0x18 */ unsigned int tpr; /* 0x04, 0x0c, 0x14, 0x1c */ } bank[4]; unsigned int pad[8]; /* 0x20 - 0x3c */ unsigned int ssr; /* 0x40 */ };
Thanks.

Dear Macpaul Lin,
In message AANLkTikh-0JvLqGm2gk3F70cg3z8=LvT5GgrfQUTuxf0@mail.gmail.com you wrote:
I'm not sure if this way I use make-asm-offset is correct.
First I add the OFFSET marco of ftsmc020 into "lib/asm-offsets.c". The file "lib/asm-offsets.c" becomes
We should probably split architecture and/or board specific additions like these into separate files in the respectice architecture / board directories. Eventually we add make targets for these, then; for now it's probably sufficient to add some #include to lib/asm-offsets.c
Otherwise lib/asm-offsets.c will quickly become an unreadable mess.
Otherwise this looks OK with me.
Then I ran make process, the result of make-asm-offset goes into "include/generated/generic-asm-offsets.h" as
...
#define FTSMC020_BANK2_TPR (20) /* offsetof(struct ftsmc020, bank[2].tpr) *> / #define FTSMC020_BANK3_CR (24) /* offsetof(struct ftsmc020, bank[3].cr) */ #define FTSMC020_BANK3_TPR (28) /* offsetof(struct ftsmc020, bank[3].tpr) *> /
Keep in mind that I dislike this manual unrolling of the nested structs. It may work in your code, but it is ugly and doesn't scale. Also, it does not allow any kind of looping over the entries which might be needed here and there. I strongly recommend to get rid of these nested declarations.
#define FTSMC020_PAD0 (32) /* offsetof(struct ftsmc020, pad[0]) */ #define FTSMC020_PAD1 (36) /* offsetof(struct ftsmc020, pad[1]) */ #define FTSMC020_PAD2 (40) /* offsetof(struct ftsmc020, pad[2]) */ #define FTSMC020_PAD3 (44) /* offsetof(struct ftsmc020, pad[3]) */ #define FTSMC020_PAD4 (48) /* offsetof(struct ftsmc020, pad[4]) */ #define FTSMC020_PAD5 (52) /* offsetof(struct ftsmc020, pad[5]) */ #define FTSMC020_PAD6 (56) /* offsetof(struct ftsmc020, pad[6]) */ #define FTSMC020_PAD7 (60) /* offsetof(struct ftsmc020, pad[7]) */ #define FTSMC020_SSR (64) /* offsetof(struct ftsmc020, ssr) */
However, this looks weird. It doesn't look like the other automated generated code.
What exactly looks weird? And what "other automated generated code" do you mean?
And, how does the offset address in decimal could be generated in hex?
I don't know of a way to do that - it's the cpp + assembler which generates this code, and I am not aware of any ways to ask them for specific formatting or number bases.
Could I move the generated code into ftsmc020.h?
No - what for? This is automatically generated code, that gets used somewhere. No human eye is supposed to have to read it.
Best regards,
Wolfgang Denk

Hi Wolfgang
2011/3/31 Wolfgang Denk wd@denx.de:
Dear Macpaul Lin,
We should probably split architecture and/or board specific additions like these into separate files in the respectice architecture / board directories. Eventually we add make targets for these, then; for now it's probably sufficient to add some #include to lib/asm-offsets.c
Otherwise lib/asm-offsets.c will quickly become an unreadable mess.
Otherwise this looks OK with me.
There are lots of register offset is widely been used both in lowlevel_init and C environment. If we really want assembly offset of these registers is generated from structures, lots of includes files with OFFSET() marco to generate asm-offsets will be required. For example: in "arch/arm/include/asm/arch-at91/at91sam9_smc.h", there exist the similar problem as ftsmc020.
#ifdef __ASSEMBLY__
#ifndef AT91_SMC_BASE #define AT91_SMC_BASE AT91_SMC0_BASE #endif
#define AT91_ASM_SMC_SETUP0 AT91_SMC_BASE #define AT91_ASM_SMC_PULSE0 (AT91_SMC_BASE + 0x04) #define AT91_ASM_SMC_CYCLE0 (AT91_SMC_BASE + 0x08) #define AT91_ASM_SMC_MODE0 (AT91_SMC_BASE + 0x0C)
#else
typedef struct at91_cs { u32 setup; /* 0x00 SMC Setup Register */ u32 pulse; /* 0x04 SMC Pulse Register */ u32 cycle; /* 0x08 SMC Cycle Register */ u32 mode; /* 0x0C SMC Mode Register */ } at91_cs_t;
typedef struct at91_smc { at91_cs_t cs[8]; } at91_smc_t;
#endif /* __ASSEMBLY__ */
Thus we may need to write some code like OFFSET(AT91_ASM_SMC_SETUP0, at91_cs, setup); some where in the included file then generate the code like. #define AT91_ASM_SMC_SETUP0 (0) /* offsetof(struct at91_cs, setup) */
Even like this, we cannot directly use AT91_ASM_SMC_SETUP0 like the code above in lowlevel_init.c. If there is a code wrote as writel(0x1, AT91_ASM_SMC_SETUP0); originally must be rewrote as writel(0x1, AT91_SMC_BASE + AT91_ASM_SMC_SETUP0);
Hence we really need some scalable rework for the both a split arch/board make-asm-offset directories.
I'm not sure if my thought of this scenario correct?
Keep in mind that I dislike this manual unrolling of the nested structs. It may work in your code, but it is ugly and doesn't scale. Also, it does not allow any kind of looping over the entries which might be needed here and there. I strongly recommend to get rid of these nested declarations.
Ok, since the original structure was commit by other people, I'm still trying to rewrite the original C code.
#define FTSMC020_PAD4 (48) /* offsetof(struct ftsmc020, pad[4]) */ #define FTSMC020_PAD5 (52) /* offsetof(struct ftsmc020, pad[5]) */ #define FTSMC020_PAD6 (56) /* offsetof(struct ftsmc020, pad[6]) */ #define FTSMC020_PAD7 (60) /* offsetof(struct ftsmc020, pad[7]) */ #define FTSMC020_SSR (64) /* offsetof(struct ftsmc020, ssr) */
However, this looks weird. It doesn't look like the other automated generated code.
What exactly looks weird? And what "other automated generated code" do you mean?
I meant, should we make a script that could auto generate asm-offset like a translation from struct ftsmc020 { unsigned bank0_cr; unsigned bank0_tpr; ... } into #define FTSMC020_BANK0_CR 0x00; or #define FTSMC020_BANK0_TPR (4);
without manually reworte the structure in the way as OFFSET(FTSMC020_BANK0_CR, ftsmc020, bank0_cr); and create a new specific header file for make-asm-offset?
Could I move the generated code into ftsmc020.h?
No - what for? This is automatically generated code, that gets used somewhere. No human eye is supposed to have to read it.
You are right, the comments of FTSMC020_BANK0_TPR (4) is really bad for human reading. However, when people implementing lowlevel_init or other assembly files, they still need such kind of reference to write *.S files before the asm-offset has been generated by make.
Thanks.

Dear Macpaul Lin,
In message AANLkTi=umWPj8zK+AvL6H8EarhbqSxN2G=8itXXZG6cS@mail.gmail.com you wrote:
There are lots of register offset is widely been used both in lowlevel_init and C environment.
Yes, there is a lot os mess that piled up over the years. It will take time to clean this up.
If there is a code wrote as writel(0x1, AT91_ASM_SMC_SETUP0); originally must be rewrote as writel(0x1, AT91_SMC_BASE + AT91_ASM_SMC_SETUP0);
No, this should be rewritten to acces a C struct instead. These offesets must ONLY be used in assembler files, but NOT in any C code.
I meant, should we make a script that could auto generate asm-offset like a translation from struct ftsmc020 { unsigned bank0_cr; unsigned bank0_tpr; ... } into #define FTSMC020_BANK0_CR 0x00; or #define FTSMC020_BANK0_TPR (4);
No. It makes no sense to provide offset fefinitions for allexisting struct entries. Onle those are needed that are actually being used in assembler code, and this should be only a handful.
If you find yourself using more of them, you should stop and ask yourself why you are not writing this code in C.
without manually reworte the structure in the way as OFFSET(FTSMC020_BANK0_CR, ftsmc020, bank0_cr); and create a new specific header file for make-asm-offset?
I repeat again: I consider this manual unrolling of the nested structs a Bad Thing. You should have separate offsets for each of the nested structs.
You are right, the comments of FTSMC020_BANK0_TPR (4) is really bad for human reading.
Actually not. They explain exactly what's going on there.
However, when people implementing lowlevel_init or other assembly files, they still need such kind of reference to write *.S files before the asm-offset has been generated by make.
First of all, people should stop writing assembly code when they could use C instead. The remaining (small!) parts of aseembler code will need only a small number of offset definitions. These should be easy to handle.
Again: if you need larger numbers of such entries you are doing something fundamentally wrong. Reconsider your coding style. What exactly enforces you to use assembly?
Best regards,
Wolfgang Denk
participants (3)
-
Macpaul Lin
-
macpaul@andestech.com
-
Wolfgang Denk