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
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"
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
31 #define IO_OPENPIC_SIZE 0x00040000
32 #define IO_OPENPIC_OFFSET 0x00040000
36 static int macio_nvram_shift(void)
41 return OW_IO_NVRAM_SHIFT;
43 nvram_flat = fw_cfg_read_i32(FW_CFG_PPC_NVRAM_FLAT);
44 return nvram_flat ? 0 : 1;
48 macio_get_nvram_size(void)
50 int shift = macio_nvram_shift();
52 return OW_IO_NVRAM_SIZE >> shift;
54 return NW_IO_NVRAM_SIZE >> shift;
57 static unsigned long macio_nvram_offset(void)
61 /* Hypervisor tells us where NVRAM lies */
62 r = fw_cfg_read_i32(FW_CFG_PPC_NVRAM_ADDR);
66 /* Fall back to hardcoded addresses */
68 return OW_IO_NVRAM_OFFSET;
70 return NW_IO_NVRAM_OFFSET;
73 static unsigned long macio_nvram_size(void)
76 return OW_IO_NVRAM_SIZE;
78 return NW_IO_NVRAM_SIZE;
81 void macio_nvram_init(const char *path, phys_addr_t addr)
83 phandle_t chosen, aliases;
87 unsigned long nvram_size, nvram_offset;
89 nvram_offset = macio_nvram_offset();
90 nvram_size = macio_nvram_size();
92 nvram = (char*)addr + nvram_offset;
93 snprintf(buf, sizeof(buf), "%s/nvram", path);
95 dnode = find_dev(buf);
96 set_int_property(dnode, "#bytes", arch_nvram_size() );
97 props[0] = __cpu_to_be32(nvram_offset);
98 props[1] = __cpu_to_be32(nvram_size);
99 set_property(dnode, "reg", (char *)&props, sizeof(props));
100 set_property(dnode, "device_type", "nvram", 6);
101 NEWWORLD(set_property(dnode, "compatible", "nvram,flash", 12));
103 chosen = find_dev("/chosen");
106 set_int_property(chosen, "nvram", POP());
108 aliases = find_dev("/aliases");
109 set_property(aliases, "nvram", buf, strlen(buf) + 1);
117 for (i = 0; i < 10; i++)
119 for (j = 0; j < 16; j++)
120 printk ("%02x ", nvram[(i*16+j)<<4]);
122 for (j = 0; j < 16; j++)
123 if (isprint(nvram[(i*16+j)<<4]))
124 printk("%c", nvram[(i*16+j)<<4]);
134 macio_nvram_put(char *buf)
137 unsigned int it_shift = macio_nvram_shift();
139 for (i=0; i < arch_nvram_size(); i++)
140 nvram[i << it_shift] = buf[i];
142 printk("new nvram:\n");
148 macio_nvram_get(char *buf)
151 unsigned int it_shift = macio_nvram_shift();
153 for (i=0; i< arch_nvram_size(); i++)
154 buf[i] = nvram[i << it_shift];
157 printk("current nvram:\n");
163 openpic_init(const char *path, phys_addr_t addr)
170 fword("find-device");
172 push_str("interrupt-controller");
173 fword("device-name");
175 snprintf(buf, sizeof(buf), "%s/interrupt-controller", path);
176 dnode = find_dev(buf);
177 set_property(dnode, "device_type", "open-pic", 9);
178 set_property(dnode, "compatible", "chrp,open-pic", 14);
179 set_property(dnode, "built-in", "", 0);
180 props[0] = __cpu_to_be32(IO_OPENPIC_OFFSET);
181 props[1] = __cpu_to_be32(IO_OPENPIC_SIZE);
182 set_property(dnode, "reg", (char *)&props, sizeof(props));
183 set_int_property(dnode, "#interrupt-cells", 2);
184 set_int_property(dnode, "#address-cells", 0);
185 set_property(dnode, "interrupt-controller", "", 0);
186 set_int_property(dnode, "clock-frequency", 4166666);
188 fword("finish-device");
191 DECLARE_NODE(ob_macio, INSTALL_OPEN, sizeof(int), "Tmac-io");
193 /* ( str len -- addr ) */
196 ob_macio_decode_unit(void *private)
200 const char *arg = pop_fstr_copy();
202 addr = strtol(arg, NULL, 16);
209 /* ( addr -- str len ) */
212 ob_macio_encode_unit(void *private)
218 snprintf(buf, sizeof(buf), "%x", addr);
223 NODE_METHODS(ob_macio) = {
224 { "decode-unit", ob_macio_decode_unit },
225 { "encode-unit", ob_macio_encode_unit },
235 fword("find-device");
238 fword("device-name");
240 dnode = find_dev("/uni-n");
241 set_property(dnode, "device_type", "memory-controller", 18);
242 set_property(dnode, "compatible", "uni-north", 10);
243 set_int_property(dnode, "device-rev", 0);
244 props[0] = __cpu_to_be32(0xf8000000);
245 props[1] = __cpu_to_be32(0x1000000);
246 set_property(dnode, "reg", (char *)&props, sizeof(props));
248 fword("finish-device");
252 ob_macio_heathrow_init(const char *path, phys_addr_t addr)
256 REGISTER_NODE(ob_macio);
257 aliases = find_dev("/aliases");
258 set_property(aliases, "mac-io", path, strlen(path) + 1);
260 cuda_init(path, addr);
261 macio_nvram_init(path, addr);
262 escc_init(path, addr);
263 macio_ide_init(path, addr, 2);
267 ob_macio_keylargo_init(const char *path, phys_addr_t addr)
271 aliases = find_dev("/aliases");
272 set_property(aliases, "mac-io", path, strlen(path) + 1);
274 cuda_init(path, addr);
275 /* The NewWorld NVRAM is not located in the MacIO device */
276 macio_nvram_init("", 0);
277 escc_init(path, addr);
278 macio_ide_init(path, addr, 2);
279 openpic_init(path, addr);