mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 15:56:49 +00:00
c16b2293fe
This resurrects the support for IXP4xx using device tree rather than the old (deleted) board files. The final pieces of IXP4xx board files were deleted in Linux v5.19. Ext4 root filesystems on CF and USB are supported by the default config. We support these three initial targets: - The Gateworks Avila GW2348 reference design has 64MB of RAM and 32MB of flash and also supports USB and CompactFlash. - The Gateworks Cambria GW2358 reference design has 128MB of RAM and 32MB of flash and also supports USB and CompactFlash. - The old and stable Linksys NSLU2 works fine as well, albeit it only has 32MB of RAM so it has been marked as non-default. The 8MB of flash can only fit the kernel, so it has been patched to boot from exteral media on USB. I have used it successfully as a NAS with ksmbd and LUCI web API, see: https://dflund.se/~triad/krad/ixp4xx/ Signed-off-by: Howard Harte <hharte@magicandroidapps.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Tomasz Maciej Nowak <tmn505@gmail.com>
75 lines
2.6 KiB
Diff
75 lines
2.6 KiB
Diff
From 4e242d6e08ad1d85b832e158cd0eafcb8f3f76a1 Mon Sep 17 00:00:00 2001
|
|
From: Linus Walleij <linus.walleij@linaro.org>
|
|
Date: Tue, 30 May 2023 22:40:31 +0200
|
|
Subject: [PATCH v3] mtd: cfi_cmdset_0001: Byte swap OTP info
|
|
|
|
Currently the offset into the device when looking for OTP
|
|
bits can go outside of the address of the MTD NOR devices,
|
|
and if that memory isn't readable, bad things happen
|
|
on the IXP4xx (added prints that illustrate the problem before
|
|
the crash):
|
|
|
|
cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100
|
|
ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78
|
|
cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000
|
|
ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78
|
|
8<--- cut here ---
|
|
Unable to handle kernel paging request at virtual address db000000
|
|
[db000000] *pgd=00000000
|
|
(...)
|
|
|
|
This happens in this case because the IXP4xx is big endian and
|
|
the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not
|
|
properly byteswapped. Compare to how the code in read_pri_intelext()
|
|
byteswaps the fields in struct cfi_pri_intelext.
|
|
|
|
Adding a small byte swapping loop for the OTP in read_pri_intelext()
|
|
and the crash goes away.
|
|
|
|
The problem went unnoticed for many years until I enabled
|
|
CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug.
|
|
|
|
Cc: Nicolas Pitre <npitre@baylibre.com>
|
|
Cc: stable@vger.kernel.org
|
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
---
|
|
ChangeLog v2->v3:
|
|
- Move the byte swapping to a small loop in read_pri_intelext()
|
|
so all bytes are swapped as we reach cfi_intelext_otp_walk().
|
|
ChangeLog v1->v2:
|
|
- Drill deeper and discover a big endian compatibility issue.
|
|
---
|
|
drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++++++++++--
|
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
|
|
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
|
|
@@ -421,9 +421,25 @@ read_pri_intelext(struct map_info *map,
|
|
extra_size = 0;
|
|
|
|
/* Protection Register info */
|
|
- if (extp->NumProtectionFields)
|
|
+ if (extp->NumProtectionFields) {
|
|
+ struct cfi_intelext_otpinfo *otp =
|
|
+ (struct cfi_intelext_otpinfo *)&extp->extra[0];
|
|
+
|
|
extra_size += (extp->NumProtectionFields - 1) *
|
|
- sizeof(struct cfi_intelext_otpinfo);
|
|
+ sizeof(struct cfi_intelext_otpinfo);
|
|
+
|
|
+ if (extp_size >= sizeof(*extp) + extra_size) {
|
|
+ int i;
|
|
+
|
|
+ /* Do some byteswapping if necessary */
|
|
+ for (i = 0; i < extp->NumProtectionFields - 1; i++) {
|
|
+ otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr);
|
|
+ otp->FactGroups = le16_to_cpu(otp->FactGroups);
|
|
+ otp->UserGroups = le16_to_cpu(otp->UserGroups);
|
|
+ otp++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
if (extp->MinorVersion >= '1') {
|