summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/ofw/rtas.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2015-01-22 22:04:43 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2015-01-22 22:04:43 +0000
commit02b832180aa3a176b14e8e39b81ee5ac693a8e95 (patch)
tree699efdbca6bd1d1c7f7cc8738698867a26c00040 /sys/powerpc/ofw/rtas.c
parenta74cf6ece6a4ccf2bb4ff12aaa01aea80ebd1aac (diff)
downloadFreeBSD-src-02b832180aa3a176b14e8e39b81ee5ac693a8e95.zip
FreeBSD-src-02b832180aa3a176b14e8e39b81ee5ac693a8e95.tar.gz
Allow use of a pre-instantiated RTAS as well as a self-instantiated one. This
lets the kernel boot on RTAS-based systems by being kexec'ed from Linux.
Diffstat (limited to 'sys/powerpc/ofw/rtas.c')
-rw-r--r--sys/powerpc/ofw/rtas.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c
index 3e751b3..15cb58e 100644
--- a/sys/powerpc/ofw/rtas.c
+++ b/sys/powerpc/ofw/rtas.c
@@ -86,12 +86,6 @@ rtas_setup(void *junk)
return;
}
OF_package_to_path(rtas, path, sizeof(path));
- rtasi = OF_open(path);
- if (rtasi == 0) {
- rtas = 0;
- printf("Error initializing RTAS: could not open node\n");
- return;
- }
mtx_init(&rtas_mtx, "RTAS", NULL, MTX_SPIN);
@@ -110,7 +104,7 @@ rtas_setup(void *junk)
* It must be 4KB-aligned and not cross a 256 MB boundary.
*/
- OF_getprop(rtas, "rtas-size", &rtas_size, sizeof(rtas_size));
+ OF_getencprop(rtas, "rtas-size", &rtas_size, sizeof(rtas_size));
rtas_size = round_page(rtas_size);
rtas_bounce_virt = contigmalloc(rtas_size + PAGE_SIZE, M_RTAS, 0, 0,
ulmin(platform_real_maxaddr(), BUS_SPACE_MAXADDR_32BIT),
@@ -125,15 +119,32 @@ rtas_setup(void *junk)
* Instantiate RTAS. We always use the 32-bit version.
*/
- result = OF_call_method("instantiate-rtas", rtasi, 1, 1,
- (cell_t)rtas_private_data, &rtas_ptr);
- OF_close(rtasi);
-
- if (result != 0) {
- rtas = 0;
- rtas_ptr = 0;
- printf("Error initializing RTAS (%d)\n", result);
- return;
+ if (OF_hasprop(rtas, "linux,rtas-entry") &&
+ OF_hasprop(rtas, "linux,rtas-base")) {
+ OF_getencprop(rtas, "linux,rtas-base", &rtas_ptr,
+ sizeof(rtas_ptr));
+ rtas_private_data = rtas_ptr;
+ OF_getencprop(rtas, "linux,rtas-entry", &rtas_ptr,
+ sizeof(rtas_ptr));
+ } else {
+ rtasi = OF_open(path);
+ if (rtasi == 0) {
+ rtas = 0;
+ printf("Error initializing RTAS: could not open "
+ "node\n");
+ return;
+ }
+
+ result = OF_call_method("instantiate-rtas", rtasi, 1, 1,
+ (cell_t)rtas_private_data, &rtas_ptr);
+ OF_close(rtasi);
+
+ if (result != 0) {
+ rtas = 0;
+ rtas_ptr = 0;
+ printf("Error initializing RTAS (%d)\n", result);
+ return;
+ }
}
rtas_entry = (uintptr_t)(rtas_ptr);
@@ -252,7 +263,7 @@ rtas_token_lookup(const char *method)
if (!rtas_exists())
return (-1);
- if (OF_getprop(rtas, method, &token, sizeof(token)) == -1)
+ if (OF_getencprop(rtas, method, &token, sizeof(token)) == -1)
return (-1);
return (token);
OpenPOWER on IntegriCloud