octeon_machdep.c revision 201881
1194140Simp/*-
2194140Simp * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org>
3194140Simp * All rights reserved.
4194140Simp *
5194140Simp * Redistribution and use in source and binary forms, with or without
6194140Simp * modification, are permitted provided that the following conditions
7194140Simp * are met:
8194140Simp * 1. Redistributions of source code must retain the above copyright
9194140Simp *    notice, this list of conditions and the following disclaimer.
10194140Simp * 2. Redistributions in binary form must reproduce the above copyright
11194140Simp *    notice, this list of conditions and the following disclaimer in the
12194140Simp *    documentation and/or other materials provided with the distribution.
13194140Simp *
14194140Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15194140Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16194140Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17194140Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18194140Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19194140Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20194140Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21194140Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22194140Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23194140Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24194140Simp * SUCH DAMAGE.
25194140Simp *
26194140Simp * $FreeBSD: projects/mips/sys/mips/octeon1/octeon_machdep.c 201881 2010-01-09 03:08:22Z imp $
27194140Simp */
28194140Simp#include <sys/cdefs.h>
29194140Simp__FBSDID("$FreeBSD: projects/mips/sys/mips/octeon1/octeon_machdep.c 201881 2010-01-09 03:08:22Z imp $");
30194140Simp
31194140Simp#include <sys/param.h>
32196262Simp#include <sys/conf.h>
33196262Simp#include <sys/kernel.h>
34194140Simp#include <sys/systm.h>
35196262Simp#include <sys/imgact.h>
36196262Simp#include <sys/bio.h>
37196262Simp#include <sys/buf.h>
38196262Simp#include <sys/bus.h>
39196262Simp#include <sys/cpu.h>
40196262Simp#include <sys/cons.h>
41196262Simp#include <sys/exec.h>
42196262Simp#include <sys/ucontext.h>
43196262Simp#include <sys/proc.h>
44196262Simp#include <sys/kdb.h>
45196262Simp#include <sys/ptrace.h>
46196262Simp#include <sys/reboot.h>
47196262Simp#include <sys/signalvar.h>
48196262Simp#include <sys/sysent.h>
49196262Simp#include <sys/sysproto.h>
50196262Simp#include <sys/user.h>
51196262Simp
52196262Simp#include <vm/vm.h>
53196262Simp#include <vm/vm_object.h>
54196262Simp#include <vm/vm_page.h>
55196262Simp#include <vm/vm_pager.h>
56196262Simp
57196262Simp#include <machine/atomic.h>
58196262Simp#include <machine/cache.h>
59196262Simp#include <machine/clock.h>
60196262Simp#include <machine/cpu.h>
61194140Simp#include <machine/cpuregs.h>
62194140Simp#include <machine/cpufunc.h>
63194174Simp#include <mips/octeon1/octeon_pcmap_regs.h>
64194155Simp#include <mips/octeon1/octeonreg.h>
65196262Simp#include <machine/hwfunc.h>
66196262Simp#include <machine/intr_machdep.h>
67196262Simp#include <machine/locore.h>
68196262Simp#include <machine/md_var.h>
69194140Simp#include <machine/pcpu.h>
70196262Simp#include <machine/pte.h>
71196262Simp#include <machine/trap.h>
72196262Simp#include <machine/vmparam.h>
73194140Simp
74194140Simp#if defined(__mips_n64)
75196262Simp#define MAX_APP_DESC_ADDR     0xffffffffafffffff
76194140Simp#else
77196262Simp#define MAX_APP_DESC_ADDR     0xafffffff
78194140Simp#endif
79194140Simp
80196262Simpextern int	*edata;
81196262Simpextern int	*end;
82194140Simp
83201530Simpuint64_t ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip);
84201530Simpvoid ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip);
85201530Simp
86200344Simpstatic void octeon_boot_params_init(register_t ptr);
87201530Simpstatic uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx);
88201530Simpstatic uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx);
89200344Simp
90198669Srrsvoid
91198669Srrsplatform_cpu_init()
92198669Srrs{
93198669Srrs	/* Nothing special yet */
94198669Srrs}
95196262Simp
96194140Simp/*
97194140Simp * Perform a board-level soft-reset.
98194140Simp */
99196314Simpvoid
100196314Simpplatform_reset(void)
101194140Simp{
102196314Simp	((void(*)(void))0x1fc00000)();	/* Jump to this hex address */
103194140Simp}
104194140Simp
105194140Simp
106201530Simpstatic inline uint32_t
107201530Simpocteon_disable_interrupts(void)
108194140Simp{
109201530Simp	uint32_t status_bits;
110194140Simp
111201530Simp	status_bits = mips_rd_status();
112201530Simp	mips_wr_status(status_bits & ~MIPS_SR_INT_IE);
113201530Simp	return (status_bits);
114194140Simp}
115194140Simp
116194140Simp
117201530Simpstatic inline void
118201530Simpocteon_set_interrupts(uint32_t status_bits)
119194140Simp{
120201530Simp	mips_wr_status(status_bits);
121194140Simp}
122194140Simp
123194140Simp
124201530Simpvoid
125201530Simpocteon_led_write_char(int char_position, char val)
126194140Simp{
127201530Simp	uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
128194140Simp
129201530Simp	if (!octeon_board_real())
130201530Simp		return;
131194140Simp
132201530Simp	char_position &= 0x7;  /* only 8 chars */
133201530Simp	ptr += char_position;
134201530Simp	oct_write8_x8(ptr, val);
135194140Simp}
136194140Simp
137201530Simpvoid
138201530Simpocteon_led_write_char0(char val)
139194140Simp{
140201530Simp	uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
141194140Simp
142201530Simp	if (!octeon_board_real())
143201530Simp		return;
144201530Simp	oct_write8_x8(ptr, val);
145194140Simp}
146194140Simp
147201530Simpvoid
148201530Simpocteon_led_write_hexchar(int char_position, char hexval)
149194140Simp{
150201530Simp	uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
151201530Simp	char char1, char2;
152194140Simp
153201530Simp	if (!octeon_board_real())
154201530Simp		return;
155194140Simp
156201530Simp	char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7';
157201530Simp	char2 = (hexval  & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7';
158201530Simp	char_position &= 0x7;  /* only 8 chars */
159201530Simp	if (char_position > 6)
160201530Simp		char_position = 6;
161201530Simp	ptr += char_position;
162201530Simp	oct_write8_x8(ptr, char1);
163201530Simp	ptr++;
164201530Simp	oct_write8_x8(ptr, char2);
165194140Simp}
166194140Simp
167201530Simpvoid
168201530Simpocteon_led_write_string(const char *str)
169194140Simp{
170201530Simp	uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
171201530Simp	int i;
172194140Simp
173201530Simp	if (!octeon_board_real())
174201530Simp		return;
175194140Simp
176201530Simp	for (i=0; i<8; i++, ptr++) {
177201530Simp		if (str && *str)
178201530Simp			oct_write8_x8(ptr, *str++);
179201530Simp		else
180201530Simp			oct_write8_x8(ptr, ' ');
181201530Simp		oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
182201530Simp	}
183194140Simp}
184194140Simp
185194140Simpstatic char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'};
186194140Simp
187201530Simpvoid
188201530Simpocteon_led_run_wheel(int *prog_count, int led_position)
189194140Simp{
190201530Simp	if (!octeon_board_real())
191201530Simp		return;
192201530Simp	octeon_led_write_char(led_position, progress[*prog_count]);
193201530Simp	*prog_count += 1;
194201530Simp	*prog_count &= 0x7;
195194140Simp}
196194140Simp
197194140Simp#define LSR_DATAREADY        0x01    /* Data ready */
198194140Simp#define LSR_THRE             0x20    /* Transmit holding register empty */
199194140Simp#define LSR_TEMT	     0x40    /* Transmitter Empty. THR, TSR & FIFO */
200194140Simp#define USR_TXFIFO_NOTFULL   0x02    /* Uart TX FIFO Not full */
201194140Simp
202194140Simp/*
203194140Simp * octeon_uart_write_byte
204194140Simp *
205194140Simp * Put out a single byte off of uart port.
206194140Simp */
207194140Simp
208201530Simpvoid
209201530Simpocteon_uart_write_byte(int uart_index, uint8_t ch)
210194140Simp{
211201530Simp	uint64_t val, val2;
212201530Simp	if (uart_index < 0 || uart_index > 1)
213201530Simp		return;
214194140Simp
215201530Simp	while (1) {
216201530Simp		val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
217201530Simp		val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400));
218201530Simp		if ((((uint8_t) val) & LSR_THRE) ||
219201530Simp		    (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
220201530Simp			break;
221201530Simp		}
222201530Simp	}
223194140Simp
224201530Simp	/* Write the byte */
225201530Simp	oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch);
226194140Simp
227201530Simp	/* Force Flush the IOBus */
228201530Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
229194140Simp}
230194140Simp
231194140Simp
232201530Simpvoid
233201530Simpocteon_uart_write_byte0(uint8_t ch)
234194140Simp{
235201530Simp	uint64_t val, val2;
236194140Simp
237201530Simp	while (1) {
238201530Simp		val = oct_read64(OCTEON_MIO_UART0_LSR);
239201530Simp		val2 = oct_read64(OCTEON_MIO_UART0_USR);
240201530Simp		if ((((uint8_t) val) & LSR_THRE) ||
241201530Simp		    (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
242201530Simp			break;
243201530Simp		}
244201530Simp	}
245194140Simp
246201530Simp	/* Write the byte */
247201530Simp	oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch);
248194140Simp
249201530Simp	/* Force Flush the IOBus */
250201530Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
251194140Simp}
252194140Simp
253194140Simp/*
254194140Simp * octeon_uart_write_string
255194140Simp *
256194140Simp */
257201530Simpvoid
258201530Simpocteon_uart_write_string(int uart_index, const char *str)
259194140Simp{
260201530Simp	/* Just loop writing one byte at a time */
261194140Simp
262201530Simp	while (*str) {
263201530Simp		octeon_uart_write_byte(uart_index, *str);
264201530Simp		if (*str == '\n') {
265201530Simp			octeon_uart_write_byte(uart_index, '\r');
266201530Simp		}
267201530Simp		str++;
268201530Simp	}
269201530Simp}
270194140Simp
271194140Simpstatic char wstr[30];
272194140Simp
273201530Simpvoid
274201530Simpocteon_led_write_hex(uint32_t wl)
275194140Simp{
276201530Simp	char nbuf[80];
277194140Simp
278201530Simp	sprintf(nbuf, "%X", wl);
279201530Simp	octeon_led_write_string(nbuf);
280194140Simp}
281194140Simp
282194140Simp
283201530Simpvoid octeon_uart_write_hex2(uint32_t wl, uint32_t wh)
284194140Simp{
285201530Simp	sprintf(wstr, "0x%X-0x%X  ", wh, wl);
286201530Simp	octeon_uart_write_string(0, wstr);
287194140Simp}
288194140Simp
289201530Simpvoid
290201530Simpocteon_uart_write_hex(uint32_t wl)
291194140Simp{
292201530Simp	sprintf(wstr, " 0x%X  ", wl);
293201530Simp	octeon_uart_write_string(0, wstr);
294194140Simp}
295194140Simp
296194140Simp/*
297194140Simp * octeon_wait_uart_flush
298194140Simp */
299201530Simpvoid
300201530Simpocteon_wait_uart_flush(int uart_index, uint8_t ch)
301194140Simp{
302201530Simp	uint64_t val;
303201530Simp	int64_t val3;
304201530Simp	uint32_t cpu_status_bits;
305194140Simp
306201530Simp	if (uart_index < 0 || uart_index > 1)
307201530Simp		return;
308194140Simp
309201530Simp	cpu_status_bits = octeon_disable_interrupts();
310201530Simp	/* Force Flush the IOBus */
311201530Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
312201530Simp	for (val3 = 0xfffffffff; val3 > 0; val3--) {
313201530Simp		val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
314201530Simp		if (((uint8_t) val) & LSR_TEMT)
315201530Simp			break;
316201530Simp	}
317201530Simp	octeon_set_interrupts(cpu_status_bits);
318194140Simp}
319194140Simp
320194140Simp
321194140Simp/*
322194140Simp * octeon_debug_symbol
323194140Simp *
324194140Simp * Does nothing.
325194140Simp * Used to mark the point for simulator to begin tracing
326194140Simp */
327201530Simpvoid
328201530Simpocteon_debug_symbol(void)
329194140Simp{
330194140Simp}
331194140Simp
332201530Simpvoid
333201530Simpocteon_ciu_stop_gtimer(int timer)
334194140Simp{
335201530Simp	oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll);
336194140Simp}
337194140Simp
338201530Simpvoid
339201530Simpocteon_ciu_start_gtimer(int timer, u_int one_shot, uint64_t time_cycles)
340194140Simp{
341194140Simp    	octeon_ciu_gentimer gentimer;
342194140Simp
343194140Simp        gentimer.word64 = 0;
344194140Simp        gentimer.bits.one_shot = one_shot;
345194140Simp        gentimer.bits.len = time_cycles - 1;
346194140Simp        oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), gentimer.word64);
347194140Simp}
348194140Simp
349194140Simp/*
350194140Simp * octeon_ciu_reset
351194140Simp *
352194140Simp * Shutdown all CIU to IP2, IP3 mappings
353194140Simp */
354201530Simpvoid
355201530Simpocteon_ciu_reset(void)
356194140Simp{
357194140Simp
358201530Simp	octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0);
359201530Simp	octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1);
360201530Simp	octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2);
361201530Simp	octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3);
362194140Simp
363201530Simp	ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0);
364201530Simp	ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1);
365201530Simp	ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0);
366201530Simp	ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1);
367194140Simp
368201530Simp	ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll);
369201530Simp	ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll);
370201530Simp	ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll);
371194140Simp}
372194140Simp
373194140Simp/*
374194140Simp * mips_disable_interrupt_controllers
375194140Simp *
376194140Simp * Disable interrupts in the CPU controller
377194140Simp */
378201530Simpvoid
379201530Simpmips_disable_interrupt_controls(void)
380194140Simp{
381201530Simp	/*
382201530Simp	 * Disable interrupts in CIU.
383201530Simp	 */
384201530Simp	octeon_ciu_reset();
385194140Simp}
386194140Simp
387194140Simp/*
388194140Simp * ciu_get_intr_sum_reg_addr
389194140Simp */
390201530Simpstatic uint64_t
391201530Simpciu_get_intr_sum_reg_addr(int core_num, int intx, int enx)
392194140Simp{
393201530Simp	uint64_t ciu_intr_sum_reg_addr;
394194140Simp
395201530Simp    	if (enx == CIU_EN_0)
396201530Simp            	ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR +
397201530Simp		    (core_num * 0x10) + (intx * 0x8);
398201530Simp	else
399194140Simp            	ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_INT1_ADDR;
400194140Simp
401194140Simp        return (ciu_intr_sum_reg_addr);
402194140Simp}
403194140Simp
404194140Simp
405194140Simp/*
406194140Simp * ciu_get_intr_en_reg_addr
407194140Simp */
408201530Simpstatic uint64_t
409201530Simpciu_get_intr_en_reg_addr(int core_num, int intx, int enx)
410194140Simp{
411201530Simp	uint64_t ciu_intr_reg_addr;
412194140Simp
413201530Simp    	ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR +
414201530Simp	    ((enx == 0) ? 0x0 : 0x8) + (intx * 0x10) +  (core_num * 0x20);
415194140Simp        return (ciu_intr_reg_addr);
416194140Simp}
417194140Simp
418194140Simp
419194140Simp
420194140Simp
421194140Simp/*
422194140Simp * ciu_get_intr_reg_addr
423194140Simp *
424194140Simp * 200 ---int0,en0 ip2
425194140Simp * 208 ---int0,en1 ip2 ----> this is wrong... this is watchdog
426194140Simp *
427194140Simp * 210 ---int0,en0 ip3 --
428194140Simp * 218 ---int0,en1 ip3 ----> same here.. .this is watchdog... right?
429194140Simp *
430194140Simp * 220 ---int1,en0 ip2
431194140Simp * 228 ---int1,en1 ip2
432194140Simp * 230 ---int1,en0 ip3 --
433194140Simp * 238 ---int1,en1 ip3
434194140Simp *
435194140Simp */
436201530Simpuint64_t
437201530Simpciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip)
438194140Simp{
439201530Simp	uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR;
440194140Simp
441201530Simp	/* XXX kasserts? */
442201530Simp	if (enx < CIU_EN_0 || enx > CIU_EN_1) {
443201530Simp		printf("%s: invalid enx value %d, should be %d or %d\n",
444201530Simp		    __FUNCTION__, enx, CIU_EN_0, CIU_EN_1);
445201530Simp		return 0;
446201530Simp	}
447201530Simp	if (intx < CIU_INT_0 || intx > CIU_INT_1) {
448201530Simp		printf("%s: invalid intx value %d, should be %d or %d\n",
449201530Simp		    __FUNCTION__, enx, CIU_INT_0, CIU_INT_1);
450201530Simp		return 0;
451201530Simp	}
452201530Simp	if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) {
453201530Simp		printf("%s: invalid ciu_ip value %d, should be %d or %d\n",
454201530Simp		    __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
455201530Simp		return 0;
456201530Simp	}
457194140Simp
458201530Simp	ciu_intr_reg_addr += (enx    * 0x8);
459201530Simp	ciu_intr_reg_addr += (ciu_ip * 0x10);
460201530Simp	ciu_intr_reg_addr += (intx   * 0x20);
461201530Simp	return (ciu_intr_reg_addr);
462194140Simp}
463194140Simp
464194140Simp/*
465194140Simp * ciu_get_int_summary
466194140Simp */
467201530Simpuint64_t
468201530Simpciu_get_int_summary(int core_num, int intx, int enx)
469194140Simp{
470201530Simp	uint64_t ciu_intr_sum_reg_addr;
471194140Simp
472201530Simp	if (core_num == CIU_THIS_CORE)
473194140Simp        	core_num = octeon_get_core_num();
474201530Simp	ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
475201530Simp	return (oct_read64(ciu_intr_sum_reg_addr));
476194140Simp}
477194140Simp
478194140Simp//#define DEBUG_CIU 1
479194140Simp
480194140Simp#ifdef DEBUG_CIU
481194140Simp#define DEBUG_CIU_SUM 1
482194140Simp#define DEBUG_CIU_EN 1
483194140Simp#endif
484194140Simp
485194140Simp
486194140Simp/*
487194140Simp * ciu_clear_int_summary
488194140Simp */
489201530Simpvoid
490201530Simpciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits)
491194140Simp{
492201530Simp	uint32_t cpu_status_bits;
493201530Simp	uint64_t ciu_intr_sum_reg_addr;
494194140Simp
495194140Simp//#define DEBUG_CIU_SUM 1
496194140Simp
497194140Simp#ifdef DEBUG_CIU_SUM
498201530Simp	uint64_t ciu_intr_sum_bits;
499194140Simp#endif
500194140Simp
501194140Simp
502201530Simp	if (core_num == CIU_THIS_CORE) {
503194140Simp        	core_num = octeon_get_core_num();
504201530Simp	}
505194140Simp
506194140Simp#ifdef DEBUG_CIU_SUM
507194140Simp        printf(" CIU: core %u clear sum IntX %u  Enx %u  Bits: 0x%llX\n",
508201530Simp	    core_num, intx, enx, write_bits);
509194140Simp#endif
510194140Simp
511201530Simp	cpu_status_bits = octeon_disable_interrupts();
512194140Simp
513201530Simp	ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
514194140Simp
515194140Simp#ifdef DEBUG_CIU_SUM
516194140Simp    	ciu_intr_sum_bits =  oct_read64(ciu_intr_sum_reg_addr);	/* unneeded dummy read */
517194140Simp        printf(" CIU: status: 0x%X  reg_addr: 0x%llX   Val: 0x%llX   ->  0x%llX",
518201530Simp	    cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits,
519201530Simp	    ciu_intr_sum_bits | write_bits);
520194140Simp#endif
521194140Simp
522201530Simp	oct_write64(ciu_intr_sum_reg_addr, write_bits);
523201530Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
524194140Simp
525194140Simp#ifdef DEBUG_CIU_SUM
526194140Simp        printf(" Readback: 0x%llX\n\n   ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr));
527194140Simp#endif
528194140Simp
529201530Simp	octeon_set_interrupts(cpu_status_bits);
530194140Simp}
531194140Simp
532194140Simp/*
533194140Simp * ciu_disable_intr
534194140Simp */
535201530Simpvoid
536201530Simpciu_disable_intr(int core_num, int intx, int enx)
537194140Simp{
538201530Simp	uint32_t cpu_status_bits;
539201530Simp	uint64_t ciu_intr_reg_addr;
540194140Simp
541201530Simp	if (core_num == CIU_THIS_CORE)
542194140Simp        	core_num = octeon_get_core_num();
543194140Simp
544201530Simp	cpu_status_bits = octeon_disable_interrupts();
545194140Simp
546201530Simp	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
547194140Simp
548201530Simp	oct_read64(ciu_intr_reg_addr);	/* Dummy read */
549194140Simp
550201530Simp	oct_write64(ciu_intr_reg_addr, 0LL);
551201530Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
552194140Simp
553201530Simp	octeon_set_interrupts(cpu_status_bits);
554194140Simp}
555194140Simp
556201530Simpvoid
557201530Simpciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip)
558194140Simp{
559194140Simp
560194140Simp	uint64_t ciu_intr_reg_addr;
561194140Simp	uint64_t ciu_intr_bits;
562194140Simp
563194140Simp        if (core_num == CIU_THIS_CORE) {
564194140Simp            	core_num = octeon_get_core_num();
565194140Simp        }
566194140Simp
567194140Simp#ifndef OCTEON_SMP_1
568194140Simp	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
569194140Simp#else
570194140Simp	ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip);
571194140Simp#endif
572194140Simp
573194140Simp        if (!ciu_intr_reg_addr) {
574194140Simp            printf("Bad call to %s\n", __FUNCTION__);
575194140Simp            while(1);
576194140Simp            return;
577194140Simp        }
578194140Simp
579194140Simp	ciu_intr_bits =  oct_read64(ciu_intr_reg_addr);
580199593Simp        printf(" CIU core %d  int: %d  en: %d  ip: %d  Add: %#llx  enabled: %#llx  SR: %x\n",
581199593Simp	    core_num, intx, enx, ciu_ip, (unsigned long long)ciu_intr_reg_addr,
582195414Simp	    (unsigned long long)ciu_intr_bits, mips_rd_status());
583194140Simp}
584194140Simp
585194140Simp
586194140Simp/*
587194140Simp * ciu_enable_interrupts
588194140Simp */
589201530Simpvoid ciu_enable_interrupts(int core_num, int intx, int enx,
590201530Simp    uint64_t set_these_interrupt_bits, int ciu_ip)
591194140Simp{
592194140Simp	uint32_t cpu_status_bits;
593194140Simp	uint64_t ciu_intr_reg_addr;
594194140Simp	uint64_t ciu_intr_bits;
595194140Simp
596201530Simp        if (core_num == CIU_THIS_CORE)
597194140Simp            	core_num = octeon_get_core_num();
598194140Simp
599194140Simp//#define DEBUG_CIU_EN 1
600194140Simp
601194140Simp#ifdef DEBUG_CIU_EN
602194140Simp        printf(" CIU: core %u enabling Intx %u  Enx %u IP %d  Bits: 0x%llX\n",
603201530Simp	    core_num, intx, enx, ciu_ip, set_these_interrupt_bits);
604194140Simp#endif
605194140Simp
606194140Simp	cpu_status_bits = octeon_disable_interrupts();
607194140Simp
608194140Simp#ifndef OCTEON_SMP_1
609194140Simp	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
610194140Simp#else
611194140Simp	ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip);
612194140Simp#endif
613194140Simp
614194140Simp        if (!ciu_intr_reg_addr) {
615201530Simp		printf("Bad call to %s\n", __FUNCTION__);
616201530Simp		while(1);
617201530Simp		return;	/* XXX */
618194140Simp        }
619194140Simp
620194140Simp	ciu_intr_bits =  oct_read64(ciu_intr_reg_addr);
621194140Simp
622194140Simp#ifdef DEBUG_CIU_EN
623194140Simp        printf(" CIU: status: 0x%X  reg_addr: 0x%llX   Val: 0x%llX   ->  0x%llX",
624201530Simp	    cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits);
625194140Simp#endif
626194140Simp	ciu_intr_bits |=  set_these_interrupt_bits;
627194140Simp	oct_write64(ciu_intr_reg_addr, ciu_intr_bits);
628194140Simp#ifdef OCTEON_SMP
629194140Simp	mips_wbflush();
630194140Simp#endif
631194140Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
632194140Simp
633194140Simp#ifdef DEBUG_CIU_EN
634201530Simp        printf(" Readback: 0x%llX\n\n   ",
635201530Simp	    (uint64_t)oct_read64(ciu_intr_reg_addr));
636194140Simp#endif
637194140Simp
638194140Simp	octeon_set_interrupts(cpu_status_bits);
639194140Simp}
640194140Simp
641196262Simpvoid
642201530Simpplatform_start(__register_t a0, __register_t a1, __register_t a2 __unused,
643201530Simp    __register_t a3)
644196262Simp{
645196262Simp	uint64_t platform_counter_freq;
646196262Simp	vm_offset_t kernend;
647196262Simp	int argc = a0;
648196262Simp	char **argv = (char **)a1;
649196262Simp	int i, mem;
650194140Simp
651196262Simp	/* clear the BSS and SBSS segments */
652196262Simp	kernend = round_page((vm_offset_t)&end);
653196262Simp	memset(&edata, 0, kernend - (vm_offset_t)(&edata));
654194140Simp
655201845Simp	/* Initialize pcpu stuff */
656201881Simp	mips_pcpu0_init();
657201845Simp
658200344Simp	octeon_boot_params_init(a3);
659200344Simp	/* XXX octeon boot decriptor has args in it... */
660194140Simp        octeon_ciu_reset();
661199740Simp    	octeon_uart_write_string(0, "Platform Starting\n");
662194140Simp
663196262Simp	/*
664196262Simp	 * Looking for mem=XXM argument
665196262Simp	 */
666196262Simp	mem = 0; /* Just something to start with */
667196262Simp	for (i=0; i < argc; i++) {
668196262Simp		if (strncmp(argv[i], "mem=", 4) == 0) {
669196262Simp			mem = strtol(argv[i] + 4, NULL, 0);
670196262Simp			break;
671196262Simp		}
672196262Simp	}
673194140Simp
674196262Simp	bootverbose = 1;
675196262Simp	if (mem > 0)
676196262Simp		realmem = btoc(mem << 20);
677196262Simp	else
678196262Simp		realmem = btoc(32 << 20);
679194140Simp
680200344Simp	for (i = 0; i < 10; i++)
681196262Simp		phys_avail[i] = 0;
682196262Simp
683196262Simp	/* phys_avail regions are in bytes */
684196262Simp	phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end);
685196262Simp	phys_avail[1] = ctob(realmem);
686196262Simp
687196262Simp	physmem = realmem;
688196262Simp
689200344Simp	pmap_bootstrap();
690200344Simp	mips_proc0_init();
691200344Simp
692196262Simp	init_param1();
693196262Simp	/* TODO: parse argc,argv */
694196262Simp	platform_counter_freq = 330000000UL; /* XXX: from idt */
695196262Simp	mips_timer_init_params(platform_counter_freq, 1);
696196262Simp	cninit();
697196262Simp	printf("cmd line: ");
698196262Simp	for (i=0; i < argc; i++)
699196262Simp		printf("%s ", argv[i]);
700196262Simp	printf("\n");
701196262Simp	init_param2(physmem);
702196262Simp	mips_cpu_init();
703196262Simp	mutex_init();
704196262Simp#ifdef DDB
705196262Simp	kdb_init();
706196262Simp#endif
707196262Simp}
708196262Simp
709194140Simp/*
710194140Simp ****************************************************************************************
711194140Simp *
712194140Simp * APP/BOOT  DESCRIPTOR  STUFF
713194140Simp *
714194140Simp ****************************************************************************************
715194140Simp */
716194140Simp
717194140Simp/* Define the struct that is initialized by the bootloader used by the
718194140Simp * startup code.
719194140Simp *
720194140Simp * Copyright (c) 2004, 2005, 2006 Cavium Networks.
721194140Simp *
722194140Simp * The authors hereby grant permission to use, copy, modify, distribute,
723194140Simp * and license this software and its documentation for any purpose, provided
724194140Simp * that existing copyright notices are retained in all copies and that this
725194140Simp * notice is included verbatim in any distributions. No written agreement,
726194140Simp * license, or royalty fee is required for any of the authorized uses.
727194140Simp * Modifications to this software may be copyrighted by their authors
728194140Simp * and need not follow the licensing terms described here, provided that
729194140Simp * the new terms are clearly indicated on the first page of each file where
730194140Simp * they apply.
731194140Simp */
732194140Simp
733194140Simp#define OCTEON_CURRENT_DESC_VERSION     6
734194140Simp#define OCTEON_ARGV_MAX_ARGS            (64)
735194140Simp#define OCTOEN_SERIAL_LEN 20
736194140Simp
737194140Simp
738194140Simptypedef struct {
739200344Simp	/* Start of block referenced by assembly code - do not change! */
740200344Simp	uint32_t desc_version;
741200344Simp	uint32_t desc_size;
742194140Simp
743200344Simp	uint64_t stack_top;
744200344Simp	uint64_t heap_base;
745200344Simp	uint64_t heap_end;
746200344Simp	uint64_t entry_point;   /* Only used by bootloader */
747200344Simp	uint64_t desc_vaddr;
748200344Simp	/* End of This block referenced by assembly code - do not change! */
749194140Simp
750200344Simp	uint32_t exception_base_addr;
751200344Simp	uint32_t stack_size;
752200344Simp	uint32_t heap_size;
753200344Simp	uint32_t argc;  /* Argc count for application */
754200344Simp	uint32_t argv[OCTEON_ARGV_MAX_ARGS];
755200344Simp	uint32_t flags;
756200344Simp	uint32_t core_mask;
757200344Simp	uint32_t dram_size;  /**< DRAM size in megabyes */
758200344Simp	uint32_t phy_mem_desc_addr;  /**< physical address of free memory descriptor block*/
759200344Simp	uint32_t debugger_flags_base_addr;  /**< used to pass flags from app to debugger */
760200344Simp	uint32_t eclock_hz;  /**< CPU clock speed, in hz */
761200344Simp	uint32_t dclock_hz;  /**< DRAM clock speed, in hz */
762200344Simp	uint32_t spi_clock_hz;  /**< SPI4 clock in hz */
763200344Simp	uint16_t board_type;
764200344Simp	uint8_t board_rev_major;
765200344Simp	uint8_t board_rev_minor;
766200344Simp	uint16_t chip_type;
767200344Simp	uint8_t chip_rev_major;
768200344Simp	uint8_t chip_rev_minor;
769200344Simp	char board_serial_number[OCTOEN_SERIAL_LEN];
770200344Simp	uint8_t mac_addr_base[6];
771200344Simp	uint8_t mac_addr_count;
772200344Simp	uint64_t cvmx_desc_vaddr;
773194140Simp} octeon_boot_descriptor_t;
774194140Simp
775194140Simp
776194140Simptypedef struct {
777200344Simp	uint32_t major_version;
778200344Simp	uint32_t minor_version;
779194140Simp
780200344Simp	uint64_t stack_top;
781200344Simp	uint64_t heap_base;
782200344Simp	uint64_t heap_end;
783200344Simp	uint64_t desc_vaddr;
784194140Simp
785200344Simp	uint32_t exception_base_addr;
786200344Simp	uint32_t stack_size;
787200344Simp	uint32_t flags;
788200344Simp	uint32_t core_mask;
789200344Simp	uint32_t dram_size;  /**< DRAM size in megabyes */
790200344Simp	uint32_t phy_mem_desc_addr;  /**< physical address of free memory descriptor block*/
791200344Simp	uint32_t debugger_flags_base_addr;  /**< used to pass flags from app to debugger */
792200344Simp	uint32_t eclock_hz;  /**< CPU clock speed, in hz */
793200344Simp	uint32_t dclock_hz;  /**< DRAM clock speed, in hz */
794200344Simp	uint32_t spi_clock_hz;  /**< SPI4 clock in hz */
795200344Simp	uint16_t board_type;
796200344Simp	uint8_t board_rev_major;
797200344Simp	uint8_t board_rev_minor;
798200344Simp	uint16_t chip_type;
799200344Simp	uint8_t chip_rev_major;
800200344Simp	uint8_t chip_rev_minor;
801200344Simp	char board_serial_number[OCTOEN_SERIAL_LEN];
802200344Simp	uint8_t mac_addr_base[6];
803200344Simp	uint8_t mac_addr_count;
804194140Simp} cvmx_bootinfo_t;
805194140Simp
806194140Simpuint32_t octeon_cpu_clock;
807194140Simpuint64_t octeon_dram;
808194140Simpuint32_t octeon_bd_ver = 0, octeon_cvmx_bd_ver = 0, octeon_board_rev_major, octeon_board_rev_minor, octeon_board_type;
809194140Simpuint8_t octeon_mac_addr[6] = { 0 };
810194140Simpint octeon_core_mask, octeon_mac_addr_count;
811194140Simpint octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0;
812194140Simp
813200344Simpextern int32_t app_descriptor_addr;
814194140Simpstatic octeon_boot_descriptor_t *app_desc_ptr;
815194140Simpstatic cvmx_bootinfo_t *cvmx_desc_ptr;
816194140Simp
817194140Simp#define OCTEON_BOARD_TYPE_NONE 0
818194140Simp#define OCTEON_BOARD_TYPE_SIM  1
819194140Simp
820194140Simp#define OCTEON_CLOCK_MIN     (100 * 1000 * 1000)
821194140Simp#define OCTEON_CLOCK_MAX     (800 * 1000 * 1000)
822194140Simp#define OCTEON_DRAM_DEFAULT  (256 * 1024 * 1024)
823194140Simp#define OCTEON_DRAM_MIN	     30
824194140Simp#define OCTEON_DRAM_MAX	     3000
825194140Simp
826194140Simp
827200344Simpint
828200344Simpocteon_board_real(void)
829194140Simp{
830200344Simp	if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) ||
831200344Simp	    (octeon_board_type == OCTEON_BOARD_TYPE_SIM) ||
832200344Simp	    !octeon_board_rev_major)
833200344Simp		return 0;
834200344Simp	return 1;
835194140Simp}
836194140Simp
837200344Simpstatic void
838200344Simpocteon_process_app_desc_ver_unknown(void)
839194140Simp{
840194140Simp    	printf(" Unknown Boot-Descriptor: Using Defaults\n");
841194140Simp
842194140Simp    	octeon_cpu_clock = OCTEON_CLOCK_DEFAULT;
843194140Simp        octeon_dram = OCTEON_DRAM_DEFAULT;
844194140Simp        octeon_board_rev_major = octeon_board_rev_minor = octeon_board_type = 0;
845194140Simp        octeon_core_mask = 1;
846194140Simp        octeon_cpu_clock  = OCTEON_CLOCK_DEFAULT;
847194140Simp        octeon_chip_type = octeon_chip_rev_major = octeon_chip_rev_minor = 0;
848194140Simp        octeon_mac_addr[0] = 0x00; octeon_mac_addr[1] = 0x0f;
849194140Simp        octeon_mac_addr[2] = 0xb7; octeon_mac_addr[3] = 0x10;
850194140Simp        octeon_mac_addr[4] = 0x09; octeon_mac_addr[5] = 0x06;
851194140Simp        octeon_mac_addr_count = 1;
852194140Simp}
853194140Simp
854200344Simpstatic int
855200344Simpocteon_process_app_desc_ver_6(void)
856194140Simp{
857200344Simp	/* XXX Why is 0x00000000ffffffffULL a bad value?  */
858200344Simp	if (app_desc_ptr->cvmx_desc_vaddr == 0 ||
859200344Simp	    app_desc_ptr->cvmx_desc_vaddr == 0xfffffffful) {
860194174Simp            	printf ("Bad cvmx_desc_ptr %p\n", cvmx_desc_ptr);
861194140Simp                return 1;
862200344Simp	}
863200344Simp    	cvmx_desc_ptr =
864200344Simp	    (cvmx_bootinfo_t *)(intptr_t)app_desc_ptr->cvmx_desc_vaddr;
865200344Simp        cvmx_desc_ptr =
866200344Simp	    (cvmx_bootinfo_t *) ((intptr_t)cvmx_desc_ptr | MIPS_KSEG0_START);
867194140Simp        octeon_cvmx_bd_ver = (cvmx_desc_ptr->major_version * 100) +
868200344Simp	    cvmx_desc_ptr->minor_version;
869200344Simp	/* Too early for panic? */
870194140Simp        if (cvmx_desc_ptr->major_version != 1) {
871194174Simp            	printf("Incompatible CVMX descriptor from bootloader: %d.%d %p\n",
872194140Simp                       (int) cvmx_desc_ptr->major_version,
873194140Simp                       (int) cvmx_desc_ptr->minor_version, cvmx_desc_ptr);
874194140Simp                while (1);	/*  Never return */
875194140Simp                return 1;	/*  Satisfy the compiler */
876194140Simp        }
877194140Simp
878194140Simp        octeon_core_mask = cvmx_desc_ptr->core_mask;
879194140Simp        octeon_cpu_clock  = cvmx_desc_ptr->eclock_hz;
880194140Simp        octeon_board_type = cvmx_desc_ptr->board_type;
881194140Simp        octeon_board_rev_major = cvmx_desc_ptr->board_rev_major;
882194140Simp        octeon_board_rev_minor = cvmx_desc_ptr->board_rev_minor;
883194140Simp        octeon_chip_type = cvmx_desc_ptr->chip_type;
884194140Simp        octeon_chip_rev_major = cvmx_desc_ptr->chip_rev_major;
885194140Simp        octeon_chip_rev_minor = cvmx_desc_ptr->chip_rev_minor;
886194140Simp        octeon_mac_addr[0] = cvmx_desc_ptr->mac_addr_base[0];
887194140Simp        octeon_mac_addr[1] = cvmx_desc_ptr->mac_addr_base[1];
888194140Simp        octeon_mac_addr[2] = cvmx_desc_ptr->mac_addr_base[2];
889194140Simp        octeon_mac_addr[3] = cvmx_desc_ptr->mac_addr_base[3];
890194140Simp        octeon_mac_addr[4] = cvmx_desc_ptr->mac_addr_base[4];
891194140Simp        octeon_mac_addr[5] = cvmx_desc_ptr->mac_addr_base[5];
892194140Simp        octeon_mac_addr_count = cvmx_desc_ptr->mac_addr_count;
893194140Simp
894200344Simp        if (app_desc_ptr->dram_size > 16*1024*1024)
895194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size;
896200344Simp	else
897200344Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20;
898194140Simp        return 0;
899194140Simp}
900194140Simp
901200344Simpstatic int
902200344Simpocteon_process_app_desc_ver_3_4_5(void)
903194140Simp{
904194140Simp
905194140Simp    	octeon_cvmx_bd_ver = octeon_bd_ver;
906194140Simp        octeon_core_mask = app_desc_ptr->core_mask;
907194140Simp
908200344Simp        if (app_desc_ptr->desc_version > 3)
909194140Simp            	octeon_cpu_clock = app_desc_ptr->eclock_hz;
910200344Simp	else
911194140Simp            	octeon_cpu_clock  = OCTEON_CLOCK_DEFAULT;
912200344Simp        if (app_desc_ptr->dram_size > 16*1024*1024)
913194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size;
914200344Simp	else
915200344Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20;
916194140Simp
917194140Simp        if (app_desc_ptr->desc_version > 4) {
918194140Simp            	octeon_board_type = app_desc_ptr->board_type;
919194140Simp                octeon_board_rev_major = app_desc_ptr->board_rev_major;
920194140Simp                octeon_board_rev_minor = app_desc_ptr->board_rev_minor;
921194140Simp                octeon_chip_type = app_desc_ptr->chip_type;
922194140Simp                octeon_chip_rev_major = app_desc_ptr->chip_rev_major;
923194140Simp                octeon_chip_rev_minor = app_desc_ptr->chip_rev_minor;
924194140Simp
925194140Simp                octeon_mac_addr[0] = app_desc_ptr->mac_addr_base[0];
926194140Simp                octeon_mac_addr[1] = app_desc_ptr->mac_addr_base[1];
927194140Simp                octeon_mac_addr[2] = app_desc_ptr->mac_addr_base[2];
928194140Simp                octeon_mac_addr[3] = app_desc_ptr->mac_addr_base[3];
929194140Simp                octeon_mac_addr[4] = app_desc_ptr->mac_addr_base[4];
930194140Simp                octeon_mac_addr[5] = app_desc_ptr->mac_addr_base[5];
931194140Simp                octeon_mac_addr_count = app_desc_ptr->mac_addr_count;
932194140Simp        }
933194140Simp        return 0;
934194140Simp}
935194140Simp
936194140Simp
937200344Simpstatic void
938200344Simpocteon_boot_params_init(register_t ptr)
939194140Simp{
940200344Simp	int bad_desc = 1;
941194140Simp
942200344Simp    	if (ptr != 0 && ptr < MAX_APP_DESC_ADDR) {
943200344Simp	        app_desc_ptr = (octeon_boot_descriptor_t *)(intptr_t)ptr;
944194140Simp		octeon_bd_ver = app_desc_ptr->desc_version;
945200344Simp                if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5))
946200344Simp			bad_desc = octeon_process_app_desc_ver_3_4_5();
947200344Simp		else if (app_desc_ptr->desc_version == 6)
948200344Simp			bad_desc = octeon_process_app_desc_ver_6();
949194140Simp        }
950200344Simp        if (bad_desc)
951194140Simp        	octeon_process_app_desc_ver_unknown();
952194140Simp
953194140Simp        printf("Boot Descriptor Ver: %u -> %u/%u",
954194140Simp               octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100);
955194140Simp        printf("  CPU clock: %uMHz\n", octeon_cpu_clock/1000000);
956194140Simp        printf("  Dram: %u MB", (uint32_t)(octeon_dram >> 20));
957194140Simp        printf("  Board Type: %u  Revision: %u/%u\n",
958194140Simp               octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor);
959194140Simp        printf("  Octeon Chip: %u  Rev %u/%u",
960194140Simp               octeon_chip_type, octeon_chip_rev_major, octeon_chip_rev_minor);
961194140Simp
962194140Simp        printf("  Mac Address %02X.%02X.%02X.%02X.%02X.%02X\n",
963194140Simp               octeon_mac_addr[0], octeon_mac_addr[1], octeon_mac_addr[2],
964194140Simp               octeon_mac_addr[3], octeon_mac_addr[4], octeon_mac_addr[5]);
965194140Simp}
966