Mack Wallace sent me some kernel prints of the emmc errors on raspberry pi 400 and cm4 compute module, which look like this: sdhc: read error intr 2008002 stat 1fff0000 this means theres a DMA error there because bit 25 is set in the interrupt status. checking the linux device tree, i found the following comment: /* * emmc2 has different DMA constraints based on SoC revisions. It was * moved into its own bus, so as for RPi4's firmware to update them. * The firmware will find whether the emmc2bus alias is defined, and if * so, it'll edit the dma-ranges property below accordingly. */ emmc2bus: emmc2bus { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; emmc2: mmc@7e340000 { compatible = "brcm,bcm2711-emmc2"; reg = <0x0 0x7e340000 0x100>; interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clocks BCM2711_CLOCK_EMMC2>; status = "disabled"; }; }; this means the dram bus address for adma changes depending on the moon phase and is only discoverable using the device tree blob. so i wrote the following patch, adding a *emmc2bus kernel parameter, which we can eigther set manually, or will be discovered from the device tree. the issue with device tree is that linux people like to pointlessly re-arrange stuff all the time so it constantly breaks with firmware updates. so first experiment is to apply the patches and see if we created the *emmc2bus parameter like: cat '#ec/*emmc2bus' expected value should be eigther: c0000000 or 0 if the file isnt found, then my bootargs.c patch doesnt work. we can still manually override the offset by putting *emmc2bus=0 in config.txt and then see if the mmc errors go away. anyone with a pi 400 or cm4 can try this out please? --- /mnt/git/object/6c70026fa4b2ff235f60c883db15f55b4096bf6b/tree/sys/src/9/bcm/bootargs.c +++ sys/src/9/bcm/bootargs.c @@ -12,6 +12,7 @@ static char *confval[MAXCONF]; static int nconf; static char maxmem[256]; +static char emmc2bus[32]; static char pciwin[38], pcidmawin[38]; static int @@ -111,6 +112,15 @@ len -= 3*4; } addconf("*maxmem", maxmem); + } + return; + } + if(strcmp(path, "/emmc2bus") == 0 && strcmp(key, "dma-ranges") == 0 + && len == (2*4 + 2*4 + 1*4) && (beget4(p+2*4) | beget4(p+3*4)) == 0){ + if(findconf("*emmc2bus") < 0){ + addr = (uvlong)beget4(p+0*4)<<32 | beget4(p+1*4); + snprint(emmc2bus, sizeof(emmc2bus), "%llux", addr); + addconf("*emmc2bus", emmc2bus); } return; } --- /mnt/git/object/6c70026fa4b2ff235f60c883db15f55b4096bf6b/tree/sys/src/9/bcm64/sdhc.c +++ sys/src/9/bcm64/sdhc.c @@ -204,6 +204,7 @@ ulong extclk; int appcmd; Adma *dma; + uintptr busdram; }; static Ctlr emmc; @@ -247,7 +248,7 @@ p->desc |= len<<OLength | End | Int; else p->desc |= Maxdma<<OLength; - p->addr = dmaaddr((void*)a); + p->addr = emmc.busdram + (PADDR(a) - PHYSDRAM); a += Maxdma; len -= Maxdma; n--; @@ -293,7 +294,11 @@ { u32int *r; ulong clk; + char *s; + emmc.busdram = soc.busdram; + if((s = getconf("*emmc2bus")) != nil) + emmc.busdram = strtoul(s, nil, 16); clk = getclkrate(ClkEmmc2); if(clk == 0){ clk = Extfreq; @@ -507,7 +512,7 @@ cachedwbse(buf, len); else cachedwbinvse(buf, len); - WR(Dmadesc, dmaaddr(emmc.dma)); + WR(Dmadesc, emmc.busdram + (PADDR(emmc.dma) - PHYSDRAM)); okay(1); } -- cinap
[-- Attachment #1: Type: text/plain, Size: 4382 bytes --] Hey, if someone can guide me on how to use the the bootargs.c file (im assuming i have to build) i can test on my pi400 On Sat, Nov 6, 2021 at 5:13 AM <cinap_lenrek@felloff.net> wrote: > Mack Wallace sent me some kernel prints of the > emmc errors on raspberry pi 400 and cm4 compute module, > which look like this: > > sdhc: read error intr 2008002 stat 1fff0000 > > this means theres a DMA error there because bit 25 is set > in the interrupt status. > > checking the linux device tree, i found the following > comment: > > /* > * emmc2 has different DMA constraints based on SoC revisions. It was > * moved into its own bus, so as for RPi4's firmware to update them. > * The firmware will find whether the emmc2bus alias is defined, and if > * so, it'll edit the dma-ranges property below accordingly. > */ > emmc2bus: emmc2bus { > compatible = "simple-bus"; > #address-cells = <2>; > #size-cells = <1>; > ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; > dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; > emmc2: mmc@7e340000 { > compatible = "brcm,bcm2711-emmc2"; > reg = <0x0 0x7e340000 0x100>; > interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; > clocks = <&clocks BCM2711_CLOCK_EMMC2>; > status = "disabled"; > }; > }; > > this means the dram bus address for adma changes depending on the moon > phase and is only discoverable using the device tree blob. > > so i wrote the following patch, adding a *emmc2bus kernel parameter, > which we can eigther set manually, or will be discovered from the > device tree. > > the issue with device tree is that linux people like to pointlessly > re-arrange stuff all the time so it constantly breaks with firmware > updates. > > so first experiment is to apply the patches and see if we created > the *emmc2bus parameter like: > > cat '#ec/*emmc2bus' > > expected value should be eigther: c0000000 or 0 > > if the file isnt found, then my bootargs.c patch doesnt work. > > we can still manually override the offset by putting *emmc2bus=0 > in config.txt and then see if the mmc errors go away. > > anyone with a pi 400 or cm4 can try this out please? > > --- > /mnt/git/object/6c70026fa4b2ff235f60c883db15f55b4096bf6b/tree/sys/src/9/bcm/bootargs.c > +++ sys/src/9/bcm/bootargs.c > @@ -12,6 +12,7 @@ > static char *confval[MAXCONF]; > static int nconf; > static char maxmem[256]; > +static char emmc2bus[32]; > static char pciwin[38], pcidmawin[38]; > > static int > @@ -111,6 +112,15 @@ > len -= 3*4; > } > addconf("*maxmem", maxmem); > + } > + return; > + } > + if(strcmp(path, "/emmc2bus") == 0 && strcmp(key, "dma-ranges") == 0 > + && len == (2*4 + 2*4 + 1*4) && (beget4(p+2*4) | beget4(p+3*4)) == > 0){ > + if(findconf("*emmc2bus") < 0){ > + addr = (uvlong)beget4(p+0*4)<<32 | beget4(p+1*4); > + snprint(emmc2bus, sizeof(emmc2bus), "%llux", addr); > + addconf("*emmc2bus", emmc2bus); > } > return; > } > --- > /mnt/git/object/6c70026fa4b2ff235f60c883db15f55b4096bf6b/tree/sys/src/9/bcm64/sdhc.c > +++ sys/src/9/bcm64/sdhc.c > @@ -204,6 +204,7 @@ > ulong extclk; > int appcmd; > Adma *dma; > + uintptr busdram; > }; > > static Ctlr emmc; > @@ -247,7 +248,7 @@ > p->desc |= len<<OLength | End | Int; > else > p->desc |= Maxdma<<OLength; > - p->addr = dmaaddr((void*)a); > + p->addr = emmc.busdram + (PADDR(a) - PHYSDRAM); > a += Maxdma; > len -= Maxdma; > n--; > @@ -293,7 +294,11 @@ > { > u32int *r; > ulong clk; > + char *s; > > + emmc.busdram = soc.busdram; > + if((s = getconf("*emmc2bus")) != nil) > + emmc.busdram = strtoul(s, nil, 16); > clk = getclkrate(ClkEmmc2); > if(clk == 0){ > clk = Extfreq; > @@ -507,7 +512,7 @@ > cachedwbse(buf, len); > else > cachedwbinvse(buf, len); > - WR(Dmadesc, dmaaddr(emmc.dma)); > + WR(Dmadesc, emmc.busdram + (PADDR(emmc.dma) - PHYSDRAM)); > okay(1); > } > > -- > cinap > [-- Attachment #2: Type: text/html, Size: 5613 bytes --]
it is not difficult. cd / ape/patch -p0 < patch.txt cd /sys/src/9/bcm64 mk 'CONF=pi4' install thats all you need to compile a kernel. this will produce /arm64/9pi4, which is the kernel that goes into your tftp directory or sdcard fat filesystem. -- cinap
as you might have seen. i pushed the changes to sdhc and bootargs yesterday to 9front, also adding some improvements to sdmmc so it will not block too long when there is no sdcard inserted. i tested with my raspberry pi 4 model b and all worked like expected. so no need to apply the patches manually anymore... in case anyone wants helping to test this. -- cinap
I took the individual files from git and compiled them into a new kernel. I tried that kernel on a 4GB Pi400, an 8GB Raspberry Pi 4b, and a 1GB Pi Compute Module 4 (w/o eMMC) on the DFRobot mini router board. All were able to boot and mount the SD card with this change where previously one would boot, get errors, and not be able to mount the SD. So great catch cinap!
I did not expect any changes with a Compute Module 4 with eMMC as that is trying to boot from the eMMC and not the SD card. I tried anyway, and get the usual emmc: cmd 371a0000 arg 0 error intr 0 stat 1fff0001 that seems to indicate a missing SD card.
I haven’t done extensive testing, but for the first three; Pi400, CM4 w/o eMMC, and 8BB PI4b; things seem to work - I can’t imagine the changes affecting much else. I have other problems (which I am sure others can affirm with pity and derision), but those are for another thread.
Thank you!
mackbw
> On Nov 8, 2021, at 4:45 AM, cinap_lenrek@felloff.net wrote:
>
> as you might have seen. i pushed the changes to sdhc and bootargs
> yesterday to 9front, also adding some improvements to sdmmc so it
> will not block too long when there is no sdcard inserted.
>
> i tested with my raspberry pi 4 model b and all worked like expected.
>
> so no need to apply the patches manually anymore... in case anyone
> wants helping to test this.
>
> --
> cinap
>
nice. makes sense. anyone with a cm4 != 1GB (with eMMC)? we'd definitely need to adjust port/sdmmc.c code to deal with eMMC cards, but it shouldnt be too difficult. one can find the JDEC standard for eMMC in duckduckgo. -- cinap
yo. I wrote a patch a while ago at https://raw.githubusercontent.com/echoline/9emmc/master/9emmc.patch this was for the eMMC chips in the CM3+ to work (at all) it does need more changes still... other machine architectures... it does not take buswidth (happy halloween!!!) into account, I wrote a lot of it just from looking at the linux kernel, etc... be safe out there! love, uppity 9fans On Mon, Nov 8, 2021 at 1:54 PM <cinap_lenrek@felloff.net> wrote: > > nice. > > makes sense. > > anyone with a cm4 != 1GB (with eMMC)? > > we'd definitely need to adjust port/sdmmc.c code to deal with eMMC cards, > but it shouldnt be too difficult. > > one can find the JDEC standard for eMMC in duckduckgo. > > -- > cinap
oh nice! that looks like a good start. thank you eli! -- cinap
[-- Attachment #1: Type: text/plain, Size: 2832 bytes --] So I applied the patch to bcm/emmc.c and port/sdmmc.c, changed the config in emmc to use emmc for sdmmc rather than sdhc. - just in case it was that stupid simple as I am stupid. Apparently not. After some searching I came upon the following: A thread that starts to discuss 'Differences between SD card and eMMC access (CM4)? <https://forums.raspberrypi.com/viewtopic.php?t=293966#p1775503>' https://forums.raspberrypi.com/viewtopic.php?t=293966 <https://forums.raspberrypi.com/viewtopic.php?t=293966> but is not very conclusive. However, it does have a reverence to a bare metal driver that the originator of the thread wrote in C++ https://github.com/rsta2/circle/blob/master/addon/SDCard/emmc.cpp <https://github.com/rsta2/circle/blob/master/addon/SDCard/emmc.cpp> Another individual was looking to be able to use both the eMMC and an SD card in this thread: https://forums.raspberrypi.com/viewtopic.php?t=288772 <https://forums.raspberrypi.com/viewtopic.php?t=288772> If I understand correctly, the same EMMC2 controller is used for either the eMMC or the microSD card. One could reroute the older SDHOST which is still on the silicon to run the microSD, but then other things would be precluded… I don’t think any of that is a concern. In emmc.cpp, there are logs of pre-compiler directive conditionals. But from what I think I understand (which I could be completely wrong), there are not many differences between using the EMMC and an SD card. (I’m assuming the USE_SDHOST directive refers to using the older SD controller). Looks like there are some minor command changes and chunks of code that are bypassed (like checking on properties of an SD card). I had started to try to compare what is in emmc.cpp with sdhc.c. Some of the defines and structures line up nicely, but I was having issues lining up the commands (i.e. CEMMCDevice::sd_commands[] and cmdinfo[64] ). Hope some of my babble is useful. mackbw > On Nov 9, 2021, at 10:38 AM, Eli Cohen <echoline@gmail.com> wrote: > > yo. I wrote a patch a while ago at > https://raw.githubusercontent.com/echoline/9emmc/master/9emmc.patch > > this was for the eMMC chips in the CM3+ to work (at all) > > it does need more changes still... other machine architectures... it > does not take buswidth (happy halloween!!!) into account, I wrote a > lot of it just from looking at the linux kernel, etc... > > be safe out there! > > love, > uppity 9fans > > On Mon, Nov 8, 2021 at 1:54 PM <cinap_lenrek@felloff.net> wrote: >> >> nice. >> >> makes sense. >> >> anyone with a cm4 != 1GB (with eMMC)? >> >> we'd definitely need to adjust port/sdmmc.c code to deal with eMMC cards, >> but it shouldnt be too difficult. >> >> one can find the JDEC standard for eMMC in duckduckgo. >> >> -- >> cinap > [-- Attachment #2: Type: text/html, Size: 5040 bytes --]
(Sorry if this is a repeat, I forgot to make sure my message was plain text) So I applied the patch to bcm/emmc.c and port/sdmmc.c, changed the config in emmc to use emmc for sdmmc rather than sdhc. - just in case it was that stupid simple as I am stupid. Apparently not. After some searching I came upon the following: A thread that starts to discuss 'Differences between SD card and eMMC access (CM4)?' https://forums.raspberrypi.com/viewtopic.php?t=293966 but is not very conclusive. However, it does have a reverence to a bare metal driver that the originator of the thread wrote in C++ https://github.com/rsta2/circle/blob/master/addon/SDCard/emmc.cpp Another individual was looking to be able to use both the eMMC and an SD card in this thread: https://forums.raspberrypi.com/viewtopic.php?t=288772 If I understand correctly, the same EMMC2 controller is used for either the eMMC or the microSD card. One could reroute the older SDHOST which is still on the silicon to run the microSD, but then other things would be precluded… I don’t think any of that is a concern. In emmc.cpp, there are logs of pre-compiler directive conditionals. But from what I think I understand (which I could be completely wrong), there are not many differences between using the EMMC and an SD card. (I’m assuming the USE_SDHOST directive refers to using the older SD controller). Looks like there are some minor command changes and chunks of code that are bypassed (like checking on properties of an SD card). I had started to try to compare what is in emmc.cpp with sdhc.c. Some of the defines and structures line up nicely, but I was having issues lining up the commands (i.e. CEMMCDevice::sd_commands[] and cmdinfo[64] ). Hope some of my babble is useful. mackbw …The following may have been thrown out of the mailing list as I probably did not make sure I was sending plain text. > Begin forwarded message: > > From: Mack Wallace <mackbw@mapinternet.com> > Subject: Re: [9front] pi 400 and cm4 mmc issues > Date: November 8, 2021 at 1:25:25 PM EST > To: 9front@9front.org > > I took the individual files from git and compiled them into a new kernel. I tried that kernel on a 4GB Pi400, an 8GB Raspberry Pi 4b, and a 1GB Pi Compute Module 4 (w/o eMMC) on the DFRobot mini router board. All were able to boot and mount the SD card with this change where previously one would boot, get errors, and not be able to mount the SD. So great catch cinap! > > I did not expect any changes with a Compute Module 4 with eMMC as that is trying to boot from the eMMC and not the SD card. I tried anyway, and get the usual emmc: cmd 371a0000 arg 0 error intr 0 stat 1fff0001 that seems to indicate a missing SD card. > > I haven’t done extensive testing, but for the first three; Pi400, CM4 w/o eMMC, and 8BB PI4b; things seem to work - I can’t imagine the changes affecting much else. I have other problems (which I am sure others can affirm with pity and derision), but those are for another thread. > > Thank you! > > mackbw > On Nov 9, 2021, at 10:38 AM, Eli Cohen <echoline@gmail.com> wrote: > > yo. I wrote a patch a while ago at > https://raw.githubusercontent.com/echoline/9emmc/master/9emmc.patch > > this was for the eMMC chips in the CM3+ to work (at all) > > it does need more changes still... other machine architectures... it > does not take buswidth (happy halloween!!!) into account, I wrote a > lot of it just from looking at the linux kernel, etc... > > be safe out there! > > love, > uppity 9fans > > On Mon, Nov 8, 2021 at 1:54 PM <cinap_lenrek@felloff.net> wrote: >> >> nice. >> >> makes sense. >> >> anyone with a cm4 != 1GB (with eMMC)? >> >> we'd definitely need to adjust port/sdmmc.c code to deal with eMMC cards, >> but it shouldnt be too difficult. >> >> one can find the JDEC standard for eMMC in duckduckgo. >> >> -- >> cinap >
> Hope some of my babble is useful.
no. just read the standard and write the code instead
of cargo culting garbage from some infernet formus.
--
cinap