Commit a2dd5da77f2cc9fc9ff11ea6b699556254e94a6c

Authored by Anton Blanchard
Committed by Benjamin Herrenschmidt
1 parent bbad3e50e8

powerpc: Rename duplicate COMMAND_LINE_SIZE define

We have two definitions of COMMAND_LINE_SIZE, one for the kernel
and one for the boot wrapper. I assume this is so the boot
wrapper can be self sufficient and not rely on kernel headers.

Having two defines with the same name is confusing, I just
updated the wrong one when trying to bump it.

Make the boot wrapper define unique by calling it
BOOT_COMMAND_LINE_SIZE.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 3 changed files with 7 additions and 7 deletions Inline Diff

arch/powerpc/boot/main.c
1 /* 1 /*
2 * Copyright (C) Paul Mackerras 1997. 2 * Copyright (C) Paul Mackerras 1997.
3 * 3 *
4 * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner. 4 * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 #include <stdarg.h> 11 #include <stdarg.h>
12 #include <stddef.h> 12 #include <stddef.h>
13 #include "elf.h" 13 #include "elf.h"
14 #include "page.h" 14 #include "page.h"
15 #include "string.h" 15 #include "string.h"
16 #include "stdio.h" 16 #include "stdio.h"
17 #include "ops.h" 17 #include "ops.h"
18 #include "gunzip_util.h" 18 #include "gunzip_util.h"
19 #include "reg.h" 19 #include "reg.h"
20 20
21 static struct gunzip_state gzstate; 21 static struct gunzip_state gzstate;
22 22
23 struct addr_range { 23 struct addr_range {
24 void *addr; 24 void *addr;
25 unsigned long size; 25 unsigned long size;
26 }; 26 };
27 27
28 #undef DEBUG 28 #undef DEBUG
29 29
30 static struct addr_range prep_kernel(void) 30 static struct addr_range prep_kernel(void)
31 { 31 {
32 char elfheader[256]; 32 char elfheader[256];
33 void *vmlinuz_addr = _vmlinux_start; 33 void *vmlinuz_addr = _vmlinux_start;
34 unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start; 34 unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
35 void *addr = 0; 35 void *addr = 0;
36 struct elf_info ei; 36 struct elf_info ei;
37 int len; 37 int len;
38 38
39 /* gunzip the ELF header of the kernel */ 39 /* gunzip the ELF header of the kernel */
40 gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size); 40 gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
41 gunzip_exactly(&gzstate, elfheader, sizeof(elfheader)); 41 gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
42 42
43 if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei)) 43 if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei))
44 fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); 44 fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
45 45
46 if (platform_ops.image_hdr) 46 if (platform_ops.image_hdr)
47 platform_ops.image_hdr(elfheader); 47 platform_ops.image_hdr(elfheader);
48 48
49 /* We need to alloc the memsize: gzip will expand the kernel 49 /* We need to alloc the memsize: gzip will expand the kernel
50 * text/data, then possible rubbish we don't care about. But 50 * text/data, then possible rubbish we don't care about. But
51 * the kernel bss must be claimed (it will be zero'd by the 51 * the kernel bss must be claimed (it will be zero'd by the
52 * kernel itself) 52 * kernel itself)
53 */ 53 */
54 printf("Allocating 0x%lx bytes for kernel ...\n\r", ei.memsize); 54 printf("Allocating 0x%lx bytes for kernel ...\n\r", ei.memsize);
55 55
56 if (platform_ops.vmlinux_alloc) { 56 if (platform_ops.vmlinux_alloc) {
57 addr = platform_ops.vmlinux_alloc(ei.memsize); 57 addr = platform_ops.vmlinux_alloc(ei.memsize);
58 } else { 58 } else {
59 /* 59 /*
60 * Check if the kernel image (without bss) would overwrite the 60 * Check if the kernel image (without bss) would overwrite the
61 * bootwrapper. The device tree has been moved in fdt_init() 61 * bootwrapper. The device tree has been moved in fdt_init()
62 * to an area allocated with malloc() (somewhere past _end). 62 * to an area allocated with malloc() (somewhere past _end).
63 */ 63 */
64 if ((unsigned long)_start < ei.loadsize) 64 if ((unsigned long)_start < ei.loadsize)
65 fatal("Insufficient memory for kernel at address 0!" 65 fatal("Insufficient memory for kernel at address 0!"
66 " (_start=%p, uncompressed size=%08lx)\n\r", 66 " (_start=%p, uncompressed size=%08lx)\n\r",
67 _start, ei.loadsize); 67 _start, ei.loadsize);
68 68
69 if ((unsigned long)_end < ei.memsize) 69 if ((unsigned long)_end < ei.memsize)
70 fatal("The final kernel image would overwrite the " 70 fatal("The final kernel image would overwrite the "
71 "device tree\n\r"); 71 "device tree\n\r");
72 } 72 }
73 73
74 /* Finally, gunzip the kernel */ 74 /* Finally, gunzip the kernel */
75 printf("gunzipping (0x%p <- 0x%p:0x%p)...", addr, 75 printf("gunzipping (0x%p <- 0x%p:0x%p)...", addr,
76 vmlinuz_addr, vmlinuz_addr+vmlinuz_size); 76 vmlinuz_addr, vmlinuz_addr+vmlinuz_size);
77 /* discard up to the actual load data */ 77 /* discard up to the actual load data */
78 gunzip_discard(&gzstate, ei.elfoffset - sizeof(elfheader)); 78 gunzip_discard(&gzstate, ei.elfoffset - sizeof(elfheader));
79 len = gunzip_finish(&gzstate, addr, ei.loadsize); 79 len = gunzip_finish(&gzstate, addr, ei.loadsize);
80 if (len != ei.loadsize) 80 if (len != ei.loadsize)
81 fatal("ran out of data! only got 0x%x of 0x%lx bytes.\n\r", 81 fatal("ran out of data! only got 0x%x of 0x%lx bytes.\n\r",
82 len, ei.loadsize); 82 len, ei.loadsize);
83 printf("done 0x%x bytes\n\r", len); 83 printf("done 0x%x bytes\n\r", len);
84 84
85 flush_cache(addr, ei.loadsize); 85 flush_cache(addr, ei.loadsize);
86 86
87 return (struct addr_range){addr, ei.memsize}; 87 return (struct addr_range){addr, ei.memsize};
88 } 88 }
89 89
90 static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, 90 static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen,
91 unsigned long initrd_addr, 91 unsigned long initrd_addr,
92 unsigned long initrd_size) 92 unsigned long initrd_size)
93 { 93 {
94 /* If we have an image attached to us, it overrides anything 94 /* If we have an image attached to us, it overrides anything
95 * supplied by the loader. */ 95 * supplied by the loader. */
96 if (_initrd_end > _initrd_start) { 96 if (_initrd_end > _initrd_start) {
97 printf("Attached initrd image at 0x%p-0x%p\n\r", 97 printf("Attached initrd image at 0x%p-0x%p\n\r",
98 _initrd_start, _initrd_end); 98 _initrd_start, _initrd_end);
99 initrd_addr = (unsigned long)_initrd_start; 99 initrd_addr = (unsigned long)_initrd_start;
100 initrd_size = _initrd_end - _initrd_start; 100 initrd_size = _initrd_end - _initrd_start;
101 } else if (initrd_size > 0) { 101 } else if (initrd_size > 0) {
102 printf("Using loader supplied ramdisk at 0x%lx-0x%lx\n\r", 102 printf("Using loader supplied ramdisk at 0x%lx-0x%lx\n\r",
103 initrd_addr, initrd_addr + initrd_size); 103 initrd_addr, initrd_addr + initrd_size);
104 } 104 }
105 105
106 /* If there's no initrd at all, we're done */ 106 /* If there's no initrd at all, we're done */
107 if (! initrd_size) 107 if (! initrd_size)
108 return (struct addr_range){0, 0}; 108 return (struct addr_range){0, 0};
109 109
110 /* 110 /*
111 * If the initrd is too low it will be clobbered when the 111 * If the initrd is too low it will be clobbered when the
112 * kernel relocates to its final location. In this case, 112 * kernel relocates to its final location. In this case,
113 * allocate a safer place and move it. 113 * allocate a safer place and move it.
114 */ 114 */
115 if (initrd_addr < vmlinux.size) { 115 if (initrd_addr < vmlinux.size) {
116 void *old_addr = (void *)initrd_addr; 116 void *old_addr = (void *)initrd_addr;
117 117
118 printf("Allocating 0x%lx bytes for initrd ...\n\r", 118 printf("Allocating 0x%lx bytes for initrd ...\n\r",
119 initrd_size); 119 initrd_size);
120 initrd_addr = (unsigned long)malloc(initrd_size); 120 initrd_addr = (unsigned long)malloc(initrd_size);
121 if (! initrd_addr) 121 if (! initrd_addr)
122 fatal("Can't allocate memory for initial " 122 fatal("Can't allocate memory for initial "
123 "ramdisk !\n\r"); 123 "ramdisk !\n\r");
124 printf("Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r", 124 printf("Relocating initrd 0x%lx <- 0x%p (0x%lx bytes)\n\r",
125 initrd_addr, old_addr, initrd_size); 125 initrd_addr, old_addr, initrd_size);
126 memmove((void *)initrd_addr, old_addr, initrd_size); 126 memmove((void *)initrd_addr, old_addr, initrd_size);
127 } 127 }
128 128
129 printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd_addr)); 129 printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd_addr));
130 130
131 /* Tell the kernel initrd address via device tree */ 131 /* Tell the kernel initrd address via device tree */
132 setprop_val(chosen, "linux,initrd-start", (u32)(initrd_addr)); 132 setprop_val(chosen, "linux,initrd-start", (u32)(initrd_addr));
133 setprop_val(chosen, "linux,initrd-end", (u32)(initrd_addr+initrd_size)); 133 setprop_val(chosen, "linux,initrd-end", (u32)(initrd_addr+initrd_size));
134 134
135 return (struct addr_range){(void *)initrd_addr, initrd_size}; 135 return (struct addr_range){(void *)initrd_addr, initrd_size};
136 } 136 }
137 137
138 /* A buffer that may be edited by tools operating on a zImage binary so as to 138 /* A buffer that may be edited by tools operating on a zImage binary so as to
139 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 139 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
140 * The buffer is put in it's own section so that tools may locate it easier. 140 * The buffer is put in it's own section so that tools may locate it easier.
141 */ 141 */
142 static char cmdline[COMMAND_LINE_SIZE] 142 static char cmdline[BOOT_COMMAND_LINE_SIZE]
143 __attribute__((__section__("__builtin_cmdline"))); 143 __attribute__((__section__("__builtin_cmdline")));
144 144
145 static void prep_cmdline(void *chosen) 145 static void prep_cmdline(void *chosen)
146 { 146 {
147 if (cmdline[0] == '\0') 147 if (cmdline[0] == '\0')
148 getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); 148 getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1);
149 149
150 printf("\n\rLinux/PowerPC load: %s", cmdline); 150 printf("\n\rLinux/PowerPC load: %s", cmdline);
151 /* If possible, edit the command line */ 151 /* If possible, edit the command line */
152 if (console_ops.edit_cmdline) 152 if (console_ops.edit_cmdline)
153 console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); 153 console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE);
154 printf("\n\r"); 154 printf("\n\r");
155 155
156 /* Put the command line back into the devtree for the kernel */ 156 /* Put the command line back into the devtree for the kernel */
157 setprop_str(chosen, "bootargs", cmdline); 157 setprop_str(chosen, "bootargs", cmdline);
158 } 158 }
159 159
160 struct platform_ops platform_ops; 160 struct platform_ops platform_ops;
161 struct dt_ops dt_ops; 161 struct dt_ops dt_ops;
162 struct console_ops console_ops; 162 struct console_ops console_ops;
163 struct loader_info loader_info; 163 struct loader_info loader_info;
164 164
165 void start(void) 165 void start(void)
166 { 166 {
167 struct addr_range vmlinux, initrd; 167 struct addr_range vmlinux, initrd;
168 kernel_entry_t kentry; 168 kernel_entry_t kentry;
169 unsigned long ft_addr = 0; 169 unsigned long ft_addr = 0;
170 void *chosen; 170 void *chosen;
171 171
172 /* Do this first, because malloc() could clobber the loader's 172 /* Do this first, because malloc() could clobber the loader's
173 * command line. Only use the loader command line if a 173 * command line. Only use the loader command line if a
174 * built-in command line wasn't set by an external tool */ 174 * built-in command line wasn't set by an external tool */
175 if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) 175 if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0'))
176 memmove(cmdline, loader_info.cmdline, 176 memmove(cmdline, loader_info.cmdline,
177 min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); 177 min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1));
178 178
179 if (console_ops.open && (console_ops.open() < 0)) 179 if (console_ops.open && (console_ops.open() < 0))
180 exit(); 180 exit();
181 if (platform_ops.fixups) 181 if (platform_ops.fixups)
182 platform_ops.fixups(); 182 platform_ops.fixups();
183 183
184 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", 184 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
185 _start, get_sp()); 185 _start, get_sp());
186 186
187 /* Ensure that the device tree has a /chosen node */ 187 /* Ensure that the device tree has a /chosen node */
188 chosen = finddevice("/chosen"); 188 chosen = finddevice("/chosen");
189 if (!chosen) 189 if (!chosen)
190 chosen = create_node(NULL, "chosen"); 190 chosen = create_node(NULL, "chosen");
191 191
192 vmlinux = prep_kernel(); 192 vmlinux = prep_kernel();
193 initrd = prep_initrd(vmlinux, chosen, 193 initrd = prep_initrd(vmlinux, chosen,
194 loader_info.initrd_addr, loader_info.initrd_size); 194 loader_info.initrd_addr, loader_info.initrd_size);
195 prep_cmdline(chosen); 195 prep_cmdline(chosen);
196 196
197 printf("Finalizing device tree..."); 197 printf("Finalizing device tree...");
198 if (dt_ops.finalize) 198 if (dt_ops.finalize)
199 ft_addr = dt_ops.finalize(); 199 ft_addr = dt_ops.finalize();
200 if (ft_addr) 200 if (ft_addr)
201 printf(" flat tree at 0x%lx\n\r", ft_addr); 201 printf(" flat tree at 0x%lx\n\r", ft_addr);
202 else 202 else
203 printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr); 203 printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr);
204 204
205 if (console_ops.close) 205 if (console_ops.close)
206 console_ops.close(); 206 console_ops.close();
207 207
208 kentry = (kernel_entry_t) vmlinux.addr; 208 kentry = (kernel_entry_t) vmlinux.addr;
209 if (ft_addr) 209 if (ft_addr)
210 kentry(ft_addr, 0, NULL); 210 kentry(ft_addr, 0, NULL);
211 else 211 else
212 kentry((unsigned long)initrd.addr, initrd.size, 212 kentry((unsigned long)initrd.addr, initrd.size,
213 loader_info.promptr); 213 loader_info.promptr);
214 214
215 /* console closed so printf in fatal below may not work */ 215 /* console closed so printf in fatal below may not work */
216 fatal("Error: Linux kernel returned to zImage boot wrapper!\n\r"); 216 fatal("Error: Linux kernel returned to zImage boot wrapper!\n\r");
217 } 217 }
218 218
arch/powerpc/boot/ops.h
1 /* 1 /*
2 * Global definition of all the bootwrapper operations. 2 * Global definition of all the bootwrapper operations.
3 * 3 *
4 * Author: Mark A. Greer <mgreer@mvista.com> 4 * Author: Mark A. Greer <mgreer@mvista.com>
5 * 5 *
6 * 2006 (c) MontaVista Software, Inc. This file is licensed under 6 * 2006 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program 7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express 8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied. 9 * or implied.
10 */ 10 */
11 #ifndef _PPC_BOOT_OPS_H_ 11 #ifndef _PPC_BOOT_OPS_H_
12 #define _PPC_BOOT_OPS_H_ 12 #define _PPC_BOOT_OPS_H_
13 13
14 #include <stddef.h> 14 #include <stddef.h>
15 #include "types.h" 15 #include "types.h"
16 #include "string.h" 16 #include "string.h"
17 17
18 #define COMMAND_LINE_SIZE 512 18 #define BOOT_COMMAND_LINE_SIZE 512
19 #define MAX_PATH_LEN 256 19 #define MAX_PATH_LEN 256
20 #define MAX_PROP_LEN 256 /* What should this be? */ 20 #define MAX_PROP_LEN 256 /* What should this be? */
21 21
22 typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5); 22 typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
23 23
24 /* Platform specific operations */ 24 /* Platform specific operations */
25 struct platform_ops { 25 struct platform_ops {
26 void (*fixups)(void); 26 void (*fixups)(void);
27 void (*image_hdr)(const void *); 27 void (*image_hdr)(const void *);
28 void * (*malloc)(unsigned long size); 28 void * (*malloc)(unsigned long size);
29 void (*free)(void *ptr); 29 void (*free)(void *ptr);
30 void * (*realloc)(void *ptr, unsigned long size); 30 void * (*realloc)(void *ptr, unsigned long size);
31 void (*exit)(void); 31 void (*exit)(void);
32 void * (*vmlinux_alloc)(unsigned long size); 32 void * (*vmlinux_alloc)(unsigned long size);
33 }; 33 };
34 extern struct platform_ops platform_ops; 34 extern struct platform_ops platform_ops;
35 35
36 /* Device Tree operations */ 36 /* Device Tree operations */
37 struct dt_ops { 37 struct dt_ops {
38 void * (*finddevice)(const char *name); 38 void * (*finddevice)(const char *name);
39 int (*getprop)(const void *phandle, const char *name, void *buf, 39 int (*getprop)(const void *phandle, const char *name, void *buf,
40 const int buflen); 40 const int buflen);
41 int (*setprop)(const void *phandle, const char *name, 41 int (*setprop)(const void *phandle, const char *name,
42 const void *buf, const int buflen); 42 const void *buf, const int buflen);
43 int (*del_node)(const void *phandle); 43 int (*del_node)(const void *phandle);
44 void *(*get_parent)(const void *phandle); 44 void *(*get_parent)(const void *phandle);
45 /* The node must not already exist. */ 45 /* The node must not already exist. */
46 void *(*create_node)(const void *parent, const char *name); 46 void *(*create_node)(const void *parent, const char *name);
47 void *(*find_node_by_prop_value)(const void *prev, 47 void *(*find_node_by_prop_value)(const void *prev,
48 const char *propname, 48 const char *propname,
49 const char *propval, int proplen); 49 const char *propval, int proplen);
50 void *(*find_node_by_compatible)(const void *prev, 50 void *(*find_node_by_compatible)(const void *prev,
51 const char *compat); 51 const char *compat);
52 unsigned long (*finalize)(void); 52 unsigned long (*finalize)(void);
53 char *(*get_path)(const void *phandle, char *buf, int len); 53 char *(*get_path)(const void *phandle, char *buf, int len);
54 }; 54 };
55 extern struct dt_ops dt_ops; 55 extern struct dt_ops dt_ops;
56 56
57 /* Console operations */ 57 /* Console operations */
58 struct console_ops { 58 struct console_ops {
59 int (*open)(void); 59 int (*open)(void);
60 void (*write)(const char *buf, int len); 60 void (*write)(const char *buf, int len);
61 void (*edit_cmdline)(char *buf, int len); 61 void (*edit_cmdline)(char *buf, int len);
62 void (*close)(void); 62 void (*close)(void);
63 void *data; 63 void *data;
64 }; 64 };
65 extern struct console_ops console_ops; 65 extern struct console_ops console_ops;
66 66
67 /* Serial console operations */ 67 /* Serial console operations */
68 struct serial_console_data { 68 struct serial_console_data {
69 int (*open)(void); 69 int (*open)(void);
70 void (*putc)(unsigned char c); 70 void (*putc)(unsigned char c);
71 unsigned char (*getc)(void); 71 unsigned char (*getc)(void);
72 u8 (*tstc)(void); 72 u8 (*tstc)(void);
73 void (*close)(void); 73 void (*close)(void);
74 }; 74 };
75 75
76 struct loader_info { 76 struct loader_info {
77 void *promptr; 77 void *promptr;
78 unsigned long initrd_addr, initrd_size; 78 unsigned long initrd_addr, initrd_size;
79 char *cmdline; 79 char *cmdline;
80 int cmdline_len; 80 int cmdline_len;
81 }; 81 };
82 extern struct loader_info loader_info; 82 extern struct loader_info loader_info;
83 83
84 void start(void); 84 void start(void);
85 void fdt_init(void *blob); 85 void fdt_init(void *blob);
86 int serial_console_init(void); 86 int serial_console_init(void);
87 int ns16550_console_init(void *devp, struct serial_console_data *scdp); 87 int ns16550_console_init(void *devp, struct serial_console_data *scdp);
88 int mpsc_console_init(void *devp, struct serial_console_data *scdp); 88 int mpsc_console_init(void *devp, struct serial_console_data *scdp);
89 int cpm_console_init(void *devp, struct serial_console_data *scdp); 89 int cpm_console_init(void *devp, struct serial_console_data *scdp);
90 int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp); 90 int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp);
91 int uartlite_console_init(void *devp, struct serial_console_data *scdp); 91 int uartlite_console_init(void *devp, struct serial_console_data *scdp);
92 void *simple_alloc_init(char *base, unsigned long heap_size, 92 void *simple_alloc_init(char *base, unsigned long heap_size,
93 unsigned long granularity, unsigned long max_allocs); 93 unsigned long granularity, unsigned long max_allocs);
94 extern void flush_cache(void *, unsigned long); 94 extern void flush_cache(void *, unsigned long);
95 int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size); 95 int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
96 int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr); 96 int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
97 int dt_is_compatible(void *node, const char *compat); 97 int dt_is_compatible(void *node, const char *compat);
98 void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize); 98 void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize);
99 int dt_get_virtual_reg(void *node, void **addr, int nres); 99 int dt_get_virtual_reg(void *node, void **addr, int nres);
100 100
101 static inline void *finddevice(const char *name) 101 static inline void *finddevice(const char *name)
102 { 102 {
103 return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL; 103 return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
104 } 104 }
105 105
106 static inline int getprop(void *devp, const char *name, void *buf, int buflen) 106 static inline int getprop(void *devp, const char *name, void *buf, int buflen)
107 { 107 {
108 return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1; 108 return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
109 } 109 }
110 110
111 static inline int setprop(void *devp, const char *name, 111 static inline int setprop(void *devp, const char *name,
112 const void *buf, int buflen) 112 const void *buf, int buflen)
113 { 113 {
114 return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1; 114 return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
115 } 115 }
116 #define setprop_val(devp, name, val) \ 116 #define setprop_val(devp, name, val) \
117 do { \ 117 do { \
118 typeof(val) x = (val); \ 118 typeof(val) x = (val); \
119 setprop((devp), (name), &x, sizeof(x)); \ 119 setprop((devp), (name), &x, sizeof(x)); \
120 } while (0) 120 } while (0)
121 121
122 static inline int setprop_str(void *devp, const char *name, const char *buf) 122 static inline int setprop_str(void *devp, const char *name, const char *buf)
123 { 123 {
124 if (dt_ops.setprop) 124 if (dt_ops.setprop)
125 return dt_ops.setprop(devp, name, buf, strlen(buf) + 1); 125 return dt_ops.setprop(devp, name, buf, strlen(buf) + 1);
126 126
127 return -1; 127 return -1;
128 } 128 }
129 129
130 static inline int del_node(const void *devp) 130 static inline int del_node(const void *devp)
131 { 131 {
132 return dt_ops.del_node ? dt_ops.del_node(devp) : -1; 132 return dt_ops.del_node ? dt_ops.del_node(devp) : -1;
133 } 133 }
134 134
135 static inline void *get_parent(const char *devp) 135 static inline void *get_parent(const char *devp)
136 { 136 {
137 return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; 137 return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL;
138 } 138 }
139 139
140 static inline void *create_node(const void *parent, const char *name) 140 static inline void *create_node(const void *parent, const char *name)
141 { 141 {
142 return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL; 142 return dt_ops.create_node ? dt_ops.create_node(parent, name) : NULL;
143 } 143 }
144 144
145 145
146 static inline void *find_node_by_prop_value(const void *prev, 146 static inline void *find_node_by_prop_value(const void *prev,
147 const char *propname, 147 const char *propname,
148 const char *propval, int proplen) 148 const char *propval, int proplen)
149 { 149 {
150 if (dt_ops.find_node_by_prop_value) 150 if (dt_ops.find_node_by_prop_value)
151 return dt_ops.find_node_by_prop_value(prev, propname, 151 return dt_ops.find_node_by_prop_value(prev, propname,
152 propval, proplen); 152 propval, proplen);
153 153
154 return NULL; 154 return NULL;
155 } 155 }
156 156
157 static inline void *find_node_by_prop_value_str(const void *prev, 157 static inline void *find_node_by_prop_value_str(const void *prev,
158 const char *propname, 158 const char *propname,
159 const char *propval) 159 const char *propval)
160 { 160 {
161 return find_node_by_prop_value(prev, propname, propval, 161 return find_node_by_prop_value(prev, propname, propval,
162 strlen(propval) + 1); 162 strlen(propval) + 1);
163 } 163 }
164 164
165 static inline void *find_node_by_devtype(const void *prev, 165 static inline void *find_node_by_devtype(const void *prev,
166 const char *type) 166 const char *type)
167 { 167 {
168 return find_node_by_prop_value_str(prev, "device_type", type); 168 return find_node_by_prop_value_str(prev, "device_type", type);
169 } 169 }
170 170
171 static inline void *find_node_by_alias(const char *alias) 171 static inline void *find_node_by_alias(const char *alias)
172 { 172 {
173 void *devp = finddevice("/aliases"); 173 void *devp = finddevice("/aliases");
174 174
175 if (devp) { 175 if (devp) {
176 char path[MAX_PATH_LEN]; 176 char path[MAX_PATH_LEN];
177 if (getprop(devp, alias, path, MAX_PATH_LEN) > 0) 177 if (getprop(devp, alias, path, MAX_PATH_LEN) > 0)
178 return finddevice(path); 178 return finddevice(path);
179 } 179 }
180 180
181 return NULL; 181 return NULL;
182 } 182 }
183 183
184 static inline void *find_node_by_compatible(const void *prev, 184 static inline void *find_node_by_compatible(const void *prev,
185 const char *compat) 185 const char *compat)
186 { 186 {
187 if (dt_ops.find_node_by_compatible) 187 if (dt_ops.find_node_by_compatible)
188 return dt_ops.find_node_by_compatible(prev, compat); 188 return dt_ops.find_node_by_compatible(prev, compat);
189 189
190 return NULL; 190 return NULL;
191 } 191 }
192 192
193 void dt_fixup_memory(u64 start, u64 size); 193 void dt_fixup_memory(u64 start, u64 size);
194 void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); 194 void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq);
195 void dt_fixup_clock(const char *path, u32 freq); 195 void dt_fixup_clock(const char *path, u32 freq);
196 void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); 196 void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr);
197 void dt_fixup_mac_address(u32 index, const u8 *addr); 197 void dt_fixup_mac_address(u32 index, const u8 *addr);
198 void __dt_fixup_mac_addresses(u32 startindex, ...); 198 void __dt_fixup_mac_addresses(u32 startindex, ...);
199 #define dt_fixup_mac_addresses(...) \ 199 #define dt_fixup_mac_addresses(...) \
200 __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL) 200 __dt_fixup_mac_addresses(0, __VA_ARGS__, NULL)
201 201
202 202
203 static inline void *find_node_by_linuxphandle(const u32 linuxphandle) 203 static inline void *find_node_by_linuxphandle(const u32 linuxphandle)
204 { 204 {
205 return find_node_by_prop_value(NULL, "linux,phandle", 205 return find_node_by_prop_value(NULL, "linux,phandle",
206 (char *)&linuxphandle, sizeof(u32)); 206 (char *)&linuxphandle, sizeof(u32));
207 } 207 }
208 208
209 static inline char *get_path(const void *phandle, char *buf, int len) 209 static inline char *get_path(const void *phandle, char *buf, int len)
210 { 210 {
211 if (dt_ops.get_path) 211 if (dt_ops.get_path)
212 return dt_ops.get_path(phandle, buf, len); 212 return dt_ops.get_path(phandle, buf, len);
213 213
214 return NULL; 214 return NULL;
215 } 215 }
216 216
217 static inline void *malloc(unsigned long size) 217 static inline void *malloc(unsigned long size)
218 { 218 {
219 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; 219 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
220 } 220 }
221 221
222 static inline void free(void *ptr) 222 static inline void free(void *ptr)
223 { 223 {
224 if (platform_ops.free) 224 if (platform_ops.free)
225 platform_ops.free(ptr); 225 platform_ops.free(ptr);
226 } 226 }
227 227
228 static inline void exit(void) 228 static inline void exit(void)
229 { 229 {
230 if (platform_ops.exit) 230 if (platform_ops.exit)
231 platform_ops.exit(); 231 platform_ops.exit();
232 for(;;); 232 for(;;);
233 } 233 }
234 #define fatal(args...) { printf(args); exit(); } 234 #define fatal(args...) { printf(args); exit(); }
235 235
236 236
237 #define BSS_STACK(size) \ 237 #define BSS_STACK(size) \
238 static char _bss_stack[size]; \ 238 static char _bss_stack[size]; \
239 void *_platform_stack_top = _bss_stack + sizeof(_bss_stack); 239 void *_platform_stack_top = _bss_stack + sizeof(_bss_stack);
240 240
241 extern unsigned long timebase_period_ns; 241 extern unsigned long timebase_period_ns;
242 void udelay(long delay); 242 void udelay(long delay);
243 243
244 extern char _start[]; 244 extern char _start[];
245 extern char __bss_start[]; 245 extern char __bss_start[];
246 extern char _end[]; 246 extern char _end[];
247 extern char _vmlinux_start[]; 247 extern char _vmlinux_start[];
248 extern char _vmlinux_end[]; 248 extern char _vmlinux_end[];
249 extern char _initrd_start[]; 249 extern char _initrd_start[];
250 extern char _initrd_end[]; 250 extern char _initrd_end[];
251 extern char _dtb_start[]; 251 extern char _dtb_start[];
252 extern char _dtb_end[]; 252 extern char _dtb_end[];
253 253
254 static inline __attribute__((const)) 254 static inline __attribute__((const))
255 int __ilog2_u32(u32 n) 255 int __ilog2_u32(u32 n)
256 { 256 {
257 int bit; 257 int bit;
258 asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n)); 258 asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n));
259 return 31 - bit; 259 return 31 - bit;
260 } 260 }
261 261
262 #endif /* _PPC_BOOT_OPS_H_ */ 262 #endif /* _PPC_BOOT_OPS_H_ */
263 263
arch/powerpc/boot/ps3.c
1 /* 1 /*
2 * PS3 bootwrapper support. 2 * PS3 bootwrapper support.
3 * 3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc. 4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp. 5 * Copyright 2007 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #include <stdarg.h> 21 #include <stdarg.h>
22 #include <stddef.h> 22 #include <stddef.h>
23 #include "types.h" 23 #include "types.h"
24 #include "elf.h" 24 #include "elf.h"
25 #include "string.h" 25 #include "string.h"
26 #include "stdio.h" 26 #include "stdio.h"
27 #include "page.h" 27 #include "page.h"
28 #include "ops.h" 28 #include "ops.h"
29 29
30 extern int lv1_panic(u64 in_1); 30 extern int lv1_panic(u64 in_1);
31 extern int lv1_get_logical_partition_id(u64 *out_1); 31 extern int lv1_get_logical_partition_id(u64 *out_1);
32 extern int lv1_get_logical_ppe_id(u64 *out_1); 32 extern int lv1_get_logical_ppe_id(u64 *out_1);
33 extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, 33 extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3,
34 u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); 34 u64 in_4, u64 in_5, u64 *out_1, u64 *out_2);
35 35
36 #ifdef DEBUG 36 #ifdef DEBUG
37 #define DBG(fmt...) printf(fmt) 37 #define DBG(fmt...) printf(fmt)
38 #else 38 #else
39 static inline int __attribute__ ((format (printf, 1, 2))) DBG( 39 static inline int __attribute__ ((format (printf, 1, 2))) DBG(
40 const char *fmt, ...) {return 0;} 40 const char *fmt, ...) {return 0;}
41 #endif 41 #endif
42 42
43 BSS_STACK(4096); 43 BSS_STACK(4096);
44 44
45 /* A buffer that may be edited by tools operating on a zImage binary so as to 45 /* A buffer that may be edited by tools operating on a zImage binary so as to
46 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 46 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
47 * The buffer is put in it's own section so that tools may locate it easier. 47 * The buffer is put in it's own section so that tools may locate it easier.
48 */ 48 */
49 49
50 static char cmdline[COMMAND_LINE_SIZE] 50 static char cmdline[BOOT_COMMAND_LINE_SIZE]
51 __attribute__((__section__("__builtin_cmdline"))); 51 __attribute__((__section__("__builtin_cmdline")));
52 52
53 static void prep_cmdline(void *chosen) 53 static void prep_cmdline(void *chosen)
54 { 54 {
55 if (cmdline[0] == '\0') 55 if (cmdline[0] == '\0')
56 getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); 56 getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1);
57 else 57 else
58 setprop_str(chosen, "bootargs", cmdline); 58 setprop_str(chosen, "bootargs", cmdline);
59 59
60 printf("cmdline: '%s'\n", cmdline); 60 printf("cmdline: '%s'\n", cmdline);
61 } 61 }
62 62
63 static void ps3_console_write(const char *buf, int len) 63 static void ps3_console_write(const char *buf, int len)
64 { 64 {
65 } 65 }
66 66
67 static void ps3_exit(void) 67 static void ps3_exit(void)
68 { 68 {
69 printf("ps3_exit\n"); 69 printf("ps3_exit\n");
70 70
71 /* lv1_panic will shutdown the lpar. */ 71 /* lv1_panic will shutdown the lpar. */
72 72
73 lv1_panic(0); /* zero = do not reboot */ 73 lv1_panic(0); /* zero = do not reboot */
74 while (1); 74 while (1);
75 } 75 }
76 76
77 static int ps3_repository_read_rm_size(u64 *rm_size) 77 static int ps3_repository_read_rm_size(u64 *rm_size)
78 { 78 {
79 int result; 79 int result;
80 u64 lpar_id; 80 u64 lpar_id;
81 u64 ppe_id; 81 u64 ppe_id;
82 u64 v2; 82 u64 v2;
83 83
84 result = lv1_get_logical_partition_id(&lpar_id); 84 result = lv1_get_logical_partition_id(&lpar_id);
85 85
86 if (result) 86 if (result)
87 return -1; 87 return -1;
88 88
89 result = lv1_get_logical_ppe_id(&ppe_id); 89 result = lv1_get_logical_ppe_id(&ppe_id);
90 90
91 if (result) 91 if (result)
92 return -1; 92 return -1;
93 93
94 /* 94 /*
95 * n1: 0000000062690000 : ....bi.. 95 * n1: 0000000062690000 : ....bi..
96 * n2: 7075000000000000 : pu...... 96 * n2: 7075000000000000 : pu......
97 * n3: 0000000000000001 : ........ 97 * n3: 0000000000000001 : ........
98 * n4: 726d5f73697a6500 : rm_size. 98 * n4: 726d5f73697a6500 : rm_size.
99 */ 99 */
100 100
101 result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, 101 result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
102 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, 102 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
103 &v2); 103 &v2);
104 104
105 printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, 105 printf("%s:%d: ppe_id %lu \n", __func__, __LINE__,
106 (unsigned long)ppe_id); 106 (unsigned long)ppe_id);
107 printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, 107 printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
108 (unsigned long)lpar_id); 108 (unsigned long)lpar_id);
109 printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); 109 printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);
110 110
111 return result ? -1 : 0; 111 return result ? -1 : 0;
112 } 112 }
113 113
114 void ps3_copy_vectors(void) 114 void ps3_copy_vectors(void)
115 { 115 {
116 extern char __system_reset_kernel[]; 116 extern char __system_reset_kernel[];
117 117
118 memcpy((void *)0x100, __system_reset_kernel, 512); 118 memcpy((void *)0x100, __system_reset_kernel, 512);
119 flush_cache((void *)0x100, 512); 119 flush_cache((void *)0x100, 512);
120 } 120 }
121 121
122 void platform_init(unsigned long null_check) 122 void platform_init(unsigned long null_check)
123 { 123 {
124 const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ 124 const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
125 void *chosen; 125 void *chosen;
126 unsigned long ft_addr; 126 unsigned long ft_addr;
127 u64 rm_size; 127 u64 rm_size;
128 unsigned long val; 128 unsigned long val;
129 129
130 console_ops.write = ps3_console_write; 130 console_ops.write = ps3_console_write;
131 platform_ops.exit = ps3_exit; 131 platform_ops.exit = ps3_exit;
132 132
133 printf("\n-- PS3 bootwrapper --\n"); 133 printf("\n-- PS3 bootwrapper --\n");
134 134
135 simple_alloc_init(_end, heapsize, 32, 64); 135 simple_alloc_init(_end, heapsize, 32, 64);
136 fdt_init(_dtb_start); 136 fdt_init(_dtb_start);
137 137
138 chosen = finddevice("/chosen"); 138 chosen = finddevice("/chosen");
139 139
140 ps3_repository_read_rm_size(&rm_size); 140 ps3_repository_read_rm_size(&rm_size);
141 dt_fixup_memory(0, rm_size); 141 dt_fixup_memory(0, rm_size);
142 142
143 if (_initrd_end > _initrd_start) { 143 if (_initrd_end > _initrd_start) {
144 setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); 144 setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start));
145 setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); 145 setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end));
146 } 146 }
147 147
148 prep_cmdline(chosen); 148 prep_cmdline(chosen);
149 149
150 ft_addr = dt_ops.finalize(); 150 ft_addr = dt_ops.finalize();
151 151
152 ps3_copy_vectors(); 152 ps3_copy_vectors();
153 153
154 printf(" flat tree at 0x%lx\n\r", ft_addr); 154 printf(" flat tree at 0x%lx\n\r", ft_addr);
155 155
156 val = *(unsigned long *)0; 156 val = *(unsigned long *)0;
157 157
158 if (val != null_check) 158 if (val != null_check)
159 printf("null check failed: %lx != %lx\n\r", val, null_check); 159 printf("null check failed: %lx != %lx\n\r", val, null_check);
160 160
161 ((kernel_entry_t)0)(ft_addr, 0, NULL); 161 ((kernel_entry_t)0)(ft_addr, 0, NULL);
162 162
163 ps3_exit(); 163 ps3_exit();
164 } 164 }
165 165