enable start-stop-daemon by default, i want to use this to clean up a few init script...
[15.05/openwrt.git] / target / linux / adm5120-2.6 / files / arch / mips / adm5120 / prom / routerboot.c
1 /*
2  *  $Id$
3  *
4  *  Mikrotik's RouterBOOT specific prom routines
5  *
6  *  Copyright (C) 2007 OpenWrt.org
7  *  Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
8  *
9  *  This program is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU General Public License
11  *  as published by the Free Software Foundation; either version 2
12  *  of the License, or (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the
21  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/types.h>
26 #include <linux/autoconf.h>
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/string.h>
30
31 #include <asm/bootinfo.h>
32 #include <asm/addrspace.h>
33
34 #include <adm5120_defs.h>
35 #include <prom/routerboot.h>
36 #include "prom_read.h"
37
38 static struct rb_hard_settings rb_hs;
39 static int rb_found = 0;
40
41 static int __init routerboot_load_hs(u8 *buf, u16 buflen)
42 {
43         u16 id,len;
44         u8 *mac;
45         int i,j;
46
47         memset(&rb_hs, 0, sizeof(rb_hs));
48
49         if (buflen < 4)
50                 return -1;
51
52         if (prom_read_le32(buf) != RB_MAGIC_HARD)
53                 return -1;
54
55         /* skip magic value */
56         buf += 4;
57         buflen -= 4;
58
59         while (buflen > 2) {
60                 id = prom_read_le16(buf);
61                 buf += 2;
62                 buflen -= 2;
63                 if (id == RB_ID_TERMINATOR || buflen < 2)
64                         break;
65
66                 len = prom_read_le16(buf);
67                 buf += 2;
68                 buflen -= 2;
69
70                 if (buflen < len)
71                         break;
72
73                 switch (id) {
74                 case RB_ID_BIOS_VERSION:
75                         rb_hs.bios_ver = (char *)buf;
76                         break;
77                 case RB_ID_BOARD_NAME:
78                         rb_hs.name = (char *)buf;
79                         break;
80                 case RB_ID_MEMORY_SIZE:
81                         rb_hs.mem_size = prom_read_le32(buf);
82                         break;
83                 case RB_ID_MAC_ADDRESS_COUNT:
84                         rb_hs.mac_count = prom_read_le32(buf);
85                         break;
86                 case RB_ID_MAC_ADDRESS_PACK:
87                         rb_hs.mac_count = len/RB_MAC_SIZE;
88                         if (rb_hs.mac_count > RB_MAX_MAC_COUNT)
89                                 rb_hs.mac_count = RB_MAX_MAC_COUNT;
90                         mac = buf;
91                         for (i=0; i < rb_hs.mac_count; i++) {
92                                 for (j=0; j < RB_MAC_SIZE; j++)
93                                         rb_hs.macs[i][j] = mac[j];
94                                 mac += RB_MAC_SIZE;
95                         }
96                         break;
97                 }
98
99                 buf += len;
100                 buflen -= len;
101
102         }
103
104         return 0;
105 }
106
107 #define RB_BS_OFFS      0x14
108 #define RB_OFFS_MAX     (128*1024)
109
110 int __init routerboot_present(void)
111 {
112         struct rb_bios_settings *bs;
113         u8 *base;
114         u32 off,len;
115
116         if (rb_found)
117                 goto out;
118
119         base = (u8 *)KSEG1ADDR(ADM5120_SRAM0_BASE);
120         bs = (struct rb_bios_settings *)(base + RB_BS_OFFS);
121
122         off = prom_read_le32(&bs->hs_offs);
123         len = prom_read_le32(&bs->hs_size);
124         if (off > RB_OFFS_MAX)
125                 goto out;
126
127         if (routerboot_load_hs(base+off, len) != 0)
128                 goto out;
129
130         rb_found = 1;
131
132 out:
133         return rb_found;
134 }
135
136 char *routerboot_get_boardname(void)
137 {
138         if (rb_found == 0)
139                 return NULL;
140
141         return rb_hs.name;
142 }