~ubuntu-branches/ubuntu/trusty/apex/trusty

« back to all changes in this revision

Viewing changes to arm-kernel-shim/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2009-11-10 11:55:15 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091110115515-6jjsf6rc8py35awe
Tags: 1.6.10ubuntu1
* Merge from debian testing, remaining changes:
  - Move apex VMA address to 4MiB to leave enough space for the ubuntu
  kernel and not overwrite apex in ram when loading.
  - nslu2 configuration: set CONFIG_RAMDISK_SIZE=0x0055FFF0 instead of
  0x005FFFF0 to make enough room for ubuntu initramfs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
   Copyright (C) 2006 Marc Singer
7
7
 
8
8
   This program is free software; you can redistribute it and/or
9
 
   modify it under the terms of the GNU General Public License as
10
 
   published by the Free Software Foundation; either version 2 of the
11
 
   License, or (at your option) any later version.
12
 
 
13
 
   This program is distributed in the hope that it will be useful, but
14
 
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
   General Public License for more details.
17
 
 
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21
 
   USA.
 
9
   modify it under the terms of the GNU General Public License
 
10
   version 2 as published by the Free Software Foundation.
 
11
   Please refer to the file debian/copyright for further details.
22
12
 
23
13
   -----------
24
14
   DESCRIPTION
30
20
   the ATAGS and the machine type in the EXTREME circumstance that the
31
21
   platform bootloader cannot be replaced.
32
22
 
 
23
   Offset
 
24
   ------
 
25
 
 
26
   Because we don't know where we're going to be executing, we do a
 
27
   little shenanigans to figure out the execution offset.  With it, we
 
28
   can reference data that was fixed-up with an absolute address even
 
29
   though we are not executing from that address.
 
30
 
 
31
   Endianness
 
32
   ----------
 
33
 
 
34
   This code can be used with either big or little endian kernels, and
 
35
   it can be used to switch the endan-ness of the system from the
 
36
   boot-up default to the desired orientation for the kernel.
 
37
   However, you must swap the bytes of this file and the kernel if you
 
38
   are going to write this data to flash.
 
39
 
33
40
*/
34
41
 
35
42
#define __KERNEL__
38
45
#include "types.h"              /* include/asm-arm/types.h */
39
46
#include "setup.h"              /* include/asm-arm/setup.h */
40
47
 
41
 
#define H_SIZE(pv)      (((struct tag_header*)pv)->size)
42
 
#define H_TAG(pv)       (((struct tag_header*)pv)->tag)
43
 
 
44
 
#define P_CORE(pv)      ((struct tag_core*)(pv + sizeof (struct tag_header)))
45
 
#define P_MEM32(pv)     ((struct tag_mem32*)(pv + sizeof (struct tag_header)))
46
 
#define P_CMDLINE(pv)  ((struct tag_cmdline*)(pv + sizeof (struct tag_header)))
47
 
 
48
48
#define NAKED           __attribute__((naked))
 
49
#define BOOT            __attribute__((section(".boot")))
49
50
 
50
51
#if defined (COMMANDLINE)
51
 
const char __attribute__((section(".rodata"))) cmdline[] = COMMANDLINE;
 
52
const char cmdline[] = COMMANDLINE;
52
53
#endif
53
54
 
54
 
void NAKED __attribute__((section(".boot"))) boot (u32 r0, u32 r1, u32 r2)
 
55
 
 
56
void NAKED BOOT boot (u32 r0, u32 r1, u32 r2)
55
57
{
56
 
  __asm volatile (" nop");
 
58
  __asm volatile ("nop");       /* Require to get compiler to jump here */
57
59
}
58
60
 
59
61
int NAKED start (void)
60
62
{
61
 
  void* pv;
62
 
  extern char SHIM_VMA_END;
 
63
  struct tag* p;
 
64
  extern unsigned long reloc;
 
65
  unsigned long offset = (unsigned long) &reloc;
63
66
 
64
67
#if defined (FORCE_BIGENDIAN)
65
68
 
81
84
  }
82
85
#endif
83
86
 
84
 
  pv = (void*) PHYS_PARAMS;
 
87
  __asm volatile ("bl reloc\n\t"
 
88
           "reloc: sub %0, lr, %0\n\t"
 
89
           ".globl reloc\n\t"
 
90
                  :  "+r" (offset)
 
91
                  :: "lr", "cc");
 
92
 
 
93
#if defined (IXP4XX_SDR_CONFIG)
 
94
  *(volatile unsigned long*) 0xcc000000 = IXP4XX_SDR_CONFIG;
 
95
#endif
 
96
 
 
97
#if defined (CREATE_ATAGS) && defined (PHYS_PARAMS)
 
98
  p = (struct tag*) PHYS_PARAMS;
85
99
 
86
100
        /* Always start with the CORE tag */
87
 
  H_SIZE(pv)            = tag_size (tag_core);
88
 
  H_TAG(pv)             = ATAG_CORE;
89
 
  P_CORE(pv)->flags = 0;
90
 
  P_CORE(pv)->pagesize = 0;
91
 
  P_CORE(pv)->rootdev = 0;
92
 
  pv += H_SIZE(pv)*4;
 
101
  p->hdr.tag            = ATAG_CORE;
 
102
  p->hdr.size           = tag_size (tag_core);
 
103
  p->u.core.flags       = 0;
 
104
  p->u.core.pagesize    = 0;
 
105
  p->u.core.rootdev     = 0;
 
106
  p = tag_next (p);
93
107
 
94
108
        /* Memory tags are always second */
95
 
  H_SIZE(pv)            = tag_size (tag_mem32);
96
 
  H_TAG(pv)             = ATAG_MEM;
97
 
  P_MEM32(pv)->size     = RAM_BANK0_LENGTH;
98
 
  P_MEM32(pv)->start    = RAM_BANK0_START;
99
 
  pv += H_SIZE(pv)*4;
100
 
 
101
 
#if defined (RAM_BANK1_START)
102
 
  H_SIZE(pv)            = tag_size (tag_mem32);
103
 
  H_TAG(pv)             = ATAG_MEM;
104
 
  P_MEM32(pv)->size     = RAM_BANK1_LENGTH;
105
 
  P_MEM32(pv)->start    = RAM_BANK1_START;
106
 
  pv += H_SIZE(pv)*4;
107
 
#endif
 
109
  p->hdr.tag            = ATAG_MEM;
 
110
  p->hdr.size           = tag_size (tag_mem32);
 
111
  p->u.mem.size         = RAM_BANK0_LENGTH;
 
112
  p->u.mem.start        = RAM_BANK0_START;
 
113
  p = tag_next (p);
 
114
 
 
115
# if defined (RAM_BANK1_START)
 
116
  p->hdr.tag            = ATAG_MEM;
 
117
  p->hdr.size           = tag_size (tag_mem32);
 
118
  p->u.mem.size         = RAM_BANK1_LENGTH;
 
119
  p->u.mem.start        = RAM_BANK1_START;
 
120
  p = tag_next (p);
 
121
# endif
 
122
 
 
123
# if defined (INITRD_START)
 
124
  p->hdr.tag            = ATAG_INITRD2;
 
125
  p->hdr.size           = tag_size (tag_initrd);
 
126
  p->u.initrd.start     = INITRD_START;
 
127
  p->u.initrd.size      = INITRD_LENGTH;
 
128
  p = tag_next (p);
 
129
# endif
108
130
 
109
131
        /* Command line */
110
 
#if defined (COMMANDLINE)
111
 
  H_SIZE(pv)            = tag_size(tag_cmdline) + (sizeof (cmdline)+1+3)/4;
112
 
  H_TAG(pv)             = ATAG_CMDLINE;
 
132
# if defined (COMMANDLINE)
 
133
  p->hdr.tag            = ATAG_CMDLINE;
 
134
  p->hdr.size           = tag_size (tag_cmdline)
 
135
    + (sizeof (cmdline)+3)/4 - 1;
113
136
  {
 
137
    const char* sz = cmdline + offset;
114
138
    int i;
115
139
    for (i = 0; i < sizeof (cmdline); ++i)
116
 
      P_CMDLINE(pv)->cmdline[i] = cmdline[i];
 
140
      p->u.cmdline.cmdline[i] = sz[i];
117
141
  }
118
 
  pv += H_SIZE(pv)*4;
119
 
#endif
 
142
  p = tag_next (p);
 
143
# endif
120
144
 
121
145
        /* End */
122
 
  H_SIZE(pv)            = 0;
123
 
  H_TAG(pv)             = ATAG_NONE;
124
 
 
125
 
        /* Pass control to the kernel */
 
146
  p->hdr.tag            = ATAG_NONE;
 
147
  p->hdr.size           = 0;
 
148
 
 
149
#endif
 
150
 
 
151
#if !defined (CREATE_ATAGS) && defined (GUARANTEE_ATAG_CMDLINE)\
 
152
 &&  defined (PHYS_PARAMS)  && defined (COMMANDLINE)
 
153
 
 
154
  {
 
155
    char* cmdlineFound = 0;
 
156
    for_each_tag (p, (struct tag*) PHYS_PARAMS)
 
157
      if (p->hdr.tag == ATAG_CMDLINE)
 
158
        cmdlineFound = p->u.cmdline.cmdline;
 
159
 
 
160
    /* The pointer p is left at the start of the terminating
 
161
       ATAG_NONE.  If cmdlineFound is non-null, we've found an
 
162
       instance of the ATAG_CMDLINE.  If not, we append the default
 
163
       command line and a new ATAG_NONE.
 
164
 
 
165
       The original author was concerned about the possibility that
 
166
       there may be more than one ATAG_CMDLINE record.  There is no
 
167
       stipulation in the documentation for the cmdline tags, but it
 
168
       makes sense that there would be only one.  Even if there were
 
169
       more than one, I'm not sure it would matter since we won't
 
170
       append one if we find any. */
 
171
 
 
172
    if (!cmdlineFound || !*cmdlineFound) {
 
173
      p->hdr.tag = ATAG_CMDLINE;
 
174
      p->hdr.size       = tag_size (tag_cmdline)
 
175
        + (sizeof (cmdline)+3)/4 - 1;
 
176
      {
 
177
        const char* sz = cmdline + offset;
 
178
        int i;
 
179
        for (i = 0; i < sizeof (cmdline); ++i)
 
180
          p->u.cmdline.cmdline[i] = sz[i];
 
181
      }
 
182
      p = tag_next (p);
 
183
      p->hdr.tag = ATAG_NONE;
 
184
      p->hdr.size = 0;
 
185
    }
 
186
  }
 
187
 
 
188
#endif
 
189
 
 
190
        /* Pass control to the kernel.  The compile ought to optimize
 
191
           this to a branch (instead of a branch-link), but it doesn't
 
192
           matter if it doesn't. */
126
193
  boot (0, MACH_TYPE, PHYS_PARAMS);
127
194
}