1 //==========================================================================
3 // redboot_linux_boot.c
5 // RedBoot command to boot Linux
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.
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.
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
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.
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.
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.
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####
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.
48 //####OTHERCOPYRIGHTEND####
49 //==========================================================================
50 //#####DESCRIPTIONBEGIN####
53 // Contributors: gthomas,msalter
58 // This code is part of RedBoot (tm).
60 //####DESCRIPTIONEND####
62 //==========================================================================
65 #include CYGBLD_HAL_TARGET_H
66 #include CYGBLD_HAL_PLATFORM_H
68 #include <cyg/hal/hal_intr.h>
69 #include <cyg/hal/hal_cache.h>
71 #ifdef CYGSEM_REDBOOT_HAL_LINUX_BOOT
73 #include CYGHWR_MEMORY_LAYOUT_H
75 //=========================================================================
77 // Exported CLI function(s)
78 static void do_exec(int argc, char *argv[]);
80 "Execute an image - with MMU off",
82 " [-r <ramdisk addr> [-s <ramdisk length>]]\n"
83 " [-c \"kernel command line\"] [<entry_point>]",
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.
93 /* A Board Information structure that is given to a program when
94 * EPPC-Bug starts it up.
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 */
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.
112 unsigned char bi_enetaddr[6];
113 unsigned int bi_baudrate;
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
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.
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))
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.
154 #define ISA_IO_VIRT_ADDR ((unsigned int)0xfa220000)
155 #define ISA_IO_VIRT_SIZE ((unsigned int)64 * 1024)
157 /* Interrupt assignments.
158 * These are defined (and fixed) by the MBX hardware implementation.
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 */
167 /* The MBX uses the 8259.
169 #define NR_8259_INTS 16
171 // End of imported data/structures
172 //=========================================================================
174 #define MBX_CSR_COM1 0x02 // COM1 enabled
177 // Execute a Linux kernel - this is a RedBoot CLI command
180 do_exec(int argc, char *argv[])
185 bool cmd_line_set, ramdisk_addr_set, ramdisk_size_set;
186 unsigned long ramdisk_addr, ramdisk_size;
189 struct option_info opts[6];
193 CYG_INTERRUPT_STATE oldints;
194 unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
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"))
210 // Make a little space at the top of the stack, and align to
214 // Set up parameter struct at top of stack
216 sp = sp-sizeof(bd_t);
218 board_info = (bd_t *)sp;
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; // ????
231 // Copy the commandline onto the stack, and set the SP to just below it.
233 // If no cmd_line set in args, set it to empty string.
240 // get length of string
241 for( len = 0; cmd_line[len] != '\0'; len++ );
243 // decrement sp by length of string and align to
245 sp = (sp-(len+1)) & ~3;
247 // assign this SP value to command line start
250 // copy command line over.
251 for( i = 0; i < len; i++ )
252 cline[i] = cmd_line[i];
255 // adjust SP to 64 bit boundary, and leave a little space
256 // between it and the commandline for PowerPC calling
263 // Disable interrupts
264 HAL_DISABLE_INTERRUPTS(oldints);
266 // Put the caches to sleep.
268 HAL_ICACHE_DISABLE();
269 HAL_DCACHE_DISABLE();
271 HAL_ICACHE_INVALIDATE_ALL();
272 HAL_DCACHE_INVALIDATE_ALL();
274 // diag_printf("entry %08x sp %08x bi %08x cl %08x\n",
275 // entry,sp,board_info,cline);
279 *(volatile unsigned char *)MBX_CSR_ADDR |= MBX_CSR_COM1; // Magic that says COM1 enabled
281 // Linux seems to want the I/O mapped at 0xFA200000
285 // Start by disabling MMU - the mappings are
286 // 1-1 so this should not cause any problems
294 // Now set up parameters to jump into linux
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
302 : "r"(entry),"r"(sp),"r"(board_info),"r"(cline)
308 #endif // CYGSEM_REDBOOT_HAL_LINUX_BOOT
310 //=========================================================================
311 // EOF redboot_linux_exec.c