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 30bafdb645SGeoff Levand extern s64 lv1_panic(u64 in_1); 31bafdb645SGeoff Levand extern s64 lv1_get_logical_partition_id(u64 *out_1); 32bafdb645SGeoff Levand extern s64 lv1_get_logical_ppe_id(u64 *out_1); 33bafdb645SGeoff Levand extern s64 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 */ 49bafdb645SGeoff Levand static char cmdline[COMMAND_LINE_SIZE] 50bafdb645SGeoff Levand __attribute__((__section__("__builtin_cmdline"))); 51bafdb645SGeoff Levand 52bafdb645SGeoff Levand static void prep_cmdline(void *chosen) 53bafdb645SGeoff Levand { 54bafdb645SGeoff Levand if (cmdline[0] == '\0') 55bafdb645SGeoff Levand getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); 56bafdb645SGeoff Levand else 57bafdb645SGeoff Levand setprop_str(chosen, "bootargs", cmdline); 58bafdb645SGeoff Levand 59bafdb645SGeoff Levand printf("cmdline: '%s'\n", cmdline); 60bafdb645SGeoff Levand } 61bafdb645SGeoff Levand 62bafdb645SGeoff Levand static void ps3_console_write(const char *buf, int len) 63bafdb645SGeoff Levand { 64bafdb645SGeoff Levand } 65bafdb645SGeoff Levand 66bafdb645SGeoff Levand static void ps3_exit(void) 67bafdb645SGeoff Levand { 68bafdb645SGeoff Levand printf("ps3_exit\n"); 69bafdb645SGeoff Levand 70bafdb645SGeoff Levand /* lv1_panic will shutdown the lpar. */ 71bafdb645SGeoff Levand 72bafdb645SGeoff Levand lv1_panic(0); /* zero = do not reboot */ 73bafdb645SGeoff Levand while (1); 74bafdb645SGeoff Levand } 75bafdb645SGeoff Levand 76bafdb645SGeoff Levand static int ps3_repository_read_rm_size(u64 *rm_size) 77bafdb645SGeoff Levand { 78bafdb645SGeoff Levand s64 result; 79bafdb645SGeoff Levand u64 lpar_id; 80bafdb645SGeoff Levand u64 ppe_id; 81bafdb645SGeoff Levand u64 v2; 82bafdb645SGeoff Levand 83bafdb645SGeoff Levand result = lv1_get_logical_partition_id(&lpar_id); 84bafdb645SGeoff Levand 85bafdb645SGeoff Levand if (result) 86bafdb645SGeoff Levand return -1; 87bafdb645SGeoff Levand 88bafdb645SGeoff Levand result = lv1_get_logical_ppe_id(&ppe_id); 89bafdb645SGeoff Levand 90bafdb645SGeoff Levand if (result) 91bafdb645SGeoff Levand return -1; 92bafdb645SGeoff Levand 93bafdb645SGeoff Levand /* 94bafdb645SGeoff Levand * n1: 0000000062690000 : ....bi.. 95bafdb645SGeoff Levand * n2: 7075000000000000 : pu...... 96bafdb645SGeoff Levand * n3: 0000000000000001 : ........ 97bafdb645SGeoff Levand * n4: 726d5f73697a6500 : rm_size. 98bafdb645SGeoff Levand */ 99bafdb645SGeoff Levand 100bafdb645SGeoff Levand result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, 101bafdb645SGeoff Levand 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, 102bafdb645SGeoff Levand &v2); 103bafdb645SGeoff Levand 104bafdb645SGeoff Levand printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, 105bafdb645SGeoff Levand (unsigned long)ppe_id); 106bafdb645SGeoff Levand printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, 107bafdb645SGeoff Levand (unsigned long)lpar_id); 108bafdb645SGeoff Levand printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); 109bafdb645SGeoff Levand 110bafdb645SGeoff Levand return result ? -1 : 0; 111bafdb645SGeoff Levand } 112bafdb645SGeoff Levand 113bafdb645SGeoff Levand void ps3_copy_vectors(void) 114bafdb645SGeoff Levand { 115bafdb645SGeoff Levand extern char __system_reset_kernel[]; 116bafdb645SGeoff Levand 117bafdb645SGeoff Levand memcpy((void *)0x100, __system_reset_kernel, 0x100); 118bafdb645SGeoff Levand flush_cache((void *)0x100, 0x100); 119bafdb645SGeoff Levand } 120bafdb645SGeoff Levand 121bafdb645SGeoff Levand void platform_init(void) 122bafdb645SGeoff Levand { 123bafdb645SGeoff Levand const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ 124bafdb645SGeoff Levand void *chosen; 125bafdb645SGeoff Levand unsigned long ft_addr; 126bafdb645SGeoff Levand u64 rm_size; 127bafdb645SGeoff Levand 128bafdb645SGeoff Levand console_ops.write = ps3_console_write; 129bafdb645SGeoff Levand platform_ops.exit = ps3_exit; 130bafdb645SGeoff Levand 131bafdb645SGeoff Levand printf("\n-- PS3 bootwrapper --\n"); 132bafdb645SGeoff Levand 133bafdb645SGeoff Levand simple_alloc_init(_end, heapsize, 32, 64); 134*2f0dfeaaSDavid Gibson fdt_init(_dtb_start); 135bafdb645SGeoff Levand 136bafdb645SGeoff Levand chosen = finddevice("/chosen"); 137bafdb645SGeoff Levand 138bafdb645SGeoff Levand ps3_repository_read_rm_size(&rm_size); 139bafdb645SGeoff Levand dt_fixup_memory(0, rm_size); 140bafdb645SGeoff Levand 141bafdb645SGeoff Levand if (_initrd_end > _initrd_start) { 142bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); 143bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); 144bafdb645SGeoff Levand } 145bafdb645SGeoff Levand 146bafdb645SGeoff Levand prep_cmdline(chosen); 147bafdb645SGeoff Levand 148bafdb645SGeoff Levand ft_addr = dt_ops.finalize(); 149bafdb645SGeoff Levand 150bafdb645SGeoff Levand ps3_copy_vectors(); 151bafdb645SGeoff Levand 152bafdb645SGeoff Levand printf(" flat tree at 0x%lx\n\r", ft_addr); 153bafdb645SGeoff Levand 154bafdb645SGeoff Levand ((kernel_entry_t)0)(ft_addr, 0, NULL); 155bafdb645SGeoff Levand 156bafdb645SGeoff Levand ps3_exit(); 157bafdb645SGeoff Levand } 158