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(devp: chosen, name: "bootargs" , buf: cmdline, BOOT_COMMAND_LINE_SIZE-1); |
38 | else |
39 | setprop_str(devp: chosen, name: "bootargs" , buf: cmdline); |
40 | |
41 | printf(fmt: "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(fmt: "ps3_exit\n" ); |
51 | |
52 | /* lv1_panic will shutdown the lpar. */ |
53 | |
54 | lv1_panic(in_1: 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(out_1: &lpar_id); |
66 | |
67 | if (result) |
68 | return -1; |
69 | |
70 | result = lv1_get_logical_ppe_id(out_1: &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(in_1: lpar_id, in_2: 0x0000000062690000ULL, |
83 | in_3: 0x7075000000000000ULL, in_4: ppe_id, in_5: 0x726d5f73697a6500ULL, out_1: rm_size, |
84 | out_2: &v2); |
85 | |
86 | printf(fmt: "%s:%d: ppe_id %lu \n" , __func__, __LINE__, |
87 | (unsigned long)ppe_id); |
88 | printf(fmt: "%s:%d: lpar_id %lu \n" , __func__, __LINE__, |
89 | (unsigned long)lpar_id); |
90 | printf(fmt: "%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(dest: (void *)0x100, src: __system_reset_kernel, n: 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(fmt: "\n-- PS3 bootwrapper --\n" ); |
114 | |
115 | simple_alloc_init(base: _end, heap_size: heapsize, granularity: 32, max_allocs: 64); |
116 | fdt_init(blob: _dtb_start); |
117 | |
118 | chosen = finddevice(name: "/chosen" ); |
119 | |
120 | ps3_repository_read_rm_size(rm_size: &rm_size); |
121 | dt_fixup_memory(start: 0, size: 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(fmt: " 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 | |