1873e65bcSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2bafdb645SGeoff Levand /* 3bafdb645SGeoff Levand * PS3 bootwrapper support. 4bafdb645SGeoff Levand * 5bafdb645SGeoff Levand * Copyright (C) 2007 Sony Computer Entertainment Inc. 6bafdb645SGeoff Levand * Copyright 2007 Sony Corp. 7bafdb645SGeoff Levand */ 8bafdb645SGeoff Levand 9bafdb645SGeoff Levand #include <stdarg.h> 10bafdb645SGeoff Levand #include <stddef.h> 11bafdb645SGeoff Levand #include "types.h" 12bafdb645SGeoff Levand #include "elf.h" 13bafdb645SGeoff Levand #include "string.h" 14bafdb645SGeoff Levand #include "stdio.h" 15bafdb645SGeoff Levand #include "page.h" 16bafdb645SGeoff Levand #include "ops.h" 17bafdb645SGeoff Levand 185761eaa3SGeoff Levand extern int lv1_panic(u64 in_1); 195761eaa3SGeoff Levand extern int lv1_get_logical_partition_id(u64 *out_1); 205761eaa3SGeoff Levand extern int lv1_get_logical_ppe_id(u64 *out_1); 215761eaa3SGeoff Levand extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, 22bafdb645SGeoff Levand u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); 23bafdb645SGeoff Levand 24bafdb645SGeoff Levand #ifdef DEBUG 25bafdb645SGeoff Levand #define DBG(fmt...) printf(fmt) 26bafdb645SGeoff Levand #else 27bafdb645SGeoff Levand static inline int __attribute__ ((format (printf, 1, 2))) DBG( 28bafdb645SGeoff Levand const char *fmt, ...) {return 0;} 29bafdb645SGeoff Levand #endif 30bafdb645SGeoff Levand 31bafdb645SGeoff Levand BSS_STACK(4096); 32bafdb645SGeoff Levand 33bafdb645SGeoff Levand /* A buffer that may be edited by tools operating on a zImage binary so as to 34bafdb645SGeoff Levand * edit the command line passed to vmlinux (by setting /chosen/bootargs). 35bafdb645SGeoff Levand * The buffer is put in it's own section so that tools may locate it easier. 36bafdb645SGeoff Levand */ 375761eaa3SGeoff Levand 38a2dd5da7SAnton Blanchard static char cmdline[BOOT_COMMAND_LINE_SIZE] 39bafdb645SGeoff Levand __attribute__((__section__("__builtin_cmdline"))); 40bafdb645SGeoff Levand 41bafdb645SGeoff Levand static void prep_cmdline(void *chosen) 42bafdb645SGeoff Levand { 43bafdb645SGeoff Levand if (cmdline[0] == '\0') 44a2dd5da7SAnton Blanchard getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); 45bafdb645SGeoff Levand else 46bafdb645SGeoff Levand setprop_str(chosen, "bootargs", cmdline); 47bafdb645SGeoff Levand 48bafdb645SGeoff Levand printf("cmdline: '%s'\n", cmdline); 49bafdb645SGeoff Levand } 50bafdb645SGeoff Levand 51bafdb645SGeoff Levand static void ps3_console_write(const char *buf, int len) 52bafdb645SGeoff Levand { 53bafdb645SGeoff Levand } 54bafdb645SGeoff Levand 55bafdb645SGeoff Levand static void ps3_exit(void) 56bafdb645SGeoff Levand { 57bafdb645SGeoff Levand printf("ps3_exit\n"); 58bafdb645SGeoff Levand 59bafdb645SGeoff Levand /* lv1_panic will shutdown the lpar. */ 60bafdb645SGeoff Levand 61bafdb645SGeoff Levand lv1_panic(0); /* zero = do not reboot */ 62bafdb645SGeoff Levand while (1); 63bafdb645SGeoff Levand } 64bafdb645SGeoff Levand 65bafdb645SGeoff Levand static int ps3_repository_read_rm_size(u64 *rm_size) 66bafdb645SGeoff Levand { 675761eaa3SGeoff Levand int result; 68bafdb645SGeoff Levand u64 lpar_id; 69bafdb645SGeoff Levand u64 ppe_id; 70bafdb645SGeoff Levand u64 v2; 71bafdb645SGeoff Levand 72bafdb645SGeoff Levand result = lv1_get_logical_partition_id(&lpar_id); 73bafdb645SGeoff Levand 74bafdb645SGeoff Levand if (result) 75bafdb645SGeoff Levand return -1; 76bafdb645SGeoff Levand 77bafdb645SGeoff Levand result = lv1_get_logical_ppe_id(&ppe_id); 78bafdb645SGeoff Levand 79bafdb645SGeoff Levand if (result) 80bafdb645SGeoff Levand return -1; 81bafdb645SGeoff Levand 82bafdb645SGeoff Levand /* 83bafdb645SGeoff Levand * n1: 0000000062690000 : ....bi.. 84bafdb645SGeoff Levand * n2: 7075000000000000 : pu...... 85bafdb645SGeoff Levand * n3: 0000000000000001 : ........ 86bafdb645SGeoff Levand * n4: 726d5f73697a6500 : rm_size. 87bafdb645SGeoff Levand */ 88bafdb645SGeoff Levand 89bafdb645SGeoff Levand result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, 90bafdb645SGeoff Levand 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, 91bafdb645SGeoff Levand &v2); 92bafdb645SGeoff Levand 93bafdb645SGeoff Levand printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, 94bafdb645SGeoff Levand (unsigned long)ppe_id); 95bafdb645SGeoff Levand printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, 96bafdb645SGeoff Levand (unsigned long)lpar_id); 97bafdb645SGeoff Levand printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); 98bafdb645SGeoff Levand 99bafdb645SGeoff Levand return result ? -1 : 0; 100bafdb645SGeoff Levand } 101bafdb645SGeoff Levand 102bafdb645SGeoff Levand void ps3_copy_vectors(void) 103bafdb645SGeoff Levand { 104bafdb645SGeoff Levand extern char __system_reset_kernel[]; 105bafdb645SGeoff Levand 1065761eaa3SGeoff Levand memcpy((void *)0x100, __system_reset_kernel, 512); 1075761eaa3SGeoff Levand flush_cache((void *)0x100, 512); 108bafdb645SGeoff Levand } 109bafdb645SGeoff Levand 1106dff5b67SGeoff Levand void platform_init(void) 111bafdb645SGeoff Levand { 112bafdb645SGeoff Levand const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ 113bafdb645SGeoff Levand void *chosen; 114bafdb645SGeoff Levand unsigned long ft_addr; 115bafdb645SGeoff Levand u64 rm_size; 116bafdb645SGeoff Levand 117bafdb645SGeoff Levand console_ops.write = ps3_console_write; 118bafdb645SGeoff Levand platform_ops.exit = ps3_exit; 119bafdb645SGeoff Levand 120bafdb645SGeoff Levand printf("\n-- PS3 bootwrapper --\n"); 121bafdb645SGeoff Levand 122bafdb645SGeoff Levand simple_alloc_init(_end, heapsize, 32, 64); 1232f0dfeaaSDavid Gibson fdt_init(_dtb_start); 124bafdb645SGeoff Levand 125bafdb645SGeoff Levand chosen = finddevice("/chosen"); 126bafdb645SGeoff Levand 127bafdb645SGeoff Levand ps3_repository_read_rm_size(&rm_size); 128bafdb645SGeoff Levand dt_fixup_memory(0, rm_size); 129bafdb645SGeoff Levand 130*df4232d9SNathan Chancellor if (&_initrd_end > &_initrd_start) { 131bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); 132bafdb645SGeoff Levand setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); 133bafdb645SGeoff Levand } 134bafdb645SGeoff Levand 135bafdb645SGeoff Levand prep_cmdline(chosen); 136bafdb645SGeoff Levand 137bafdb645SGeoff Levand ft_addr = dt_ops.finalize(); 138bafdb645SGeoff Levand 139bafdb645SGeoff Levand ps3_copy_vectors(); 140bafdb645SGeoff Levand 141bafdb645SGeoff Levand printf(" flat tree at 0x%lx\n\r", ft_addr); 142bafdb645SGeoff Levand 143bafdb645SGeoff Levand ((kernel_entry_t)0)(ft_addr, 0, NULL); 144bafdb645SGeoff Levand 145bafdb645SGeoff Levand ps3_exit(); 146bafdb645SGeoff Levand } 147