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 BSS_STACK(4096); 25 26 /* A buffer that may be edited by tools operating on a zImage binary so as to 27 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 28 * The buffer is put in it's own section so that tools may locate it easier. 29 */ 30 31 static char cmdline[BOOT_COMMAND_LINE_SIZE] 32 __attribute__((__section__("__builtin_cmdline"))); 33 34 static void prep_cmdline(void *chosen) 35 { 36 if (cmdline[0] == '\0') 37 getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); 38 else 39 setprop_str(chosen, "bootargs", cmdline); 40 41 printf("cmdline: '%s'\n", cmdline); 42 } 43 44 static void ps3_console_write(const char *buf, int len) 45 { 46 } 47 48 static void ps3_exit(void) 49 { 50 printf("ps3_exit\n"); 51 52 /* lv1_panic will shutdown the lpar. */ 53 54 lv1_panic(0); /* zero = do not reboot */ 55 while (1); 56 } 57 58 static int ps3_repository_read_rm_size(u64 *rm_size) 59 { 60 int result; 61 u64 lpar_id; 62 u64 ppe_id; 63 u64 v2; 64 65 result = lv1_get_logical_partition_id(&lpar_id); 66 67 if (result) 68 return -1; 69 70 result = lv1_get_logical_ppe_id(&ppe_id); 71 72 if (result) 73 return -1; 74 75 /* 76 * n1: 0000000062690000 : ....bi.. 77 * n2: 7075000000000000 : pu...... 78 * n3: 0000000000000001 : ........ 79 * n4: 726d5f73697a6500 : rm_size. 80 */ 81 82 result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, 83 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, 84 &v2); 85 86 printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, 87 (unsigned long)ppe_id); 88 printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, 89 (unsigned long)lpar_id); 90 printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); 91 92 return result ? -1 : 0; 93 } 94 95 void ps3_copy_vectors(void) 96 { 97 extern char __system_reset_kernel[]; 98 99 memcpy((void *)0x100, __system_reset_kernel, 512); 100 flush_cache((void *)0x100, 512); 101 } 102 103 void platform_init(void) 104 { 105 const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */ 106 void *chosen; 107 unsigned long ft_addr; 108 u64 rm_size; 109 110 console_ops.write = ps3_console_write; 111 platform_ops.exit = ps3_exit; 112 113 printf("\n-- PS3 bootwrapper --\n"); 114 115 simple_alloc_init(_end, heapsize, 32, 64); 116 fdt_init(_dtb_start); 117 118 chosen = finddevice("/chosen"); 119 120 ps3_repository_read_rm_size(&rm_size); 121 dt_fixup_memory(0, rm_size); 122 123 if (&_initrd_end > &_initrd_start) { 124 setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); 125 setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); 126 } 127 128 prep_cmdline(chosen); 129 130 ft_addr = dt_ops.finalize(); 131 132 ps3_copy_vectors(); 133 134 printf(" flat tree at 0x%lx\n\r", ft_addr); 135 136 ((kernel_entry_t)0)(ft_addr, 0, NULL); 137 138 ps3_exit(); 139 } 140