Implement new v3_memalloc romvec interface for allocating aligned memory.
[openbios.git] / drivers / macio.c
blob2baf29591065f49a62602b16d765c7ada7bee934
1 /*
2 * derived from mol/mol.c,
3 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2
9 */
11 #include "config.h"
12 #include "arch/common/nvram.h"
13 #include "packages/nvram.h"
14 #include "libopenbios/bindings.h"
15 #include "libc/byteorder.h"
16 #include "libc/vsprintf.h"
18 #include "drivers/drivers.h"
19 #include "macio.h"
20 #include "cuda.h"
21 #include "escc.h"
22 #include "drivers/pci.h"
24 #define OW_IO_NVRAM_SIZE 0x00020000
25 #define OW_IO_NVRAM_OFFSET 0x00060000
26 #define OW_IO_NVRAM_SHIFT 4
28 #define NW_IO_NVRAM_SIZE 0x00004000
29 #define NW_IO_NVRAM_OFFSET 0xfff04000
30 #define NW_IO_NVRAM_SHIFT 1
32 #define IO_OPENPIC_SIZE 0x00040000
33 #define IO_OPENPIC_OFFSET 0x00040000
35 static char *nvram;
37 int
38 arch_nvram_size( void )
40 if (is_oldworld())
41 return OW_IO_NVRAM_SIZE >> OW_IO_NVRAM_SHIFT;
42 else
43 return NW_IO_NVRAM_SIZE >> NW_IO_NVRAM_SHIFT;
46 void macio_nvram_init(const char *path, phys_addr_t addr)
48 phandle_t chosen, aliases;
49 phandle_t dnode;
50 int props[2];
51 char buf[64];
52 unsigned long nvram_size, nvram_offset;
54 if (is_oldworld()) {
55 nvram_offset = OW_IO_NVRAM_OFFSET;
56 nvram_size = OW_IO_NVRAM_SIZE;
57 } else {
58 nvram_offset = NW_IO_NVRAM_OFFSET;
59 nvram_size = NW_IO_NVRAM_SIZE;
60 push_str("/");
61 fword("find-device");
62 fword("new-device");
63 push_str("nvram");
64 fword("device-name");
65 fword("finish-device");
67 nvram = (char*)addr + nvram_offset;
68 snprintf(buf, sizeof(buf), "%s/nvram", path);
69 nvram_init(buf);
70 dnode = find_dev(buf);
71 set_int_property(dnode, "#bytes", arch_nvram_size() );
72 props[0] = __cpu_to_be32(nvram_offset);
73 props[1] = __cpu_to_be32(nvram_size);
74 set_property(dnode, "reg", (char *)&props, sizeof(props));
75 set_property(dnode, "device_type", "nvram", 6);
76 NEWWORLD(set_property(dnode, "compatible", "nvram,flash", 12));
78 chosen = find_dev("/chosen");
79 push_str(buf);
80 fword("open-dev");
81 set_int_property(chosen, "nvram", POP());
83 aliases = find_dev("/aliases");
84 set_property(aliases, "nvram", buf, strlen(buf) + 1);
87 #ifdef DUMP_NVRAM
88 static void
89 dump_nvram(void)
91 int i, j;
92 for (i = 0; i < 10; i++)
94 for (j = 0; j < 16; j++)
95 printk ("%02x ", nvram[(i*16+j)<<4]);
96 printk (" ");
97 for (j = 0; j < 16; j++)
98 if (isprint(nvram[(i*16+j)<<4]))
99 printk("%c", nvram[(i*16+j)<<4]);
100 else
101 printk(".");
102 printk ("\n");
105 #endif
108 void
109 arch_nvram_put( char *buf )
111 int i;
112 unsigned int it_shift;
114 if (is_oldworld())
115 it_shift = OW_IO_NVRAM_SHIFT;
116 else
117 it_shift = NW_IO_NVRAM_SHIFT;
119 for (i=0; i< arch_nvram_size() ; i++)
120 nvram[i << it_shift] = buf[i];
121 #ifdef DUMP_NVRAM
122 printk("new nvram:\n");
123 dump_nvram();
124 #endif
127 void
128 arch_nvram_get( char *buf )
130 int i;
131 unsigned int it_shift;
133 if (is_oldworld())
134 it_shift = OW_IO_NVRAM_SHIFT;
135 else
136 it_shift = NW_IO_NVRAM_SHIFT;
138 for (i=0; i< arch_nvram_size(); i++)
139 buf[i] = nvram[i << it_shift];
141 #ifdef DUMP_NVRAM
142 printk("current nvram:\n");
143 dump_nvram();
144 #endif
147 static void
148 openpic_init(const char *path, phys_addr_t addr)
150 phandle_t target_node;
151 phandle_t dnode;
152 int props[2];
153 char buf[128];
155 push_str(path);
156 fword("find-device");
157 fword("new-device");
158 push_str("interrupt-controller");
159 fword("device-name");
161 snprintf(buf, sizeof(buf), "%s/interrupt-controller", path);
162 dnode = find_dev(buf);
163 set_property(dnode, "device_type", "open-pic", 9);
164 set_property(dnode, "compatible", "chrp,open-pic", 14);
165 set_property(dnode, "built-in", "", 0);
166 props[0] = __cpu_to_be32(IO_OPENPIC_OFFSET);
167 props[1] = __cpu_to_be32(IO_OPENPIC_SIZE);
168 set_property(dnode, "reg", (char *)&props, sizeof(props));
169 set_int_property(dnode, "#interrupt-cells", 2);
170 set_int_property(dnode, "#address-cells", 0);
171 set_property(dnode, "interrupt-controller", "", 0);
172 set_int_property(dnode, "clock-frequency", 4166666);
174 fword("finish-device");
176 if (is_newworld()) {
177 u32 *interrupt_map;
178 int len, i;
180 /* patch in interrupt parent */
181 dnode = find_dev(buf);
183 target_node = find_dev("/pci/mac-io");
184 set_int_property(target_node, "interrupt-parent", dnode);
186 target_node = find_dev("/pci/mac-io/escc/ch-a");
187 set_int_property(target_node, "interrupt-parent", dnode);
189 target_node = find_dev("/pci/mac-io/escc/ch-b");
190 set_int_property(target_node, "interrupt-parent", dnode);
192 target_node = find_dev("/pci");
193 set_int_property(target_node, "interrupt-parent", dnode);
195 interrupt_map = (u32 *)get_property(target_node, "interrupt-map", &len);
196 for (i = 0; i < 4; i++) {
197 interrupt_map[(i * 7) + PCI_INT_MAP_PIC_HANDLE] = (u32)dnode;
199 set_property(target_node, "interrupt-map", (char *)interrupt_map, len);
203 DECLARE_NODE(ob_macio, INSTALL_OPEN, sizeof(int), "Tmac-io");
205 /* ( str len -- addr ) */
207 static void
208 ob_macio_decode_unit(void *private)
210 ucell addr;
212 const char *arg = pop_fstr_copy();
214 addr = strtol(arg, NULL, 16);
216 free((char*)arg);
218 PUSH(addr);
221 /* ( addr -- str len ) */
223 static void
224 ob_macio_encode_unit(void *private)
226 char buf[8];
228 ucell addr = POP();
230 snprintf(buf, sizeof(buf), "%x", addr);
232 push_str(buf);
235 NODE_METHODS(ob_macio) = {
236 { "decode-unit", ob_macio_decode_unit },
237 { "encode-unit", ob_macio_encode_unit },
240 void
241 ob_macio_heathrow_init(const char *path, phys_addr_t addr)
243 phandle_t aliases;
245 REGISTER_NODE(ob_macio);
246 aliases = find_dev("/aliases");
247 set_property(aliases, "mac-io", path, strlen(path) + 1);
249 cuda_init(path, addr);
250 macio_nvram_init(path, addr);
251 escc_init(path, addr);
252 macio_ide_init(path, addr, 1);
255 void
256 ob_macio_keylargo_init(const char *path, phys_addr_t addr)
258 phandle_t aliases;
260 aliases = find_dev("/aliases");
261 set_property(aliases, "mac-io", path, strlen(path) + 1);
263 cuda_init(path, addr);
264 /* The NewWorld NVRAM is not located in the MacIO device */
265 macio_nvram_init("", 0);
266 escc_init(path, addr);
267 macio_ide_init(path, addr, 3);
268 openpic_init(path, addr);