1
/* $Id: prom.c,v 1.2 2001/05/25 22:51:28 bencollins Exp $
2
* init.c: Initialize internal variables used by the PROM
5
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
11
struct linux_romvec *romvec;
12
enum prom_major_version prom_vers;
13
unsigned int prom_rev, prom_prev;
14
void (*prom_cif_handler)(long long *);
15
void (*prom_cif_h32)(long *);
18
/* The root node of the prom device tree. */
21
int prom_stdin, prom_stdout;
24
/* Pointer to the device tree operations structure. */
25
struct linux_nodeops *prom_nodeops;
27
/* You must call prom_init() before you attempt to use any of the
28
* routines in the prom library. It returns 0 on success, 1 on
29
* failure. It gets passed the pointer to the PROM vector.
32
static long long p1275_args[23];
34
int p1275_cmd (char *service, unsigned fmt, ...)
42
/* This means we have a P1275 PROM on a 32-bit machine. There
43
* better not be any 64-bit arguments. */
44
if (prom_cif_handler == 0) {
45
long *p1275_args32 = (long *)p1275_args;
50
p1275_args32[0] = (long)service;
51
p1275_args32[1] = args;
54
for (i = 0; i < args; i++)
55
p1275_args32[i + 3] = (long) va_arg (list, char *);
57
(*prom_cif_h32)(p1275_args32);
58
return p1275_args32[3 + args];
61
p1275_args[0] = (unsigned long long)(unsigned long)service;
65
for (i = 0; i < args; i++, fmt >>= 1) {
67
p1275_args[i + 3] = va_arg (list, unsigned long long);
69
p1275_args[i + 3] = (unsigned long long)(unsigned long) va_arg (list, char *);
72
__asm__ __volatile__ ("\t"
75
"save %0, -0xc0, %%sp\n\t"
76
"rdpr %%pstate, %%l1\n\t"
77
"andn %%l1, 8, %%l1\n\t"
78
"wrpr %%l1, 0, %%pstate\n\t"
81
"wrpr %%l1, 8, %%pstate\n\t"
83
: : "r" (prom_cif_stack), "r" (prom_cif_handler), "r" (p1275_args) :
84
"o0", "o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4",
86
return (int) p1275_args [3 + args];
89
void prom_init(struct linux_romvec *rp, void *cifh, void *cifsp)
91
if (cifh || ((int)rp & 1) != 0) {
92
prom_cif_handler = cifh;
93
prom_cif_h32 = (void *)((unsigned long)rp & ~1);
94
prom_cif_stack = cifsp;
95
prom_vers = PROM_P1275;
96
prom_chosen = p1275_cmd ("finddevice", 1, "/chosen");
97
if (prom_chosen == -1) prom_halt ();
98
prom_stdin = prom_getint (prom_chosen, "stdin");
99
prom_stdout = prom_getint (prom_chosen, "stdout");
103
switch(romvec->pv_romvers) {
115
prom_rev = romvec->pv_plugin_revision;
116
prom_prev = romvec->pv_printrev;
117
prom_nodeops = romvec->pv_nodeops;
118
if (prom_vers != PROM_V0) {
119
prom_stdin = *romvec->pv_v2bootargs.fd_stdin;
120
prom_stdout = *romvec->pv_v2bootargs.fd_stdout;
122
if((((unsigned long) prom_nodeops) == 0) ||
123
(((unsigned long) prom_nodeops) == -1))
127
prom_root_node = prom_getsibling(0);
128
if((prom_root_node == 0) || (prom_root_node == -1))
131
/* Initialization successful. */
136
prom_chain(unsigned long addr, int size, unsigned long entry, char *args, int len)
138
p1275_cmd ("chain", 5, addr, size, entry, args, len);
142
prom_reboot(char *bcommand)
144
p1275_cmd ("boot", 1, bcommand);
147
/* Drop into the prom, with the chance to continue with the 'go'
153
if (prom_vers != PROM_P1275)
154
(*(romvec->pv_abort))();
156
p1275_cmd ("enter", 0);
159
/* Drop into the prom, but completely terminate the program.
160
* No chance of continuing.
165
if (prom_vers != PROM_P1275)
166
(*(romvec->pv_halt))();
168
p1275_cmd ("exit", 0);
172
static int mmu_ihandle_cache = 0;
174
static int prom_get_mmu_ihandle(void)
178
if (mmu_ihandle_cache != 0)
179
return mmu_ihandle_cache;
181
node = prom_finddevice("/chosen");
182
ret = prom_getint(node, "mmu");
183
if (ret == -1 || ret == 0)
184
mmu_ihandle_cache = -1;
186
mmu_ihandle_cache = ret;
191
int prom_map(int mode, unsigned long long size,
192
unsigned long long vaddr,
193
unsigned long long paddr)
195
int ret = p1275_cmd("call-method",
196
P1275_ARG_64B(3) | P1275_ARG_64B(4) |
197
P1275_ARG_64B(6) | 7,
199
prom_get_mmu_ihandle(),
209
void prom_unmap(unsigned long long size, unsigned long long vaddr)
211
p1275_cmd("call-method",
212
P1275_ARG_64B(2) | P1275_ARG_64B(3) | 4,
214
prom_get_mmu_ihandle(),