1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun============================= 4*4882a593SmuzhiyunAdding a new board to LinuxSH 5*4882a593Smuzhiyun============================= 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun Paul Mundt <lethal@linux-sh.org> 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunThis document attempts to outline what steps are necessary to add support 10*4882a593Smuzhiyunfor new boards to the LinuxSH port under the new 2.5 and 2.6 kernels. This 11*4882a593Smuzhiyunalso attempts to outline some of the noticeable changes between the 2.4 12*4882a593Smuzhiyunand the 2.5/2.6 SH backend. 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun1. New Directory Structure 15*4882a593Smuzhiyun========================== 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunThe first thing to note is the new directory structure. Under 2.4, most 18*4882a593Smuzhiyunof the board-specific code (with the exception of stboards) ended up 19*4882a593Smuzhiyunin arch/sh/kernel/ directly, with board-specific headers ending up in 20*4882a593Smuzhiyuninclude/asm-sh/. For the new kernel, things are broken out by board type, 21*4882a593Smuzhiyuncompanion chip type, and CPU type. Looking at a tree view of this directory 22*4882a593Smuzhiyunhierarchy looks like the following: 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunBoard-specific code:: 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun . 27*4882a593Smuzhiyun |-- arch 28*4882a593Smuzhiyun | `-- sh 29*4882a593Smuzhiyun | `-- boards 30*4882a593Smuzhiyun | |-- adx 31*4882a593Smuzhiyun | | `-- board-specific files 32*4882a593Smuzhiyun | |-- bigsur 33*4882a593Smuzhiyun | | `-- board-specific files 34*4882a593Smuzhiyun | | 35*4882a593Smuzhiyun | ... more boards here ... 36*4882a593Smuzhiyun | 37*4882a593Smuzhiyun `-- include 38*4882a593Smuzhiyun `-- asm-sh 39*4882a593Smuzhiyun |-- adx 40*4882a593Smuzhiyun | `-- board-specific headers 41*4882a593Smuzhiyun |-- bigsur 42*4882a593Smuzhiyun | `-- board-specific headers 43*4882a593Smuzhiyun | 44*4882a593Smuzhiyun .. more boards here ... 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunNext, for companion chips:: 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun . 49*4882a593Smuzhiyun `-- arch 50*4882a593Smuzhiyun `-- sh 51*4882a593Smuzhiyun `-- cchips 52*4882a593Smuzhiyun `-- hd6446x 53*4882a593Smuzhiyun `-- hd64461 54*4882a593Smuzhiyun `-- cchip-specific files 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun... and so on. Headers for the companion chips are treated the same way as 57*4882a593Smuzhiyunboard-specific headers. Thus, include/asm-sh/hd64461 is home to all of the 58*4882a593Smuzhiyunhd64461-specific headers. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunFinally, CPU family support is also abstracted:: 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun . 63*4882a593Smuzhiyun |-- arch 64*4882a593Smuzhiyun | `-- sh 65*4882a593Smuzhiyun | |-- kernel 66*4882a593Smuzhiyun | | `-- cpu 67*4882a593Smuzhiyun | | |-- sh2 68*4882a593Smuzhiyun | | | `-- SH-2 generic files 69*4882a593Smuzhiyun | | |-- sh3 70*4882a593Smuzhiyun | | | `-- SH-3 generic files 71*4882a593Smuzhiyun | | `-- sh4 72*4882a593Smuzhiyun | | `-- SH-4 generic files 73*4882a593Smuzhiyun | `-- mm 74*4882a593Smuzhiyun | `-- This is also broken out per CPU family, so each family can 75*4882a593Smuzhiyun | have their own set of cache/tlb functions. 76*4882a593Smuzhiyun | 77*4882a593Smuzhiyun `-- include 78*4882a593Smuzhiyun `-- asm-sh 79*4882a593Smuzhiyun |-- cpu-sh2 80*4882a593Smuzhiyun | `-- SH-2 specific headers 81*4882a593Smuzhiyun |-- cpu-sh3 82*4882a593Smuzhiyun | `-- SH-3 specific headers 83*4882a593Smuzhiyun `-- cpu-sh4 84*4882a593Smuzhiyun `-- SH-4 specific headers 85*4882a593Smuzhiyun 86*4882a593SmuzhiyunIt should be noted that CPU subtypes are _not_ abstracted. Thus, these still 87*4882a593Smuzhiyunneed to be dealt with by the CPU family specific code. 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun2. Adding a New Board 90*4882a593Smuzhiyun===================== 91*4882a593Smuzhiyun 92*4882a593SmuzhiyunThe first thing to determine is whether the board you are adding will be 93*4882a593Smuzhiyunisolated, or whether it will be part of a family of boards that can mostly 94*4882a593Smuzhiyunshare the same board-specific code with minor differences. 95*4882a593Smuzhiyun 96*4882a593SmuzhiyunIn the first case, this is just a matter of making a directory for your 97*4882a593Smuzhiyunboard in arch/sh/boards/ and adding rules to hook your board in with the 98*4882a593Smuzhiyunbuild system (more on this in the next section). However, for board families 99*4882a593Smuzhiyunit makes more sense to have a common top-level arch/sh/boards/ directory 100*4882a593Smuzhiyunand then populate that with sub-directories for each member of the family. 101*4882a593SmuzhiyunBoth the Solution Engine and the hp6xx boards are an example of this. 102*4882a593Smuzhiyun 103*4882a593SmuzhiyunAfter you have setup your new arch/sh/boards/ directory, remember that you 104*4882a593Smuzhiyunshould also add a directory in include/asm-sh for headers localized to this 105*4882a593Smuzhiyunboard (if there are going to be more than one). In order to interoperate 106*4882a593Smuzhiyunseamlessly with the build system, it's best to have this directory the same 107*4882a593Smuzhiyunas the arch/sh/boards/ directory name, though if your board is again part of 108*4882a593Smuzhiyuna family, the build system has ways of dealing with this (via incdir-y 109*4882a593Smuzhiyunoverloading), and you can feel free to name the directory after the family 110*4882a593Smuzhiyunmember itself. 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunThere are a few things that each board is required to have, both in the 113*4882a593Smuzhiyunarch/sh/boards and the include/asm-sh/ hierarchy. In order to better 114*4882a593Smuzhiyunexplain this, we use some examples for adding an imaginary board. For 115*4882a593Smuzhiyunsetup code, we're required at the very least to provide definitions for 116*4882a593Smuzhiyunget_system_type() and platform_setup(). For our imaginary board, this 117*4882a593Smuzhiyunmight look something like:: 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun * arch/sh/boards/vapor/setup.c - Setup code for imaginary board 121*4882a593Smuzhiyun */ 122*4882a593Smuzhiyun #include <linux/init.h> 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun const char *get_system_type(void) 125*4882a593Smuzhiyun { 126*4882a593Smuzhiyun return "FooTech Vaporboard"; 127*4882a593Smuzhiyun } 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun int __init platform_setup(void) 130*4882a593Smuzhiyun { 131*4882a593Smuzhiyun /* 132*4882a593Smuzhiyun * If our hardware actually existed, we would do real 133*4882a593Smuzhiyun * setup here. Though it's also sane to leave this empty 134*4882a593Smuzhiyun * if there's no real init work that has to be done for 135*4882a593Smuzhiyun * this board. 136*4882a593Smuzhiyun */ 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun /* Start-up imaginary PCI ... */ 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun /* And whatever else ... */ 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun return 0; 143*4882a593Smuzhiyun } 144*4882a593Smuzhiyun 145*4882a593SmuzhiyunOur new imaginary board will also have to tie into the machvec in order for it 146*4882a593Smuzhiyunto be of any use. 147*4882a593Smuzhiyun 148*4882a593Smuzhiyunmachvec functions fall into a number of categories: 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc). 151*4882a593Smuzhiyun - I/O mapping functions (ioport_map, ioport_unmap, etc). 152*4882a593Smuzhiyun - a 'heartbeat' function. 153*4882a593Smuzhiyun - PCI and IRQ initialization routines. 154*4882a593Smuzhiyun - Consistent allocators (for boards that need special allocators, 155*4882a593Smuzhiyun particularly for allocating out of some board-specific SRAM for DMA 156*4882a593Smuzhiyun handles). 157*4882a593Smuzhiyun 158*4882a593SmuzhiyunThere are machvec functions added and removed over time, so always be sure to 159*4882a593Smuzhiyunconsult include/asm-sh/machvec.h for the current state of the machvec. 160*4882a593Smuzhiyun 161*4882a593SmuzhiyunThe kernel will automatically wrap in generic routines for undefined function 162*4882a593Smuzhiyunpointers in the machvec at boot time, as machvec functions are referenced 163*4882a593Smuzhiyununconditionally throughout most of the tree. Some boards have incredibly 164*4882a593Smuzhiyunsparse machvecs (such as the dreamcast and sh03), whereas others must define 165*4882a593Smuzhiyunvirtually everything (rts7751r2d). 166*4882a593Smuzhiyun 167*4882a593SmuzhiyunAdding a new machine is relatively trivial (using vapor as an example): 168*4882a593Smuzhiyun 169*4882a593SmuzhiyunIf the board-specific definitions are quite minimalistic, as is the case for 170*4882a593Smuzhiyunthe vast majority of boards, simply having a single board-specific header is 171*4882a593Smuzhiyunsufficient. 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun - add a new file include/asm-sh/vapor.h which contains prototypes for 174*4882a593Smuzhiyun any machine specific IO functions prefixed with the machine name, for 175*4882a593Smuzhiyun example vapor_inb. These will be needed when filling out the machine 176*4882a593Smuzhiyun vector. 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun Note that these prototypes are generated automatically by setting 179*4882a593Smuzhiyun __IO_PREFIX to something sensible. A typical example would be:: 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun #define __IO_PREFIX vapor 182*4882a593Smuzhiyun #include <asm/io_generic.h> 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun somewhere in the board-specific header. Any boards being ported that still 185*4882a593Smuzhiyun have a legacy io.h should remove it entirely and switch to the new model. 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun - Add machine vector definitions to the board's setup.c. At a bare minimum, 188*4882a593Smuzhiyun this must be defined as something like:: 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun struct sh_machine_vector mv_vapor __initmv = { 191*4882a593Smuzhiyun .mv_name = "vapor", 192*4882a593Smuzhiyun }; 193*4882a593Smuzhiyun ALIAS_MV(vapor) 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun - finally add a file arch/sh/boards/vapor/io.c, which contains definitions of 196*4882a593Smuzhiyun the machine specific io functions (if there are enough to warrant it). 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun3. Hooking into the Build System 199*4882a593Smuzhiyun================================ 200*4882a593Smuzhiyun 201*4882a593SmuzhiyunNow that we have the corresponding directories setup, and all of the 202*4882a593Smuzhiyunboard-specific code is in place, it's time to look at how to get the 203*4882a593Smuzhiyunwhole mess to fit into the build system. 204*4882a593Smuzhiyun 205*4882a593SmuzhiyunLarge portions of the build system are now entirely dynamic, and merely 206*4882a593Smuzhiyunrequire the proper entry here and there in order to get things done. 207*4882a593Smuzhiyun 208*4882a593SmuzhiyunThe first thing to do is to add an entry to arch/sh/Kconfig, under the 209*4882a593Smuzhiyun"System type" menu:: 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun config SH_VAPOR 212*4882a593Smuzhiyun bool "Vapor" 213*4882a593Smuzhiyun help 214*4882a593Smuzhiyun select Vapor if configuring for a FooTech Vaporboard. 215*4882a593Smuzhiyun 216*4882a593Smuzhiyunnext, this has to be added into arch/sh/Makefile. All boards require a 217*4882a593Smuzhiyunmachdir-y entry in order to be built. This entry needs to be the name of 218*4882a593Smuzhiyunthe board directory as it appears in arch/sh/boards, even if it is in a 219*4882a593Smuzhiyunsub-directory (in which case, all parent directories below arch/sh/boards/ 220*4882a593Smuzhiyunneed to be listed). For our new board, this entry can look like:: 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun machdir-$(CONFIG_SH_VAPOR) += vapor 223*4882a593Smuzhiyun 224*4882a593Smuzhiyunprovided that we've placed everything in the arch/sh/boards/vapor/ directory. 225*4882a593Smuzhiyun 226*4882a593SmuzhiyunNext, the build system assumes that your include/asm-sh directory will also 227*4882a593Smuzhiyunbe named the same. If this is not the case (as is the case with multiple 228*4882a593Smuzhiyunboards belonging to a common family), then the directory name needs to be 229*4882a593Smuzhiyunimplicitly appended to incdir-y. The existing code manages this for the 230*4882a593SmuzhiyunSolution Engine and hp6xx boards, so see these for an example. 231*4882a593Smuzhiyun 232*4882a593SmuzhiyunOnce that is taken care of, it's time to add an entry for the mach type. 233*4882a593SmuzhiyunThis is done by adding an entry to the end of the arch/sh/tools/mach-types 234*4882a593Smuzhiyunlist. The method for doing this is self explanatory, and so we won't waste 235*4882a593Smuzhiyunspace restating it here. After this is done, you will be able to use 236*4882a593Smuzhiyunimplicit checks for your board if you need this somewhere throughout the 237*4882a593Smuzhiyuncommon code, such as:: 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* Make sure we're on the FooTech Vaporboard */ 240*4882a593Smuzhiyun if (!mach_is_vapor()) 241*4882a593Smuzhiyun return -ENODEV; 242*4882a593Smuzhiyun 243*4882a593Smuzhiyunalso note that the mach_is_boardname() check will be implicitly forced to 244*4882a593Smuzhiyunlowercase, regardless of the fact that the mach-types entries are all 245*4882a593Smuzhiyunuppercase. You can read the script if you really care, but it's pretty ugly, 246*4882a593Smuzhiyunso you probably don't want to do that. 247*4882a593Smuzhiyun 248*4882a593SmuzhiyunNow all that's left to do is providing a defconfig for your new board. This 249*4882a593Smuzhiyunway, other people who end up with this board can simply use this config 250*4882a593Smuzhiyunfor reference instead of trying to guess what settings are supposed to be 251*4882a593Smuzhiyunused on it. 252*4882a593Smuzhiyun 253*4882a593SmuzhiyunAlso, as soon as you have copied over a sample .config for your new board 254*4882a593Smuzhiyun(assume arch/sh/configs/vapor_defconfig), you can also use this directly as a 255*4882a593Smuzhiyunbuild target, and it will be implicitly listed as such in the help text. 256*4882a593Smuzhiyun 257*4882a593SmuzhiyunLooking at the 'make help' output, you should now see something like: 258*4882a593Smuzhiyun 259*4882a593SmuzhiyunArchitecture specific targets (sh): 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun ======================= ============================================= 262*4882a593Smuzhiyun zImage Compressed kernel image (arch/sh/boot/zImage) 263*4882a593Smuzhiyun adx_defconfig Build for adx 264*4882a593Smuzhiyun cqreek_defconfig Build for cqreek 265*4882a593Smuzhiyun dreamcast_defconfig Build for dreamcast 266*4882a593Smuzhiyun ... 267*4882a593Smuzhiyun vapor_defconfig Build for vapor 268*4882a593Smuzhiyun ======================= ============================================= 269*4882a593Smuzhiyun 270*4882a593Smuzhiyunwhich then allows you to do:: 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun $ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux 273*4882a593Smuzhiyun 274*4882a593Smuzhiyunwhich will in turn copy the defconfig for this board, run it through 275*4882a593Smuzhiyunoldconfig (prompting you for any new options since the time of creation), 276*4882a593Smuzhiyunand start you on your way to having a functional kernel for your new 277*4882a593Smuzhiyunboard. 278