boot failure with __iounmap changes in v3.3
I'm working on getting out of tree support for the NXP LPC31xx ARM926EJS based CPUs ready for submission. Everything was working fine on v3.2 but I lost the ability to boot with v3.3. The boot failure is very early in the boot process. I did a bisect and came up with: [6ee723a6570a897208b76ab3e9a495e9106b2f8c] ARM: simplify __iounmap() when dealing with section based mapping I tried to revert it but there have been a bunch of edits in this file. Not sure how to go about debugging this. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: boot failure with __iounmap changes in v3.3
On Mon, Mar 12, 2012 at 4:18 PM, Nicolas Pitre wrote: > On Mon, 12 Mar 2012, jonsm...@gmail.com wrote: > >> I'm working on getting out of tree support for the NXP LPC31xx >> ARM926EJS based CPUs ready for submission. Everything was working fine >> on v3.2 but I lost the ability to boot with v3.3. The boot failure is >> very early in the boot process. I did a bisect and came up with: >> >> [6ee723a6570a897208b76ab3e9a495e9106b2f8c] ARM: simplify __iounmap() >> when dealing with section based mapping >> >> I tried to revert it but there have been a bunch of edits in this >> file. Not sure how to go about debugging this. > > The first thing to look for is any overlap in the virtual memory ranges > used in your struct map_desc array. No overlap is allowed anymore. There appear to be overlaps. I'll have to study things for a while to figure out how to eliminate them. This is from a three year old NXP BSP. We have a product based on the CPU and want to use a more recent kernel. They've defined multiple large peripheral regions... /* APB4 address range*/ #define IO_APB4_PHYS (0x1700) #define IO_APB4_SIZE (0x1000) { .virtual= io_p2v(IO_APB4_PHYS), .pfn= __phys_to_pfn(IO_APB4_PHYS), .length = IO_APB4_SIZE, .type = MT_DEVICE }, and then declared various devices inside of them... /* DMA registers address range*/ #define DMA_PHYS (0x1700) #define IO_DMA_REG_PHYS (DMA_PHYS) #define IO_DMA_REG_SIZE (0x800) { .virtual= io_p2v(IO_DMA_REG_PHYS), .pfn= __phys_to_pfn(IO_DMA_REG_PHYS), .length = IO_DMA_REG_SIZE, .type = MT_DEVICE }, > > Then make sure those virtual addresses are between VMALLOC_START > (typically 0xf000 or below depending on the armount of RAM your > system has) and VMALLOC_END which is 0xff00. > > > Nicolas -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: boot failure with __iounmap changes in v3.3
On Mon, Mar 12, 2012 at 5:35 PM, Nicolas Pitre wrote: > On Mon, 12 Mar 2012, jonsm...@gmail.com wrote: > >> On Mon, Mar 12, 2012 at 4:18 PM, Nicolas Pitre >> wrote: >> > On Mon, 12 Mar 2012, jonsm...@gmail.com wrote: >> > >> >> I'm working on getting out of tree support for the NXP LPC31xx >> >> ARM926EJS based CPUs ready for submission. Everything was working fine >> >> on v3.2 but I lost the ability to boot with v3.3. The boot failure is >> >> very early in the boot process. I did a bisect and came up with: >> >> >> >> [6ee723a6570a897208b76ab3e9a495e9106b2f8c] ARM: simplify __iounmap() >> >> when dealing with section based mapping >> >> >> >> I tried to revert it but there have been a bunch of edits in this >> >> file. Not sure how to go about debugging this. >> > >> > The first thing to look for is any overlap in the virtual memory ranges >> > used in your struct map_desc array. No overlap is allowed anymore. >> >> There appear to be overlaps. I'll have to study things for a while to >> figure out how to eliminate them. This is from a three year old NXP >> BSP. We have a product based on the CPU and want to use a more recent >> kernel. >> >> They've defined multiple large peripheral regions... >> >> /* APB4 address range*/ >> #define IO_APB4_PHYS (0x1700) >> #define IO_APB4_SIZE (0x1000) >> >> { >> .virtual = io_p2v(IO_APB4_PHYS), >> .pfn = __phys_to_pfn(IO_APB4_PHYS), >> .length = IO_APB4_SIZE, >> .type = MT_DEVICE >> }, >> >> and then declared various devices inside of them... >> >> /* DMA registers address range*/ >> #define DMA_PHYS (0x1700) >> #define IO_DMA_REG_PHYS (DMA_PHYS) >> #define IO_DMA_REG_SIZE (0x800) >> >> { >> .virtual = io_p2v(IO_DMA_REG_PHYS), >> .pfn = __phys_to_pfn(IO_DMA_REG_PHYS), >> .length = IO_DMA_REG_SIZE, >> .type = MT_DEVICE >> }, > > Just get rid of the map_desc entryes corresponding to subsets of a > larger entry that already covers them and you should be fine. Thanks, that fixed it. Now I'm booting up to the point where I have printk which makes things a lot easier. > > > Nicolas -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Linus being annoyed by the ARM kernel code
On Sun, Apr 3, 2011 at 4:38 AM, Andy Green wrote: > On 04/03/2011 04:07 AM, Somebody in the thread at some point said: > > Hi - > >>> * And very hardware specific code moved out to a controllable place, >>> i.e. something like BIOS >> >> Sorry, but I must vehemently disagree here. BIOSes are a problem for >> Open Source, not a solution. On X86 they use BIOS services only when >> there is simply no other choice, because the BIOS is too often buggy and >> it is more difficult and risky to update than the kernel. > > I followed the lkml thread and saw there bootloaders mentioned as some kind > of happy place all problems will be solved. You're quite right it's just a > carpet to shove stuff under and stumble over. > > If the kernel operation will intimately rely on this information, eg DT > tables, and needs its versioning to match kernel code precisely, in the end > it can't avoid owning it and that extends up to packaging as well. The > "attach device tree data to end of kernel" scheme you mentioned, or taking > it inside the kernel tree seems the way to go in that domain not indirecting > its availability and versioning through not only bootloader package, code > but also environment. I've worked on DT based PowerPC systems which have similar, multiple variants of the base hardware. The bootloader provides the DT to the kernel on these machines. A unified kernel image reads the DT and then adjusts to reflect the hardware specified in the device tree. Think of the DT as a way of probing a bus that doesn't have probe capabilities. This gives you a way to dynamically load drivers from initrd if you want. For example we dynamically loaded drivers for I2C devices that were previously always built in. Board specific code inside the kernel can trigger off the DT board name and then deal with variations of DT formats that exist for that particular board so you aren't forced to update the kernel and DT in lock step. Examples of that are in arch/powerpc/platforms/xxx/board-x Code in there looks for some old, messed up DTs and then modifies them to be compliant before allowing the kernel to read them. If the user updates their bootloader/DT that code won't trigger. The trick here is that the code modifies the DT, and then the kernel interprets the DT. The code detecting the old DT format does not go and directly manipulate the device drivers. The goal of this was to be able to ship single kernel image update that worked on a dozen hardware variations. I haven't been following the ARM DT work, but a scheme that might work on ARM is to build DTs into the kernel corresponding to each ARM machine ID supported by the kernel image. Use the machine ID to select the correct one and discard the rest. As ARM bootloaders are modified to directly support DTs slowly get rid of the in-kernel DTs. A key concept: think of the DT as a way of probing a bus that doesn't have probe capabilities. You can argue that C code can produce the same effect as DTs which is true. But that board specific setup code tends to grow and stick its fingers into everything. DTs mitigate that simply because they aren't C code. DTs encourage the development of generic device setup code instead of one-off platform specific code. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Linus being annoyed by the ARM kernel code
On Sun, Apr 3, 2011 at 12:46 PM, Matt Sealey wrote: > At the point where device tree specification and maintenance is done > in-kernel, device trees get very Linux-specific and very > Linux-driver-specific. Plenty of mistakes were made in the move to > flattened device trees on PowerPC which took too long to resolve. This another good point. If you find yourself sticking Linux specific information (like module names) into the device tree, then something is wrong in the kernel, go fix the kernel. The device tree should only contain a generic description of the hardware that can be used by any operating system. On the other hand, device trees aren't a static solution. For example, they haven't come up with a generic mechanism for completely describing things like clock and power management domains. But let's figure out schemes for describing these problem areas and fix the device tree model. As more architectures utilize device trees these problem areas should get figured out and the issues will go away. So if you find yourself adding thousands of lines of board specific code to the kernel, something is probably wrong in the device tree generic hardware description, go fix it. This is an evolutionary process. Start off with selecting in-kernel device trees based on machine ID. Start off with describing the basic hardware in the device tree and remove the old kernel code that was building the description. Move on to device trees provided by the bootloader. After basic hardware description is converted move on to more complex areas like clock and power domains. A big effect of switching to device trees is to make kernel developers stop and think about generic solutions to problems instead of adding another 1,000 lines of one-off code to the kernel. The quicker ARM converts to device trees the easier the task will be. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Linus being annoyed by the ARM kernel code
On Sun, Apr 3, 2011 at 1:26 PM, Andy Green wrote: > On 04/03/2011 06:19 PM, Somebody in the thread at some point said: >> hardware in the device tree and remove the old kernel code that was >> building the description. Move on to device trees provided by the >> bootloader. After basic hardware description is converted move on to > > Can you describe why code in the bootloader is a better place than code in > the kernel early init? I mean if you go and look in say U-Boot sources, > it's a lot less beautiful and elegant than kernel code. You shouldn't just move the init code into uboot, instead you should figure out how to encode the hardware specific information into the device tree using a generic schema. Then have code in the kernel that knows how to interpret this generic data. Matt and I may differ a little on the responsibilities of the bootloader. I think it should do the bare minimum needed to get the kernel loaded and to feed it a device tree. Matt has it doing more like setting up all of the pin configurations. But I don't have a strong opinion on this. The way things are set up currently I also don't believe you can remove all board specific code from the kernel. The goal with device trees is to start hacking away at the board specific code and make the piles of it smaller. In the future we may be able to remove it all like on the PC platform. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Linus being annoyed by the ARM kernel code
On Mon, Apr 4, 2011 at 4:21 AM, Andy Green wrote: >> Matt and I may differ a little on the responsibilities of the >> bootloader. I think it should do the bare minimum needed to get the >> kernel loaded and to feed it a device tree. Matt has it doing more >> like setting up all of the pin configurations. But I don't have a >> strong opinion on this. > > Well, in the iMX31 case there is only a 2KByte SRAM on-die that gets > auto-filled by the ROM. In the case of SD Card boot which I implemented - > the bootloader is on the SD Card at a defined place - it means you need to > fit your SD init, "mmc stack" and mmc host driver inside the 2KBytes so it > can load the rest of the bootloader. > > That works fine but it will never be implementable with DT in bootloader. I > don't mean it as a problem for DT I mean that it seems we all need to maybe > challenge our assumptions a bit in the face of this new stuff being > introduced. Matt is assuming the bootloader will consume DT data, if it > does do so it will only ever need a small fraction of it and doing so at all > is optional, since no bootloader does it today. > > Specifically: the bootloader prerequisites for accessing the DT data may > entirely mandate private bootloader knowledge of ALL the information it > would have required from DT. For example, bootloader must init SDRAM, > knowing the size and start address and memory types, must init the storage > device, must contain a stack for accessing data on the storage device to > even get at the DT information stored in files on the storage device... > what's actually left to do for the bootloader using the DT information? It > could go straight to getting the kernel from the same storage and boot that > with internal DT tables and leave the bootloader blissfully unaware of DT > info at no cost in terms of increasing the hardcoded knowledge in the > bootloader. Bootloaders don't need use the DTs, but they need to provide the DTs to OS. This get implements in lots of different ways. In bootloaders I worked on we wrote custom code in the bootloader to initialize everything. This code knew nothing of the DT. I wrote the DTs to match the specific hardware. They were compiled and merged into the bootloader binary. The bootloader didn't know how to read them, it just knew how to pass them onto the OS. But other bootloader implementations do this differently. Some of those implementations (open firmware) actually build the DTs on the fly. It's your choice on how the DT gets created. The DT is just supposed to be a generic description of the hardware that is provided to the OS so that the OS will know what hardware is there when that hardware can't be probed. So in this MX31 case did your 2K of code directly boot the kernel or was it a two stage boot process? If it is two stage the second stage should load the DT and pass it to the kernel. If it is booting direct to the kernel then the kernel will need the DT image built into it. The two stage boot process is the more general solution. What happens when we get 6,000 variants of hardware like we have we PCs? It is unreasonable for the kernel to load 6,000 different device trees and select one. Instead you want the bootloader to provide the DT and then the kernel just interprets it. If you don't do this then something like Ubuntu can't ship generic kernels. What if Ubuntu has shipped their kernel before your hardware is released? It can't possibly have the DT for your hardware built into it. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Linus being annoyed by the ARM kernel code
On Mon, Apr 4, 2011 at 4:54 AM, Andy Green wrote: > Another way to solve it, would be to encode the set of device trees > supported in a way that removes redundancy. Then the additional data needed > to resolve a generic OMAP3 device table into overo or beagle or any similar > board would be a small increment. The encoded table can be initdata and > gotten rid of after being rendered into the DT required. Grant, this is an interesting idea... Suppose Linux develops a standardized DT format for describing things like clock and power domains. This domain data is then acted on by generic code in the kernel. The domain data is CPU specific, not board specific. It would make sense to me to not put this data into the board specific device trees. Board specific device trees include the CPU identifier. During the Linux boot process we could look at the CPU identifier and then expand the in-memory DT with CPU specific info like the clock and power domains. Since each CPU variant would expand into the corresponding nodes we can now write generic code that acts on this data in a manner that is not bound to the specific CPU. Keeping data like this out of the board specific DT makes them easier to write. There's nothing to be gained by adding dozens of CPU specific nodes to a board level device tree. -- Jon Smirl jonsm...@gmail.com ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev