1/*-
2 * Copyright (c) 2009 Oleksandr Tymoshenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_machdep.c 220096 2011-03-28 09:10:59Z adrian $");
29
30#include <sys/param.h>
31#include <machine/cpuregs.h>
32
33#include <mips/sentry5/s5reg.h>
34
35#include "opt_ddb.h"
36
37#include <sys/param.h>
38#include <sys/conf.h>
39#include <sys/kernel.h>
40#include <sys/systm.h>
41#include <sys/bus.h>
42#include <sys/cons.h>
43#include <sys/kdb.h>
44#include <sys/reboot.h>
45
46#include <vm/vm.h>
47#include <vm/vm_page.h>
48
49#include <net/ethernet.h>
50
51#include <machine/clock.h>
52#include <machine/cpu.h>
53#include <machine/hwfunc.h>
54#include <machine/md_var.h>
55#include <machine/trap.h>
56#include <machine/vmparam.h>
57
58#include <mips/atheros/ar71xxreg.h>
59
60#include <mips/atheros/ar71xx_setup.h>
61#include <mips/atheros/ar71xx_cpudef.h>
62
63extern char edata[], end[];
64
65uint32_t ar711_base_mac[ETHER_ADDR_LEN];
66/* 4KB static data aread to keep a copy of the bootload env until
67 the dynamic kenv is setup */
68char boot1_env[4096];
69
70/*
71 * We get a string in from Redboot with the all the arguments together,
72 * "foo=bar bar=baz". Split them up and save in kenv.
73 */
74static void
75parse_argv(char *str)
76{
77 char *n, *v;
78
79 while ((v = strsep(&str, " ")) != NULL) {
80 if (*v == '\0')
81 continue;
82 if (*v == '-') {
83 while (*v != '\0') {
84 v++;
85 switch (*v) {
86 case 'a': boothowto |= RB_ASKNAME; break;
87 case 'd': boothowto |= RB_KDB; break;
88 case 'g': boothowto |= RB_GDB; break;
89 case 's': boothowto |= RB_SINGLE; break;
90 case 'v': boothowto |= RB_VERBOSE; break;
91 }
92 }
93 } else {
94 n = strsep(&v, "=");
95 if (v == NULL)
96 setenv(n, "1");
97 else
98 setenv(n, v);
99 }
100 }
101}
102
103void
104platform_cpu_init()
105{
106 /* Nothing special */
107}
108
109void
110platform_halt(void)
111{
112
113}
114
115void
116platform_identify(void)
117{
118
119}
120
121void
122platform_reset(void)
123{
124 ar71xx_device_stop(RST_RESET_FULL_CHIP);
125 /* Wait for reset */
126 while(1)
127 ;
128}
129
130void
131platform_trap_enter(void)
132{
133
134}
135
136void
137platform_trap_exit(void)
138{
139
140}
141
142/*
143 * Obtain the MAC address via the Redboot environment.
144 */
145static void
146ar71xx_redboot_get_macaddr(void)
147{
148 char *var;
149 int count = 0;
150
151 /*
152 * "ethaddr" is passed via envp on RedBoot platforms
153 * "kmac" is passed via argv on RouterBOOT platforms
154 */
155 if ((var = getenv("ethaddr")) != NULL ||
156 (var = getenv("kmac")) != NULL) {
157 count = sscanf(var, "%x%*c%x%*c%x%*c%x%*c%x%*c%x",
158 &ar711_base_mac[0], &ar711_base_mac[1],
159 &ar711_base_mac[2], &ar711_base_mac[3],
160 &ar711_base_mac[4], &ar711_base_mac[5]);
161 if (count < 6)
162 memset(ar711_base_mac, 0,
163 sizeof(ar711_base_mac));
164 freeenv(var);
165 }
166}
167
168void
169platform_start(__register_t a0 __unused, __register_t a1 __unused,
170 __register_t a2 __unused, __register_t a3 __unused)
171{
172 uint64_t platform_counter_freq;
173 int argc, i;
174 char **argv, **envp;
175 vm_offset_t kernend;
176
177 /*
178 * clear the BSS and SBSS segments, this should be first call in
179 * the function
180 */
181 kernend = (vm_offset_t)&end;
182 memset(&edata, 0, kernend - (vm_offset_t)(&edata));
183
184 mips_postboot_fixup();
185
186 /* Initialize pcpu stuff */
187 mips_pcpu0_init();
188
189 argc = a0;
190 argv = (char**)a1;
191 envp = (char**)a2;
192 /*
193 * Protect ourselves from garbage in registers
194 */
195 if (MIPS_IS_VALID_PTR(envp)) {
196 for (i = 0; envp[i]; i += 2) {
197 if (strcmp(envp[i], "memsize") == 0)
198 realmem = btoc(strtoul(envp[i+1], NULL, 16));
199 }
200 }
201
202 /*
203 * Just wild guess. RedBoot let us down and didn't reported
204 * memory size
205 */
206 if (realmem == 0)
207 realmem = btoc(32*1024*1024);
208
209 /*
210 * Allow build-time override in case Redboot lies
211 * or in other situations (eg where there's u-boot)
212 * where there isn't (yet) a convienent method of
213 * being told how much RAM is available.
214 *
215 * This happens on at least the Ubiquiti LS-SR71A
216 * board, where redboot says there's 16mb of RAM
217 * but in fact there's 32mb.
218 */
219#if defined(AR71XX_REALMEM)
220 realmem = btoc(AR71XX_REALMEM);
221#endif
222
223 /* phys_avail regions are in bytes */
224 phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
225 phys_avail[1] = ctob(realmem);
226
227 dump_avail[0] = phys_avail[0];
228 dump_avail[1] = phys_avail[1] - phys_avail[0];
229
230 physmem = realmem;
231
232 /*
233 * ns8250 uart code uses DELAY so ticker should be inititalized
234 * before cninit. And tick_init_params refers to hz, so * init_param1
235 * should be called first.
236 */
237 init_param1();
238
239 /* Detect the system type - this is needed for subsequent chipset-specific calls */
240 ar71xx_detect_sys_type();
241 ar71xx_detect_sys_frequency();
242
243 platform_counter_freq = ar71xx_cpu_freq();
244 mips_timer_init_params(platform_counter_freq, 1);
245 cninit();
246 init_static_kenv(boot1_env, sizeof(boot1_env));
247
248 printf("CPU platform: %s\n", ar71xx_get_system_type());
249 printf("CPU Frequency=%d MHz\n", u_ar71xx_cpu_freq / 1000000);
250 printf("CPU DDR Frequency=%d MHz\n", u_ar71xx_ddr_freq / 1000000);
251 printf("CPU AHB Frequency=%d MHz\n", u_ar71xx_ahb_freq / 1000000);
252
253 printf("platform frequency: %lld\n", platform_counter_freq);
254 printf("arguments: \n");
255 printf(" a0 = %08x\n", a0);
256 printf(" a1 = %08x\n", a1);
257 printf(" a2 = %08x\n", a2);
258 printf(" a3 = %08x\n", a3);
259
260 printf("Cmd line:");
261 if (MIPS_IS_VALID_PTR(argv)) {
262 for (i = 0; i < argc; i++) {
263 printf(" %s", argv[i]);
264 parse_argv(argv[i]);
265 }
266 }
267 else
268 printf ("argv is invalid");
269 printf("\n");
270
271 printf("Environment:\n");
272 if (MIPS_IS_VALID_PTR(envp)) {
273 for (i = 0; envp[i]; i+=2) {
274 printf(" %s = %s\n", envp[i], envp[i+1]);
275 setenv(envp[i], envp[i+1]);
276 }
277 }
278 else
279 printf ("envp is invalid\n");
280
281 /* Redboot if_arge MAC address is in the environment */
282 ar71xx_redboot_get_macaddr();
283
284 init_param2(physmem);
285 mips_cpu_init();
286 pmap_bootstrap();
287 mips_proc0_init();
288 mutex_init();
289
290 /*
291 * Reset USB devices
292 */
293 ar71xx_init_usb_peripheral();
294
295 kdb_init();
296#ifdef KDB
297 if (boothowto & RB_KDB)
298 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
299#endif
300}
2 * Copyright (c) 2009 Oleksandr Tymoshenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_machdep.c 220096 2011-03-28 09:10:59Z adrian $");
29
30#include <sys/param.h>
31#include <machine/cpuregs.h>
32
33#include <mips/sentry5/s5reg.h>
34
35#include "opt_ddb.h"
36
37#include <sys/param.h>
38#include <sys/conf.h>
39#include <sys/kernel.h>
40#include <sys/systm.h>
41#include <sys/bus.h>
42#include <sys/cons.h>
43#include <sys/kdb.h>
44#include <sys/reboot.h>
45
46#include <vm/vm.h>
47#include <vm/vm_page.h>
48
49#include <net/ethernet.h>
50
51#include <machine/clock.h>
52#include <machine/cpu.h>
53#include <machine/hwfunc.h>
54#include <machine/md_var.h>
55#include <machine/trap.h>
56#include <machine/vmparam.h>
57
58#include <mips/atheros/ar71xxreg.h>
59
60#include <mips/atheros/ar71xx_setup.h>
61#include <mips/atheros/ar71xx_cpudef.h>
62
63extern char edata[], end[];
64
65uint32_t ar711_base_mac[ETHER_ADDR_LEN];
66/* 4KB static data aread to keep a copy of the bootload env until
67 the dynamic kenv is setup */
68char boot1_env[4096];
69
70/*
71 * We get a string in from Redboot with the all the arguments together,
72 * "foo=bar bar=baz". Split them up and save in kenv.
73 */
74static void
75parse_argv(char *str)
76{
77 char *n, *v;
78
79 while ((v = strsep(&str, " ")) != NULL) {
80 if (*v == '\0')
81 continue;
82 if (*v == '-') {
83 while (*v != '\0') {
84 v++;
85 switch (*v) {
86 case 'a': boothowto |= RB_ASKNAME; break;
87 case 'd': boothowto |= RB_KDB; break;
88 case 'g': boothowto |= RB_GDB; break;
89 case 's': boothowto |= RB_SINGLE; break;
90 case 'v': boothowto |= RB_VERBOSE; break;
91 }
92 }
93 } else {
94 n = strsep(&v, "=");
95 if (v == NULL)
96 setenv(n, "1");
97 else
98 setenv(n, v);
99 }
100 }
101}
102
103void
104platform_cpu_init()
105{
106 /* Nothing special */
107}
108
109void
110platform_halt(void)
111{
112
113}
114
115void
116platform_identify(void)
117{
118
119}
120
121void
122platform_reset(void)
123{
124 ar71xx_device_stop(RST_RESET_FULL_CHIP);
125 /* Wait for reset */
126 while(1)
127 ;
128}
129
130void
131platform_trap_enter(void)
132{
133
134}
135
136void
137platform_trap_exit(void)
138{
139
140}
141
142/*
143 * Obtain the MAC address via the Redboot environment.
144 */
145static void
146ar71xx_redboot_get_macaddr(void)
147{
148 char *var;
149 int count = 0;
150
151 /*
152 * "ethaddr" is passed via envp on RedBoot platforms
153 * "kmac" is passed via argv on RouterBOOT platforms
154 */
155 if ((var = getenv("ethaddr")) != NULL ||
156 (var = getenv("kmac")) != NULL) {
157 count = sscanf(var, "%x%*c%x%*c%x%*c%x%*c%x%*c%x",
158 &ar711_base_mac[0], &ar711_base_mac[1],
159 &ar711_base_mac[2], &ar711_base_mac[3],
160 &ar711_base_mac[4], &ar711_base_mac[5]);
161 if (count < 6)
162 memset(ar711_base_mac, 0,
163 sizeof(ar711_base_mac));
164 freeenv(var);
165 }
166}
167
168void
169platform_start(__register_t a0 __unused, __register_t a1 __unused,
170 __register_t a2 __unused, __register_t a3 __unused)
171{
172 uint64_t platform_counter_freq;
173 int argc, i;
174 char **argv, **envp;
175 vm_offset_t kernend;
176
177 /*
178 * clear the BSS and SBSS segments, this should be first call in
179 * the function
180 */
181 kernend = (vm_offset_t)&end;
182 memset(&edata, 0, kernend - (vm_offset_t)(&edata));
183
184 mips_postboot_fixup();
185
186 /* Initialize pcpu stuff */
187 mips_pcpu0_init();
188
189 argc = a0;
190 argv = (char**)a1;
191 envp = (char**)a2;
192 /*
193 * Protect ourselves from garbage in registers
194 */
195 if (MIPS_IS_VALID_PTR(envp)) {
196 for (i = 0; envp[i]; i += 2) {
197 if (strcmp(envp[i], "memsize") == 0)
198 realmem = btoc(strtoul(envp[i+1], NULL, 16));
199 }
200 }
201
202 /*
203 * Just wild guess. RedBoot let us down and didn't reported
204 * memory size
205 */
206 if (realmem == 0)
207 realmem = btoc(32*1024*1024);
208
209 /*
210 * Allow build-time override in case Redboot lies
211 * or in other situations (eg where there's u-boot)
212 * where there isn't (yet) a convienent method of
213 * being told how much RAM is available.
214 *
215 * This happens on at least the Ubiquiti LS-SR71A
216 * board, where redboot says there's 16mb of RAM
217 * but in fact there's 32mb.
218 */
219#if defined(AR71XX_REALMEM)
220 realmem = btoc(AR71XX_REALMEM);
221#endif
222
223 /* phys_avail regions are in bytes */
224 phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
225 phys_avail[1] = ctob(realmem);
226
227 dump_avail[0] = phys_avail[0];
228 dump_avail[1] = phys_avail[1] - phys_avail[0];
229
230 physmem = realmem;
231
232 /*
233 * ns8250 uart code uses DELAY so ticker should be inititalized
234 * before cninit. And tick_init_params refers to hz, so * init_param1
235 * should be called first.
236 */
237 init_param1();
238
239 /* Detect the system type - this is needed for subsequent chipset-specific calls */
240 ar71xx_detect_sys_type();
241 ar71xx_detect_sys_frequency();
242
243 platform_counter_freq = ar71xx_cpu_freq();
244 mips_timer_init_params(platform_counter_freq, 1);
245 cninit();
246 init_static_kenv(boot1_env, sizeof(boot1_env));
247
248 printf("CPU platform: %s\n", ar71xx_get_system_type());
249 printf("CPU Frequency=%d MHz\n", u_ar71xx_cpu_freq / 1000000);
250 printf("CPU DDR Frequency=%d MHz\n", u_ar71xx_ddr_freq / 1000000);
251 printf("CPU AHB Frequency=%d MHz\n", u_ar71xx_ahb_freq / 1000000);
252
253 printf("platform frequency: %lld\n", platform_counter_freq);
254 printf("arguments: \n");
255 printf(" a0 = %08x\n", a0);
256 printf(" a1 = %08x\n", a1);
257 printf(" a2 = %08x\n", a2);
258 printf(" a3 = %08x\n", a3);
259
260 printf("Cmd line:");
261 if (MIPS_IS_VALID_PTR(argv)) {
262 for (i = 0; i < argc; i++) {
263 printf(" %s", argv[i]);
264 parse_argv(argv[i]);
265 }
266 }
267 else
268 printf ("argv is invalid");
269 printf("\n");
270
271 printf("Environment:\n");
272 if (MIPS_IS_VALID_PTR(envp)) {
273 for (i = 0; envp[i]; i+=2) {
274 printf(" %s = %s\n", envp[i], envp[i+1]);
275 setenv(envp[i], envp[i+1]);
276 }
277 }
278 else
279 printf ("envp is invalid\n");
280
281 /* Redboot if_arge MAC address is in the environment */
282 ar71xx_redboot_get_macaddr();
283
284 init_param2(physmem);
285 mips_cpu_init();
286 pmap_bootstrap();
287 mips_proc0_init();
288 mutex_init();
289
290 /*
291 * Reset USB devices
292 */
293 ar71xx_init_usb_peripheral();
294
295 kdb_init();
296#ifdef KDB
297 if (boothowto & RB_KDB)
298 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
299#endif
300}