add .32 patches
[oweals/openwrt.git] / target / linux / ifxmips / files-2.6.32 / arch / mips / ifxmips / common / prom.c
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/bootmem.h>
4 #include <linux/etherdevice.h>
5
6 #include <asm/bootinfo.h>
7 #include <machine.h>
8
9 #include <ifxmips.h>
10 #include <ifxmips_prom.h>
11
12 /* for voice cpu (MIPS24K) */
13 unsigned int *prom_cp1_base;
14 unsigned int prom_cp1_size;
15
16 /* for Multithreading (APRP) on MIPS34K */
17 unsigned long physical_memsize;
18
19 void
20 prom_free_prom_memory(void)
21 {
22 }
23
24 unsigned int*
25 prom_get_cp1_base(void)
26 {
27         return prom_cp1_base;
28 }
29 EXPORT_SYMBOL(prom_get_cp1_base);
30
31 unsigned int
32 prom_get_cp1_size(void)
33 {
34         /* return size im MB */
35         return prom_cp1_size>>20;
36 }
37 EXPORT_SYMBOL(prom_get_cp1_size);
38
39 extern unsigned char ifxmips_ethaddr[6];
40 int cmdline_mac = 0;
41
42 static int __init
43 ifxmips_set_ethaddr(char *str)
44 {
45 #define IS_HEX(x) \
46         (((x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') \
47                 || (x >= 'A' && x <= 'F')) ? (1) : (0))
48         int i;
49         str = strchr(str, '=');
50         if (!str)
51                 goto out;
52         str++;
53         if (strlen(str) != 17)
54                 goto out;
55         for (i = 0; i < 6; i++) {
56                 if (!IS_HEX(str[3 * i]) || !IS_HEX(str[(3 * i) + 1]))
57                         goto out;
58                 if ((i != 5) && (str[(3 * i) + 2] != ':'))
59                         goto out;
60                 ifxmips_ethaddr[i] = simple_strtoul(&str[3 * i], NULL, 16);
61         }
62         if (is_valid_ether_addr(ifxmips_ethaddr))
63                 cmdline_mac = 1;
64 out:
65         return 1;
66 }
67 __setup("ethaddr", ifxmips_set_ethaddr);
68
69 static void __init prom_detect_machtype(void)
70 {
71         mips_machtype = IFXMIPS_MACH_EASY50712;
72 }
73
74 static void __init prom_init_cmdline(void)
75 {
76         int argc = fw_arg0;
77         char **argv = (char **) fw_arg1;
78         char **envp = (char **) fw_arg2;
79
80         int memsize = 16; /* assume 16M as default */
81         int i;
82
83         if (argc)
84         {
85                 argv = (char **)KSEG1ADDR((unsigned long)argv);
86                 arcs_cmdline[0] = '\0';
87                 for (i = 1; i < argc; i++)
88                 {
89                         char *a = (char *)KSEG1ADDR(argv[i]);
90                         if (!argv[i])
91                                 continue;
92                         /* for voice cpu on Twinpass/Danube */
93                         if (cpu_data[0].cputype == CPU_24K)
94                                 if (!strncmp(a, "cp1_size=", 9))
95                                 {
96                                         prom_cp1_size = memparse(a + 9, &a);
97                                         continue;
98                                 }
99                         if (strlen(arcs_cmdline) + strlen(a + 1) >= sizeof(arcs_cmdline))
100                         {
101                                 early_printf("cmdline overflow, skipping: %s\n", a);
102                                 break;
103                         }
104                         strcat(arcs_cmdline, a);
105                         strcat(arcs_cmdline, " ");
106                 }
107                 if (!*arcs_cmdline)
108                         strcpy(&(arcs_cmdline[0]),
109                                 "console=ttyS0,115200 rootfstype=squashfs,jffs2");
110         }
111         envp = (char **)KSEG1ADDR((unsigned long)envp);
112         while (*envp)
113         {
114                 char *e = (char *)KSEG1ADDR(*envp);
115
116                 if (!strncmp(e, "memsize=", 8))
117                 {
118                         e += 8;
119                         memsize = simple_strtoul(e, NULL, 10);
120                 }
121                 envp++;
122         }
123         memsize *= 1024 * 1024;
124
125         /* only on Twinpass/Danube a second CPU is used for Voice */
126         if ((cpu_data[0].cputype == CPU_24K) && (prom_cp1_size))
127         {
128                 memsize -= prom_cp1_size;
129                 prom_cp1_base = (unsigned int *)KSEG1ADDR(memsize);
130
131                 early_printf("Using %dMB Ram and reserving %dMB for cp1\n",
132                         memsize>>20, prom_cp1_size>>20);
133         }
134
135         add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
136 }
137
138 void __init
139 prom_init(void)
140 {
141         prom_detect_machtype();
142         prom_init_cmdline();
143 }