OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [powerpc/] [arch/] [current/] [src/] [redboot_linux_exec.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      redboot_linux_exec.c
4
//
5
//      RedBoot command to boot Linux
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//####OTHERCOPYRIGHTBEGIN####
40
//
41
//  The structure definitions below are taken from include/asm-/redboot.h in
42
//  the Linux kernel, Copyright (c) 2002, 2003 Gary Thomas, Copyright (c) 1997 Dan Malek. 
43
//  Their presence here is for the express purpose of communication with the Linux 
44
//  kernel being booted and is considered 'fair use' by the original author and
45
//  are included with their permission.
46
//
47
//####OTHERCOPYRIGHTEND####
48
//==========================================================================
49
//#####DESCRIPTIONBEGIN####
50
//
51
// Author(s):    msalter
52
// Contributors: gthomas,msalter
53
// Date:         2002-01-14
54
// Purpose:      
55
// Description:  
56
//              
57
// This code is part of RedBoot (tm).
58
//
59
//####DESCRIPTIONEND####
60
//
61
//==========================================================================
62
 
63
#include <redboot.h>
64
 
65
#include <cyg/hal/hal_arch.h>
66
#include <cyg/hal/hal_if.h>
67
#include <cyg/hal/hal_intr.h>
68
#include <cyg/hal/hal_cache.h>
69
 
70
#ifdef CYGPKG_REDBOOT_NETWORKING
71
#include <net/net.h>
72
#endif
73
 
74
#ifdef CYGPKG_IO_ETH_DRIVERS
75
#include <cyg/io/eth/eth_drv.h>            // Logical driver interfaces
76
#endif
77
 
78
#include CYGHWR_MEMORY_LAYOUT_H
79
 
80
#include <cyg/hal/redboot_linux_exec.h>
81
 
82
//=========================================================================
83
 
84
// Exported CLI function(s)
85
static void do_exec(int argc, char *argv[]);
86
RedBoot_cmd("exec",
87
            "Execute a Linux image - with MMU off",
88
            "[-w timeout]\n"
89
            "        [-c \"kernel command line\"] [<entry_point>]",
90
            do_exec
91
    );
92
 
93
//
94
// Execute a Linux kernel - this is a RedBoot CLI command
95
//
96
static void
97
do_exec(int argc, char *argv[])
98
{
99
    unsigned long entry;
100
    bool wait_time_set, cmd_line_set;
101
    int  wait_time;
102
    char *cmd_line;
103
    char *cline;
104
    struct option_info opts[2];
105
    hal_virtual_comm_table_t *__chan;
106
    int baud_rate;
107
 
108
    bd_t *board_info;
109
    CYG_INTERRUPT_STATE oldints;
110
    unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
111
 
112
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
113
              (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
114
    init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR,
115
              (void *)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
116
    entry = entry_address;  // Default from last 'load' operation
117
    if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM,
118
                   "[physical] starting address")) {
119
        return;
120
    }
121
    if (entry == (unsigned long)NO_MEMORY) {
122
        diag_printf("Can't execute Linux - invalid entry address\n");
123
        return;
124
    }
125
 
126
    // Determine baud rate on current console
127
    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
128
    baud_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
129
    if (baud_rate <= 0) {
130
        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
131
    }
132
 
133
    // Make a little space at the top of the stack, and align to
134
    // 64-bit boundary.
135
    sp = (sp-128) & ~7;  // The Linux boot code uses this space for FIFOs
136
 
137
    // Copy the commandline onto the stack, and set the SP to just below it.
138
    if (cmd_line_set) {
139
        int len,i;
140
 
141
        // get length of string
142
        for( len = 0; cmd_line[len] != '\0'; len++ );
143
 
144
        // decrement sp by length of string and align to
145
        // word boundary.
146
        sp = (sp-(len+1)) & ~3;
147
 
148
        // assign this SP value to command line start
149
        cline = (char *)sp;
150
 
151
        // copy command line over.
152
        for( i = 0; i < len; i++ )
153
            cline[i] = cmd_line[i];
154
        cline[len] = '\0';
155
 
156
    } else {
157
        cline = (char *)NULL;
158
    }
159
 
160
    // Set up parameter struct at top of stack
161
    sp = sp-sizeof(bd_t);
162
    board_info = (bd_t *)sp;
163
    memset(board_info, sizeof(*board_info), 0);
164
 
165
    board_info->bi_tag          = 0x42444944;
166
    board_info->bi_size         = sizeof(*board_info);
167
    board_info->bi_revision     = 1;
168
    board_info->bi_bdate        = 0x06012002;
169
    board_info->bi_memstart     = CYGMEM_REGION_ram;
170
    board_info->bi_memsize      = CYGMEM_REGION_ram_SIZE;
171
    board_info->bi_baudrate     = baud_rate;
172
    board_info->bi_cmdline      = cline;
173
#ifdef CYGPKG_REDBOOT_NETWORKING
174
    memcpy(board_info->bi_enetaddr, __local_enet_addr, sizeof(enet_addr_t));
175
#endif
176
    // Call platform specific code to fill in the platform/architecture specific details
177
    plf_redboot_linux_exec(board_info);
178
 
179
    // adjust SP to 64 byte boundary, and leave a little space
180
    // between it and the commandline for PowerPC calling
181
    // conventions.
182
 
183
    sp = (sp-64)&~63;
184
 
185
    if (wait_time_set) {
186
        int script_timeout_ms = wait_time * 1000;
187
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
188
        unsigned char *hold_script = script;
189
        script = (unsigned char *)0;
190
#endif
191
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
192
                    (void *)entry, wait_time);
193
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
194
            int res;
195
            char line[80];
196
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
197
            if (res == _GETS_CTRLC) {
198
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
199
                script = hold_script;  // Re-enable script
200
#endif
201
                return;
202
            }
203
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
204
        }
205
    }
206
 
207
#ifdef CYGPKG_IO_ETH_DRIVERS
208
    eth_drv_stop();
209
#endif
210
 
211
    // Disable interrupts
212
    HAL_DISABLE_INTERRUPTS(oldints);
213
 
214
    // Put the caches to sleep.
215
    HAL_DCACHE_SYNC();
216
    HAL_ICACHE_DISABLE();
217
    HAL_DCACHE_DISABLE();
218
    HAL_DCACHE_SYNC();
219
    HAL_ICACHE_INVALIDATE_ALL();
220
    HAL_DCACHE_INVALIDATE_ALL();
221
 
222
//    diag_printf("entry %08x, sp %08x, info %08x, cmd line %08x, baud %d\n",
223
//              entry, sp, board_info, cline, baud_rate);
224
//    breakpoint();
225
 
226
    // Call into Linux
227
    __asm__ volatile (
228
                       // Start by disabling MMU - the mappings are
229
                       // 1-1 so this should not cause any problems
230
                       "mfmsr   3\n"
231
                       "li      4,0xFFFFFFCF\n"
232
                       "and     3,3,4\n"
233
                       "sync\n"
234
                       "mtmsr   3\n"
235
                       "sync\n"
236
 
237
                       // Now set up parameters to jump into linux
238
 
239
                       "mtlr    %0\n"           // set entry address in LR
240
                       "mr      1,%1\n"         // set stack pointer
241
                       "mr      3,%2\n"         // set board info in R3
242
                       "mr      4,%3\n"         // set command line in R4
243
                       "blr          \n"        // jump into linux
244
                       :
245
                       : "r"(entry),"r"(sp),"r"(board_info),"r"(cline)
246
                       : "r3", "r4"
247
 
248
                     );
249
}
250
 
251
//=========================================================================
252
// EOF redboot_linux_exec.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.