Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 =============================
0004 Adding a new board to LinuxSH
0005 =============================
0006 
0007                Paul Mundt <lethal@linux-sh.org>
0008 
0009 This document attempts to outline what steps are necessary to add support
0010 for new boards to the LinuxSH port under the new 2.5 and 2.6 kernels. This
0011 also attempts to outline some of the noticeable changes between the 2.4
0012 and the 2.5/2.6 SH backend.
0013 
0014 1. New Directory Structure
0015 ==========================
0016 
0017 The first thing to note is the new directory structure. Under 2.4, most
0018 of the board-specific code (with the exception of stboards) ended up
0019 in arch/sh/kernel/ directly, with board-specific headers ending up in
0020 include/asm-sh/. For the new kernel, things are broken out by board type,
0021 companion chip type, and CPU type. Looking at a tree view of this directory
0022 hierarchy looks like the following:
0023 
0024 Board-specific code::
0025 
0026     .
0027     |-- arch
0028     |   `-- sh
0029     |       `-- boards
0030     |           |-- adx
0031     |           |   `-- board-specific files
0032     |           |-- bigsur
0033     |           |   `-- board-specific files
0034     |           |
0035     |           ... more boards here ...
0036     |
0037     `-- include
0038         `-- asm-sh
0039             |-- adx
0040             |   `-- board-specific headers
0041             |-- bigsur
0042             |   `-- board-specific headers
0043             |
0044             .. more boards here ...
0045 
0046 Next, for companion chips::
0047 
0048     .
0049     `-- arch
0050         `-- sh
0051             `-- cchips
0052                 `-- hd6446x
0053                     `-- hd64461
0054                         `-- cchip-specific files
0055 
0056 ... and so on. Headers for the companion chips are treated the same way as
0057 board-specific headers. Thus, include/asm-sh/hd64461 is home to all of the
0058 hd64461-specific headers.
0059 
0060 Finally, CPU family support is also abstracted::
0061 
0062     .
0063     |-- arch
0064     |   `-- sh
0065     |       |-- kernel
0066     |       |   `-- cpu
0067     |       |       |-- sh2
0068     |       |       |   `-- SH-2 generic files
0069     |       |       |-- sh3
0070     |       |       |   `-- SH-3 generic files
0071     |       |       `-- sh4
0072     |       |           `-- SH-4 generic files
0073     |       `-- mm
0074     |           `-- This is also broken out per CPU family, so each family can
0075     |               have their own set of cache/tlb functions.
0076     |
0077     `-- include
0078         `-- asm-sh
0079             |-- cpu-sh2
0080             |   `-- SH-2 specific headers
0081             |-- cpu-sh3
0082             |   `-- SH-3 specific headers
0083             `-- cpu-sh4
0084                 `-- SH-4 specific headers
0085 
0086 It should be noted that CPU subtypes are _not_ abstracted. Thus, these still
0087 need to be dealt with by the CPU family specific code.
0088 
0089 2. Adding a New Board
0090 =====================
0091 
0092 The first thing to determine is whether the board you are adding will be
0093 isolated, or whether it will be part of a family of boards that can mostly
0094 share the same board-specific code with minor differences.
0095 
0096 In the first case, this is just a matter of making a directory for your
0097 board in arch/sh/boards/ and adding rules to hook your board in with the
0098 build system (more on this in the next section). However, for board families
0099 it makes more sense to have a common top-level arch/sh/boards/ directory
0100 and then populate that with sub-directories for each member of the family.
0101 Both the Solution Engine and the hp6xx boards are an example of this.
0102 
0103 After you have setup your new arch/sh/boards/ directory, remember that you
0104 should also add a directory in include/asm-sh for headers localized to this
0105 board (if there are going to be more than one). In order to interoperate
0106 seamlessly with the build system, it's best to have this directory the same
0107 as the arch/sh/boards/ directory name, though if your board is again part of
0108 a family, the build system has ways of dealing with this (via incdir-y
0109 overloading), and you can feel free to name the directory after the family
0110 member itself.
0111 
0112 There are a few things that each board is required to have, both in the
0113 arch/sh/boards and the include/asm-sh/ hierarchy. In order to better
0114 explain this, we use some examples for adding an imaginary board. For
0115 setup code, we're required at the very least to provide definitions for
0116 get_system_type() and platform_setup(). For our imaginary board, this
0117 might look something like::
0118 
0119     /*
0120     * arch/sh/boards/vapor/setup.c - Setup code for imaginary board
0121     */
0122     #include <linux/init.h>
0123 
0124     const char *get_system_type(void)
0125     {
0126             return "FooTech Vaporboard";
0127     }
0128 
0129     int __init platform_setup(void)
0130     {
0131             /*
0132             * If our hardware actually existed, we would do real
0133             * setup here. Though it's also sane to leave this empty
0134             * if there's no real init work that has to be done for
0135             * this board.
0136             */
0137 
0138             /* Start-up imaginary PCI ... */
0139 
0140             /* And whatever else ... */
0141 
0142             return 0;
0143     }
0144 
0145 Our new imaginary board will also have to tie into the machvec in order for it
0146 to be of any use.
0147 
0148 machvec functions fall into a number of categories:
0149 
0150  - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc).
0151  - I/O mapping functions (ioport_map, ioport_unmap, etc).
0152  - a 'heartbeat' function.
0153  - PCI and IRQ initialization routines.
0154  - Consistent allocators (for boards that need special allocators,
0155    particularly for allocating out of some board-specific SRAM for DMA
0156    handles).
0157 
0158 There are machvec functions added and removed over time, so always be sure to
0159 consult include/asm-sh/machvec.h for the current state of the machvec.
0160 
0161 The kernel will automatically wrap in generic routines for undefined function
0162 pointers in the machvec at boot time, as machvec functions are referenced
0163 unconditionally throughout most of the tree. Some boards have incredibly
0164 sparse machvecs (such as the dreamcast and sh03), whereas others must define
0165 virtually everything (rts7751r2d).
0166 
0167 Adding a new machine is relatively trivial (using vapor as an example):
0168 
0169 If the board-specific definitions are quite minimalistic, as is the case for
0170 the vast majority of boards, simply having a single board-specific header is
0171 sufficient.
0172 
0173  - add a new file include/asm-sh/vapor.h which contains prototypes for
0174    any machine specific IO functions prefixed with the machine name, for
0175    example vapor_inb. These will be needed when filling out the machine
0176    vector.
0177 
0178    Note that these prototypes are generated automatically by setting
0179    __IO_PREFIX to something sensible. A typical example would be::
0180 
0181         #define __IO_PREFIX vapor
0182         #include <asm/io_generic.h>
0183 
0184    somewhere in the board-specific header. Any boards being ported that still
0185    have a legacy io.h should remove it entirely and switch to the new model.
0186 
0187  - Add machine vector definitions to the board's setup.c. At a bare minimum,
0188    this must be defined as something like::
0189 
0190         struct sh_machine_vector mv_vapor __initmv = {
0191                 .mv_name = "vapor",
0192         };
0193         ALIAS_MV(vapor)
0194 
0195  - finally add a file arch/sh/boards/vapor/io.c, which contains definitions of
0196    the machine specific io functions (if there are enough to warrant it).
0197 
0198 3. Hooking into the Build System
0199 ================================
0200 
0201 Now that we have the corresponding directories setup, and all of the
0202 board-specific code is in place, it's time to look at how to get the
0203 whole mess to fit into the build system.
0204 
0205 Large portions of the build system are now entirely dynamic, and merely
0206 require the proper entry here and there in order to get things done.
0207 
0208 The first thing to do is to add an entry to arch/sh/Kconfig, under the
0209 "System type" menu::
0210 
0211     config SH_VAPOR
0212             bool "Vapor"
0213             help
0214             select Vapor if configuring for a FooTech Vaporboard.
0215 
0216 next, this has to be added into arch/sh/Makefile. All boards require a
0217 machdir-y entry in order to be built. This entry needs to be the name of
0218 the board directory as it appears in arch/sh/boards, even if it is in a
0219 sub-directory (in which case, all parent directories below arch/sh/boards/
0220 need to be listed). For our new board, this entry can look like::
0221 
0222     machdir-$(CONFIG_SH_VAPOR)  += vapor
0223 
0224 provided that we've placed everything in the arch/sh/boards/vapor/ directory.
0225 
0226 Next, the build system assumes that your include/asm-sh directory will also
0227 be named the same. If this is not the case (as is the case with multiple
0228 boards belonging to a common family), then the directory name needs to be
0229 implicitly appended to incdir-y. The existing code manages this for the
0230 Solution Engine and hp6xx boards, so see these for an example.
0231 
0232 Once that is taken care of, it's time to add an entry for the mach type.
0233 This is done by adding an entry to the end of the arch/sh/tools/mach-types
0234 list. The method for doing this is self explanatory, and so we won't waste
0235 space restating it here. After this is done, you will be able to use
0236 implicit checks for your board if you need this somewhere throughout the
0237 common code, such as::
0238 
0239         /* Make sure we're on the FooTech Vaporboard */
0240         if (!mach_is_vapor())
0241                 return -ENODEV;
0242 
0243 also note that the mach_is_boardname() check will be implicitly forced to
0244 lowercase, regardless of the fact that the mach-types entries are all
0245 uppercase. You can read the script if you really care, but it's pretty ugly,
0246 so you probably don't want to do that.
0247 
0248 Now all that's left to do is providing a defconfig for your new board. This
0249 way, other people who end up with this board can simply use this config
0250 for reference instead of trying to guess what settings are supposed to be
0251 used on it.
0252 
0253 Also, as soon as you have copied over a sample .config for your new board
0254 (assume arch/sh/configs/vapor_defconfig), you can also use this directly as a
0255 build target, and it will be implicitly listed as such in the help text.
0256 
0257 Looking at the 'make help' output, you should now see something like:
0258 
0259 Architecture specific targets (sh):
0260 
0261   =======================   =============================================
0262   zImage                    Compressed kernel image (arch/sh/boot/zImage)
0263   adx_defconfig             Build for adx
0264   cqreek_defconfig          Build for cqreek
0265   dreamcast_defconfig       Build for dreamcast
0266   ...
0267   vapor_defconfig           Build for vapor
0268   =======================   =============================================
0269 
0270 which then allows you to do::
0271 
0272     $ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux
0273 
0274 which will in turn copy the defconfig for this board, run it through
0275 oldconfig (prompting you for any new options since the time of creation),
0276 and start you on your way to having a functional kernel for your new
0277 board.