From owner-freebsd-arm@FreeBSD.ORG Sun May 24 22:39:58 2009 Return-Path: Delivered-To: freebsd-arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 61EC8106566C for ; Sun, 24 May 2009 22:39:58 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (bsdimp.com [199.45.160.85]) by mx1.freebsd.org (Postfix) with ESMTP id 137BB8FC0C for ; Sun, 24 May 2009 22:39:57 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from localhost (localhost [127.0.0.1]) by harmony.bsdimp.com (8.14.3/8.14.1) with ESMTP id n4OMcLb8047665; Sun, 24 May 2009 16:38:22 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Sun, 24 May 2009 16:38:38 -0600 (MDT) Message-Id: <20090524.163838.113805925.imp@bsdimp.com> To: ccna.syl@gmail.com From: "M. Warner Losh" In-Reply-To: <164b4c9c0905241206s570a15b1ob6214e9505329ae@mail.gmail.com> References: <164b4c9c0905241206s570a15b1ob6214e9505329ae@mail.gmail.com> X-Mailer: Mew version 5.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: freebsd-arm@freebsd.org Subject: Re: at91 SoC separation X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 May 2009 22:39:58 -0000 In message: <164b4c9c0905241206s570a15b1ob6214e9505329ae@mail.gmail.com> Sylvestre Gallon writes: : Hi, : : I am currently working on the at91sam9261ek port for the : Google Summer Of Code 2009. : : Currently I work on how I could implement the at91sam9261ek : most efficiently. I notice that all the at91 code could be at91 : System On Chip independent with some few changes. : : The big work is to extract the SoC specific code in a separate file : by SoC. It's what I tried to do on my perforce : : : perforce repo : : http://perforce.freebsd.org/depotTreeBrowser.cgi?FSPC=//depot/projects/soc2009/syl_usb/src/sys/arm/at91&HIDEDEL=NO : : Changes that I've done : : http://perforce.freebsd.org/changeList.cgi?FSPC=%2F%2Fdepot%2Fprojects%2Fsoc2009%2Fsyl_usb%2Fsrc%2Fsys%2Farm%2Fat91%2F...&USERS=syl&GROUPS=soc2009&ignore=GO! : : One thing that continues to disturb me : On At91 SoC, the IPs and : their registers are quite the same. The only big change that exists : between these SoC are the base addresses for each IPs. The different : SoC generic drivers may need IPs base addresses to perform the : mapping of registers. For the moment to not have some ugly : #ifdef like : : : #ifdef __AT91RM9200__ : #include : #elif __AT91SAM9261__ : #include : #elfi __ANOTHER_SOC__ : #include : #endif : : I have created base address accessors in the SoC file. But I'm not : sure I like that... Do you have some ideas to handle it in a better : way ? : : When All the code of at91 will be SoC independents It will be very : easy to port any other at91 board (1 or 2 days of work by cpu). : I have also access to a lot of atmel board, I live near Atmel French : R&D and know some people who work there who are ready to lend : me boards with these SoC : : : - at91sam9260 : - at91sam9261 : - at91sam9263 : - at91sam9rl : - at91sam9m10 (not officially out, and not yet in Linux ;) ) : - at91cap9 : - .. : : I'am open to all suggestions, it is important for me to implement : the at91sam9261ek (and perhaps other) port the best way I can : to have a chance to see it in current after the Google Summer Of : Code :) I've been thinking about the issues for a long time. And there's a number of interrelated problems. All of them are related to the fact that we have the core, SoC and board smashed into one file right now. We really need to finish separating out the core support (it is mostly done right now, except for some of the bus space stuff). The SoC and board support is all in at91.c, which really should be about infrastructure not about boards... First, you need to know what board you are on when you boot. uboot and others pass this information into the kernel using register r3, IIRC. So, there would need to be a way for the early boot code to probe for one of a number of different boards. For SoC, this could be just one board compiled into the kernel (eg, you don't have run time select), but Sam has done some work in this area on the xscale parts you may be able to snag. If we assume that there's a board init routine, we can assume that init routine knows what kind of SoC is installed on the board and can populate the atmelbus with the right devices by calling something like at91rm9200_soc_init(). Then, that board routine can also do the proper routing of the pins to the different peripherals as well, possibly calling some generic peripheral init routines as well (although that's a lot harder to arrange than you might otherwise think given just how flexible these things are). The board routine would also be responsible for calling cninit() as well. If we go this route, we can eliminate much of the #ifdef soup that you were otherwise looking at doing. The AT91RM9200 registers would be defined in one place, but we'd try to use the base + offset approach to isolate the number places that need this information. That's one of the problems with the current set of patches for the at91sam boards: they just do ifdefs rather than do the proper refactoring to get us the most amount of support. So the typical board package would look something like: int kb9202_probe() { if (arm_board_id_from_loader() != KB9202_BOARD_ID) return ENXIO; return 0; } int kb9202_init() { at91rm9200_soc_init(); /* * */ /* * Map in the pmap entries needed on this board for flash, CF, * etc */ /* * Create some kind of descriptor to tell the SD card what GPIO * pins are used for different things, what the MAC address * of the board is, etc. Maybe need one per driver and a list * of them for this board */ } ARM_BOARD_TYPE(kb9202_probe, kb9202_init); As an aside, you may also need to make the different boot loaders pluggable as well, or maybe we would do that as part of another pass. You could assume they were all uboot compatible or something... Linux defines a standard here, and we'd be wise to follow it... Obviously, you'd need to rewrite arm_init as well to defer some of the things it does now. You'd need to move pmap init stuff to the at91rm9200_soc_init(), except for the CF/FLASH stuff, which would move to a board-level init. Some of the mappings might need to change that are done currently inline (which may mean we'd have to do some much needed refactoring here). Right now board_init is in a very special place, and we'd likely need to move the cninit() into each board init so that the boards could control which console was used. There's also some ideas going around about being able to load hints dynamically at run time and the foo_soc_init() and board_init routines would just load them up correctly. That's another orthogonal way to move the tables out of at91rm9200_soc_init and into an easier to manage text form, but at the expense of needing to add code to the hints mechanism, and fight the bike-sheds that surround its replacement. So I'd frankly avoid this for the SoC project. Getting good separation is more important than having a perfect mechanism the separation can use. Those are just the top level ideas I have with respect to this port. In fact, we could generalize this to all embedded boards since I believe it scales well. Linux does something similar, and to add a new board is about a hundred lines, and a new SoC maybe ~400 more. I think getting a good separation would be the key element to focus on, as well as picking one or two other SoCs/boards to validate that the design works and scales. Make those the first priority. Once you have them in place and working, then if you've done things right you'll be able to add all those other cool boards quickly, subject to the availability of drivers and quirks for silicon bugs (oh, and free time). Comments? Warner