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