From 0fc5630f3cab1f7bb5b449429adfcd2b4d21edbf Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 18 Feb 2022 13:37:12 +0000 Subject: [PATCH 01/13] fel_lib: fix wrong const annotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The aw_usb_read() function is meant to *fill* the buffer given to it, so marking the pointer as "const" in the parameters list is wrong. Some compilers (for instance GCC 11) spot this and issue a warning: ---------------------------------- fel_lib.c: In function ‘aw_read_fel_status’: fel_lib.c:190:9: warning: ‘buf’ may be used uninitialized [-Wmaybe-uninitialize] 190 | aw_usb_read(dev, buf, sizeof(buf)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fel_lib.c:168:13: note: by argument 2 of type ‘const void *’ to ‘aw_usb_read’ declared here 168 | static void aw_usb_read(feldev_handle *dev, const void *data, size_t len) | ^~~~~~~~~~~ fel_lib.c:189:14: note: ‘buf’ declared here 189 | char buf[8]; | ^~~ ---------------------------------- Drop the 'const' specifier, and use the right USB bulk transfer wrapper to make this work. The usb_bulk_send() function just happened to work before because the actual libusb bulk transfer function is bidirectional. Signed-off-by: Andre Przywara --- fel_lib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fel_lib.c b/fel_lib.c index 0852cc8..485df2b 100644 --- a/fel_lib.c +++ b/fel_lib.c @@ -165,11 +165,10 @@ static void aw_usb_write(feldev_handle *dev, const void *data, size_t len, aw_read_usb_response(dev); } -static void aw_usb_read(feldev_handle *dev, const void *data, size_t len) +static void aw_usb_read(feldev_handle *dev, void *data, size_t len) { aw_send_usb_request(dev, AW_USB_READ, len); - usb_bulk_send(dev->usb->handle, dev->usb->endpoint_in, - data, len, false); + usb_bulk_recv(dev->usb->handle, dev->usb->endpoint_in, data, len); aw_read_usb_response(dev); } From 34da6cf5b9eb036050423eb7c7668b478af1af35 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 18 Feb 2022 13:42:30 +0000 Subject: [PATCH 02/13] fel_lib: make internal functions as static Some functions are only used internally in fel_lib.c, consequently their prototypes are not exported in fel_lib.h. Mark those functions as "static", to make this clear to the reader and improve the generated code. Signed-off-by: Andre Przywara --- fel_lib.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fel_lib.c b/fel_lib.c index 485df2b..f038224 100644 --- a/fel_lib.c +++ b/fel_lib.c @@ -43,7 +43,7 @@ struct _felusb_handle { }; /* a helper function to report libusb errors */ -void usb_error(int rc, const char *caption, int exitcode) +static void usb_error(int rc, const char *caption, int exitcode) { if (caption) fprintf(stderr, "%s ", caption); @@ -70,8 +70,8 @@ void usb_error(int rc, const char *caption, int exitcode) */ static const int AW_USB_MAX_BULK_SEND = 512 * 1024; /* 512 KiB per bulk request */ -void usb_bulk_send(libusb_device_handle *usb, int ep, const void *data, - size_t length, bool progress) +static void usb_bulk_send(libusb_device_handle *usb, int ep, const void *data, + size_t length, bool progress) { /* * With no progress notifications, we'll use the maximum chunk size. @@ -97,7 +97,8 @@ void usb_bulk_send(libusb_device_handle *usb, int ep, const void *data, } } -void usb_bulk_recv(libusb_device_handle *usb, int ep, void *data, int length) +static void usb_bulk_recv(libusb_device_handle *usb, int ep, void *data, + int length) { int rc, recv; while (length > 0) { @@ -172,8 +173,8 @@ static void aw_usb_read(feldev_handle *dev, void *data, size_t len) aw_read_usb_response(dev); } -void aw_send_fel_request(feldev_handle *dev, int type, - uint32_t addr, uint32_t length) +static void aw_send_fel_request(feldev_handle *dev, int type, + uint32_t addr, uint32_t length) { struct aw_fel_request req = { .request = htole32(type), @@ -183,7 +184,7 @@ void aw_send_fel_request(feldev_handle *dev, int type, aw_usb_write(dev, &req, sizeof(req), false); } -void aw_read_fel_status(feldev_handle *dev) +static void aw_read_fel_status(feldev_handle *dev) { char buf[8]; aw_usb_read(dev, buf, sizeof(buf)); @@ -624,7 +625,7 @@ static int feldev_get_endpoint(feldev_handle *dev) } /* claim USB interface associated with the libusb handle for a FEL device */ -void feldev_claim(feldev_handle *dev) +static void feldev_claim(feldev_handle *dev) { int rc = libusb_claim_interface(dev->usb->handle, 0); #if defined(__linux__) @@ -643,7 +644,7 @@ void feldev_claim(feldev_handle *dev) } /* release USB interface associated with the libusb handle for a FEL device */ -void feldev_release(feldev_handle *dev) +static void feldev_release(feldev_handle *dev) { libusb_release_interface(dev->usb->handle, 0); #if defined(__linux__) From edec4d2f6c071c5aadbd7e0075abdafb4031e6d7 Mon Sep 17 00:00:00 2001 From: RavRabbit Date: Wed, 7 Jun 2017 18:00:28 +0200 Subject: [PATCH 03/13] fex: add support for '-' and '/' characters Newer fex files like orangepi_oneplus.fex from the sunxi-boards repo fail conversion to the binary format: -------------------------- E: orangepi_oneplus.fex:258: invalid character at 4. -------------------------- This is because they contain a '-' character in section and key names, and also '/' characters in some section names, which our compiler denies. Relax the section and key filter to allow '-' and '/' as well. Signed-off-by: Andre Przywara --- script_bin.c | 2 +- script_fex.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/script_bin.c b/script_bin.c index 9c63084..ebed175 100644 --- a/script_bin.c +++ b/script_bin.c @@ -242,7 +242,7 @@ static int decompile_section(void *bin, size_t bin_size, words = (entry->pattern >> 0) & 0xffff; for (char *p = entry->name; *p; p++) - if (!(isalnum(*p) || *p == '_')) { + if (!(isalnum(*p) || *p == '_' || *p == '-')) { pr_info("Warning: Malformed entry key \"%s\"\n", entry->name); break; diff --git a/script_fex.c b/script_fex.c index 0288560..2c840d4 100644 --- a/script_fex.c +++ b/script_fex.c @@ -211,7 +211,7 @@ int script_parse_fex(FILE *in, const char *filename, struct script *script) if (*s == '[') { /* section */ char *p = ++s; - while (isalnum(*p) || *p == '_') + while (isalnum(*p) || *p == '_' || *p == '-' || *p == '/') p++; if (*p == ']' && *(p+1) == '\0') { @@ -239,7 +239,7 @@ int script_parse_fex(FILE *in, const char *filename, struct script *script) goto parse_error; }; - while (isalnum(*p) || *p == '_') + while (isalnum(*p) || *p == '_' || *p == '-') p++; mark = p; p = skip_blank(p); From a8013395e63b8b9fad7895a791656bd400c931c8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 23 Feb 2022 01:06:43 +0000 Subject: [PATCH 04/13] fex: handle trailing semicolons Some .fex files (for instance those for the H6 in sunxi-boards) contain a trailing semicolon on some lines, after the end quote of a string value. This confuses the parser and messes up our "make check" tests, so remove the semicolon both in the parser, but also in the unify-fex test conditioning tool, to make the tests pass. Signed-off-by: Andre Przywara --- script_fex.c | 4 ++++ tests/unify-fex.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/script_fex.c b/script_fex.c index 2c840d4..ec251c2 100644 --- a/script_fex.c +++ b/script_fex.c @@ -200,6 +200,10 @@ int script_parse_fex(FILE *in, const char *filename, struct script *script) pe = rtrim(s, pe); + /* Some lines end in a trailing semicolon. */ + if (pe > s && pe[-1] == ';') + *--pe = '\0'; + if (pe == s || *s == ';' || *s == '#') continue; /* empty */ if (*s == ':') { diff --git a/tests/unify-fex.c b/tests/unify-fex.c index a1ff548..57da1c2 100644 --- a/tests/unify-fex.c +++ b/tests/unify-fex.c @@ -127,6 +127,10 @@ int main(int argc, char **argv) sprintf(p, "\"%s\"", c); free(c); } + /* Remove a trailing semicolon. */ + c = strchr(p, 0); + if (*--c == ';') + *c = '\0'; } } } From e70b70eb45fe8c814db02f5aef686b1690d6dff7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sun, 20 Feb 2022 00:04:09 +0000 Subject: [PATCH 05/13] checks: fix .fex files to pass checks "make check" uses the .fex files in the sunxi-boards repository to verify the validity of our FEX compiler. To overcome an existing issue, there was one patch file applied to the mainline repository content. However this was merged into mainline sunxi-boards a while ago, so remove that patch file, as trying to apply the patch actually fails the current test early. Also some new files (H6 boards) have been added meanwhile, but they are apparently buggy: - pine64_h64.fex contains some apparently bogus characters before the leading comment, possibly an artefact of its extraction. - One DRAM TPR6 parameter seems to contain an extra trailing 0, making the value larger than 32 bit, and not matching the TPR6 values for other A31 boards. Just remove that, as the compiler rightfully complains about that. This allows the "make check" command to pass again. Signed-off-by: Andre Przywara --- tests/patches/a-star_kv49l.patch | 55 ------------------------------ tests/patches/temp_fex_fixes.patch | 23 +++++++++++++ 2 files changed, 23 insertions(+), 55 deletions(-) delete mode 100644 tests/patches/a-star_kv49l.patch create mode 100644 tests/patches/temp_fex_fixes.patch diff --git a/tests/patches/a-star_kv49l.patch b/tests/patches/a-star_kv49l.patch deleted file mode 100644 index 799ae1a..0000000 --- a/tests/patches/a-star_kv49l.patch +++ /dev/null @@ -1,55 +0,0 @@ -See https://github.com/linux-sunxi/sunxi-boards/issues/51 - ---- orig/sunxi-boards/sys_config/a33/a-star_kv49l.fex -+++ new/sunxi-boards/sys_config/a33/a-star_kv49l.fex -@@ -830,25 +830,25 @@ - - [Vdevice] - Vdevice_used = 0 --Vdevice_0 = port:P@00<0><0><0><0> --Vdevice_1 = port:P@00<0><0><0><0> -+;Vdevice_0 = port:P@00<0><0><0><0> -+;Vdevice_1 = port:P@00<0><0><0><0> - - [s_uart0] - s_uart_used = 0 --s_uart_tx = port:P@00<0><0><0><0> --s_uart_rx = port:P@00<0><0><0><0> -+;s_uart_tx = port:P@00<0><0><0><0> -+;s_uart_rx = port:P@00<0><0><0><0> - - [s_rsb0] - s_rsb_used = 0 --s_rsb_sck = port:P@00<0><0><0><0> --s_rsb_sda = port:P@00<0><0><0><0> -+;s_rsb_sck = port:P@00<0><0><0><0> -+;s_rsb_sda = port:P@00<0><0><0><0> - - [s_jtag0] - s_jtag_used = 0 --s_jtag_tms = port:P@00<0><0><0><0> --s_jtag_tck = port:P@00<0><0><0><0> --s_jtag_tdo = port:P@00<0><0><0><0> --s_jtag_tdi = port:P@00<0><0><0><0> -+;s_jtag_tms = port:P@00<0><0><0><0> -+;s_jtag_tck = port:P@00<0><0><0><0> -+;s_jtag_tdo = port:P@00<0><0><0><0> -+;s_jtag_tdi = port:P@00<0><0><0><0> - - [s_powchk] - s_powchk_used = 0 -@@ -875,9 +875,9 @@ - - [leds_para] - leds_used = 0 --;red_led = port:P@00<0><0><0><0> --;red_led_active_low = 0 --;green_led_active_low = 0 --;blue_led = --;blue_led_active_low = 0 -+;red_led = port:P@00<0><0><0><0> -+;red_led_active_low = 0 -+;green_led_active_low = 0 -+;blue_led = -+;blue_led_active_low = 0 - diff --git a/tests/patches/temp_fex_fixes.patch b/tests/patches/temp_fex_fixes.patch new file mode 100644 index 0000000..7708ab2 --- /dev/null +++ b/tests/patches/temp_fex_fixes.patch @@ -0,0 +1,23 @@ +diff --git a/sunxi-boards/sys_config/a31/mixtile_loftq.fex b/sunxi-boards/sys_config/a31/mixtile_loftq.fex +index 583b02e..2310b18 100644 +--- a/sunxi-boards/sys_config/a31/mixtile_loftq.fex ++++ b/sunxi-boards/sys_config/a31/mixtile_loftq.fex +@@ -87,7 +87,7 @@ dram_tpr2 = 0x39a70140 + dram_tpr3 = 0xa092e74c + dram_tpr4 = 0x2948c209 + dram_tpr5 = 0x8944422c +-dram_tpr6 = 0x300284800 ++dram_tpr6 = 0x30028480 + dram_tpr7 = 0x2a3279 + dram_tpr8 = 0x5034fa8 + dram_tpr9 = 0x36353d8 +diff --git a/sunxi-boards/sys_config/h6/pine64_h64.fex b/sunxi-boards/sys_config/h6/pine64_h64.fex +index 9caaecc..eb585b7 100644 +--- a/sunxi-boards/sys_config/h6/pine64_h64.fex ++++ b/sunxi-boards/sys_config/h6/pine64_h64.fex +@@ -1,4 +1,4 @@ +-gma;sun50iw6p1 application ++;sun50iw6p1 application + ;--------------------------------------------------------------------------------------------------------- + ; 说明: 脚本中的字符串区分大小写,用户可以修改"="后面的数值,但是不要修改前面的字符串 + ; 描述gpio的形式:Port:端口+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态> From d5f4fd1e12e9b239b2aca0ab56c341476378aef8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 19 Feb 2022 22:42:52 +0000 Subject: [PATCH 06/13] CI: add Github Actions control file It seems like travis-ci.org is gone, replaced by travis-ci.com, but apparently that's not truly free anymore: it requires a registered account plus credit card, and is only granted a one-time free credit allowance, with the option to get this extended by explicit request. As a result the current CI stopped working a while ago, and was broken anyway (it failed building already, and make check on its own doesn't pass on master anymore). Github itself seems to offer an alternative, so let's add a control file for that to get some basic CI back. This builds the host and misc tools on a standard Ubuntu system, and runs make check. Signed-off-by: Andre Przywara --- .github/workflows/build_check.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/build_check.yml diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml new file mode 100644 index 0000000..bb03438 --- /dev/null +++ b/.github/workflows/build_check.yml @@ -0,0 +1,21 @@ +name: Build host tools + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Install prerequisites + run: sudo apt-get install -y libusb-1.0-0-dev zlib1g-dev libfdt-dev + - name: make + run: make tools misc + - name: make check + run: make check From 0b49f88acf80ca57d3b82a49e21bbd26ac59a469 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 20 Jan 2022 01:14:54 +0000 Subject: [PATCH 07/13] fel: thunks: Fix fel-to-spl-thunk to be ARMv5TE compatible Currently the thunk we upload into the SRAM is using DSB and ISB instructions, which were introduced in ARMv7. Also it relies on movw/movt pairs, which became available in ARMv6T2. The Allwinner F1Cx00 SoCs are using an ARMv5TE compliant core, so they do not know these instructions. Change the code to be ARMv5TE compliant, so it can run on all relevant Allwinner ARM cores: - One movw is just used to compare two bits, replace that with a tst/tsteq sequence to skip the load. - The other movw/movt pairs get replaced with ldr's, that load from literal storage at the end of the code (from Icenowy). - The DSB and ISB get replaced with their CP15 MCR counterparts. Those are deprecated in ARMv7, but still work, when the CP15BEN bit is set in SCTLR. We check for this in fel.c (from Icenowy). ISB is not implemented on the ARM926, so make this conditional. A simple branch takes care of the desired pipeline flush for the old SoC. Also remove the rather pointless Ruby prolog that generates the header file. We have a less awkward version of this in the Makefile, and need that for the other thunks there anyway, so it's just duplicated code. Embedding a header generator in Ruby in an assembly file is a cute gimmick, but serves no purpose anymore. This is based on work by Icenowy, who put a similar solution in a separate file. Originally-by: Icenowy Zheng Signed-off-by: Andre Przywara --- thunks/Makefile | 2 +- thunks/fel-to-spl-thunk.S | 95 +++++++++++++++------------------------ thunks/fel-to-spl-thunk.h | 91 ++++++++++++++++++++----------------- 3 files changed, 85 insertions(+), 103 deletions(-) diff --git a/thunks/Makefile b/thunks/Makefile index 9ba6635..891ca1f 100644 --- a/thunks/Makefile +++ b/thunks/Makefile @@ -27,7 +27,7 @@ AWK_O_TO_H := LC_ALL=C awk -f objdump_to_h.awk # The SPL thunk requires a different output format. The "style" variable for # awk controls this, and causes the htole32() conversion to be omitted. fel-to-spl-thunk.h: fel-to-spl-thunk.S FORCE - $(AS) -o $(subst .S,.o,$<) $< + $(AS) -o $(subst .S,.o,$<) -march=armv5te $< $(OBJDUMP) -d $(subst .S,.o,$<) | $(AWK_O_TO_H) -v style=old > $@ $(THUNKS): %.h: %.S FORCE diff --git a/thunks/fel-to-spl-thunk.S b/thunks/fel-to-spl-thunk.S index 987a02a..577dd73 100644 --- a/thunks/fel-to-spl-thunk.S +++ b/thunks/fel-to-spl-thunk.S @@ -21,45 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -/* Usage instructions: "ruby -x fel-to-spl-thunk.S > fel-to-spl-thunk.h" */ -/*************************************************************************/ - -/* Open a comment for gas. - - Do not close the comment until after the Ruby code terminator (__END__). - Write the '*' '/' sequence of characters as "\x2a/" in string literals to - avoid doing so. - -#!/usr/bin/env ruby - -def tool_exists(tool_name) - `which #{tool_name} > /dev/null 2>&1` - return $?.to_i == 0 -end - -toolchains = [ - "arm-none-eabi-", - "arm-linux-gnueabihf-", - "arm-none-linux-gnueabi-", - "armv7a-hardfloat-linux-gnueabi-", -] - -toolchain = toolchains.find { |toolchain| tool_exists("#{toolchain}as") } -abort "Can't find any ARM crosscompiler\n" unless toolchain - -system("#{toolchain}as -o #{$PROGRAM_NAME}.o #{$PROGRAM_NAME}") -exit($?.to_i) if $?.to_i != 0 - -`#{toolchain}objdump -d #{$PROGRAM_NAME}.o`.each_line {|l| - next unless l =~ /(\h+)\:\s+(\h+)\s+(\S+)\s+([^;]*)/ - printf("\t0x%s, /* %8s: %-10s %-28s \x2a/\n", $2, $1, $3, $4.strip) -} - -__END__ -*/ - -/*************************************************************************/ +.arm BUF1 .req r0 BUF2 .req r1 @@ -75,14 +37,7 @@ entry_point: b setup_stack stack_begin: - nop - nop - nop - nop - nop - nop - nop - nop + .space 32, 0xff stack_end: nop @@ -118,15 +73,14 @@ setup_stack: /* Save the original SP, LR and CPSR to stack */ /* Check if the instructions or data cache is enabled */ mrc p15, 0, TMP1, c1, c0, 0 - movw TMP2, #((1 << 12) | (1 << 2)) - tst TMP1, TMP2 + tst TMP1, #(1 << 2) + tsteq TMP1, #(1 << 12) bne cache_is_unsupported bl swap_all_buffers verify_checksum: - movw CHECKSUM, #0x6c39 - movt CHECKSUM, #0x5f0a + ldr CHECKSUM, checksum_seed mov BUF1, SPL_ADDR ldr FULLSIZE, [BUF1, #16] check_next_word: @@ -140,13 +94,27 @@ check_next_word: bne checksum_is_bad /* Change 'eGON.BT0' -> 'eGON.FEL' */ - movw TMP1, (('F' << 8) + '.') - movt TMP1, (('L' << 8) + 'E') + ldr TMP1, egon_fel_str str TMP1, [SPL_ADDR, #8] - /* Call the SPL code */ - dsb - isb + /* + * Call the SPL code, but before that make sure the CPU sees the + * recently uploaded code. This requires a DSB and ISB. + * The "dsb" and "isb" *instructions* are not available in ARMv5TE, + * but at least for DSB we can use the CP15 register encoding. This + * works for ARMv7 and v8 as well, because we have checked our SCTLR + * before (in fel.c), so we know that CP15BEN is set. + * The ARM926 core does not implement ISB, instead the TRM recommends + * just a branch to achieve the same "flush the pipeline" effect. + * As just this is not sufficient for later cores, check the MIDR + * register, and do the DSB only for ARMv6 or later. + * The input register for the CP15 instruction is ignored. + */ + mcr p15, 0, TMP1, c7, c10, 4 /* CP15DSB */ + mrc p15, 0, TMP1, c0, c0, 0 /* read MIDR */ + and TMP1, TMP1, #(0xf << 16) /* architecture */ + cmp TMP1, #(0x6 << 16) /* ARMv5TEJ */ + mcrgt p15, 0, TMP1, c7, c5, 4 /* CP15ISB, if > ARMv5TEJ */ blx SPL_ADDR /* Return back to FEL */ @@ -154,15 +122,13 @@ check_next_word: cache_is_unsupported: /* Bail out if cache is enabled and change 'eGON.BT0' -> 'eGON.???' */ - movw TMP1, (('?' << 8) + '.') - movt TMP1, (('?' << 8) + '?') + ldr TMP1, cache_enabled_str str TMP1, [SPL_ADDR, #8] b return_to_fel_noswap checksum_is_bad: /* The checksum test failed, so change 'eGON.BT0' -> 'eGON.BAD' */ - movw TMP1, (('B' << 8) + '.') - movt TMP1, (('D' << 8) + 'A') + ldr TMP1, checksum_failed_str str TMP1, [SPL_ADDR, #8] return_to_fel: @@ -173,6 +139,15 @@ return_to_fel_noswap: ldr sp, [sp] bx lr +checksum_seed: + .word 0x5f0a6c39 +egon_fel_str: + .ascii ".FEL" +cache_enabled_str: + .ascii ".???" +checksum_failed_str: + .ascii ".BAD" + appended_data: /* * The appended data uses the following format: diff --git a/thunks/fel-to-spl-thunk.h b/thunks/fel-to-spl-thunk.h index 286ba53..47fe276 100644 --- a/thunks/fel-to-spl-thunk.h +++ b/thunks/fel-to-spl-thunk.h @@ -1,18 +1,18 @@ /* : */ 0xea000015, /* 0: b 5c */ /* : */ - 0xe1a00000, /* 4: nop */ - 0xe1a00000, /* 8: nop */ - 0xe1a00000, /* c: nop */ - 0xe1a00000, /* 10: nop */ - 0xe1a00000, /* 14: nop */ - 0xe1a00000, /* 18: nop */ - 0xe1a00000, /* 1c: nop */ - 0xe1a00000, /* 20: nop */ + 0xffffffff, /* 4: .word 0xffffffff */ + 0xffffffff, /* 8: .word 0xffffffff */ + 0xffffffff, /* c: .word 0xffffffff */ + 0xffffffff, /* 10: .word 0xffffffff */ + 0xffffffff, /* 14: .word 0xffffffff */ + 0xffffffff, /* 18: .word 0xffffffff */ + 0xffffffff, /* 1c: .word 0xffffffff */ + 0xffffffff, /* 20: .word 0xffffffff */ /* : */ 0xe1a00000, /* 24: nop */ /* : */ - 0xe28f40dc, /* 28: add r4, pc, #220 */ + 0xe28f40e8, /* 28: add r4, pc, #232 */ /* : */ 0xe4940004, /* 2c: ldr r0, [r4], #4 */ 0xe4941004, /* 30: ldr r1, [r4], #4 */ @@ -28,7 +28,7 @@ 0x1afffff9, /* 54: bne 40 */ 0xeafffff3, /* 58: b 2c */ /* : */ - 0xe59f80a4, /* 5c: ldr r8, [pc, #164] */ + 0xe59f80b0, /* 5c: ldr r8, [pc, #176] */ 0xe24f0044, /* 60: sub r0, pc, #68 */ 0xe520d004, /* 64: str sp, [r0, #-4]! */ 0xe1a0d000, /* 68: mov sp, r0 */ @@ -37,43 +37,50 @@ 0xe38220c0, /* 74: orr r2, r2, #192 */ 0xe121f002, /* 78: msr CPSR_c, r2 */ 0xee112f10, /* 7c: mrc 15, 0, r2, cr1, cr0, {0} */ - 0xe3013004, /* 80: movw r3, #4100 */ - 0xe1120003, /* 84: tst r2, r3 */ - 0x1a000012, /* 88: bne d8 */ + 0xe3120004, /* 80: tst r2, #4 */ + 0x03120a01, /* 84: tsteq r2, #4096 */ + 0x1a000013, /* 88: bne dc */ 0xebffffe5, /* 8c: bl 28 */ /* : */ - 0xe3067c39, /* 90: movw r7, #27705 */ - 0xe3457f0a, /* 94: movt r7, #24330 */ - 0xe1a00008, /* 98: mov r0, r8 */ - 0xe5905010, /* 9c: ldr r5, [r0, #16] */ + 0xe59f706c, /* 90: ldr r7, [pc, #108] */ + 0xe1a00008, /* 94: mov r0, r8 */ + 0xe5905010, /* 98: ldr r5, [r0, #16] */ /* : */ - 0xe4902004, /* a0: ldr r2, [r0], #4 */ - 0xe2555004, /* a4: subs r5, r5, #4 */ - 0xe0877002, /* a8: add r7, r7, r2 */ - 0x1afffffb, /* ac: bne a0 */ - 0xe598200c, /* b0: ldr r2, [r8, #12] */ - 0xe0577082, /* b4: subs r7, r7, r2, lsl #1 */ - 0x1a00000a, /* b8: bne e8 */ - 0xe304262e, /* bc: movw r2, #17966 */ - 0xe3442c45, /* c0: movt r2, #19525 */ - 0xe5882008, /* c4: str r2, [r8, #8] */ - 0xf57ff04f, /* c8: dsb sy */ - 0xf57ff06f, /* cc: isb sy */ - 0xe12fff38, /* d0: blx r8 */ - 0xea000006, /* d4: b f4 */ + 0xe4902004, /* 9c: ldr r2, [r0], #4 */ + 0xe2555004, /* a0: subs r5, r5, #4 */ + 0xe0877002, /* a4: add r7, r7, r2 */ + 0x1afffffb, /* a8: bne 9c */ + 0xe598200c, /* ac: ldr r2, [r8, #12] */ + 0xe0577082, /* b0: subs r7, r7, r2, lsl #1 */ + 0x1a00000b, /* b4: bne e8 */ + 0xe59f2048, /* b8: ldr r2, [pc, #72] */ + 0xe5882008, /* bc: str r2, [r8, #8] */ + 0xee072f9a, /* c0: mcr 15, 0, r2, cr7, cr10, {4} */ + 0xee102f10, /* c4: mrc 15, 0, r2, cr0, cr0, {0} */ + 0xe202280f, /* c8: and r2, r2, #983040 */ + 0xe3520806, /* cc: cmp r2, #393216 */ + 0xce072f95, /* d0: mcrgt 15, 0, r2, cr7, cr5, {4} */ + 0xe12fff38, /* d4: blx r8 */ + 0xea000004, /* d8: b f0 */ /* : */ - 0xe3032f2e, /* d8: movw r2, #16174 */ - 0xe3432f3f, /* dc: movt r2, #16191 */ + 0xe59f2028, /* dc: ldr r2, [pc, #40] */ 0xe5882008, /* e0: str r2, [r8, #8] */ - 0xea000003, /* e4: b f8 */ + 0xea000002, /* e4: b f4 */ /* : */ - 0xe304222e, /* e8: movw r2, #16942 */ - 0xe3442441, /* ec: movt r2, #17473 */ - 0xe5882008, /* f0: str r2, [r8, #8] */ + 0xe59f2020, /* e8: ldr r2, [pc, #32] */ + 0xe5882008, /* ec: str r2, [r8, #8] */ /* : */ - 0xebffffcb, /* f4: bl 28 */ + 0xebffffcc, /* f0: bl 28 */ /* : */ - 0xe8bd4004, /* f8: pop {r2, lr} */ - 0xe121f002, /* fc: msr CPSR_c, r2 */ - 0xe59dd000, /* 100: ldr sp, [sp] */ - 0xe12fff1e, /* 104: bx lr */ + 0xe8bd4004, /* f4: pop {r2, lr} */ + 0xe121f002, /* f8: msr CPSR_c, r2 */ + 0xe59dd000, /* fc: ldr sp, [sp] */ + 0xe12fff1e, /* 100: bx lr */ + /* : */ + 0x5f0a6c39, /* 104: .word 0x5f0a6c39 */ + /* : */ + 0x4c45462e, /* 108: .word 0x4c45462e */ + /* : */ + 0x3f3f3f2e, /* 10c: .word 0x3f3f3f2e */ + /* : */ + 0x4441422e, /* 110: .word 0x4441422e */ From 4fb307f1e4441b8fc3e24fa7dd0633b4572fe694 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 20 Jan 2022 20:30:05 +0000 Subject: [PATCH 08/13] fel: thunks: Use armv5te architecture for thunks Almost all thunks are already ARMv5 safe, so we can just require this architecture on the gas command line, to enforce compatibility with the F1Cx00 series. This prevents accidental changes in the future. The RMR thunk uses the ARMv7 only DSB/ISB instructions, but this runs on ARMv8 cores only anyway, so we just force ARMv7 for this file, and avoid code changes. Signed-off-by: Andre Przywara --- thunks/Makefile | 2 +- thunks/rmr-thunk.S | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/thunks/Makefile b/thunks/Makefile index 891ca1f..27ba55d 100644 --- a/thunks/Makefile +++ b/thunks/Makefile @@ -31,5 +31,5 @@ fel-to-spl-thunk.h: fel-to-spl-thunk.S FORCE $(OBJDUMP) -d $(subst .S,.o,$<) | $(AWK_O_TO_H) -v style=old > $@ $(THUNKS): %.h: %.S FORCE - $(AS) -o $(subst .S,.o,$<) $< + $(AS) -o $(subst .S,.o,$<) -march=armv5te $< $(OBJDUMP) -d $(subst .S,.o,$<) | $(AWK_O_TO_H) > $@ diff --git a/thunks/rmr-thunk.S b/thunks/rmr-thunk.S index 10429b5..7d67ccc 100644 --- a/thunks/rmr-thunk.S +++ b/thunks/rmr-thunk.S @@ -1,6 +1,8 @@ /* * Request AArch32/AArch64 warm reset, using RVBAR and Reset Management Register + * This is used on ARMv8 cores only, so force v7 code to allow dsb and isb. */ +.arch armv7-a rmr_request: ldr r0, 1f /* RVBAR register address */ From 0512f4d9164ed928bd374376fd375e35af6be483 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 13 Jan 2018 19:59:47 +0800 Subject: [PATCH 09/13] fel: ignore more bits in SCTLR Some bits are not meaningful both in ARMv5 and ARMv7/8, however they're read as 0 in ARMv5 but 1 in ARMv7/8. Ignore them. Signed-off-by: Icenowy Zheng Signed-off-by: Andre Przywara --- fel.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fel.c b/fel.c index 8268a1a..2881587 100644 --- a/fel.c +++ b/fel.c @@ -623,9 +623,14 @@ uint32_t *aw_backup_and_disable_mmu(feldev_handle *dev, * checks needs to be relaxed). */ - /* Basically, ignore M/Z/I/V/UNK bits and expect no TEX remap */ + /* + * Basically, ignore M/Z/I/V/UNK bits and expect no TEX remap. + * Bits [23:22] are Read-As-One on ARMv7, but Should-Be-Zero + * on ARMv5, so ignore them. + * We need the RES1 bits[18,16,4,3] and CP15BEN[5]. + */ sctlr = aw_get_sctlr(dev, soc_info); - if ((sctlr & ~((0x7 << 11) | (1 << 6) | 1)) != 0x00C50038) + if ((sctlr & ~((0x3 << 22) | (0x7 << 11) | (1 << 6) | 1)) != 0x00050038) pr_fatal("Unexpected SCTLR (%08X)\n", sctlr); if (!(sctlr & 1)) { From 1fc2af5c4bc30df2a8cc4af523b319d3a5fee6a8 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 13 Jan 2018 20:00:49 +0800 Subject: [PATCH 10/13] fel: add F1C100s SoC Allwinner F1C100s is one of the new ARM9 SoCs produced by Allwinner. Add support for it in FEL. Signed-off-by: Icenowy Zheng Signed-off-by: Andre Przywara --- soc_info.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/soc_info.c b/soc_info.c index 20c982b..5ae2b23 100644 --- a/soc_info.c +++ b/soc_info.c @@ -145,6 +145,23 @@ sram_swap_buffers r329_sram_swap_buffers[] = { { .size = 0 } /* End of the table */ }; +/* + * The FEL code from BROM in F1C100s also uses SRAM A in a similar way + * with A10/A13/A20. + * Unfortunately the SRAM layout of F1C100s is not documented at all, so + * we can only try by r/w under FEL mode. + * The result is that there's a contingous SRAM zone from 0x8800 to 0xb5ff. + */ +sram_swap_buffers f1c100s_sram_swap_buffers[] = { + /* 0x1C00-0x1FFF (IRQ stack) */ + { .buf1 = 0x1C00, .buf2 = 0x9000, .size = 0x0400 }, + /* 0x5C00-0x6FFF (Stack) */ + { .buf1 = 0x5C00, .buf2 = 0x9400, .size = 0x1400 }, + /* 0x7C00-0x7FFF (Something important) */ + { .buf1 = 0x7C00, .buf2 = 0xa800, .size = 0x0400 }, + { .size = 0 } /* End of the table */ +}; + const watchdog_info wd_a10_compat = { .reg_mode = 0x01C20C94, .reg_mode_value = 3, @@ -246,6 +263,15 @@ soc_info_t soc_info_table[] = { .sid_base = 0X01C0E000, .sid_offset = 0x200, .watchdog = &wd_a80, + },{ + .soc_id = 0x1663, /* Allwinner F1C100s (all new sun3i?) */ + .name = "F1C100s", + .scratch_addr = 0x1000, + .thunk_addr = 0xb400, .thunk_size = 0x200, + .swap_buffers = f1c100s_sram_swap_buffers, + .sram_size = 32 * 1024, + /* No SID */ + .watchdog = &wd_h3_compat, },{ .soc_id = 0x1673, /* Allwinner A83T */ .name = "A83T", From ece518ff61953d5c4e3db6792c7710e03a313a4f Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 19 Jan 2018 22:50:01 +0800 Subject: [PATCH 11/13] fel-remotefunc-compiler: change march parameter to armv5te Allwinner also has ARM926EJ-S (ARMv5TE) based SoCs. Consider them when set -march parameter. Also switch to -Os, since we are more interested in compact code - performance is secondary when doing mostly MMIO anyway. Signed-off-by: Icenowy Zheng Signed-off-by: Andre Przywara --- fel-remotefunc-compiler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fel-remotefunc-compiler.rb b/fel-remotefunc-compiler.rb index 4824d51..2afbbfd 100755 --- a/fel-remotefunc-compiler.rb +++ b/fel-remotefunc-compiler.rb @@ -72,7 +72,7 @@ toolchain = toolchains.find { |toolchain| tool_exists("#{toolchain}gcc") } abort "Can't find any usable ARM crosscompiler.\n" unless toolchain # Compile the source file -system("#{toolchain}gcc -c -O3 -marm -march=armv7-a -mfloat-abi=soft -fstack-usage -fpic -o #{ARGV[0]}.o #{ARGV[0]}") +system("#{toolchain}gcc -c -Os -marm -march=armv5te -mfloat-abi=soft -fstack-usage -fpic -o #{ARGV[0]}.o #{ARGV[0]}") exit($?.to_i) if $?.to_i != 0 # Read the stack usage information From 6a951f32d0ac67549b52e61dceead943ce20fe9b Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 19 Jan 2018 22:50:57 +0800 Subject: [PATCH 12/13] fel-spiflash: rebuild remotefunc to add support for ARM9 The original fel-remotefunc-spi-data-transfer.h contains code only suitable for ARMv7+. The F1C100s family is ARM9 (ARMv5TE), so rebuild it: $ ./fel-remotefunc-compiler.rb fel-remotefunc-spi-data-transfer.{c,h} Signed-off-by: Icenowy Zheng Signed-off-by: Andre Przywara --- fel-remotefunc-spi-data-transfer.h | 239 ++++++++++++++--------------- 1 file changed, 118 insertions(+), 121 deletions(-) diff --git a/fel-remotefunc-spi-data-transfer.h b/fel-remotefunc-spi-data-transfer.h index c1a64cb..673808c 100644 --- a/fel-remotefunc-spi-data-transfer.h +++ b/fel-remotefunc-spi-data-transfer.h @@ -13,127 +13,124 @@ aw_fel_remotefunc_prepare_spi_batch_data_transfer(feldev_handle *dev, uint32_t spi_bcc_reg) { static uint8_t arm_code[] = { - 0xf0, 0x0f, 0x2d, 0xe9, /* 0: push {r4, r5, r6, r7, r8, r9, sl, fp} */ - 0x18, 0xd0, 0x4d, 0xe2, /* 4: sub sp, sp, #24 */ - 0x38, 0x50, 0x9d, 0xe5, /* 8: ldr r5, [sp, #56] */ - 0x3c, 0x60, 0x9d, 0xe5, /* c: ldr r6, [sp, #60] */ - 0x06, 0x00, 0x8d, 0xe9, /* 10: stmib sp, {r1, r2} */ - 0x00, 0xa0, 0xd0, 0xe5, /* 14: ldrb sl, [r0] */ - 0x01, 0x20, 0xd0, 0xe5, /* 18: ldrb r2, [r0, #1] */ - 0x0a, 0xa4, 0x92, 0xe1, /* 1c: orrs sl, r2, sl, lsl #8 */ - 0x6a, 0x00, 0x00, 0x0a, /* 20: beq 1d0 */ - 0xff, 0x2f, 0x0f, 0xe3, /* 24: movw r2, #65535 */ - 0x02, 0x00, 0x5a, 0xe1, /* 28: cmp sl, r2 */ - 0x18, 0x80, 0x8d, 0x02, /* 2c: addeq r8, sp, #24 */ - 0x02, 0x80, 0x80, 0x12, /* 30: addne r8, r0, #2 */ - 0x05, 0xb0, 0xa0, 0x03, /* 34: moveq fp, #5 */ - 0x48, 0xc0, 0x9d, 0xe5, /* 38: ldr ip, [sp, #72] */ - 0x08, 0xb0, 0x68, 0x05, /* 3c: strbeq fp, [r8, #-8]! */ - 0x00, 0x10, 0x68, 0xe2, /* 40: rsb r1, r8, #0 */ - 0x40, 0x20, 0x9d, 0xe5, /* 44: ldr r2, [sp, #64] */ - 0x03, 0x10, 0x01, 0xe2, /* 48: and r1, r1, #3 */ - 0x44, 0xb0, 0x9d, 0xe5, /* 4c: ldr fp, [sp, #68] */ - 0x0a, 0x70, 0xa0, 0x11, /* 50: movne r7, sl */ - 0x0c, 0x00, 0x8d, 0x05, /* 54: streq r0, [sp, #12] */ - 0x3c, 0x00, 0x81, 0xe2, /* 58: add r0, r1, #60 */ - 0x02, 0x70, 0xa0, 0x03, /* 5c: moveq r7, #2 */ - 0x00, 0x00, 0x5c, 0xe3, /* 60: cmp ip, #0 */ - 0x00, 0x70, 0x82, 0xe5, /* 64: str r7, [r2] */ - 0x08, 0x20, 0xa0, 0xe1, /* 68: mov r2, r8 */ - 0x00, 0x70, 0x8b, 0xe5, /* 6c: str r7, [fp] */ - 0x00, 0x70, 0x8c, 0x15, /* 70: strne r7, [ip] */ - 0x07, 0x00, 0x50, 0xe1, /* 74: cmp r0, r7 */ - 0x07, 0x00, 0xa0, 0x21, /* 78: movcs r0, r7 */ - 0x00, 0x40, 0x88, 0xe0, /* 7c: add r4, r8, r0 */ - 0x01, 0xc0, 0xd2, 0xe4, /* 80: ldrb ip, [r2], #1 */ - 0x04, 0x00, 0x52, 0xe1, /* 84: cmp r2, r4 */ - 0x00, 0xc0, 0xc5, 0xe5, /* 88: strb ip, [r5] */ - 0xfb, 0xff, 0xff, 0x1a, /* 8c: bne 80 */ - 0x07, 0x00, 0x60, 0xe0, /* 90: rsb r0, r0, r7 */ - 0x00, 0x90, 0x0f, 0xe1, /* 94: mrs r9, CPSR */ - 0xc0, 0xc0, 0x89, 0xe3, /* 98: orr ip, r9, #192 */ - 0x0c, 0xf0, 0x21, 0xe1, /* 9c: msr CPSR_c, ip */ - 0x04, 0xc0, 0x9d, 0xe5, /* a0: ldr ip, [sp, #4] */ - 0x07, 0x00, 0x51, 0xe1, /* a4: cmp r1, r7 */ - 0x07, 0x10, 0xa0, 0x21, /* a8: movcs r1, r7 */ - 0x08, 0xb0, 0x9d, 0xe5, /* ac: ldr fp, [sp, #8] */ - 0x00, 0x40, 0x9c, 0xe5, /* b0: ldr r4, [ip] */ - 0x01, 0xc0, 0x88, 0xe0, /* b4: add ip, r8, r1 */ - 0x00, 0xc0, 0x8d, 0xe5, /* b8: str ip, [sp] */ - 0x08, 0xc0, 0xa0, 0xe1, /* bc: mov ip, r8 */ - 0x0b, 0x40, 0x84, 0xe1, /* c0: orr r4, r4, fp */ - 0x04, 0xb0, 0x9d, 0xe5, /* c4: ldr fp, [sp, #4] */ - 0x00, 0x40, 0x8b, 0xe5, /* c8: str r4, [fp] */ - 0x00, 0xb0, 0x9d, 0xe5, /* cc: ldr fp, [sp] */ - 0x0b, 0x00, 0x5c, 0xe1, /* d0: cmp ip, fp */ - 0x06, 0x00, 0x00, 0x0a, /* d4: beq f4 */ - 0x00, 0x40, 0x93, 0xe5, /* d8: ldr r4, [r3] */ - 0x7f, 0x00, 0x14, 0xe3, /* dc: tst r4, #127 */ - 0xfc, 0xff, 0xff, 0x0a, /* e0: beq d8 */ - 0x00, 0x40, 0xd6, 0xe5, /* e4: ldrb r4, [r6] */ - 0x01, 0x40, 0xcc, 0xe4, /* e8: strb r4, [ip], #1 */ - 0x0b, 0x00, 0x5c, 0xe1, /* ec: cmp ip, fp */ - 0xf8, 0xff, 0xff, 0x1a, /* f0: bne d8 */ - 0x07, 0x10, 0x61, 0xe0, /* f4: rsb r1, r1, r7 */ - 0x03, 0x00, 0x51, 0xe3, /* f8: cmp r1, #3 */ - 0x12, 0x00, 0x00, 0x9a, /* fc: bls 14c */ - 0x00, 0x40, 0x93, 0xe5, /* 100: ldr r4, [r3] */ - 0x7f, 0xb0, 0x04, 0xe2, /* 104: and fp, r4, #127 */ - 0x54, 0x48, 0xe6, 0xe7, /* 108: ubfx r4, r4, #16, #7 */ - 0x03, 0x00, 0x5b, 0xe3, /* 10c: cmp fp, #3 */ - 0x04, 0x10, 0x41, 0xc2, /* 110: subgt r1, r1, #4 */ - 0x00, 0xb0, 0x96, 0xc5, /* 114: ldrgt fp, [r6] */ - 0x04, 0xb0, 0x8c, 0xc4, /* 118: strgt fp, [ip], #4 */ - 0x03, 0x00, 0x50, 0xe3, /* 11c: cmp r0, #3 */ - 0x00, 0xb0, 0xa0, 0x93, /* 120: movls fp, #0 */ - 0x01, 0xb0, 0xa0, 0x83, /* 124: movhi fp, #1 */ - 0x3b, 0x00, 0x54, 0xe3, /* 128: cmp r4, #59 */ - 0x00, 0xb0, 0xa0, 0xc3, /* 12c: movgt fp, #0 */ - 0x00, 0x00, 0x5b, 0xe3, /* 130: cmp fp, #0 */ - 0xef, 0xff, 0xff, 0x0a, /* 134: beq f8 */ - 0x04, 0x40, 0x92, 0xe4, /* 138: ldr r4, [r2], #4 */ - 0x03, 0x00, 0x51, 0xe3, /* 13c: cmp r1, #3 */ - 0x04, 0x00, 0x40, 0xe2, /* 140: sub r0, r0, #4 */ - 0x00, 0x40, 0x85, 0xe5, /* 144: str r4, [r5] */ - 0xec, 0xff, 0xff, 0x8a, /* 148: bhi 100 */ - 0x00, 0x00, 0x51, 0xe3, /* 14c: cmp r1, #0 */ - 0x10, 0x00, 0x00, 0x0a, /* 150: beq 198 */ - 0x00, 0x40, 0x93, 0xe5, /* 154: ldr r4, [r3] */ - 0x7f, 0x00, 0x14, 0xe3, /* 158: tst r4, #127 */ - 0x54, 0x48, 0xe6, 0xe7, /* 15c: ubfx r4, r4, #16, #7 */ - 0x01, 0x10, 0x41, 0x12, /* 160: subne r1, r1, #1 */ - 0x00, 0xb0, 0xd6, 0x15, /* 164: ldrbne fp, [r6] */ - 0x01, 0xb0, 0xcc, 0x14, /* 168: strbne fp, [ip], #1 */ - 0x00, 0xb0, 0x90, 0xe2, /* 16c: adds fp, r0, #0 */ - 0x01, 0xb0, 0xa0, 0x13, /* 170: movne fp, #1 */ - 0x3b, 0x00, 0x54, 0xe3, /* 174: cmp r4, #59 */ - 0x00, 0xb0, 0xa0, 0xc3, /* 178: movgt fp, #0 */ - 0x00, 0x00, 0x5b, 0xe3, /* 17c: cmp fp, #0 */ - 0xf1, 0xff, 0xff, 0x0a, /* 180: beq 14c */ - 0x01, 0x40, 0xd2, 0xe4, /* 184: ldrb r4, [r2], #1 */ - 0x00, 0x00, 0x51, 0xe3, /* 188: cmp r1, #0 */ - 0x01, 0x00, 0x40, 0xe2, /* 18c: sub r0, r0, #1 */ - 0x00, 0x40, 0xc5, 0xe5, /* 190: strb r4, [r5] */ - 0xee, 0xff, 0xff, 0x1a, /* 194: bne 154 */ - 0x09, 0xf0, 0x21, 0xe1, /* 198: msr CPSR_c, r9 */ - 0xff, 0xcf, 0x0f, 0xe3, /* 19c: movw ip, #65535 */ - 0x0c, 0x00, 0x5a, 0xe1, /* 1a0: cmp sl, ip */ - 0x07, 0x00, 0x88, 0x10, /* 1a4: addne r0, r8, r7 */ - 0x99, 0xff, 0xff, 0x1a, /* 1a8: bne 14 */ - 0x11, 0x20, 0xdd, 0xe5, /* 1ac: ldrb r2, [sp, #17] */ - 0x01, 0x00, 0x12, 0xe3, /* 1b0: tst r2, #1 */ - 0x08, 0x00, 0x00, 0x1a, /* 1b4: bne 1dc */ - 0x0c, 0xb0, 0x9d, 0xe5, /* 1b8: ldr fp, [sp, #12] */ - 0x02, 0x00, 0x8b, 0xe2, /* 1bc: add r0, fp, #2 */ - 0x00, 0xa0, 0xd0, 0xe5, /* 1c0: ldrb sl, [r0] */ - 0x01, 0x20, 0xd0, 0xe5, /* 1c4: ldrb r2, [r0, #1] */ - 0x0a, 0xa4, 0x92, 0xe1, /* 1c8: orrs sl, r2, sl, lsl #8 */ - 0x94, 0xff, 0xff, 0x1a, /* 1cc: bne 24 */ - 0x18, 0xd0, 0x8d, 0xe2, /* 1d0: add sp, sp, #24 */ - 0xf0, 0x0f, 0xbd, 0xe8, /* 1d4: pop {r4, r5, r6, r7, r8, r9, sl, fp} */ - 0x1e, 0xff, 0x2f, 0xe1, /* 1d8: bx lr */ - 0x0c, 0x00, 0x9d, 0xe5, /* 1dc: ldr r0, [sp, #12] */ - 0x8b, 0xff, 0xff, 0xea, /* 1e0: b 14 */ + 0xf0, 0x4f, 0x2d, 0xe9, /* 0: push {r4, r5, r6, r7, r8, r9, sl, fp, lr} */ + 0xc8, 0x91, 0x9f, 0xe5, /* 4: ldr r9, [pc, #456] */ + 0x14, 0xd0, 0x4d, 0xe2, /* 8: sub sp, sp, #20 */ + 0x00, 0x20, 0x8d, 0xe5, /* c: str r2, [sp] */ + 0x0c, 0x20, 0x8d, 0xe2, /* 10: add r2, sp, #12 */ + 0x04, 0x20, 0x8d, 0xe5, /* 14: str r2, [sp, #4] */ + 0x01, 0x60, 0xd0, 0xe5, /* 18: ldrb r6, [r0, #1] */ + 0x00, 0x20, 0xd0, 0xe5, /* 1c: ldrb r2, [r0] */ + 0x06, 0x24, 0x82, 0xe1, /* 20: orr r2, r2, r6, lsl #8 */ + 0x22, 0x64, 0xa0, 0xe1, /* 24: lsr r6, r2, #8 */ + 0x02, 0x64, 0x86, 0xe1, /* 28: orr r6, r6, r2, lsl #8 */ + 0x06, 0x68, 0xa0, 0xe1, /* 2c: lsl r6, r6, #16 */ + 0x26, 0x68, 0xa0, 0xe1, /* 30: lsr r6, r6, #16 */ + 0x00, 0x00, 0x56, 0xe3, /* 34: cmp r6, #0 */ + 0x63, 0x00, 0x00, 0x0a, /* 38: beq 1cc */ + 0x09, 0x00, 0x56, 0xe1, /* 3c: cmp r6, r9 */ + 0x05, 0x20, 0xa0, 0x03, /* 40: moveq r2, #5 */ + 0x0c, 0x20, 0xcd, 0x05, /* 44: strbeq r2, [sp, #12] */ + 0x40, 0x20, 0x9d, 0xe5, /* 48: ldr r2, [sp, #64] */ + 0x06, 0x50, 0xa0, 0x11, /* 4c: movne r5, r6 */ + 0x02, 0x50, 0xa0, 0x03, /* 50: moveq r5, #2 */ + 0x00, 0x50, 0x82, 0xe5, /* 54: str r5, [r2] */ + 0x44, 0x20, 0x9d, 0xe5, /* 58: ldr r2, [sp, #68] */ + 0x00, 0x70, 0xa0, 0x01, /* 5c: moveq r7, r0 */ + 0x00, 0x50, 0x82, 0xe5, /* 60: str r5, [r2] */ + 0x48, 0x20, 0x9d, 0xe5, /* 64: ldr r2, [sp, #72] */ + 0x04, 0x00, 0x9d, 0x05, /* 68: ldreq r0, [sp, #4] */ + 0x02, 0x00, 0x80, 0x12, /* 6c: addne r0, r0, #2 */ + 0x00, 0x00, 0x52, 0xe3, /* 70: cmp r2, #0 */ + 0x00, 0x50, 0x82, 0x15, /* 74: strne r5, [r2] */ + 0x00, 0x20, 0x60, 0xe2, /* 78: rsb r2, r0, #0 */ + 0x03, 0x20, 0x02, 0xe2, /* 7c: and r2, r2, #3 */ + 0x3c, 0x40, 0x82, 0xe2, /* 80: add r4, r2, #60 */ + 0x04, 0x00, 0x55, 0xe1, /* 84: cmp r5, r4 */ + 0x05, 0x40, 0xa0, 0x31, /* 88: movcc r4, r5 */ + 0x04, 0xe0, 0x80, 0xe0, /* 8c: add lr, r0, r4 */ + 0x00, 0xc0, 0xa0, 0xe1, /* 90: mov ip, r0 */ + 0x0e, 0x00, 0x5c, 0xe1, /* 94: cmp ip, lr */ + 0x1b, 0x00, 0x00, 0x1a, /* 98: bne 10c */ + 0x04, 0x40, 0x45, 0xe0, /* 9c: sub r4, r5, r4 */ + 0x00, 0xa0, 0x0f, 0xe1, /* a0: mrs sl, CPSR */ + 0xc0, 0xc0, 0x8a, 0xe3, /* a4: orr ip, sl, #192 */ + 0x0c, 0xf0, 0x21, 0xe1, /* a8: msr CPSR_c, ip */ + 0x00, 0xc0, 0x91, 0xe5, /* ac: ldr ip, [r1] */ + 0x00, 0x80, 0x9d, 0xe5, /* b0: ldr r8, [sp] */ + 0x02, 0x00, 0x55, 0xe1, /* b4: cmp r5, r2 */ + 0x0c, 0xc0, 0x88, 0xe1, /* b8: orr ip, r8, ip */ + 0x05, 0x20, 0xa0, 0x31, /* bc: movcc r2, r5 */ + 0x00, 0xc0, 0x81, 0xe5, /* c0: str ip, [r1] */ + 0x02, 0x80, 0x80, 0xe0, /* c4: add r8, r0, r2 */ + 0x00, 0xc0, 0xa0, 0xe1, /* c8: mov ip, r0 */ + 0x0c, 0x00, 0x58, 0xe1, /* cc: cmp r8, ip */ + 0x11, 0x00, 0x00, 0x1a, /* d0: bne 11c */ + 0x02, 0x20, 0x45, 0xe0, /* d4: sub r2, r5, r2 */ + 0x03, 0x00, 0x52, 0xe3, /* d8: cmp r2, #3 */ + 0x14, 0x00, 0x00, 0x8a, /* dc: bhi 134 */ + 0x00, 0x00, 0x52, 0xe3, /* e0: cmp r2, #0 */ + 0x25, 0x00, 0x00, 0x1a, /* e4: bne 180 */ + 0x0a, 0xf0, 0x21, 0xe1, /* e8: msr CPSR_c, sl */ + 0x09, 0x00, 0x56, 0xe1, /* ec: cmp r6, r9 */ + 0x05, 0x00, 0x80, 0x10, /* f0: addne r0, r0, r5 */ + 0xc7, 0xff, 0xff, 0x1a, /* f4: bne 18 */ + 0x0d, 0x20, 0xdd, 0xe5, /* f8: ldrb r2, [sp, #13] */ + 0x01, 0x00, 0x12, 0xe3, /* fc: tst r2, #1 */ + 0x02, 0x00, 0x87, 0x02, /* 100: addeq r0, r7, #2 */ + 0x07, 0x00, 0xa0, 0x11, /* 104: movne r0, r7 */ + 0xc2, 0xff, 0xff, 0xea, /* 108: b 18 */ + 0x38, 0xa0, 0x9d, 0xe5, /* 10c: ldr sl, [sp, #56] */ + 0x01, 0x80, 0xdc, 0xe4, /* 110: ldrb r8, [ip], #1 */ + 0x00, 0x80, 0xca, 0xe5, /* 114: strb r8, [sl] */ + 0xdd, 0xff, 0xff, 0xea, /* 118: b 94 */ + 0x00, 0xb0, 0x93, 0xe5, /* 11c: ldr fp, [r3] */ + 0x7f, 0x00, 0x1b, 0xe3, /* 120: tst fp, #127 */ + 0x3c, 0xb0, 0x9d, 0x15, /* 124: ldrne fp, [sp, #60] */ + 0x00, 0xb0, 0xdb, 0x15, /* 128: ldrbne fp, [fp] */ + 0x01, 0xb0, 0xcc, 0x14, /* 12c: strbne fp, [ip], #1 */ + 0xe5, 0xff, 0xff, 0xea, /* 130: b cc */ + 0x00, 0xb0, 0x93, 0xe5, /* 134: ldr fp, [r3] */ + 0x7c, 0x00, 0x1b, 0xe3, /* 138: tst fp, #124 */ + 0x2b, 0x88, 0xa0, 0xe1, /* 13c: lsr r8, fp, #16 */ + 0x3c, 0xb0, 0x9d, 0x15, /* 140: ldrne fp, [sp, #60] */ + 0x7f, 0x80, 0x08, 0xe2, /* 144: and r8, r8, #127 */ + 0x00, 0xb0, 0x9b, 0x15, /* 148: ldrne fp, [fp] */ + 0x04, 0xb0, 0x8c, 0x14, /* 14c: strne fp, [ip], #4 */ + 0x04, 0x20, 0x42, 0x12, /* 150: subne r2, r2, #4 */ + 0x3b, 0x00, 0x58, 0xe3, /* 154: cmp r8, #59 */ + 0x00, 0x80, 0xa0, 0xc3, /* 158: movgt r8, #0 */ + 0x01, 0x80, 0xa0, 0xd3, /* 15c: movle r8, #1 */ + 0x03, 0x00, 0x54, 0xe3, /* 160: cmp r4, #3 */ + 0x00, 0x80, 0xa0, 0x93, /* 164: movls r8, #0 */ + 0x00, 0x00, 0x58, 0xe3, /* 168: cmp r8, #0 */ + 0x38, 0xb0, 0x9d, 0x15, /* 16c: ldrne fp, [sp, #56] */ + 0x04, 0x80, 0x9e, 0x14, /* 170: ldrne r8, [lr], #4 */ + 0x04, 0x40, 0x44, 0x12, /* 174: subne r4, r4, #4 */ + 0x00, 0x80, 0x8b, 0x15, /* 178: strne r8, [fp] */ + 0xd5, 0xff, 0xff, 0xea, /* 17c: b d8 */ + 0x00, 0xb0, 0x93, 0xe5, /* 180: ldr fp, [r3] */ + 0x7f, 0x00, 0x1b, 0xe3, /* 184: tst fp, #127 */ + 0x2b, 0x88, 0xa0, 0xe1, /* 188: lsr r8, fp, #16 */ + 0x3c, 0xb0, 0x9d, 0x15, /* 18c: ldrne fp, [sp, #60] */ + 0x7f, 0x80, 0x08, 0xe2, /* 190: and r8, r8, #127 */ + 0x00, 0xb0, 0xdb, 0x15, /* 194: ldrbne fp, [fp] */ + 0x01, 0xb0, 0xcc, 0x14, /* 198: strbne fp, [ip], #1 */ + 0x01, 0x20, 0x42, 0x12, /* 19c: subne r2, r2, #1 */ + 0x3b, 0x00, 0x58, 0xe3, /* 1a0: cmp r8, #59 */ + 0x00, 0x80, 0xa0, 0xc3, /* 1a4: movgt r8, #0 */ + 0x01, 0x80, 0xa0, 0xd3, /* 1a8: movle r8, #1 */ + 0x00, 0x00, 0x54, 0xe3, /* 1ac: cmp r4, #0 */ + 0x00, 0x80, 0xa0, 0x03, /* 1b0: moveq r8, #0 */ + 0x00, 0x00, 0x58, 0xe3, /* 1b4: cmp r8, #0 */ + 0x38, 0xb0, 0x9d, 0x15, /* 1b8: ldrne fp, [sp, #56] */ + 0x01, 0x80, 0xde, 0x14, /* 1bc: ldrbne r8, [lr], #1 */ + 0x01, 0x40, 0x44, 0x12, /* 1c0: subne r4, r4, #1 */ + 0x00, 0x80, 0xcb, 0x15, /* 1c4: strbne r8, [fp] */ + 0xc4, 0xff, 0xff, 0xea, /* 1c8: b e0 */ + 0x14, 0xd0, 0x8d, 0xe2, /* 1cc: add sp, sp, #20 */ + 0xf0, 0x8f, 0xbd, 0xe8, /* 1d0: pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} */ + 0xff, 0xff, 0x00, 0x00, /* 1d4: .word 0x0000ffff */ }; uint32_t args[] = { buf, From db0fba3fd0e1794e5ef87b2338a8f9afc75c709c Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 19 Jan 2018 22:52:07 +0800 Subject: [PATCH 13/13] fel-spiflash: add support for suniv SoCs The suniv SoCs has a SPI controller like the one in H3, but with base address like sun4i and no SPI module clock in CCU. Add support for it. Signed-off-by: Icenowy Zheng Signed-off-by: Giulio Benetti Signed-off-by: Andre Przywara --- fel-spiflash.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/fel-spiflash.c b/fel-spiflash.c index fa728f9..b21dfb5 100644 --- a/fel-spiflash.c +++ b/fel-spiflash.c @@ -80,11 +80,14 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val); #define CCM_AHB_GATE_SPI0 (1 << 20) #define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0) #define SUN6I_SPI0_RST (1 << 20) +#define SUNIV_PLL6_CTL (0x01c20000 + 0x28) +#define SUNIV_AHB_APB_CFG (0x01c20000 + 0x54) #define H6_CCM_SPI0_CLK (0x03001000 + 0x940) #define H6_CCM_SPI_BGR (0x03001000 + 0x96C) #define H6_CCM_SPI0_GATE_RESET (1 << 0 | 1 << 16) +#define SUNIV_GPC_SPI0 (2) #define SUNXI_GPC_SPI0 (3) #define SUN50I_GPC_SPI0 (4) @@ -117,6 +120,7 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val); #define CCM_SPI0_CLK_DIV_BY_2 (0x1000) #define CCM_SPI0_CLK_DIV_BY_4 (0x1001) #define CCM_SPI0_CLK_DIV_BY_6 (0x1002) +#define CCM_SPI0_CLK_DIV_BY_32 (0x100f) static uint32_t gpio_base(feldev_handle *dev) { @@ -138,6 +142,7 @@ static uint32_t spi_base(feldev_handle *dev) case 0x1623: /* A10 */ case 0x1625: /* A13 */ case 0x1651: /* A20 */ + case 0x1663: /* F1C100s */ case 0x1701: /* R40 */ return 0x01C05000; case 0x1817: /* V831 */ @@ -205,6 +210,12 @@ static bool spi0_init(feldev_handle *dev) /* Setup SPI0 pins muxing */ switch (soc_info->soc_id) { + case 0x1663: /* Allwinner F1C100s/F1C600/R6/F1C100A/F1C500 */ + gpio_set_cfgpin(dev, PC, 0, SUNIV_GPC_SPI0); + gpio_set_cfgpin(dev, PC, 1, SUNIV_GPC_SPI0); + gpio_set_cfgpin(dev, PC, 2, SUNIV_GPC_SPI0); + gpio_set_cfgpin(dev, PC, 3, SUNIV_GPC_SPI0); + break; case 0x1625: /* Allwinner A13 */ case 0x1680: /* Allwinner H3 */ case 0x1681: /* Allwinner V3s */ @@ -267,11 +278,28 @@ static bool spi0_init(feldev_handle *dev) writel(reg_val, CCM_AHB_GATING0); } - /* divide by 4 */ - writel(CCM_SPI0_CLK_DIV_BY_4, spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL : - SUN4I_SPI0_CCTL); - /* Choose 24MHz from OSC24M and enable clock */ - writel(1U << 31, soc_is_h6_style(dev) ? H6_CCM_SPI0_CLK : CCM_SPI0_CLK); + if (soc_info->soc_id == 0x1663) { /* suniv F1C100s */ + /* + * suniv doesn't have a module clock for SPI0 and the clock + * source is always the AHB clock. Setup AHB to 200 MHz by + * setting PLL6 to 600 MHz with a divider of 3, then program + * the internal SPI dividier to 32. + */ + + /* Set PLL6 to 600MHz */ + writel(0x80041801, SUNIV_PLL6_CTL); + /* PLL6:AHB:APB = 6:2:1 */ + writel(0x00003180, SUNIV_AHB_APB_CFG); + /* divide by 32 */ + writel(CCM_SPI0_CLK_DIV_BY_32, SUN6I_SPI0_CCTL); + } else { + /* divide 24MHz OSC by 4 */ + writel(CCM_SPI0_CLK_DIV_BY_4, + spi_is_sun6i(dev) ? SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL); + /* Choose 24MHz from OSC24M and enable clock */ + writel(1U << 31, + soc_is_h6_style(dev) ? H6_CCM_SPI0_CLK : CCM_SPI0_CLK); + } if (spi_is_sun6i(dev)) { /* Enable SPI in the master mode and do a soft reset */