aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/prom.c
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@mvista.com>2006-09-19 00:05:08 -0400
committerPaul Mackerras <paulus@samba.org>2006-09-20 01:09:58 -0400
commitb2c5f61920eeee9c4e78698de4fde4586fe5ae79 (patch)
tree53927c324413786b34db4f0e79cd0aa436d3f930 /arch/powerpc/boot/prom.c
parenta4dc7ff08915a2035aa6d6decc53fa1deaa410bb (diff)
[POWERPC] Start arch/powerpc/boot code reorganization
This abstracts the operations used in the bootwrapper, and defines the operations needed for the bootwrapper to run on an OF platform. The operations have been divided up into platform ops (platform_ops), firmware ops (fw_ops), device tree ops (dt_ops), and console ops (console_ops). The proper operations will be hooked up at runtime to provide the functionality that you need. Signed-off-by: Mark A. Greer <mgreer@mvista.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/boot/prom.c')
-rw-r--r--arch/powerpc/boot/prom.c165
1 files changed, 0 insertions, 165 deletions
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/prom.c
deleted file mode 100644
index fa0057736f6b..000000000000
--- a/arch/powerpc/boot/prom.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <stdarg.h>
10#include <stddef.h>
11#include "string.h"
12#include "stdio.h"
13#include "prom.h"
14
15int (*prom)(void *);
16phandle chosen_handle;
17ihandle stdout;
18
19int call_prom(const char *service, int nargs, int nret, ...)
20{
21 int i;
22 struct prom_args {
23 const char *service;
24 int nargs;
25 int nret;
26 unsigned int args[12];
27 } args;
28 va_list list;
29
30 args.service = service;
31 args.nargs = nargs;
32 args.nret = nret;
33
34 va_start(list, nret);
35 for (i = 0; i < nargs; i++)
36 args.args[i] = va_arg(list, unsigned int);
37 va_end(list);
38
39 for (i = 0; i < nret; i++)
40 args.args[nargs+i] = 0;
41
42 if (prom(&args) < 0)
43 return -1;
44
45 return (nret > 0)? args.args[nargs]: 0;
46}
47
48int call_prom_ret(const char *service, int nargs, int nret,
49 unsigned int *rets, ...)
50{
51 int i;
52 struct prom_args {
53 const char *service;
54 int nargs;
55 int nret;
56 unsigned int args[12];
57 } args;
58 va_list list;
59
60 args.service = service;
61 args.nargs = nargs;
62 args.nret = nret;
63
64 va_start(list, rets);
65 for (i = 0; i < nargs; i++)
66 args.args[i] = va_arg(list, unsigned int);
67 va_end(list);
68
69 for (i = 0; i < nret; i++)
70 args.args[nargs+i] = 0;
71
72 if (prom(&args) < 0)
73 return -1;
74
75 if (rets != (void *) 0)
76 for (i = 1; i < nret; ++i)
77 rets[i-1] = args.args[nargs+i];
78
79 return (nret > 0)? args.args[nargs]: 0;
80}
81
82int write(void *handle, void *ptr, int nb)
83{
84 return call_prom("write", 3, 1, handle, ptr, nb);
85}
86
87/*
88 * Older OF's require that when claiming a specific range of addresses,
89 * we claim the physical space in the /memory node and the virtual
90 * space in the chosen mmu node, and then do a map operation to
91 * map virtual to physical.
92 */
93static int need_map = -1;
94static ihandle chosen_mmu;
95static phandle memory;
96
97/* returns true if s2 is a prefix of s1 */
98static int string_match(const char *s1, const char *s2)
99{
100 for (; *s2; ++s2)
101 if (*s1++ != *s2)
102 return 0;
103 return 1;
104}
105
106static int check_of_version(void)
107{
108 phandle oprom, chosen;
109 char version[64];
110
111 oprom = finddevice("/openprom");
112 if (oprom == (phandle) -1)
113 return 0;
114 if (getprop(oprom, "model", version, sizeof(version)) <= 0)
115 return 0;
116 version[sizeof(version)-1] = 0;
117 printf("OF version = '%s'\r\n", version);
118 if (!string_match(version, "Open Firmware, 1.")
119 && !string_match(version, "FirmWorks,3."))
120 return 0;
121 chosen = finddevice("/chosen");
122 if (chosen == (phandle) -1) {
123 chosen = finddevice("/chosen@0");
124 if (chosen == (phandle) -1) {
125 printf("no chosen\n");
126 return 0;
127 }
128 }
129 if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
130 printf("no mmu\n");
131 return 0;
132 }
133 memory = (ihandle) call_prom("open", 1, 1, "/memory");
134 if (memory == (ihandle) -1) {
135 memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
136 if (memory == (ihandle) -1) {
137 printf("no memory node\n");
138 return 0;
139 }
140 }
141 printf("old OF detected\r\n");
142 return 1;
143}
144
145void *claim(unsigned long virt, unsigned long size, unsigned long align)
146{
147 int ret;
148 unsigned int result;
149
150 if (need_map < 0)
151 need_map = check_of_version();
152 if (align || !need_map)
153 return (void *) call_prom("claim", 3, 1, virt, size, align);
154
155 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
156 align, size, virt);
157 if (ret != 0 || result == -1)
158 return (void *) -1;
159 ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
160 align, size, virt);
161 /* 0x12 == coherent + read/write */
162 ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
163 0x12, size, virt, virt);
164 return (void *) virt;
165}