octeon_machdep.c revision 198669
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 198669 2009-10-30 08:53:11Z rrs $
27194140Simp */
28194140Simp#include <sys/cdefs.h>
29194140Simp__FBSDID("$FreeBSD: projects/mips/sys/mips/octeon1/octeon_machdep.c 198669 2009-10-30 08:53:11Z rrs $");
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
83198669Srrsvoid
84198669Srrsplatform_cpu_init()
85198669Srrs{
86198669Srrs	/* Nothing special yet */
87198669Srrs}
88196262Simp
89194140Simp/*
90194140Simp * Perform a board-level soft-reset.
91194140Simp * Note that this is not emulated by gxemul.
92194140Simp */
93196314Simpvoid
94196314Simpplatform_reset(void)
95194140Simp{
96196314Simp	((void(*)(void))0x1fc00000)();	/* Jump to this hex address */
97194140Simp}
98194140Simp
99194140Simp
100194140Simpstatic inline uint32_t octeon_disable_interrupts (void)
101194140Simp{
102194140Simp    uint32_t status_bits;
103194140Simp
104194140Simp    status_bits = mips_rd_status();
105194140Simp    mips_wr_status(status_bits & ~MIPS_SR_INT_IE);
106194140Simp    return (status_bits);
107194140Simp}
108194140Simp
109194140Simp
110194140Simpstatic inline void octeon_set_interrupts (uint32_t status_bits)
111194140Simp{
112194140Simp    mips_wr_status(status_bits);
113194140Simp}
114194140Simp
115194140Simp
116194140Simpvoid octeon_led_write_char (int char_position, char val)
117194140Simp{
118194140Simp    uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
119194140Simp
120194140Simp    if (!octeon_board_real()) return;
121194140Simp
122194140Simp    char_position &= 0x7;  /* only 8 chars */
123194140Simp    ptr += char_position;
124194140Simp    oct_write8_x8(ptr, val);
125194140Simp}
126194140Simp
127194140Simpvoid octeon_led_write_char0 (char val)
128194140Simp{
129194140Simp    uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
130194140Simp
131194140Simp    if (!octeon_board_real()) return;
132194140Simp
133194140Simp    oct_write8_x8(ptr, val);
134194140Simp}
135194140Simp
136194140Simpvoid octeon_led_write_hexchar (int char_position, char hexval)
137194140Simp{
138194140Simp    uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
139194140Simp    char char1, char2;
140194140Simp
141194140Simp    if (!octeon_board_real()) return;
142194140Simp
143194140Simp    char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7';
144194140Simp    char2 = (hexval  & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7';
145194140Simp    char_position &= 0x7;  /* only 8 chars */
146194140Simp    if (char_position > 6) char_position = 6;
147194140Simp    ptr += char_position;
148194140Simp    oct_write8_x8(ptr, char1);
149194140Simp    ptr++;
150194140Simp    oct_write8_x8(ptr, char2);
151194140Simp}
152194140Simp
153194140Simpvoid octeon_led_write_string (const char *str)
154194140Simp{
155194140Simp    uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8);
156194140Simp    int i;
157194140Simp
158194140Simp    if (!octeon_board_real()) return;
159194140Simp
160194140Simp    for (i=0; i<8; i++, ptr++) {
161194140Simp        if (str && *str) {
162194140Simp            oct_write8_x8(ptr, *str++);
163194140Simp        } else {
164194140Simp            oct_write8_x8(ptr, ' ');
165194140Simp        }
166194140Simp        oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
167194140Simp    }
168194140Simp}
169194140Simp
170194140Simpstatic char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'};
171194140Simp
172194140Simpvoid octeon_led_run_wheel (/*int count, */int *prog_count, int led_position)
173194140Simp{
174194140Simp    if (!octeon_board_real()) return;
175194140Simp
176194140Simp    octeon_led_write_char(led_position, progress[*prog_count]);
177194140Simp    *prog_count += 1;
178194140Simp    *prog_count &= 0x7;
179194140Simp}
180194140Simp
181194140Simp#define LSR_DATAREADY        0x01    /* Data ready */
182194140Simp#define LSR_THRE             0x20    /* Transmit holding register empty */
183194140Simp#define LSR_TEMT	     0x40    /* Transmitter Empty. THR, TSR & FIFO */
184194140Simp#define USR_TXFIFO_NOTFULL   0x02    /* Uart TX FIFO Not full */
185194140Simp
186194140Simp/*
187194140Simp * octeon_uart_write_byte
188194140Simp *
189194140Simp * Put out a single byte off of uart port.
190194140Simp */
191194140Simp
192194140Simpvoid octeon_uart_write_byte (int uart_index, uint8_t ch)
193194140Simp{
194194140Simp    uint64_t val, val2;
195194140Simp    if ((uart_index < 0) || (uart_index > 1)) {
196194140Simp        return;
197194140Simp    }
198194140Simp
199194140Simp    while (1) {
200194140Simp        val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
201194140Simp        val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400));
202194140Simp        if ((((uint8_t) val) & LSR_THRE) ||
203194140Simp            (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
204194140Simp            break;
205194140Simp        }
206194140Simp    }
207194140Simp
208194140Simp    /* Write the byte */
209194140Simp    oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch);
210194140Simp
211194140Simp    /* Force Flush the IOBus */
212194140Simp    oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
213194140Simp}
214194140Simp
215194140Simp
216194140Simpvoid octeon_uart_write_byte0 (uint8_t ch)
217194140Simp{
218194140Simp    uint64_t val, val2;
219194140Simp
220194140Simp    while (1) {
221194140Simp        val = oct_read64(OCTEON_MIO_UART0_LSR);
222194140Simp        val2 = oct_read64(OCTEON_MIO_UART0_USR);
223194140Simp        if ((((uint8_t) val) & LSR_THRE) ||
224194140Simp            (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
225194140Simp            break;
226194140Simp        }
227194140Simp    }
228194140Simp
229194140Simp    /* Write the byte */
230194140Simp    oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch);
231194140Simp
232194140Simp    /* Force Flush the IOBus */
233194140Simp    oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
234194140Simp}
235194140Simp
236194140Simp/*
237194140Simp * octeon_uart_write_string
238194140Simp *
239194140Simp */
240194140Simpvoid octeon_uart_write_string (int uart_index, const char *str)
241194140Simp{
242194140Simp     /* Just loop writing one byte at a time */
243194140Simp
244194140Simp    while (*str)
245194140Simp    {
246194140Simp        octeon_uart_write_byte(uart_index, *str);
247194140Simp        if (*str == '\n') {
248194140Simp            octeon_uart_write_byte(uart_index, '\r');
249194140Simp        }
250194140Simp        str++;
251194140Simp    }
252194140Simp }
253194140Simp
254194140Simpstatic char wstr[30];
255194140Simp
256194140Simpvoid octeon_led_write_hex (uint32_t wl)
257194140Simp{
258194140Simp    char nbuf[80];
259194140Simp
260194140Simp    sprintf(nbuf, "%X", wl);
261194140Simp    octeon_led_write_string(nbuf);
262194140Simp}
263194140Simp
264194140Simp
265194140Simpvoid octeon_uart_write_hex2 (uint32_t wl, uint32_t wh)
266194140Simp{
267194140Simp    sprintf(wstr, "0x%X-0x%X  ", wh, wl);
268194140Simp    octeon_uart_write_string(0, wstr);
269194140Simp}
270194140Simp
271194140Simpvoid octeon_uart_write_hex (uint32_t wl)
272194140Simp{
273194140Simp    sprintf(wstr, " 0x%X  ", wl);
274194140Simp    octeon_uart_write_string(0, wstr);
275194140Simp}
276194140Simp
277194174Simp#ifdef __not_used__
278194140Simp#define OCT_CONS_BUFLEN	200
279194140Simpstatic char console_str_buff0[OCT_CONS_BUFLEN + 1];
280194140Simp#include <machine/stdarg.h>
281194140Simp
282194140Simp//#define USE_KERN_SUBR_PRINTF
283194140Simp#ifndef USE_KERN_SUBR_PRINTF
284194140Simpstatic int oct_printf (const char *fmt, va_list ap);
285194140Simp#endif
286194140Simp
287194174Simpint kern_cons_printf(const char *fmt, ...)
288194140Simp{
289194140Simp	va_list ap;
290194140Simp
291194140Simp	va_start(ap, fmt);
292194140Simp#ifndef USE_KERN_SUBR_PRINTF
293194140Simp        oct_printf(fmt, ap);
294194140Simp#else
295194140Simp        ker_printf(fmt, ap);
296194140Simp#endif
297194140Simp        va_end(ap);
298194140Simp        return (0);
299194140Simp}
300194140Simp
301194140Simp#ifndef USE_KERN_SUBR_PRINTF
302194174Simpstatic int oct_printf(const char *fmt, va_list ap)
303194140Simp{
304194140Simp        snprintf(console_str_buff0, OCT_CONS_BUFLEN, fmt, ap);
305194140Simp        octeon_uart_write_string(0, console_str_buff0);
306194140Simp        return (0);
307194140Simp}
308194140Simp#endif
309194140Simp
310194174Simpint console_printf(const char *fmt, ...)
311194140Simp{
312194140Simp	va_list ap;
313194140Simp
314194140Simp	va_start(ap, fmt);
315194140Simp        sprintf(console_str_buff0, fmt, ap);
316194140Simp        va_end(ap);
317194140Simp        octeon_uart_write_string(0, console_str_buff0);
318194140Simp        return (0);
319194140Simp}
320194174Simp#endif
321194140Simp
322194140Simp
323194140Simp/*
324194140Simp * octeon_wait_uart_flush
325194140Simp */
326194140Simpvoid octeon_wait_uart_flush (int uart_index, uint8_t ch)
327194140Simp{
328194140Simp    uint64_t val;
329194140Simp    int64_t val3;
330194140Simp    uint32_t cpu_status_bits;
331194140Simp
332194140Simp    if ((uart_index < 0) || (uart_index > 1)) {
333194140Simp        return;
334194140Simp    }
335194140Simp
336194140Simp    cpu_status_bits = octeon_disable_interrupts();
337194140Simp    /* Force Flush the IOBus */
338194140Simp    oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
339194140Simp    for (val3 = 0xfffffffff; val3 > 0; val3--) {
340194140Simp        val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
341194140Simp        if (((uint8_t) val) & LSR_TEMT) {
342194140Simp            break;
343194140Simp        }
344194140Simp    }
345194140Simp    octeon_set_interrupts(cpu_status_bits);
346194140Simp}
347194140Simp
348194140Simp
349194140Simp/*
350194140Simp * octeon_debug_symbol
351194140Simp *
352194140Simp * Does nothing.
353194140Simp * Used to mark the point for simulator to begin tracing
354194140Simp */
355194140Simpvoid octeon_debug_symbol (void)
356194140Simp{
357194140Simp}
358194140Simp
359194140Simpvoid octeon_ciu_stop_gtimer (int timer)
360194140Simp{
361194140Simp    oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll);
362194140Simp}
363194140Simp
364194140Simpvoid octeon_ciu_start_gtimer (int timer, u_int one_shot, uint64_t time_cycles)
365194140Simp{
366194140Simp    	octeon_ciu_gentimer gentimer;
367194140Simp
368194140Simp        gentimer.word64 = 0;
369194140Simp        gentimer.bits.one_shot = one_shot;
370194140Simp        gentimer.bits.len = time_cycles - 1;
371194140Simp        oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), gentimer.word64);
372194140Simp}
373194140Simp
374194140Simp/*
375194140Simp * octeon_ciu_reset
376194140Simp *
377194140Simp * Shutdown all CIU to IP2, IP3 mappings
378194140Simp */
379194140Simpvoid octeon_ciu_reset (void)
380194140Simp{
381194140Simp
382194140Simp    octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0);
383194140Simp    octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1);
384194140Simp    octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2);
385194140Simp    octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3);
386194140Simp
387194140Simp    ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0);
388194140Simp    ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1);
389194140Simp    ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0);
390194140Simp    ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1);
391194140Simp
392194140Simp    ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll);
393194140Simp    ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll);
394194140Simp    ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll);
395194140Simp}
396194140Simp
397194140Simp/*
398194140Simp * mips_disable_interrupt_controllers
399194140Simp *
400194140Simp * Disable interrupts in the CPU controller
401194140Simp */
402194140Simpvoid mips_disable_interrupt_controls (void)
403194140Simp{
404194140Simp    /*
405194140Simp     * Disable interrupts in CIU.
406194140Simp     */
407194140Simp    octeon_ciu_reset();
408194140Simp}
409194140Simp
410194140Simpstatic uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx);
411194140Simp
412194140Simp/*
413194140Simp * ciu_get_intr_sum_reg_addr
414194140Simp */
415194140Simpstatic uint64_t ciu_get_intr_sum_reg_addr (int core_num, int intx, int enx)
416194140Simp{
417194140Simp    uint64_t ciu_intr_sum_reg_addr;
418194140Simp
419194140Simp    	if (enx == CIU_EN_0) {
420194140Simp            	ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR + (core_num * 0x10) +
421194140Simp                                        (intx * 0x8);
422194140Simp        } else {
423194140Simp            	ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_INT1_ADDR;
424194140Simp        }
425194140Simp
426194140Simp        return (ciu_intr_sum_reg_addr);
427194140Simp}
428194140Simp
429194140Simp
430194140Simpstatic uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx);
431194140Simp
432194140Simp/*
433194140Simp * ciu_get_intr_en_reg_addr
434194140Simp */
435194140Simpstatic uint64_t ciu_get_intr_en_reg_addr (int core_num, int intx, int enx)
436194140Simp{
437194140Simp    uint64_t ciu_intr_reg_addr;
438194140Simp
439194140Simp
440194140Simp    	ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR + ((enx == 0) ? 0x0 : 0x8) +
441194140Simp                            (intx * 0x10) +  (core_num * 0x20);
442194140Simp
443194140Simp        return (ciu_intr_reg_addr);
444194140Simp}
445194140Simp
446194140Simp
447194140Simp
448194140Simp
449194140Simpuint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip);
450194140Simp
451194140Simp/*
452194140Simp * ciu_get_intr_reg_addr
453194140Simp *
454194140Simp * 200 ---int0,en0 ip2
455194140Simp * 208 ---int0,en1 ip2 ----> this is wrong... this is watchdog
456194140Simp *
457194140Simp * 210 ---int0,en0 ip3 --
458194140Simp * 218 ---int0,en1 ip3 ----> same here.. .this is watchdog... right?
459194140Simp *
460194140Simp * 220 ---int1,en0 ip2
461194140Simp * 228 ---int1,en1 ip2
462194140Simp * 230 ---int1,en0 ip3 --
463194140Simp * 238 ---int1,en1 ip3
464194140Simp *
465194140Simp */
466194140Simpuint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip)
467194140Simp{
468194140Simp    uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR;
469194140Simp
470194140Simp    if (enx < CIU_EN_0 || enx > CIU_EN_1) {
471194140Simp        printf("%s: invalid enx value %d, should be %d or %d\n",
472194140Simp               __FUNCTION__, enx, CIU_EN_0, CIU_EN_1);
473194140Simp        return 0;
474194140Simp    }
475194140Simp    if (intx < CIU_INT_0 || intx > CIU_INT_1) {
476194140Simp        printf("%s: invalid intx value %d, should be %d or %d\n",
477194140Simp               __FUNCTION__, enx, CIU_INT_0, CIU_INT_1);
478194140Simp        return 0;
479194140Simp    }
480194140Simp    if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) {
481194140Simp        printf("%s: invalid ciu_ip value %d, should be %d or %d\n",
482194140Simp               __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
483194140Simp        return 0;
484194140Simp    }
485194140Simp
486194140Simp    ciu_intr_reg_addr += (enx    * 0x8);
487194140Simp    ciu_intr_reg_addr += (ciu_ip * 0x10);
488194140Simp    ciu_intr_reg_addr += (intx   * 0x20);
489194140Simp
490194140Simp    return (ciu_intr_reg_addr);
491194140Simp}
492194140Simp
493194140Simp/*
494194140Simp * ciu_get_int_summary
495194140Simp */
496194140Simpuint64_t ciu_get_int_summary (int core_num, int intx, int enx)
497194140Simp{
498194140Simp    uint64_t ciu_intr_sum_reg_addr;
499194140Simp
500194140Simp    if (core_num == CIU_THIS_CORE) {
501194140Simp        	core_num = octeon_get_core_num();
502194140Simp    }
503194140Simp    ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
504194140Simp    return (oct_read64(ciu_intr_sum_reg_addr));
505194140Simp}
506194140Simp
507194140Simp//#define DEBUG_CIU 1
508194140Simp
509194140Simp#ifdef DEBUG_CIU
510194140Simp#define DEBUG_CIU_SUM 1
511194140Simp#define DEBUG_CIU_EN 1
512194140Simp#endif
513194140Simp
514194140Simp
515194140Simp/*
516194140Simp * ciu_clear_int_summary
517194140Simp */
518194140Simpvoid ciu_clear_int_summary (int core_num, int intx, int enx, uint64_t write_bits)
519194140Simp{
520194140Simp    uint32_t cpu_status_bits;
521194140Simp    uint64_t ciu_intr_sum_reg_addr;
522194140Simp
523194140Simp//#define DEBUG_CIU_SUM 1
524194140Simp
525194140Simp#ifdef DEBUG_CIU_SUM
526194140Simp    uint64_t ciu_intr_sum_bits;
527194140Simp#endif
528194140Simp
529194140Simp
530194140Simp    if (core_num == CIU_THIS_CORE) {
531194140Simp        	core_num = octeon_get_core_num();
532194140Simp    }
533194140Simp
534194140Simp#ifdef DEBUG_CIU_SUM
535194140Simp        printf(" CIU: core %u clear sum IntX %u  Enx %u  Bits: 0x%llX\n",
536194140Simp               core_num, intx, enx, write_bits);
537194140Simp#endif
538194140Simp
539194140Simp    cpu_status_bits = octeon_disable_interrupts();
540194140Simp
541194140Simp    ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
542194140Simp
543194140Simp#ifdef DEBUG_CIU_SUM
544194140Simp    	ciu_intr_sum_bits =  oct_read64(ciu_intr_sum_reg_addr);	/* unneeded dummy read */
545194140Simp        printf(" CIU: status: 0x%X  reg_addr: 0x%llX   Val: 0x%llX   ->  0x%llX",
546194140Simp               cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits,
547194140Simp               ciu_intr_sum_bits | write_bits);
548194140Simp#endif
549194140Simp
550194140Simp    oct_write64(ciu_intr_sum_reg_addr, write_bits);
551194140Simp    oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
552194140Simp
553194140Simp#ifdef DEBUG_CIU_SUM
554194140Simp        printf(" Readback: 0x%llX\n\n   ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr));
555194140Simp#endif
556194140Simp
557194140Simp    octeon_set_interrupts(cpu_status_bits);
558194140Simp}
559194140Simp
560194140Simp/*
561194140Simp * ciu_disable_intr
562194140Simp */
563194140Simpvoid ciu_disable_intr (int core_num, int intx, int enx)
564194140Simp{
565194140Simp    uint32_t cpu_status_bits;
566194140Simp    uint64_t ciu_intr_reg_addr;
567194140Simp
568194140Simp    if (core_num == CIU_THIS_CORE) {
569194140Simp        	core_num = octeon_get_core_num();
570194140Simp    }
571194140Simp
572194140Simp    cpu_status_bits = octeon_disable_interrupts();
573194140Simp
574194140Simp    ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
575194140Simp
576194140Simp    oct_read64(ciu_intr_reg_addr);	/* Dummy read */
577194140Simp
578194140Simp    oct_write64(ciu_intr_reg_addr, 0LL);
579194140Simp    oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
580194140Simp
581194140Simp    octeon_set_interrupts(cpu_status_bits);
582194140Simp}
583194140Simp
584194140Simpvoid ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip);
585194140Simpvoid ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip)
586194140Simp{
587194140Simp
588194140Simp	uint64_t ciu_intr_reg_addr;
589194140Simp	uint64_t ciu_intr_bits;
590194140Simp
591194140Simp        if (core_num == CIU_THIS_CORE) {
592194140Simp            	core_num = octeon_get_core_num();
593194140Simp        }
594194140Simp
595194140Simp#ifndef OCTEON_SMP_1
596194140Simp	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
597194140Simp#else
598194140Simp	ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip);
599194140Simp#endif
600194140Simp
601194140Simp        if (!ciu_intr_reg_addr) {
602194140Simp            printf("Bad call to %s\n", __FUNCTION__);
603194140Simp            while(1);
604194140Simp            return;
605194140Simp        }
606194140Simp
607194140Simp	ciu_intr_bits =  oct_read64(ciu_intr_reg_addr);
608195414Simp        printf(" CIU core %d  int: %d  en: %d  ip: %d  Add: %p  enabled: 0x%llX  SR: %x\n",
609195414Simp	    core_num, intx, enx, ciu_ip, (void *)ciu_intr_reg_addr,
610195414Simp	    (unsigned long long)ciu_intr_bits, mips_rd_status());
611194140Simp}
612194140Simp
613194140Simp
614194140Simp/*
615194140Simp * ciu_enable_interrupts
616194140Simp */
617194140Simpvoid ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_interrupt_bits,
618194140Simp                            int ciu_ip)
619194140Simp{
620194140Simp
621194140Simp	uint32_t cpu_status_bits;
622194140Simp	uint64_t ciu_intr_reg_addr;
623194140Simp	uint64_t ciu_intr_bits;
624194140Simp
625194140Simp        if (core_num == CIU_THIS_CORE) {
626194140Simp            	core_num = octeon_get_core_num();
627194140Simp        }
628194140Simp
629194140Simp//#define DEBUG_CIU_EN 1
630194140Simp
631194140Simp#ifdef DEBUG_CIU_EN
632194140Simp        printf(" CIU: core %u enabling Intx %u  Enx %u IP %d  Bits: 0x%llX\n",
633194140Simp               core_num, intx, enx, ciu_ip, set_these_interrupt_bits);
634194140Simp#endif
635194140Simp
636194140Simp	cpu_status_bits = octeon_disable_interrupts();
637194140Simp
638194140Simp#ifndef OCTEON_SMP_1
639194140Simp	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
640194140Simp#else
641194140Simp	ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip);
642194140Simp#endif
643194140Simp
644194140Simp        if (!ciu_intr_reg_addr) {
645194140Simp            printf("Bad call to %s\n", __FUNCTION__);
646194140Simp            while(1);
647194140Simp            return;
648194140Simp        }
649194140Simp
650194140Simp	ciu_intr_bits =  oct_read64(ciu_intr_reg_addr);
651194140Simp
652194140Simp#ifdef DEBUG_CIU_EN
653194140Simp        printf(" CIU: status: 0x%X  reg_addr: 0x%llX   Val: 0x%llX   ->  0x%llX",
654194140Simp               cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits);
655194140Simp#endif
656194140Simp	ciu_intr_bits |=  set_these_interrupt_bits;
657194140Simp	oct_write64(ciu_intr_reg_addr, ciu_intr_bits);
658194140Simp#ifdef OCTEON_SMP
659194140Simp	mips_wbflush();
660194140Simp#endif
661194140Simp	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
662194140Simp
663194140Simp#ifdef DEBUG_CIU_EN
664194140Simp        printf(" Readback: 0x%llX\n\n   ", (uint64_t) oct_read64(ciu_intr_reg_addr));
665194140Simp#endif
666194140Simp
667194140Simp	octeon_set_interrupts(cpu_status_bits);
668194140Simp}
669194140Simp
670196262Simpvoid
671196262Simpplatform_start(__register_t a0, __register_t a1,
672196262Simp    __register_t a2 __unused, __register_t a3 __unused)
673196262Simp{
674196262Simp	uint64_t platform_counter_freq;
675196262Simp	vm_offset_t kernend;
676196262Simp	int argc = a0;
677196262Simp	char **argv = (char **)a1;
678196262Simp	int i, mem;
679194140Simp
680196262Simp	/* clear the BSS and SBSS segments */
681196262Simp	kernend = round_page((vm_offset_t)&end);
682196262Simp	memset(&edata, 0, kernend - (vm_offset_t)(&edata));
683194140Simp
684194140Simp        octeon_ciu_reset();
685194140Simp    	octeon_uart_write_string(0, "\nPlatform Starting");
686194140Simp
687196262Simp/* From here on down likely is bogus */
688196262Simp	/*
689196262Simp	 * Looking for mem=XXM argument
690196262Simp	 */
691196262Simp	mem = 0; /* Just something to start with */
692196262Simp	for (i=0; i < argc; i++) {
693196262Simp		if (strncmp(argv[i], "mem=", 4) == 0) {
694196262Simp			mem = strtol(argv[i] + 4, NULL, 0);
695196262Simp			break;
696196262Simp		}
697196262Simp	}
698194140Simp
699196262Simp	bootverbose = 1;
700196262Simp	if (mem > 0)
701196262Simp		realmem = btoc(mem << 20);
702196262Simp	else
703196262Simp		realmem = btoc(32 << 20);
704194140Simp
705196262Simp	for (i = 0; i < 10; i++) {
706196262Simp		phys_avail[i] = 0;
707196262Simp	}
708196262Simp
709196262Simp	/* phys_avail regions are in bytes */
710196262Simp	phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end);
711196262Simp	phys_avail[1] = ctob(realmem);
712196262Simp
713196262Simp	physmem = realmem;
714196262Simp
715196262Simp	/*
716196262Simp	 * ns8250 uart code uses DELAY so ticker should be inititalized
717196262Simp	 * before cninit. And tick_init_params refers to hz, so * init_param1
718196262Simp	 * should be called first.
719196262Simp	 */
720196262Simp	init_param1();
721196262Simp	/* TODO: parse argc,argv */
722196262Simp	platform_counter_freq = 330000000UL; /* XXX: from idt */
723196262Simp	mips_timer_init_params(platform_counter_freq, 1);
724196262Simp	cninit();
725196262Simp	/* Panic here, after cninit */
726196262Simp	if (mem == 0)
727196262Simp		panic("No mem=XX parameter in arguments");
728196262Simp
729196262Simp	printf("cmd line: ");
730196262Simp	for (i=0; i < argc; i++)
731196262Simp		printf("%s ", argv[i]);
732196262Simp	printf("\n");
733196262Simp
734196262Simp	init_param2(physmem);
735196262Simp	mips_cpu_init();
736196262Simp	pmap_bootstrap();
737196262Simp	mips_proc0_init();
738196262Simp	mutex_init();
739196262Simp#ifdef DDB
740196262Simp	kdb_init();
741196262Simp#endif
742196262Simp}
743196262Simp
744194140Simp/*
745194140Simp ****************************************************************************************
746194140Simp *
747194140Simp * APP/BOOT  DESCRIPTOR  STUFF
748194140Simp *
749194140Simp ****************************************************************************************
750194140Simp */
751194140Simp
752194140Simp/* Define the struct that is initialized by the bootloader used by the
753194140Simp * startup code.
754194140Simp *
755194140Simp * Copyright (c) 2004, 2005, 2006 Cavium Networks.
756194140Simp *
757194140Simp * The authors hereby grant permission to use, copy, modify, distribute,
758194140Simp * and license this software and its documentation for any purpose, provided
759194140Simp * that existing copyright notices are retained in all copies and that this
760194140Simp * notice is included verbatim in any distributions. No written agreement,
761194140Simp * license, or royalty fee is required for any of the authorized uses.
762194140Simp * Modifications to this software may be copyrighted by their authors
763194140Simp * and need not follow the licensing terms described here, provided that
764194140Simp * the new terms are clearly indicated on the first page of each file where
765194140Simp * they apply.
766194140Simp */
767194140Simp
768194140Simp#define OCTEON_CURRENT_DESC_VERSION     6
769194140Simp#define OCTEON_ARGV_MAX_ARGS            (64)
770194140Simp#define OCTOEN_SERIAL_LEN 20
771194140Simp
772194140Simp
773194140Simptypedef struct {
774194140Simp    /* Start of block referenced by assembly code - do not change! */
775194140Simp    uint32_t desc_version;
776194140Simp    uint32_t desc_size;
777194140Simp
778194140Simp    uint64_t stack_top;
779194140Simp    uint64_t heap_base;
780194140Simp    uint64_t heap_end;
781194140Simp    uint64_t entry_point;   /* Only used by bootloader */
782194140Simp    uint64_t desc_vaddr;
783194140Simp    /* End of This block referenced by assembly code - do not change! */
784194140Simp
785194140Simp    uint32_t exception_base_addr;
786194140Simp    uint32_t stack_size;
787194140Simp    uint32_t heap_size;
788194140Simp    uint32_t argc;  /* Argc count for application */
789194140Simp    uint32_t argv[OCTEON_ARGV_MAX_ARGS];
790194140Simp    uint32_t flags;
791194140Simp    uint32_t core_mask;
792194140Simp    uint32_t dram_size;  /**< DRAM size in megabyes */
793194140Simp    uint32_t phy_mem_desc_addr;  /**< physical address of free memory descriptor block*/
794194140Simp    uint32_t debugger_flags_base_addr;  /**< used to pass flags from app to debugger */
795194140Simp    uint32_t eclock_hz;  /**< CPU clock speed, in hz */
796194140Simp    uint32_t dclock_hz;  /**< DRAM clock speed, in hz */
797194140Simp    uint32_t spi_clock_hz;  /**< SPI4 clock in hz */
798194140Simp    uint16_t board_type;
799194140Simp    uint8_t board_rev_major;
800194140Simp    uint8_t board_rev_minor;
801194140Simp    uint16_t chip_type;
802194140Simp    uint8_t chip_rev_major;
803194140Simp    uint8_t chip_rev_minor;
804194140Simp    char board_serial_number[OCTOEN_SERIAL_LEN];
805194140Simp    uint8_t mac_addr_base[6];
806194140Simp    uint8_t mac_addr_count;
807194140Simp    uint64_t cvmx_desc_vaddr;
808194140Simp
809194140Simp} octeon_boot_descriptor_t;
810194140Simp
811194140Simp
812194140Simptypedef struct {
813194140Simp    uint32_t major_version;
814194140Simp    uint32_t minor_version;
815194140Simp
816194140Simp    uint64_t stack_top;
817194140Simp    uint64_t heap_base;
818194140Simp    uint64_t heap_end;
819194140Simp    uint64_t desc_vaddr;
820194140Simp
821194140Simp    uint32_t exception_base_addr;
822194140Simp    uint32_t stack_size;
823194140Simp    uint32_t flags;
824194140Simp    uint32_t core_mask;
825194140Simp    uint32_t dram_size;  /**< DRAM size in megabyes */
826194140Simp    uint32_t phy_mem_desc_addr;  /**< physical address of free memory descriptor block*/
827194140Simp    uint32_t debugger_flags_base_addr;  /**< used to pass flags from app to debugger */
828194140Simp    uint32_t eclock_hz;  /**< CPU clock speed, in hz */
829194140Simp    uint32_t dclock_hz;  /**< DRAM clock speed, in hz */
830194140Simp    uint32_t spi_clock_hz;  /**< SPI4 clock in hz */
831194140Simp    uint16_t board_type;
832194140Simp    uint8_t board_rev_major;
833194140Simp    uint8_t board_rev_minor;
834194140Simp    uint16_t chip_type;
835194140Simp    uint8_t chip_rev_major;
836194140Simp    uint8_t chip_rev_minor;
837194140Simp    char board_serial_number[OCTOEN_SERIAL_LEN];
838194140Simp    uint8_t mac_addr_base[6];
839194140Simp    uint8_t mac_addr_count;
840194140Simp
841194140Simp} cvmx_bootinfo_t;
842194140Simp
843194140Simpuint32_t octeon_cpu_clock;
844194140Simpuint64_t octeon_dram;
845194140Simpuint32_t octeon_bd_ver = 0, octeon_cvmx_bd_ver = 0, octeon_board_rev_major, octeon_board_rev_minor, octeon_board_type;
846194140Simpuint8_t octeon_mac_addr[6] = { 0 };
847194140Simpint octeon_core_mask, octeon_mac_addr_count;
848194140Simpint octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0;
849194140Simp
850194140Simp#if defined(__mips_n64)
851194140Simpextern uint64_t app_descriptor_addr;
852194140Simp#else
853194140Simpextern uint32_t app_descriptor_addr;
854194140Simp#endif
855194140Simpstatic octeon_boot_descriptor_t *app_desc_ptr;
856194140Simpstatic cvmx_bootinfo_t *cvmx_desc_ptr;
857194140Simp
858194140Simp#define OCTEON_BOARD_TYPE_NONE 0
859194140Simp#define OCTEON_BOARD_TYPE_SIM  1
860194140Simp
861194140Simp#define OCTEON_CLOCK_MIN     (100 * 1000 * 1000)
862194140Simp#define OCTEON_CLOCK_MAX     (800 * 1000 * 1000)
863194140Simp#define OCTEON_DRAM_DEFAULT  (256 * 1024 * 1024)
864194140Simp#define OCTEON_DRAM_MIN	     30
865194140Simp#define OCTEON_DRAM_MAX	     3000
866194140Simp
867194140Simp
868194140Simpint octeon_board_real (void)
869194140Simp{
870194140Simp     if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) ||
871194140Simp        (octeon_board_type == OCTEON_BOARD_TYPE_SIM) ||
872194140Simp        !octeon_board_rev_major) {
873194140Simp        return 0;
874194140Simp     }
875194140Simp     return 1;
876194140Simp}
877194140Simp
878194140Simpstatic void octeon_process_app_desc_ver_unknown (void)
879194140Simp{
880194140Simp    	printf(" Unknown Boot-Descriptor: Using Defaults\n");
881194140Simp
882194140Simp    	octeon_cpu_clock = OCTEON_CLOCK_DEFAULT;
883194140Simp        octeon_dram = OCTEON_DRAM_DEFAULT;
884194140Simp        octeon_board_rev_major = octeon_board_rev_minor = octeon_board_type = 0;
885194140Simp
886194140Simp        octeon_core_mask = 1;
887194140Simp        octeon_cpu_clock  = OCTEON_CLOCK_DEFAULT;
888194140Simp        octeon_chip_type = octeon_chip_rev_major = octeon_chip_rev_minor = 0;
889194140Simp
890194140Simp        octeon_mac_addr[0] = 0x00; octeon_mac_addr[1] = 0x0f;
891194140Simp        octeon_mac_addr[2] = 0xb7; octeon_mac_addr[3] = 0x10;
892194140Simp        octeon_mac_addr[4] = 0x09; octeon_mac_addr[5] = 0x06;
893194140Simp        octeon_mac_addr_count = 1;
894194140Simp}
895194140Simp
896194140Simpstatic int octeon_process_app_desc_ver_6 (void)
897194140Simp{
898194140Simp    	cvmx_desc_ptr = (cvmx_bootinfo_t *) ((long) app_desc_ptr->cvmx_desc_vaddr);
899194140Simp
900194140Simp        if ((cvmx_desc_ptr == NULL) || (cvmx_desc_ptr == (cvmx_bootinfo_t *)0xffffffff)) {
901194174Simp            	printf ("Bad cvmx_desc_ptr %p\n", cvmx_desc_ptr);
902194140Simp                return 1;
903194140Simp        }
904194140Simp
905194140Simp        cvmx_desc_ptr = (cvmx_bootinfo_t *) (((long) cvmx_desc_ptr) | MIPS_KSEG0_START);
906194140Simp        octeon_cvmx_bd_ver = (cvmx_desc_ptr->major_version * 100) +
907194140Simp                             cvmx_desc_ptr->minor_version;
908194140Simp
909194140Simp        if (cvmx_desc_ptr->major_version != 1) {
910194174Simp            	printf("Incompatible CVMX descriptor from bootloader: %d.%d %p\n",
911194140Simp                       (int) cvmx_desc_ptr->major_version,
912194140Simp                       (int) cvmx_desc_ptr->minor_version, cvmx_desc_ptr);
913194140Simp                while (1);	/*  Never return */
914194140Simp                return 1;	/*  Satisfy the compiler */
915194140Simp        }
916194140Simp
917194140Simp        octeon_core_mask = cvmx_desc_ptr->core_mask;
918194140Simp        octeon_cpu_clock  = cvmx_desc_ptr->eclock_hz;
919194140Simp        octeon_board_type = cvmx_desc_ptr->board_type;
920194140Simp        octeon_board_rev_major = cvmx_desc_ptr->board_rev_major;
921194140Simp        octeon_board_rev_minor = cvmx_desc_ptr->board_rev_minor;
922194140Simp        octeon_chip_type = cvmx_desc_ptr->chip_type;
923194140Simp        octeon_chip_rev_major = cvmx_desc_ptr->chip_rev_major;
924194140Simp        octeon_chip_rev_minor = cvmx_desc_ptr->chip_rev_minor;
925194140Simp        octeon_mac_addr[0] = cvmx_desc_ptr->mac_addr_base[0];
926194140Simp        octeon_mac_addr[1] = cvmx_desc_ptr->mac_addr_base[1];
927194140Simp        octeon_mac_addr[2] = cvmx_desc_ptr->mac_addr_base[2];
928194140Simp        octeon_mac_addr[3] = cvmx_desc_ptr->mac_addr_base[3];
929194140Simp        octeon_mac_addr[4] = cvmx_desc_ptr->mac_addr_base[4];
930194140Simp        octeon_mac_addr[5] = cvmx_desc_ptr->mac_addr_base[5];
931194140Simp        octeon_mac_addr_count = cvmx_desc_ptr->mac_addr_count;
932194140Simp
933194140Simp        if (app_desc_ptr->dram_size > 16*1024*1024) {
934194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size;
935194140Simp        } else {
936194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024;
937194140Simp        }
938194140Simp        return 0;
939194140Simp}
940194140Simp
941194140Simpstatic int octeon_process_app_desc_ver_3_4_5 (void)
942194140Simp{
943194140Simp
944194140Simp    	octeon_cvmx_bd_ver = octeon_bd_ver;
945194140Simp        octeon_core_mask = app_desc_ptr->core_mask;
946194140Simp
947194140Simp        if (app_desc_ptr->desc_version > 3) {
948194140Simp            	octeon_cpu_clock = app_desc_ptr->eclock_hz;
949194140Simp        } else {
950194140Simp            	octeon_cpu_clock  = OCTEON_CLOCK_DEFAULT;
951194140Simp        }
952194140Simp
953194140Simp        if (app_desc_ptr->dram_size > 16*1024*1024) {
954194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size;
955194140Simp        } else {
956194140Simp            	octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024;
957194140Simp        }
958194140Simp
959194140Simp        if (app_desc_ptr->desc_version > 4) {
960194140Simp            	octeon_board_type = app_desc_ptr->board_type;
961194140Simp                octeon_board_rev_major = app_desc_ptr->board_rev_major;
962194140Simp                octeon_board_rev_minor = app_desc_ptr->board_rev_minor;
963194140Simp                octeon_chip_type = app_desc_ptr->chip_type;
964194140Simp                octeon_chip_rev_major = app_desc_ptr->chip_rev_major;
965194140Simp                octeon_chip_rev_minor = app_desc_ptr->chip_rev_minor;
966194140Simp
967194140Simp                octeon_mac_addr[0] = app_desc_ptr->mac_addr_base[0];
968194140Simp                octeon_mac_addr[1] = app_desc_ptr->mac_addr_base[1];
969194140Simp                octeon_mac_addr[2] = app_desc_ptr->mac_addr_base[2];
970194140Simp                octeon_mac_addr[3] = app_desc_ptr->mac_addr_base[3];
971194140Simp                octeon_mac_addr[4] = app_desc_ptr->mac_addr_base[4];
972194140Simp                octeon_mac_addr[5] = app_desc_ptr->mac_addr_base[5];
973194140Simp                octeon_mac_addr_count = app_desc_ptr->mac_addr_count;
974194140Simp        }
975194140Simp        return 0;
976194140Simp}
977194140Simp
978194140Simp
979194140Simpvoid mips_boot_params_init(void);
980194140Simp
981194140Simpvoid mips_boot_params_init (void)
982194140Simp{
983194140Simp    int descriptor_not_parsed = 1;
984194140Simp
985194140Simp    	if ((app_descriptor_addr == 0) || (app_descriptor_addr >= MAX_APP_DESC_ADDR)) {
986194140Simp
987194140Simp        } else {
988194140Simp
989194140Simp	        app_desc_ptr = (octeon_boot_descriptor_t *) app_descriptor_addr;
990194140Simp		octeon_bd_ver = app_desc_ptr->desc_version;
991194140Simp
992194140Simp                if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5)) {
993194140Simp		  descriptor_not_parsed = octeon_process_app_desc_ver_3_4_5();
994194140Simp
995194140Simp                } else if (app_desc_ptr->desc_version == 6) {
996194140Simp                    	descriptor_not_parsed = octeon_process_app_desc_ver_6();
997194140Simp                }
998194140Simp
999194140Simp        }
1000194140Simp
1001194140Simp        if (descriptor_not_parsed) {
1002194140Simp        	octeon_process_app_desc_ver_unknown();
1003194140Simp        }
1004194140Simp
1005194140Simp        printf("Boot Descriptor Ver: %u -> %u/%u",
1006194140Simp               octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100);
1007194140Simp        printf("  CPU clock: %uMHz\n", octeon_cpu_clock/1000000);
1008194140Simp        printf("  Dram: %u MB", (uint32_t)(octeon_dram >> 20));
1009194140Simp        printf("  Board Type: %u  Revision: %u/%u\n",
1010194140Simp               octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor);
1011194140Simp        printf("  Octeon Chip: %u  Rev %u/%u",
1012194140Simp               octeon_chip_type, octeon_chip_rev_major, octeon_chip_rev_minor);
1013194140Simp
1014194140Simp        printf("  Mac Address %02X.%02X.%02X.%02X.%02X.%02X\n",
1015194140Simp               octeon_mac_addr[0], octeon_mac_addr[1], octeon_mac_addr[2],
1016194140Simp               octeon_mac_addr[3], octeon_mac_addr[4], octeon_mac_addr[5]);
1017194140Simp}
1018