]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/powerpc/mbx/v2_0/src/redboot_linux_exec.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / powerpc / mbx / v2_0 / src / redboot_linux_exec.c
1 //==========================================================================
2 //
3 //      redboot_linux_boot.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 Red Hat, 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 version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //####OTHERCOPYRIGHTBEGIN####
41 //
42 //  The structure definitions below are taken from include/asm-ppc/mbx.h in
43 //  the Linux kernel, Copyright (c) 1997 Dan Malek. Their presence
44 //  here is for the express purpose of communication with the Linux kernel
45 //  being booted and is considered 'fair use' by the original author and
46 //  are included with his permission.
47 //
48 //####OTHERCOPYRIGHTEND####
49 //==========================================================================
50 //#####DESCRIPTIONBEGIN####
51 //
52 // Author(s):    msalter
53 // Contributors: gthomas,msalter
54 // Date:         2002-01-14
55 // Purpose:      
56 // Description:  
57 //              
58 // This code is part of RedBoot (tm).
59 //
60 //####DESCRIPTIONEND####
61 //
62 //==========================================================================
63
64 #include <redboot.h>
65 #include CYGBLD_HAL_TARGET_H
66 #include CYGBLD_HAL_PLATFORM_H
67
68 #include <cyg/hal/hal_intr.h>
69 #include <cyg/hal/hal_cache.h>
70
71 #ifdef CYGSEM_REDBOOT_HAL_LINUX_BOOT
72
73 #include CYGHWR_MEMORY_LAYOUT_H
74
75 //=========================================================================
76
77 // Exported CLI function(s)
78 static void do_exec(int argc, char *argv[]);
79 RedBoot_cmd("exec", 
80             "Execute an image - with MMU off", 
81             "[-w timeout]\n"
82             "        [-r <ramdisk addr> [-s <ramdisk length>]]\n"
83             "        [-c \"kernel command line\"] [<entry_point>]",
84             do_exec
85     );
86
87 //=========================================================================
88 // Imported from Linux kernel include/asm-ppc/mbx.h
89 //   Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
90 //   Used with permission of author.
91
92
93 /* A Board Information structure that is given to a program when
94  * EPPC-Bug starts it up.
95  */
96 typedef struct bd_info {
97         unsigned int    bi_tag;         /* Should be 0x42444944 "BDID" */
98         unsigned int    bi_size;        /* Size of this structure */
99         unsigned int    bi_revision;    /* revision of this structure */
100         unsigned int    bi_bdate;       /* EPPCbug date, i.e. 0x11061997 */
101         unsigned int    bi_memstart;    /* Memory start address */
102         unsigned int    bi_memsize;     /* Memory (end) size in bytes */
103         unsigned int    bi_intfreq;     /* Internal Freq, in Hz */
104         unsigned int    bi_busfreq;     /* Bus Freq, in Hz */
105         unsigned int    bi_clun;        /* Boot device controller */
106         unsigned int    bi_dlun;        /* Boot device logical dev */
107
108         /* These fields are not part of the board information structure
109          * provided by the boot rom.  They are filled in by embed_config.c
110          * so we have the information consistent with other platforms.
111          */
112         unsigned char   bi_enetaddr[6];
113         unsigned int    bi_baudrate;
114 } bd_t;
115
116 /* Memory map for the MBX as configured by EPPC-Bug.  We could reprogram
117  * The SIU and PCI bridge, and try to use larger MMU pages, but the
118  * performance gain is not measureable and it certainly complicates the
119  * generic MMU model.
120  *
121  * In a effort to minimize memory usage for embedded applications, any
122  * PCI driver or ISA driver must request or map the region required by
123  * the device.  For convenience (and since we can map up to 4 Mbytes with
124  * a single page table page), the MMU initialization will map the
125  * NVRAM, Status/Control registers, CPM Dual Port RAM, and the PCI
126  * Bridge CSRs 1:1 into the kernel address space.
127  */
128 #define PCI_ISA_IO_ADDR         ((unsigned)0x80000000)
129 #define PCI_ISA_IO_SIZE         ((unsigned int)(512 * 1024 * 1024))
130 #define PCI_IDE_ADDR            ((unsigned)0x81000000)
131 #define PCI_ISA_MEM_ADDR        ((unsigned)0xc0000000)
132 #define PCI_ISA_MEM_SIZE        ((unsigned int)(512 * 1024 * 1024))
133 #define PCMCIA_MEM_ADDR         ((unsigned int)0xe0000000)
134 #define PCMCIA_MEM_SIZE         ((unsigned int)(64 * 1024 * 1024))
135 #define PCMCIA_DMA_ADDR         ((unsigned int)0xe4000000)
136 #define PCMCIA_DMA_SIZE         ((unsigned int)(64 * 1024 * 1024))
137 #define PCMCIA_ATTRB_ADDR       ((unsigned int)0xe8000000)
138 #define PCMCIA_ATTRB_SIZE       ((unsigned int)(64 * 1024 * 1024))
139 #define PCMCIA_IO_ADDR          ((unsigned int)0xec000000)
140 #define PCMCIA_IO_SIZE          ((unsigned int)(64 * 1024 * 1024))
141 #define NVRAM_ADDR              ((unsigned int)0xfa000000)
142 #define NVRAM_SIZE              ((unsigned int)(1 * 1024 * 1024))
143 #define MBX_CSR_ADDR            ((unsigned int)0xfa100000)
144 #define MBX_CSR_SIZE            ((unsigned int)(1 * 1024 * 1024))
145 #define IMAP_ADDR               ((unsigned int)0xfa200000)
146 #define IMAP_SIZE               ((unsigned int)(64 * 1024))
147 #define PCI_CSR_ADDR            ((unsigned int)0xfa210000)
148 #define PCI_CSR_SIZE            ((unsigned int)(64 * 1024))
149
150 /* Map additional physical space into well known virtual addresses.  Due
151  * to virtual address mapping, these physical addresses are not accessible
152  * in a 1:1 virtual to physical mapping.
153  */
154 #define ISA_IO_VIRT_ADDR        ((unsigned int)0xfa220000)
155 #define ISA_IO_VIRT_SIZE        ((unsigned int)64 * 1024)
156
157 /* Interrupt assignments.
158  * These are defined (and fixed) by the MBX hardware implementation.
159  */
160 #define POWER_FAIL_INT  SIU_IRQ0        /* Power fail */
161 #define TEMP_HILO_INT   SIU_IRQ1        /* Temperature sensor */
162 #define QSPAN_INT       SIU_IRQ2        /* PCI Bridge (DMA CTLR?) */
163 #define ISA_BRIDGE_INT  SIU_IRQ3        /* All those PC things */
164 #define COMM_L_INT      SIU_IRQ6        /* MBX Comm expansion connector pin */
165 #define STOP_ABRT_INT   SIU_IRQ7        /* Stop/Abort header pin */
166
167 /* The MBX uses the 8259.
168 */
169 #define NR_8259_INTS    16
170
171 // End of imported data/structures
172 //=========================================================================
173
174 #define MBX_CSR_COM1            0x02  // COM1 enabled
175
176 //
177 // Execute a Linux kernel - this is a RedBoot CLI command
178 //
179 static void 
180 do_exec(int argc, char *argv[])
181 {
182     unsigned long entry;
183     bool wait_time_set;
184     int  wait_time;
185     bool cmd_line_set, ramdisk_addr_set, ramdisk_size_set;
186     unsigned long ramdisk_addr, ramdisk_size;
187     char *cmd_line;
188     char *cline;
189     struct option_info opts[6];
190     
191     bd_t *board_info;
192
193     CYG_INTERRUPT_STATE oldints;
194     unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
195     
196     init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, 
197               (void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
198     init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR, 
199               (void **)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
200     init_opts(&opts[2], 'r', true, OPTION_ARG_TYPE_NUM, 
201               (void **)&ramdisk_addr, (bool *)&ramdisk_addr_set, "ramdisk_addr");
202     init_opts(&opts[3], 's', true, OPTION_ARG_TYPE_NUM, 
203               (void **)&ramdisk_size, (bool *)&ramdisk_size_set, "ramdisk_size");
204     if (!scan_opts(argc, argv, 1, opts, 4, (void *)&entry, OPTION_ARG_TYPE_NUM, 
205                    "[physical] starting address"))
206     {
207         return;
208     }
209
210     // Make a little space at the top of the stack, and align to
211     // 64-bit boundary.
212     sp = (sp-8) & ~7;
213     
214     // Set up parameter struct at top of stack
215
216     sp = sp-sizeof(bd_t);
217     
218     board_info = (bd_t *)sp;
219     
220     board_info->bi_tag          = 0x42444944;
221     board_info->bi_size         = sizeof(board_info);
222     board_info->bi_revision     = 1;
223     board_info->bi_bdate        = 0x11061997;
224     board_info->bi_memstart     = CYGMEM_REGION_ram;
225     board_info->bi_memsize      = CYGMEM_REGION_ram_SIZE;
226     board_info->bi_intfreq      = CYGHWR_HAL_POWERPC_BOARD_SPEED;
227     board_info->bi_busfreq      = 66; // ????
228     board_info->bi_clun         = 0;  // ????
229     board_info->bi_dlun         = 0;  // ????
230
231     // Copy the commandline onto the stack, and set the SP to just below it.
232
233     // If no cmd_line set in args, set it to empty string.
234     if( !cmd_line_set )
235         cmd_line = "";
236     
237     {
238         int len,i;
239
240         // get length of string
241         for( len = 0; cmd_line[len] != '\0'; len++ );
242
243         // decrement sp by length of string and align to
244         // word boundary.
245         sp = (sp-(len+1)) & ~3;
246
247         // assign this SP value to command line start
248         cline = (char *)sp;
249
250         // copy command line over.
251         for( i = 0; i < len; i++ )
252             cline[i] = cmd_line[i];
253         cline[len] = '\0';
254
255         // adjust SP to 64 bit boundary, and leave a little space
256         // between it and the commandline for PowerPC calling
257         // conventions.
258         
259         sp = (sp-32)&~7;
260     
261     }
262
263     // Disable interrupts
264     HAL_DISABLE_INTERRUPTS(oldints);
265
266     // Put the caches to sleep.
267     HAL_DCACHE_SYNC();
268     HAL_ICACHE_DISABLE();
269     HAL_DCACHE_DISABLE();
270     HAL_DCACHE_SYNC();
271     HAL_ICACHE_INVALIDATE_ALL();
272     HAL_DCACHE_INVALIDATE_ALL();
273
274 //    diag_printf("entry %08x sp %08x bi %08x cl %08x\n",
275 //              entry,sp,board_info,cline);
276 //    breakpoint();
277     
278     // Call into Linux
279     *(volatile unsigned char *)MBX_CSR_ADDR |= MBX_CSR_COM1;  // Magic that says COM1 enabled
280     __asm__ volatile (        
281                        // Linux seems to want the I/O mapped at 0xFA200000
282                        "lis     3,0xFA20\n"
283                        "mtspr   638,3\n"
284
285                        // Start by disabling MMU - the mappings are
286                        // 1-1 so this should not cause any problems
287                        "mfmsr   3\n"
288                        "li      4,0xFFFFFFCF\n"
289                        "and     3,3,4\n"
290                        "sync\n"
291                        "mtmsr   3\n"
292                        "sync\n"
293
294                        // Now set up parameters to jump into linux
295
296                        "mtlr    %0\n"           // set entry address in LR
297                        "mr      1,%1\n"         // set stack pointer
298                        "mr      3,%2\n"         // set board info in R3
299                        "mr      4,%3\n"         // set command line in R4
300                        "blr          \n"        // jump into linux
301                        :
302                        : "r"(entry),"r"(sp),"r"(board_info),"r"(cline)
303                        : "r3", "r4"
304                      
305                      );
306 }
307
308 #endif // CYGSEM_REDBOOT_HAL_LINUX_BOOT
309
310 //=========================================================================
311 // EOF redboot_linux_exec.c