1bafdb645SGeoff Levand /* 2bafdb645SGeoff Levand * PS3 bootwrapper support. 3bafdb645SGeoff Levand * 4bafdb645SGeoff Levand * Copyright (C) 2007 Sony Computer Entertainment Inc. 5bafdb645SGeoff Levand * Copyright 2007 Sony Corp. 6bafdb645SGeoff Levand * 7bafdb645SGeoff Levand * This program is free software; you can redistribute it and/or modify 8bafdb645SGeoff Levand * it under the terms of the GNU General Public License as published by 9bafdb645SGeoff Levand * the Free Software Foundation; version 2 of the License. 10bafdb645SGeoff Levand * 11bafdb645SGeoff Levand * This program is distributed in the hope that it will be useful, 12bafdb645SGeoff Levand * but WITHOUT ANY WARRANTY; without even the implied warranty of 13bafdb645SGeoff Levand * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14bafdb645SGeoff Levand * GNU General Public License for more details. 15bafdb645SGeoff Levand * 16bafdb645SGeoff Levand * You should have received a copy of the GNU General Public License 17bafdb645SGeoff Levand * along with this program; if not, write to the Free Software 18bafdb645SGeoff Levand * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19bafdb645SGeoff Levand */ 20bafdb645SGeoff Levand 21bafdb645SGeoff Levand #include <stdarg.h> 22bafdb645SGeoff Levand #include <stddef.h> 23bafdb645SGeoff Levand #include "types.h" 24bafdb645SGeoff Levand #include "elf.h" 25bafdb645SGeoff Levand #include "string.h" 26bafdb645SGeoff Levand #include "stdio.h" 27bafdb645SGeoff Levand #include "page.h" 28bafdb645SGeoff Levand #include "ops.h" 29bafdb645SGeoff Levand 305761eaa3SGeoff Levand extern int lv1_panic(u64 in_1); 315761eaa3SGeoff Levand extern int lv1_get_logical_partition_id(u64 *out_1); 325761eaa3SGeoff Levand extern int lv1_get_logical_ppe_id(u64 *out_1); 335761eaa3SGeoff Levand extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, 34bafdb645SGeoff Levand u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); 35bafdb645SGeoff Levand 36bafdb645SGeoff Levand #ifdef DEBUG 37bafdb645SGeoff Levand #define DBG(fmt...) printf(fmt) 38bafdb645SGeoff Levand #else 39bafdb645SGeoff Levand static inline int __attribute__ ((format (printf, 1, 2))) DBG( 40bafdb645SGeoff Levand const char *fmt, ...) {return 0;} 41bafdb645SGeoff Levand #endif 42bafdb645SGeoff Levand 43bafdb645SGeoff Levand BSS_STACK(4096); 44bafdb645SGeoff Levand 45bafdb645SGeoff Levand /* A buffer that may be edited by tools operating on a zImage binary so as to 46bafdb645SGeoff Levand * edit the command line passed to vmlinux (by setting /chosen/bootargs). 47bafdb645SGeoff Levand * The buffer is put in it's own section so that tools may locate it easier. 48bafdb645SGeoff Levand */ 495761eaa3SGeoff Levand 50a2dd5da7SAnton Blanchard static char cmdline[BOOT_COMMAND_LINE_SIZE] 51bafdb645SGeoff Levand __attribute__((__section__("__builtin_cmdline"))); 52bafdb645SGeoff Levand 53bafdb645SGeoff Levand static void prep_cmdline(void *chosen) 54bafdb645SGeoff Levand { 55bafdb645SGeoff Levand if (cmdline[0] == '\0') 56a2dd5da7SAnton Blanchard getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); 57bafdb645SGeoff Levand else 58bafdb645SGeoff Levand setprop_str(chosen, "bootargs", cmdline); 59bafdb645SGeoff Levand 60bafdb645SGeoff Levand printf("cmdline: '%s'\n", cmdline); 61bafdb645SGeoff Levand } 62bafdb645SGeoff Levand 63bafdb645SGeoff Levand static void ps3_console_write(const char *buf, int len) 64bafdb645SGeoff Levand { 65bafdb645SGeoff Levand } 66bafdb645SGeoff Levand 67bafdb645SGeoff Levand static void ps3_exit(void) 68bafdb645SGeoff Levand { 69bafdb645SGeoff Levand printf("ps3_exit\n"); 70bafdb645SGeoff Levand 71bafdb645SGeoff Levand /* lv1_panic will shutdown the lpar. */ 72bafdb645SGeoff Levand 73bafdb645SGeoff Levand lv1_panic(0); /* zero = do not reboot */ 74bafdb645SGeoff Levand while (1); 75bafdb645SGeoff Levand } 76bafdb645SGeoff Levand 77bafdb645SGeoff Levand static int ps3_repository_read_rm_size(u64 *rm_size) 78bafdb645SGeoff Levand { 795761eaa3SGeoff Levand int result; 80bafdb645SGeoff Levand u64 lpar_id; 81bafdb645SGeoff Levand u64 ppe_id; 82bafdb645SGeoff Levand u64 v2; 83bafdb645SGeoff Levand 84bafdb645SGeoff Levand result = lv1_get_logical_partition_id(&lpar_id); 85bafdb645SGeoff Levand 86bafdb645SGeoff Levand if (result) 87bafdb645SGeoff Levand return -1; 88bafdb645SGeoff Levand 89bafdb645SGeoff Levand result = lv1_get_logical_ppe_id(&ppe_id); 90bafdb645SGeoff Levand 91bafdb645SGeoff Levand if (result) 92bafdb645SGeoff Levand return -1; 93bafdb645SGeoff Levand 94bafdb645SGeoff Levand /* 95bafdb645SGeoff Levand * n1: 0000000062690000 : ....bi.. 96bafdb645SGeoff Levand * n2: 7075000000000000 : pu...... 97bafdb645SGeoff Levand * n3: 0000000000000001 : ........ 98bafdb645SGeoff Levand * n4: 726d5f73697a6500 : rm_size. 99bafdb645SGeoff Levand */ 100bafdb645SGeoff Levand 101bafdb645SGeoff Levand result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, 102bafdb645SGeoff Levand 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, 103bafdb645SGeoff Levand &v2); 104bafdb645SGeoff Levand 105bafdb645SGeoff Levand printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, 106bafdb645SGeoff Levand (unsigned long)ppe_id); 107bafdb645SGeoff Levand printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, 108bafdb645SGeoff Levand (unsigned long)lpar_id); 109bafdb645SGeoff Levand printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); 110bafdb645SGeoff Levand 111bafdb645SGeoff Levand return result ? -1 : 0; 112bafdb645SGeoff Levand } 113bafdb645SGeoff Levand 114bafdb645SGeoff Levand void ps3_copy_vectors(void) 115bafdb645SGeoff Levand { 116bafdb645SGeoff Levand extern char __system_reset_kernel[]; 117bafdb645SGeoff Levand 1185761eaa3SGeoff Levand memcpy((void *)0x100, __system_reset_kernel, 512); 1195761eaa3SGeoff Levand flush_cache((void *)0x100, 512); 120bafdb645SGeoff Levand } 121bafdb645SGeoff Levand 122*6dff5b67SGeoff Levand void platform_init(void) 123bafdb645SGeoff Levand { 124bafdb645SGeoff Levand const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ 125bafdb645SGeoff Levand void *chosen; 126bafdb645SGeoff Levand unsigned long ft_addr; 127bafdb645SGeoff Levand u64 rm_size; 128bafdb645SGeoff Levand 129bafdb645SGeoff Levand console_ops.write = ps3_console_write; 130bafdb645SGeoff Levand platform_ops.exit = ps3_exit; 131bafdb645SGeoff Levand 132bafdb645SGeoff Levand printf("\n-- PS3 bootwrapper --\n"); 133bafdb645SGeoff Levand 134bafdb645SGeoff Levand simple_alloc_init(_end, heapsize, 32, 64); 1352f0dfeaaSDavid Gibson fdt_init(_dtb_start); 136bafdb645SGeoff Levand 137bafdb645SGeoff Levand chosen = finddevice("/chosen"); 138bafdb645SGeoff Levand 139bafdb645SGeoff Levand ps3_repository_read_rm_size(&rm_size); 140bafdb645SGeoff Levand dt_fixup_memory(0, rm_size); 141bafdb645SGeoff Levand 142bafdb645SGeoff Levand if (_initrd_end > _initrd_start) { 143bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); 144bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); 145bafdb645SGeoff Levand } 146bafdb645SGeoff Levand 147bafdb645SGeoff Levand prep_cmdline(chosen); 148bafdb645SGeoff Levand 149bafdb645SGeoff Levand ft_addr = dt_ops.finalize(); 150bafdb645SGeoff Levand 151bafdb645SGeoff Levand ps3_copy_vectors(); 152bafdb645SGeoff Levand 153bafdb645SGeoff Levand printf(" flat tree at 0x%lx\n\r", ft_addr); 154bafdb645SGeoff Levand 155bafdb645SGeoff Levand ((kernel_entry_t)0)(ft_addr, 0, NULL); 156bafdb645SGeoff Levand 157bafdb645SGeoff Levand ps3_exit(); 158bafdb645SGeoff Levand } 159