Index: projects/mips/sys/mips/adm5120/adm5120_machdep.c =================================================================== --- projects/mips/sys/mips/adm5120/adm5120_machdep.c (revision 201880) +++ projects/mips/sys/mips/adm5120/adm5120_machdep.c (revision 201881) @@ -1,163 +1,163 @@ /*- * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int *edata; extern int *end; void platform_cpu_init() { /* Nothing special */ } static void mips_init(void) { int i; printf("entry: mips_init()\n"); bootverbose = 1; realmem = btoc(16 << 20); for (i = 0; i < 10; i++) { phys_avail[i] = 0; } /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { __asm __volatile("li $25, 0xbfc00000"); __asm __volatile("j $25"); } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; uint64_t platform_counter_freq = 175 * 1000 * 1000; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); cninit(); mips_init(); mips_timer_init_params(platform_counter_freq, 0); } Index: projects/mips/sys/mips/alchemy/alchemy_machdep.c =================================================================== --- projects/mips/sys/mips/alchemy/alchemy_machdep.c (revision 201880) +++ projects/mips/sys/mips/alchemy/alchemy_machdep.c (revision 201881) @@ -1,166 +1,166 @@ /*- * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int *edata; extern int *end; void platform_cpu_init() { /* Nothing special */ } static void mips_init(void) { int i; printf("entry: mips_init()\n"); bootverbose = 1; realmem = btoc(16 << 20); for (i = 0; i < 10; i++) { phys_avail[i] = 0; } /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { __asm __volatile("li $25, 0xbfc00000"); __asm __volatile("j $25"); } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; uint64_t platform_counter_freq = 175 * 1000 * 1000; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); cninit(); mips_init(); /* Set counter_freq for tick_init_params() */ platform_counter_freq = 175 * 1000 * 1000; mips_timer_init_params(platform_counter_freq, 0); } Index: projects/mips/sys/mips/atheros/ar71xx_machdep.c =================================================================== --- projects/mips/sys/mips/atheros/ar71xx_machdep.c (revision 201880) +++ projects/mips/sys/mips/atheros/ar71xx_machdep.c (revision 201881) @@ -1,262 +1,262 @@ /*- * Copyright (c) 2009 Oleksandr Tymoshenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int *edata; extern int *end; uint32_t ar711_base_mac[ETHER_ADDR_LEN]; /* 4KB static data aread to keep a copy of the bootload env until the dynamic kenv is setup */ char boot1_env[4096]; /* * We get a string in from Redboot with the all the arguments together, * "foo=bar bar=baz". Split them up and save in kenv. */ static void parse_argv(char *str) { char *n, *v; while ((v = strsep(&str, " ")) != NULL) { if (*v == '\0') continue; if (*v == '-') { while (*v != '\0') { v++; switch (*v) { case 'a': boothowto |= RB_ASKNAME; break; case 'd': boothowto |= RB_KDB; break; case 'g': boothowto |= RB_GDB; break; case 's': boothowto |= RB_SINGLE; break; case 'v': boothowto |= RB_VERBOSE; break; } } } else { n = strsep(&v, "="); if (v == NULL) setenv(n, "1"); else setenv(n, v); } } } void platform_cpu_init() { /* Nothing special */ } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { uint32_t reg = ATH_READ_REG(AR71XX_RST_RESET); ATH_WRITE_REG(AR71XX_RST_RESET, reg | RST_RESET_FULL_CHIP); /* Wait for reset */ while(1) ; } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; uint64_t platform_counter_freq; uint32_t reg; int argc, i, count = 0; char **argv, **envp; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); argc = a0; argv = (char**)a1; envp = (char**)a2; /* * Protect ourselves from garbage in registers */ if (MIPS_IS_VALID_PTR(envp)) { for (i = 0; envp[i]; i += 2) { if (strcmp(envp[i], "memsize") == 0) realmem = btoc(strtoul(envp[i+1], NULL, 16)); else if (strcmp(envp[i], "ethaddr") == 0) { count = sscanf(envp[i+1], "%x.%x.%x.%x.%x.%x", &ar711_base_mac[0], &ar711_base_mac[1], &ar711_base_mac[2], &ar711_base_mac[3], &ar711_base_mac[4], &ar711_base_mac[5]); if (count < 6) memset(ar711_base_mac, 0, sizeof(ar711_base_mac)); } } } /* * Just wild guess. RedBoot let us down and didn't reported * memory size */ if (realmem == 0) realmem = btoc(32*1024*1024); /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; /* * ns8250 uart code uses DELAY so ticker should be inititalized * before cninit. And tick_init_params refers to hz, so * init_param1 * should be called first. */ init_param1(); platform_counter_freq = ar71xx_cpu_freq(); mips_timer_init_params(platform_counter_freq, 1); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); printf("platform frequency: %lld\n", platform_counter_freq); printf("arguments: \n"); printf(" a0 = %08x\n", a0); printf(" a1 = %08x\n", a1); printf(" a2 = %08x\n", a2); printf(" a3 = %08x\n", a3); printf("Cmd line:"); if (MIPS_IS_VALID_PTR(argv)) { for (i = 0; i < argc; i++) { printf(" %s", argv[i]); parse_argv(argv[i]); } } else printf ("argv is invalid"); printf("\n"); printf("Environment:\n"); if (MIPS_IS_VALID_PTR(envp)) { for (i = 0; envp[i]; i+=2) { printf(" %s = %s\n", envp[i], envp[i+1]); setenv(envp[i], envp[i+1]); } } else printf ("envp is invalid\n"); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); /* * Reset USB devices */ reg = ATH_READ_REG(AR71XX_RST_RESET); reg |= RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY; ATH_WRITE_REG(AR71XX_RST_RESET, reg); DELAY(1000); reg &= ~(RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY); ATH_WRITE_REG(AR71XX_RST_RESET, reg); ATH_WRITE_REG(AR71XX_USB_CTRL_CONFIG, USB_CTRL_CONFIG_OHCI_DES_SWAP | USB_CTRL_CONFIG_OHCI_BUF_SWAP | USB_CTRL_CONFIG_EHCI_DES_SWAP | USB_CTRL_CONFIG_EHCI_BUF_SWAP); ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, (32 << USB_CTRL_FLADJ_HOST_SHIFT) | (3 << USB_CTRL_FLADJ_A5_SHIFT)); DELAY(1000); #ifdef DDB kdb_init(); #endif } Index: projects/mips/sys/mips/idt/idt_machdep.c =================================================================== --- projects/mips/sys/mips/idt/idt_machdep.c (revision 201880) +++ projects/mips/sys/mips/idt/idt_machdep.c (revision 201881) @@ -1,197 +1,197 @@ /*- * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * $Id: $ * */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int *edata; extern int *end; void platform_cpu_init() { /* Nothing special */ } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { volatile unsigned int * p = (void *)0xb8008000; /* * TODO: we should take care of TLB stuff here. Otherwise * board does not boots properly next time */ /* Write 0x8000_0001 to the Reset register */ *p = 0x80000001; __asm __volatile("li $25, 0xbfc00000"); __asm __volatile("j $25"); } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, __register_t a3 __unused) { uint64_t platform_counter_freq; vm_offset_t kernend; int argc = a0; char **argv = (char **)a1; int i, mem; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); /* * Looking for mem=XXM argument */ mem = 0; /* Just something to start with */ for (i=0; i < argc; i++) { if (strncmp(argv[i], "mem=", 4) == 0) { mem = strtol(argv[i] + 4, NULL, 0); break; } } bootverbose = 1; if (mem > 0) realmem = btoc(mem << 20); else realmem = btoc(32 << 20); for (i = 0; i < 10; i++) { phys_avail[i] = 0; } /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; /* * ns8250 uart code uses DELAY so ticker should be inititalized * before cninit. And tick_init_params refers to hz, so * init_param1 * should be called first. */ init_param1(); /* TODO: parse argc,argv */ platform_counter_freq = 330000000UL; mips_timer_init_params(platform_counter_freq, 1); cninit(); /* Panic here, after cninit */ if (mem == 0) panic("No mem=XX parameter in arguments"); printf("cmd line: "); for (i=0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } Index: projects/mips/sys/mips/include/md_var.h =================================================================== --- projects/mips/sys/mips/include/md_var.h (revision 201880) +++ projects/mips/sys/mips/include/md_var.h (revision 201881) @@ -1,77 +1,78 @@ /*- * Copyright (c) 1995 Bruce D. Evans. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: src/sys/i386/include/md_var.h,v 1.35 2000/02/20 20:51:23 bsd * JNPR: md_var.h,v 1.4 2006/10/16 12:30:34 katta * $FreeBSD$ */ #ifndef _MACHINE_MD_VAR_H_ #define _MACHINE_MD_VAR_H_ #include /* * Miscellaneous machine-dependent declarations. */ extern long Maxmem; extern char sigcode[]; extern int szsigcode, szosigcode; extern vm_offset_t kstack0; void MipsSaveCurFPState(struct thread *); void fork_trampoline(void); void cpu_swapin(struct proc *); uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); void MipsSwitchFPState(struct thread *, struct trapframe *); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); #define is_cacheable_mem(pa) is_physical_memory((pa)) #define MIPS_DEBUG 0 #if MIPS_DEBUG #define MIPS_DEBUG_PRINT(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args) #else #define MIPS_DEBUG_PRINT(fmt, args...) #endif void mips_vector_init(void); void cpu_identify(void); void mips_cpu_init(void); +void mips_pcpu0_init(void); void mips_proc0_init(void); /* Platform call-downs. */ void platform_identify(void); extern int busdma_swi_pending; void busdma_swi(void); #endif /* !_MACHINE_MD_VAR_H_ */ Index: projects/mips/sys/mips/malta/malta_machdep.c =================================================================== --- projects/mips/sys/mips/malta/malta_machdep.c (revision 201880) +++ projects/mips/sys/mips/malta/malta_machdep.c (revision 201881) @@ -1,321 +1,322 @@ /*- * Copyright (c) 2006 Wojciech A. Koszek * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TICK_USE_YAMON_FREQ #include #endif #ifdef TICK_USE_MALTA_RTC #include #include #include #endif #include extern int *edata; extern int *end; void lcd_init(void); void lcd_puts(char *); void malta_reset(void); /* * Offsets to MALTA LCD characters. */ static int malta_lcd_offs[] = { MALTA_ASCIIPOS0, MALTA_ASCIIPOS1, MALTA_ASCIIPOS2, MALTA_ASCIIPOS3, MALTA_ASCIIPOS4, MALTA_ASCIIPOS5, MALTA_ASCIIPOS6, MALTA_ASCIIPOS7 }; void platform_cpu_init() { /* Nothing special */ } /* * Put character to Malta LCD at given position. */ static void malta_lcd_putc(int pos, char c) { void *addr; char *ch; if (pos < 0 || pos > 7) return; addr = (void *)(MALTA_ASCII_BASE + malta_lcd_offs[pos]); ch = (char *)MIPS_PHYS_TO_KSEG0(addr); *ch = c; } /* * Print given string on LCD. */ static void malta_lcd_print(char *str) { int i; if (str == NULL) return; for (i = 0; *str != '\0'; i++, str++) malta_lcd_putc(i, *str); } void lcd_init(void) { malta_lcd_print("FreeBSD_"); } void lcd_puts(char *s) { malta_lcd_print(s); } #ifdef TICK_USE_MALTA_RTC static __inline uint8_t rtcin(uint8_t addr) { *((volatile uint8_t *) MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCADR))) = addr; return (*((volatile uint8_t *) MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCDAT)))); } static __inline void writertc(uint8_t addr, uint8_t val) { *((volatile uint8_t *) MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCADR))) = addr; *((volatile uint8_t *) MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCDAT))) = val; } #endif static void mips_init(void) { int i; for (i = 0; i < 10; i++) { phys_avail[i] = 0; } /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } void platform_halt(void) { } void platform_identify(void) { } /* * Perform a board-level soft-reset. * Note that this is not emulated by gxemul. */ void platform_reset(void) { char *c; c = (char *)MIPS_PHYS_TO_KSEG0(MALTA_SOFTRES); *c = MALTA_GORESET; } void platform_trap_enter(void) { } void platform_trap_exit(void) { } static uint64_t malta_cpu_freq(void) { uint64_t platform_counter_freq = 0; #if defined(TICK_USE_YAMON_FREQ) /* * If we are running on a board which uses YAMON firmware, * then query CPU pipeline clock from the syscon object. * If unsuccessful, use hard-coded default. */ platform_counter_freq = yamon_getcpufreq(); #elif defined(TICK_USE_MALTA_RTC) /* * If we are running on a board with the MC146818 RTC, * use it to determine CPU pipeline clock frequency. */ u_int64_t counterval[2]; /* Set RTC to binary mode. */ writertc(RTC_STATUSB, (rtcin(RTC_STATUSB) | RTCSB_BCD)); /* Busy-wait for falling edge of RTC update. */ while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) ; while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) ; counterval[0] = mips_rd_count(); /* Busy-wait for falling edge of RTC update. */ while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) ; while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) ; counterval[1] = mips_rd_count(); platform_counter_freq = counterval[1] - counterval[0]; #endif if (platform_counter_freq == 0) platform_counter_freq = MIPS_DEFAULT_HZ; return (platform_counter_freq); } void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; int argc = a0; char **argv = (char **)a1; char **envp = (char **)a2; unsigned int memsize = a3; int i; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + mips_pcpu0_init(); platform_counter_freq = malta_cpu_freq(); mips_timer_early_init(platform_counter_freq); cninit(); printf("entry: platform_start()\n"); bootverbose = 1; if (bootverbose) { printf("cmd line: "); for (i = 0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); printf("envp:\n"); for (i = 0; envp[i]; i += 2) printf("\t%s = %s\n", envp[i], envp[i+1]); printf("memsize = %08x\n", memsize); } realmem = btoc(memsize); mips_init(); mips_timer_init_params(platform_counter_freq, 0); } Index: projects/mips/sys/mips/mips/machdep.c =================================================================== --- projects/mips/sys/mips/mips/machdep.c (revision 201880) +++ projects/mips/sys/mips/mips/machdep.c (revision 201881) @@ -1,461 +1,461 @@ /* $OpenBSD: machdep.c,v 1.33 1998/09/15 10:58:54 pefo Exp $ */ /* tracked to 1.38 */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department, The Mach Operating System project at * Carnegie-Mellon University and Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)machdep.c 8.3 (Berkeley) 1/12/94 * Id: machdep.c,v 1.33 1998/09/15 10:58:54 pefo Exp * JNPR: machdep.c,v 1.11.2.3 2007/08/29 12:24:49 */ #include __FBSDID("$FreeBSD$"); #include "opt_cputype.h" #include "opt_ddb.h" #include "opt_md.h" #include "opt_msgbuf.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DDB #include #include #endif #include #include #define BOOTINFO_DEBUG 0 char machine[] = "mips"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class"); static char cpu_model[30]; SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model"); int cold = 1; long realmem = 0; long Maxmem = 0; int cpu_clock = MIPS_DEFAULT_HZ; SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &cpu_clock, 0, "CPU instruction clock rate"); int clocks_running = 0; vm_offset_t kstack0; #ifdef SMP struct pcpu __pcpu[MAXCPU]; char pcpu_boot_stack[KSTACK_PAGES * PAGE_SIZE * MAXCPU]; #else struct pcpu pcpu; struct pcpu *pcpup = &pcpu; #endif vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; #ifdef UNIMPLEMENTED struct platform platform; #endif vm_paddr_t mips_wired_tlb_physmem_start; vm_paddr_t mips_wired_tlb_physmem_end; u_int need_wired_tlb_page_pool; static void cpu_startup(void *); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); struct kva_md_info kmi; int cpucfg; /* Value of processor config register */ int num_tlbentries = 64; /* Size of the CPU tlb */ int cputype; extern char MipsException[], MipsExceptionEnd[]; /* TLB miss handler address and end */ extern char MipsTLBMiss[], MipsTLBMissEnd[]; /* Cache error handler */ extern char MipsCache[], MipsCacheEnd[]; extern char edata[], end[]; u_int32_t bootdev; struct bootinfo bootinfo; static void cpu_startup(void *dummy) { if (boothowto & RB_VERBOSE) bootverbose++; bootverbose++; printf("real memory = %lu (%luK bytes)\n", ptoa(realmem), ptoa(realmem) / 1024); /* * Display any holes after the first chunk of extended memory. */ if (bootverbose) { int indx; printf("Physical memory chunk(s):\n"); for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { uintptr_t size1 = phys_avail[indx + 1] - phys_avail[indx]; printf("0x%08llx - 0x%08llx, %llu bytes (%llu pages)\n", (unsigned long long)phys_avail[indx], (unsigned long long)phys_avail[indx + 1] - 1, (unsigned long long)size1, (unsigned long long)size1 / PAGE_SIZE); } } vm_ksubmap_init(&kmi); printf("avail memory = %lu (%luMB)\n", ptoa(cnt.v_free_count), ptoa(cnt.v_free_count) / 1048576); cpu_init_interrupts(); /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); vm_pager_bufferinit(); } /* * Shutdown the CPU as much as possible */ void cpu_reset(void) { platform_reset(); } /* * Flush the D-cache for non-DMA I/O so that the I-cache can * be made coherent later. */ void cpu_flush_dcache(void *ptr, size_t len) { /* TBD */ } /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) { return (ENXIO); } /* * Shutdown the CPU as much as possible */ void cpu_halt(void) { for (;;) ; } SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, CTLFLAG_RD, &bootinfo, bootinfo, "Bootinfo struct: kernel filename, BIOS harddisk geometry, etc"); #ifdef PORT_TO_JMIPS static int sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) { } SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT | CTLFLAG_RW, &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", "Local offset from GMT in seconds"); SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set, 0, "Disable setting the real time clock to system time"); SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, &wall_cmos_clock, 0, "Wall CMOS clock assumed"); #endif /* PORT_TO_JMIPS */ /* * Initialize per cpu data structures, include curthread. */ void -mips_pcpu_init() +mips_pcpu0_init() { /* Initialize pcpu info of cpu-zero */ #ifdef SMP pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); #else pcpu_init(pcpup, 0, sizeof(struct pcpu)); #endif PCPU_SET(curthread, &thread0); } /* * Initialize mips and configure to run kernel */ void mips_proc0_init(void) { proc_linkup0(&proc0, &thread0); KASSERT((kstack0 & PAGE_MASK) == 0, ("kstack0 is not aligned on a page boundary: 0x%0lx", (long)kstack0)); thread0.td_kstack = kstack0; thread0.td_kstack_pages = KSTACK_PAGES; thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* * Do not use cpu_thread_alloc to initialize these fields * thread0 is the only thread that has kstack located in KSEG0 * while cpu_thread_alloc handles kstack allocated in KSEG2. */ thread0.td_pcb = (struct pcb *)(thread0.td_md.md_realstack + (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1; thread0.td_frame = &thread0.td_pcb->pcb_regs; /* Steal memory for the dynamic per-cpu area. */ dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); PCPU_SET(curpcb, thread0.td_pcb); /* * There is no need to initialize md_upte array for thread0 as it's * located in .bss section and should be explicitly zeroed during * kernel initialization. */ } void cpu_initclocks(void) { platform_initclocks(); } struct msgbuf *msgbufp=0; /* * Initialize the hardware exception vectors, and the jump table used to * call locore cache and TLB management functions, based on the kind * of CPU the kernel is running on. */ void mips_vector_init(void) { /* * Copy down exception vector code. */ if (MipsTLBMissEnd - MipsTLBMiss > 0x80) panic("startup: UTLB code too large"); if (MipsCacheEnd - MipsCache > 0x80) panic("startup: Cache error code too large"); bcopy(MipsTLBMiss, (void *)TLB_MISS_EXC_VEC, MipsTLBMissEnd - MipsTLBMiss); #ifdef TARGET_OCTEON /* Fake, but sufficient, for the 32-bit with 64-bit hardware addresses */ bcopy(MipsTLBMiss, (void *)XTLB_MISS_EXC_VEC, MipsTLBMissEnd - MipsTLBMiss); #endif bcopy(MipsException, (void *)GEN_EXC_VEC, MipsExceptionEnd - MipsException); bcopy(MipsCache, (void *)CACHE_ERR_EXC_VEC, MipsCacheEnd - MipsCache); /* * Clear out the I and D caches. */ mips_icache_sync_all(); mips_dcache_wbinv_all(); /* * Mask all interrupts. Each interrupt will be enabled * when handler is installed for it */ set_intr_mask (ALL_INT_MASK); /* Clear BEV in SR so we start handling our own exceptions */ mips_cp0_status_write(mips_cp0_status_read() & ~SR_BOOT_EXC_VEC); } /* * Initialise a struct pcpu. */ void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) { #ifdef SMP if (cpuid != 0) pcpu->pc_boot_stack = (void *)(pcpu_boot_stack + cpuid * (KSTACK_PAGES * PAGE_SIZE)); #endif pcpu->pc_next_asid = 1; pcpu->pc_asid_generation = 1; } int fill_dbregs(struct thread *td, struct dbreg *dbregs) { /* No debug registers on mips */ return (ENOSYS); } int set_dbregs(struct thread *td, struct dbreg *dbregs) { /* No debug registers on mips */ return (ENOSYS); } void spinlock_enter(void) { struct thread *td; td = curthread; if (td->td_md.md_spinlock_count == 0) td->td_md.md_saved_intr = disableintr(); td->td_md.md_spinlock_count++; critical_enter(); } void spinlock_exit(void) { struct thread *td; td = curthread; critical_exit(); td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) restoreintr(td->td_md.md_saved_intr); } u_int32_t get_cyclecount(void) { u_int32_t count; mfc0_macro(count, 9); return (count); } /* * call platform specific code to halt (until next interrupt) for the idle loop */ void cpu_idle(int busy) { if (mips_cp0_status_read() & SR_INT_ENAB) __asm __volatile ("wait"); else panic("ints disabled in idleproc!"); } void dumpsys(struct dumperinfo *di __unused) { printf("Kernel dumps not implemented on this architecture\n"); } int cpu_idle_wakeup(int cpu) { return (0); } int is_physical_memory(vm_offset_t addr) { int i; for (i = 0; physmem_desc[i + 1] != 0; i += 2) { if (addr >= physmem_desc[i] && addr < physmem_desc[i + 1]) return (1); } return (0); } Index: projects/mips/sys/mips/octeon1/octeon_machdep.c =================================================================== --- projects/mips/sys/mips/octeon1/octeon_machdep.c (revision 201880) +++ projects/mips/sys/mips/octeon1/octeon_machdep.c (revision 201881) @@ -1,965 +1,965 @@ /*- * Copyright (c) 2006 Wojciech A. Koszek * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__mips_n64) #define MAX_APP_DESC_ADDR 0xffffffffafffffff #else #define MAX_APP_DESC_ADDR 0xafffffff #endif extern int *edata; extern int *end; uint64_t ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip); void ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip); static void octeon_boot_params_init(register_t ptr); static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx); static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx); void platform_cpu_init() { /* Nothing special yet */ } /* * Perform a board-level soft-reset. */ void platform_reset(void) { ((void(*)(void))0x1fc00000)(); /* Jump to this hex address */ } static inline uint32_t octeon_disable_interrupts(void) { uint32_t status_bits; status_bits = mips_rd_status(); mips_wr_status(status_bits & ~MIPS_SR_INT_IE); return (status_bits); } static inline void octeon_set_interrupts(uint32_t status_bits) { mips_wr_status(status_bits); } void octeon_led_write_char(int char_position, char val) { uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); if (!octeon_board_real()) return; char_position &= 0x7; /* only 8 chars */ ptr += char_position; oct_write8_x8(ptr, val); } void octeon_led_write_char0(char val) { uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); if (!octeon_board_real()) return; oct_write8_x8(ptr, val); } void octeon_led_write_hexchar(int char_position, char hexval) { uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); char char1, char2; if (!octeon_board_real()) return; char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7'; char2 = (hexval & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7'; char_position &= 0x7; /* only 8 chars */ if (char_position > 6) char_position = 6; ptr += char_position; oct_write8_x8(ptr, char1); ptr++; oct_write8_x8(ptr, char2); } void octeon_led_write_string(const char *str) { uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); int i; if (!octeon_board_real()) return; for (i=0; i<8; i++, ptr++) { if (str && *str) oct_write8_x8(ptr, *str++); else oct_write8_x8(ptr, ' '); oct_read64(OCTEON_MIO_BOOT_BIST_STAT); } } static char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'}; void octeon_led_run_wheel(int *prog_count, int led_position) { if (!octeon_board_real()) return; octeon_led_write_char(led_position, progress[*prog_count]); *prog_count += 1; *prog_count &= 0x7; } #define LSR_DATAREADY 0x01 /* Data ready */ #define LSR_THRE 0x20 /* Transmit holding register empty */ #define LSR_TEMT 0x40 /* Transmitter Empty. THR, TSR & FIFO */ #define USR_TXFIFO_NOTFULL 0x02 /* Uart TX FIFO Not full */ /* * octeon_uart_write_byte * * Put out a single byte off of uart port. */ void octeon_uart_write_byte(int uart_index, uint8_t ch) { uint64_t val, val2; if (uart_index < 0 || uart_index > 1) return; while (1) { val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400)); if ((((uint8_t) val) & LSR_THRE) || (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { break; } } /* Write the byte */ oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch); /* Force Flush the IOBus */ oct_read64(OCTEON_MIO_BOOT_BIST_STAT); } void octeon_uart_write_byte0(uint8_t ch) { uint64_t val, val2; while (1) { val = oct_read64(OCTEON_MIO_UART0_LSR); val2 = oct_read64(OCTEON_MIO_UART0_USR); if ((((uint8_t) val) & LSR_THRE) || (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { break; } } /* Write the byte */ oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch); /* Force Flush the IOBus */ oct_read64(OCTEON_MIO_BOOT_BIST_STAT); } /* * octeon_uart_write_string * */ void octeon_uart_write_string(int uart_index, const char *str) { /* Just loop writing one byte at a time */ while (*str) { octeon_uart_write_byte(uart_index, *str); if (*str == '\n') { octeon_uart_write_byte(uart_index, '\r'); } str++; } } static char wstr[30]; void octeon_led_write_hex(uint32_t wl) { char nbuf[80]; sprintf(nbuf, "%X", wl); octeon_led_write_string(nbuf); } void octeon_uart_write_hex2(uint32_t wl, uint32_t wh) { sprintf(wstr, "0x%X-0x%X ", wh, wl); octeon_uart_write_string(0, wstr); } void octeon_uart_write_hex(uint32_t wl) { sprintf(wstr, " 0x%X ", wl); octeon_uart_write_string(0, wstr); } /* * octeon_wait_uart_flush */ void octeon_wait_uart_flush(int uart_index, uint8_t ch) { uint64_t val; int64_t val3; uint32_t cpu_status_bits; if (uart_index < 0 || uart_index > 1) return; cpu_status_bits = octeon_disable_interrupts(); /* Force Flush the IOBus */ oct_read64(OCTEON_MIO_BOOT_BIST_STAT); for (val3 = 0xfffffffff; val3 > 0; val3--) { val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); if (((uint8_t) val) & LSR_TEMT) break; } octeon_set_interrupts(cpu_status_bits); } /* * octeon_debug_symbol * * Does nothing. * Used to mark the point for simulator to begin tracing */ void octeon_debug_symbol(void) { } void octeon_ciu_stop_gtimer(int timer) { oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll); } void octeon_ciu_start_gtimer(int timer, u_int one_shot, uint64_t time_cycles) { octeon_ciu_gentimer gentimer; gentimer.word64 = 0; gentimer.bits.one_shot = one_shot; gentimer.bits.len = time_cycles - 1; oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), gentimer.word64); } /* * octeon_ciu_reset * * Shutdown all CIU to IP2, IP3 mappings */ void octeon_ciu_reset(void) { octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0); octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1); octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2); octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3); ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0); ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1); ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0); ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1); ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll); ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll); ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll); } /* * mips_disable_interrupt_controllers * * Disable interrupts in the CPU controller */ void mips_disable_interrupt_controls(void) { /* * Disable interrupts in CIU. */ octeon_ciu_reset(); } /* * ciu_get_intr_sum_reg_addr */ static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx) { uint64_t ciu_intr_sum_reg_addr; if (enx == CIU_EN_0) ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR + (core_num * 0x10) + (intx * 0x8); else ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_INT1_ADDR; return (ciu_intr_sum_reg_addr); } /* * ciu_get_intr_en_reg_addr */ static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx) { uint64_t ciu_intr_reg_addr; ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR + ((enx == 0) ? 0x0 : 0x8) + (intx * 0x10) + (core_num * 0x20); return (ciu_intr_reg_addr); } /* * ciu_get_intr_reg_addr * * 200 ---int0,en0 ip2 * 208 ---int0,en1 ip2 ----> this is wrong... this is watchdog * * 210 ---int0,en0 ip3 -- * 218 ---int0,en1 ip3 ----> same here.. .this is watchdog... right? * * 220 ---int1,en0 ip2 * 228 ---int1,en1 ip2 * 230 ---int1,en0 ip3 -- * 238 ---int1,en1 ip3 * */ uint64_t ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip) { uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR; /* XXX kasserts? */ if (enx < CIU_EN_0 || enx > CIU_EN_1) { printf("%s: invalid enx value %d, should be %d or %d\n", __FUNCTION__, enx, CIU_EN_0, CIU_EN_1); return 0; } if (intx < CIU_INT_0 || intx > CIU_INT_1) { printf("%s: invalid intx value %d, should be %d or %d\n", __FUNCTION__, enx, CIU_INT_0, CIU_INT_1); return 0; } if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) { printf("%s: invalid ciu_ip value %d, should be %d or %d\n", __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); return 0; } ciu_intr_reg_addr += (enx * 0x8); ciu_intr_reg_addr += (ciu_ip * 0x10); ciu_intr_reg_addr += (intx * 0x20); return (ciu_intr_reg_addr); } /* * ciu_get_int_summary */ uint64_t ciu_get_int_summary(int core_num, int intx, int enx) { uint64_t ciu_intr_sum_reg_addr; if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); return (oct_read64(ciu_intr_sum_reg_addr)); } //#define DEBUG_CIU 1 #ifdef DEBUG_CIU #define DEBUG_CIU_SUM 1 #define DEBUG_CIU_EN 1 #endif /* * ciu_clear_int_summary */ void ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits) { uint32_t cpu_status_bits; uint64_t ciu_intr_sum_reg_addr; //#define DEBUG_CIU_SUM 1 #ifdef DEBUG_CIU_SUM uint64_t ciu_intr_sum_bits; #endif if (core_num == CIU_THIS_CORE) { core_num = octeon_get_core_num(); } #ifdef DEBUG_CIU_SUM printf(" CIU: core %u clear sum IntX %u Enx %u Bits: 0x%llX\n", core_num, intx, enx, write_bits); #endif cpu_status_bits = octeon_disable_interrupts(); ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); #ifdef DEBUG_CIU_SUM ciu_intr_sum_bits = oct_read64(ciu_intr_sum_reg_addr); /* unneeded dummy read */ printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits, ciu_intr_sum_bits | write_bits); #endif oct_write64(ciu_intr_sum_reg_addr, write_bits); oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ #ifdef DEBUG_CIU_SUM printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr)); #endif octeon_set_interrupts(cpu_status_bits); } /* * ciu_disable_intr */ void ciu_disable_intr(int core_num, int intx, int enx) { uint32_t cpu_status_bits; uint64_t ciu_intr_reg_addr; if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); cpu_status_bits = octeon_disable_interrupts(); ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); oct_read64(ciu_intr_reg_addr); /* Dummy read */ oct_write64(ciu_intr_reg_addr, 0LL); oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ octeon_set_interrupts(cpu_status_bits); } void ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip) { uint64_t ciu_intr_reg_addr; uint64_t ciu_intr_bits; if (core_num == CIU_THIS_CORE) { core_num = octeon_get_core_num(); } #ifndef OCTEON_SMP_1 ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); #else ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip); #endif if (!ciu_intr_reg_addr) { printf("Bad call to %s\n", __FUNCTION__); while(1); return; } ciu_intr_bits = oct_read64(ciu_intr_reg_addr); printf(" CIU core %d int: %d en: %d ip: %d Add: %#llx enabled: %#llx SR: %x\n", core_num, intx, enx, ciu_ip, (unsigned long long)ciu_intr_reg_addr, (unsigned long long)ciu_intr_bits, mips_rd_status()); } /* * ciu_enable_interrupts */ void ciu_enable_interrupts(int core_num, int intx, int enx, uint64_t set_these_interrupt_bits, int ciu_ip) { uint32_t cpu_status_bits; uint64_t ciu_intr_reg_addr; uint64_t ciu_intr_bits; if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); //#define DEBUG_CIU_EN 1 #ifdef DEBUG_CIU_EN printf(" CIU: core %u enabling Intx %u Enx %u IP %d Bits: 0x%llX\n", core_num, intx, enx, ciu_ip, set_these_interrupt_bits); #endif cpu_status_bits = octeon_disable_interrupts(); #ifndef OCTEON_SMP_1 ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); #else ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip); #endif if (!ciu_intr_reg_addr) { printf("Bad call to %s\n", __FUNCTION__); while(1); return; /* XXX */ } ciu_intr_bits = oct_read64(ciu_intr_reg_addr); #ifdef DEBUG_CIU_EN printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits); #endif ciu_intr_bits |= set_these_interrupt_bits; oct_write64(ciu_intr_reg_addr, ciu_intr_bits); #ifdef OCTEON_SMP mips_wbflush(); #endif oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ #ifdef DEBUG_CIU_EN printf(" Readback: 0x%llX\n\n ", (uint64_t)oct_read64(ciu_intr_reg_addr)); #endif octeon_set_interrupts(cpu_status_bits); } void platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, __register_t a3) { uint64_t platform_counter_freq; vm_offset_t kernend; int argc = a0; char **argv = (char **)a1; int i, mem; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); octeon_boot_params_init(a3); /* XXX octeon boot decriptor has args in it... */ octeon_ciu_reset(); octeon_uart_write_string(0, "Platform Starting\n"); /* * Looking for mem=XXM argument */ mem = 0; /* Just something to start with */ for (i=0; i < argc; i++) { if (strncmp(argv[i], "mem=", 4) == 0) { mem = strtol(argv[i] + 4, NULL, 0); break; } } bootverbose = 1; if (mem > 0) realmem = btoc(mem << 20); else realmem = btoc(32 << 20); for (i = 0; i < 10; i++) phys_avail[i] = 0; /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); physmem = realmem; pmap_bootstrap(); mips_proc0_init(); init_param1(); /* TODO: parse argc,argv */ platform_counter_freq = 330000000UL; /* XXX: from idt */ mips_timer_init_params(platform_counter_freq, 1); cninit(); printf("cmd line: "); for (i=0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); init_param2(physmem); mips_cpu_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } /* **************************************************************************************** * * APP/BOOT DESCRIPTOR STUFF * **************************************************************************************** */ /* Define the struct that is initialized by the bootloader used by the * startup code. * * Copyright (c) 2004, 2005, 2006 Cavium Networks. * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this * notice is included verbatim in any distributions. No written agreement, * license, or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their authors * and need not follow the licensing terms described here, provided that * the new terms are clearly indicated on the first page of each file where * they apply. */ #define OCTEON_CURRENT_DESC_VERSION 6 #define OCTEON_ARGV_MAX_ARGS (64) #define OCTOEN_SERIAL_LEN 20 typedef struct { /* Start of block referenced by assembly code - do not change! */ uint32_t desc_version; uint32_t desc_size; uint64_t stack_top; uint64_t heap_base; uint64_t heap_end; uint64_t entry_point; /* Only used by bootloader */ uint64_t desc_vaddr; /* End of This block referenced by assembly code - do not change! */ uint32_t exception_base_addr; uint32_t stack_size; uint32_t heap_size; uint32_t argc; /* Argc count for application */ uint32_t argv[OCTEON_ARGV_MAX_ARGS]; uint32_t flags; uint32_t core_mask; uint32_t dram_size; /**< DRAM size in megabyes */ uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ uint32_t eclock_hz; /**< CPU clock speed, in hz */ uint32_t dclock_hz; /**< DRAM clock speed, in hz */ uint32_t spi_clock_hz; /**< SPI4 clock in hz */ uint16_t board_type; uint8_t board_rev_major; uint8_t board_rev_minor; uint16_t chip_type; uint8_t chip_rev_major; uint8_t chip_rev_minor; char board_serial_number[OCTOEN_SERIAL_LEN]; uint8_t mac_addr_base[6]; uint8_t mac_addr_count; uint64_t cvmx_desc_vaddr; } octeon_boot_descriptor_t; typedef struct { uint32_t major_version; uint32_t minor_version; uint64_t stack_top; uint64_t heap_base; uint64_t heap_end; uint64_t desc_vaddr; uint32_t exception_base_addr; uint32_t stack_size; uint32_t flags; uint32_t core_mask; uint32_t dram_size; /**< DRAM size in megabyes */ uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ uint32_t eclock_hz; /**< CPU clock speed, in hz */ uint32_t dclock_hz; /**< DRAM clock speed, in hz */ uint32_t spi_clock_hz; /**< SPI4 clock in hz */ uint16_t board_type; uint8_t board_rev_major; uint8_t board_rev_minor; uint16_t chip_type; uint8_t chip_rev_major; uint8_t chip_rev_minor; char board_serial_number[OCTOEN_SERIAL_LEN]; uint8_t mac_addr_base[6]; uint8_t mac_addr_count; } cvmx_bootinfo_t; uint32_t octeon_cpu_clock; uint64_t octeon_dram; uint32_t octeon_bd_ver = 0, octeon_cvmx_bd_ver = 0, octeon_board_rev_major, octeon_board_rev_minor, octeon_board_type; uint8_t octeon_mac_addr[6] = { 0 }; int octeon_core_mask, octeon_mac_addr_count; int octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0; extern int32_t app_descriptor_addr; static octeon_boot_descriptor_t *app_desc_ptr; static cvmx_bootinfo_t *cvmx_desc_ptr; #define OCTEON_BOARD_TYPE_NONE 0 #define OCTEON_BOARD_TYPE_SIM 1 #define OCTEON_CLOCK_MIN (100 * 1000 * 1000) #define OCTEON_CLOCK_MAX (800 * 1000 * 1000) #define OCTEON_DRAM_DEFAULT (256 * 1024 * 1024) #define OCTEON_DRAM_MIN 30 #define OCTEON_DRAM_MAX 3000 int octeon_board_real(void) { if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) || (octeon_board_type == OCTEON_BOARD_TYPE_SIM) || !octeon_board_rev_major) return 0; return 1; } static void octeon_process_app_desc_ver_unknown(void) { printf(" Unknown Boot-Descriptor: Using Defaults\n"); octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; octeon_dram = OCTEON_DRAM_DEFAULT; octeon_board_rev_major = octeon_board_rev_minor = octeon_board_type = 0; octeon_core_mask = 1; octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; octeon_chip_type = octeon_chip_rev_major = octeon_chip_rev_minor = 0; octeon_mac_addr[0] = 0x00; octeon_mac_addr[1] = 0x0f; octeon_mac_addr[2] = 0xb7; octeon_mac_addr[3] = 0x10; octeon_mac_addr[4] = 0x09; octeon_mac_addr[5] = 0x06; octeon_mac_addr_count = 1; } static int octeon_process_app_desc_ver_6(void) { /* XXX Why is 0x00000000ffffffffULL a bad value? */ if (app_desc_ptr->cvmx_desc_vaddr == 0 || app_desc_ptr->cvmx_desc_vaddr == 0xfffffffful) { printf ("Bad cvmx_desc_ptr %p\n", cvmx_desc_ptr); return 1; } cvmx_desc_ptr = (cvmx_bootinfo_t *)(intptr_t)app_desc_ptr->cvmx_desc_vaddr; cvmx_desc_ptr = (cvmx_bootinfo_t *) ((intptr_t)cvmx_desc_ptr | MIPS_KSEG0_START); octeon_cvmx_bd_ver = (cvmx_desc_ptr->major_version * 100) + cvmx_desc_ptr->minor_version; /* Too early for panic? */ if (cvmx_desc_ptr->major_version != 1) { printf("Incompatible CVMX descriptor from bootloader: %d.%d %p\n", (int) cvmx_desc_ptr->major_version, (int) cvmx_desc_ptr->minor_version, cvmx_desc_ptr); while (1); /* Never return */ return 1; /* Satisfy the compiler */ } octeon_core_mask = cvmx_desc_ptr->core_mask; octeon_cpu_clock = cvmx_desc_ptr->eclock_hz; octeon_board_type = cvmx_desc_ptr->board_type; octeon_board_rev_major = cvmx_desc_ptr->board_rev_major; octeon_board_rev_minor = cvmx_desc_ptr->board_rev_minor; octeon_chip_type = cvmx_desc_ptr->chip_type; octeon_chip_rev_major = cvmx_desc_ptr->chip_rev_major; octeon_chip_rev_minor = cvmx_desc_ptr->chip_rev_minor; octeon_mac_addr[0] = cvmx_desc_ptr->mac_addr_base[0]; octeon_mac_addr[1] = cvmx_desc_ptr->mac_addr_base[1]; octeon_mac_addr[2] = cvmx_desc_ptr->mac_addr_base[2]; octeon_mac_addr[3] = cvmx_desc_ptr->mac_addr_base[3]; octeon_mac_addr[4] = cvmx_desc_ptr->mac_addr_base[4]; octeon_mac_addr[5] = cvmx_desc_ptr->mac_addr_base[5]; octeon_mac_addr_count = cvmx_desc_ptr->mac_addr_count; if (app_desc_ptr->dram_size > 16*1024*1024) octeon_dram = (uint64_t)app_desc_ptr->dram_size; else octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20; return 0; } static int octeon_process_app_desc_ver_3_4_5(void) { octeon_cvmx_bd_ver = octeon_bd_ver; octeon_core_mask = app_desc_ptr->core_mask; if (app_desc_ptr->desc_version > 3) octeon_cpu_clock = app_desc_ptr->eclock_hz; else octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; if (app_desc_ptr->dram_size > 16*1024*1024) octeon_dram = (uint64_t)app_desc_ptr->dram_size; else octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20; if (app_desc_ptr->desc_version > 4) { octeon_board_type = app_desc_ptr->board_type; octeon_board_rev_major = app_desc_ptr->board_rev_major; octeon_board_rev_minor = app_desc_ptr->board_rev_minor; octeon_chip_type = app_desc_ptr->chip_type; octeon_chip_rev_major = app_desc_ptr->chip_rev_major; octeon_chip_rev_minor = app_desc_ptr->chip_rev_minor; octeon_mac_addr[0] = app_desc_ptr->mac_addr_base[0]; octeon_mac_addr[1] = app_desc_ptr->mac_addr_base[1]; octeon_mac_addr[2] = app_desc_ptr->mac_addr_base[2]; octeon_mac_addr[3] = app_desc_ptr->mac_addr_base[3]; octeon_mac_addr[4] = app_desc_ptr->mac_addr_base[4]; octeon_mac_addr[5] = app_desc_ptr->mac_addr_base[5]; octeon_mac_addr_count = app_desc_ptr->mac_addr_count; } return 0; } static void octeon_boot_params_init(register_t ptr) { int bad_desc = 1; if (ptr != 0 && ptr < MAX_APP_DESC_ADDR) { app_desc_ptr = (octeon_boot_descriptor_t *)(intptr_t)ptr; octeon_bd_ver = app_desc_ptr->desc_version; if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5)) bad_desc = octeon_process_app_desc_ver_3_4_5(); else if (app_desc_ptr->desc_version == 6) bad_desc = octeon_process_app_desc_ver_6(); } if (bad_desc) octeon_process_app_desc_ver_unknown(); printf("Boot Descriptor Ver: %u -> %u/%u", octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100); printf(" CPU clock: %uMHz\n", octeon_cpu_clock/1000000); printf(" Dram: %u MB", (uint32_t)(octeon_dram >> 20)); printf(" Board Type: %u Revision: %u/%u\n", octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor); printf(" Octeon Chip: %u Rev %u/%u", octeon_chip_type, octeon_chip_rev_major, octeon_chip_rev_minor); printf(" Mac Address %02X.%02X.%02X.%02X.%02X.%02X\n", octeon_mac_addr[0], octeon_mac_addr[1], octeon_mac_addr[2], octeon_mac_addr[3], octeon_mac_addr[4], octeon_mac_addr[5]); } Index: projects/mips/sys/mips/rmi/xlr_machdep.c =================================================================== --- projects/mips/sys/mips/rmi/xlr_machdep.c (revision 201880) +++ projects/mips/sys/mips/rmi/xlr_machdep.c (revision 201881) @@ -1,726 +1,726 @@ /*- * Copyright (c) 2006-2009 RMI Corporation * Copyright (c) 2002-2004 Juli Mallett * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* cinit() */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef XLR_PERFMON #include #endif void platform_prep_smp_launch(void); unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE); /* 4KB static data aread to keep a copy of the bootload env until the dynamic kenv is setup */ char boot1_env[4096]; extern unsigned long _gp; int rmi_spin_mutex_safe=0; /* * Parameters from boot loader */ struct boot1_info xlr_boot1_info; struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */ int xlr_run_mode; int xlr_argc; char **xlr_argv, **xlr_envp; uint64_t cpu_mask_info; uint32_t xlr_online_cpumask; #ifdef SMP static unsigned long xlr_secondary_gp[MAXCPU]; static unsigned long xlr_secondary_sp[MAXCPU]; #endif extern int mips_cpu_online_mask; extern int mips_cpu_logical_mask; uint32_t cpu_ltop_map[MAXCPU]; uint32_t cpu_ptol_map[MAXCPU]; uint32_t xlr_core_cpu_mask = 0x1; /* Core 0 thread 0 is always there */ void platform_reset(void) { /* FIXME : use proper define */ u_int32_t *mmio = (u_int32_t *) 0xbef18000; printf("Rebooting the system now\n"); mmio[8] = 0x1; } void platform_secondary_init(void) { #ifdef SMP xlr_msgring_cpu_init(); /* Setup interrupts for secondary CPUs here */ mips_mask_hard_irq(IPI_SMP_CALL_FUNCTION); mips_mask_hard_irq(IPI_STOP); mips_mask_hard_irq(IPI_RENDEZVOUS); mips_mask_hard_irq(IPI_AST); mips_mask_hard_irq(IRQ_TIMER); #ifdef XLR_PERFMON mips_mask_hard_irq(IPI_PERFMON); #endif return; #endif } int xlr_asid_pcpu = 256; /* This the default */ int xlr_shtlb_enabled = 0; /* This function sets up the number of tlb entries available to the kernel based on the number of threads brought up. The ASID range also gets divided similarly. THE NUMBER OF THREADS BROUGHT UP IN EACH CORE MUST BE THE SAME NOTE: This function will mark all 64TLB entries as available to the threads brought up in the core. If kernel is brought with say mask 0x33333333, no TLBs will be available to the threads in each core. */ static void setup_tlb_resource(void) { int mmu_setup; int value = 0; uint32_t cpu_map = xlr_boot1_info.cpu_online_map; uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2); uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf; uint8_t core_thr_mask; int i = 0, count = 0; /* If CPU0 did not enable shared TLB, other cores need to follow */ if ((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0)) return; /* First check if each core is brought up with the same mask */ for (i = 1; i < 8; i++) { core_thr_mask = cpu_map >> (i << 2); core_thr_mask &= 0xf; if (core_thr_mask && core_thr_mask != core0) { printf ("Each core must be brought with same cpu mask\n"); printf("Cannot enabled shared TLB. "); printf("Falling back to split TLB mode\n"); return; } } xlr_shtlb_enabled = 1; for (i = 0; i < 4; i++) if (thr_mask & (1 << i)) count++; switch (count) { case 1: xlr_asid_pcpu = 256; break; case 2: xlr_asid_pcpu = 128; value = 0x2; break; default: xlr_asid_pcpu = 64; value = 0x3; break; } mmu_setup = read_32bit_phnx_ctrl_reg(4, 0); mmu_setup = mmu_setup & ~0x06; mmu_setup |= (value << 1); /* turn on global mode */ mmu_setup |= 0x01; write_32bit_phnx_ctrl_reg(4, 0, mmu_setup); } /* * Platform specific register setup for CPUs * XLR has control registers accessible with MFCR/MTCR instructions, this * code initialized them from the environment variable xlr.cr of form: * xlr.cr=reg:val[,reg:val]*, all values in hex. * To enable shared TLB option use xlr.shtlb=1 */ void platform_cpu_init() { char *hw_env; char *start, *end; uint32_t reg, val; int thr_id = xlr_thr_id(); if (thr_id == 0) { if ((hw_env = getenv("xlr.shtlb")) != NULL) { start = hw_env; reg = strtoul(start, &end, 16); if (start != end && reg != 0) setup_tlb_resource(); } else { /* By default TLB entries are shared in a core */ setup_tlb_resource(); } } if ((hw_env = getenv("xlr.cr")) == NULL) return; start = hw_env; while (*start != '\0') { reg = strtoul(start, &end, 16); if (start == end) { printf("Invalid value in xlr.cr %s, cannot read a hex value at %d\n", hw_env, start - hw_env); goto err_return; } if (*end != ':') { printf("Invalid format in xlr.cr %s, ':' expected at pos %d\n", hw_env, end - hw_env); goto err_return; } start = end + 1;/* step over ':' */ val = strtoul(start, &end, 16); if (start == end) { printf("Invalid value in xlr.cr %s, cannot read a hex value at pos %d\n", hw_env, start - hw_env); goto err_return; } if (*end != ',' && *end != '\0') { printf("Invalid format in xlr.cr %s, ',' expected at pos %d\n", hw_env, end - hw_env); goto err_return; } xlr_mtcr(reg, val); if (*end == ',') start = end + 1; /* skip over ',' */ else start = end; } freeenv(hw_env); return; err_return: panic("Invalid xlr.cr setting!"); return; } #ifdef SMP extern void xlr_secondary_start(unsigned long, unsigned long, unsigned long); static void xlr_secondary_entry(void *data) { unsigned long sp, gp; unsigned int cpu = (xlr_cpu_id() << 2) + xlr_thr_id(); sp = xlr_secondary_sp[cpu]; gp = xlr_secondary_gp[cpu]; xlr_secondary_start((unsigned long)mips_secondary_wait, sp, gp); } #endif static void xlr_set_boot_flags(void) { char *p; for (p = getenv("boot_flags"); p && *p != '\0'; p++) { switch (*p) { case 'd': case 'D': boothowto |= RB_KDB; break; case 'g': case 'G': boothowto |= RB_GDB; break; case 'v': case 'V': boothowto |= RB_VERBOSE; break; case 's': /* single-user (default, supported for sanity) */ case 'S': boothowto |= RB_SINGLE; break; default: printf("Unrecognized boot flag '%c'.\n", *p); break; } } if (p) freeenv(p); return; } extern uint32_t _end; static void mips_init(void) { init_param1(); init_param2(physmem); /* XXX: Catch 22. Something touches the tlb. */ mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); write_c0_register32(MIPS_COP_0_OSSCRATCH, 7, pcpup->pc_curthread); mutex_init(); PMAP_LOCK_INIT(kernel_pmap); #ifdef DDB #ifdef SMP setup_nmi(); #endif /* SMP */ kdb_init(); if (boothowto & RB_KDB) { kdb_enter("Boot flags requested debugger", NULL); } #endif } void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_size_t physsz = 0; int i, j; struct xlr_boot1_mem_map *boot_map; #ifdef SMP uint32_t tmp; void (*wakeup) (void *, void *, unsigned int); #endif /* XXX no zeroing of BSS? */ /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); /* XXX FIXME the code below is not 64 bit clean */ /* Save boot loader and other stuff from scratch regs */ xlr_boot1_info = *(struct boot1_info *)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0); cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1); xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2); xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3); xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4); xlr_argv = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 5); xlr_envp = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6); /* TODO: Verify the magic number here */ /* FIXMELATER: xlr_boot1_info.magic_number */ /* initialize console so that we have printf */ boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ /* clockrate used by delay, so initialize it here */ cpu_clock = xlr_boot1_info.cpu_frequency / 1000000; /* * Note the time counter on CPU0 runs not at system clock speed, but * at PIC time counter speed (which is returned by * platform_get_frequency(). Thus we do not use * xlr_boot1_info.cpu_frequency here. */ mips_timer_early_init(platform_get_frequency()); /* Init the time counter in the PIC and local putc routine*/ rmi_early_counter_init(); /* Init console please */ cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); printf("Environment (from %d args):\n", xlr_argc - 1); if (xlr_argc == 1) printf("\tNone\n"); for (i = 1; i < xlr_argc; i++) { char *n; printf("\t%s\n", xlr_argv[i]); n = strsep(&xlr_argv[i], "="); if (xlr_argv[i] == NULL) setenv(n, "1"); else setenv(n, xlr_argv[i]); } xlr_set_boot_flags(); /* get physical memory info from boot loader */ boot_map = (struct xlr_boot1_mem_map *) (unsigned long)xlr_boot1_info.psb_mem_map; for (i = 0, j = 0; i < boot_map->num_entries; i++, j += 2) { if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) { if (j == 14) { printf("*** ERROR *** memory map too large ***\n"); break; } if (j == 0) { /* TODO FIXME */ /* start after kernel end */ phys_avail[0] = (vm_paddr_t) MIPS_KSEG0_TO_PHYS(&_end) + 0x20000; /* boot loader start */ /* HACK to Use bootloaders memory region */ /* TODO FIXME */ if (boot_map->physmem_map[0].size == 0x0c000000) { boot_map->physmem_map[0].size = 0x0ff00000; } phys_avail[1] = boot_map->physmem_map[0].addr + boot_map->physmem_map[0].size; } else { /* * Can't use this code yet, because most of the fixed allocations happen from * the biggest physical area. If we have more than 512M memory the kernel will try * to map from the second are which is not in KSEG0 and not mapped */ phys_avail[j] = (vm_paddr_t) boot_map->physmem_map[i].addr; phys_avail[j + 1] = phys_avail[j] + boot_map->physmem_map[i].size; #if 0 /* FIXME TOD0 */ phys_avail[j] = phys_avail[j + 1] = 0; #endif } physsz += boot_map->physmem_map[i].size; } } /* FIXME XLR TODO */ phys_avail[j] = phys_avail[j + 1] = 0; realmem = physmem = btoc(physsz); /* Store pcpu in scratch 5 */ write_c0_register32(MIPS_COP_0_OSSCRATCH, 5, pcpup); /* Set up hz, among others. */ mips_init(); #ifdef SMP /* * If thread 0 of any core is not available then mark whole core as * not available */ tmp = xlr_boot1_info.cpu_online_map; for (i = 4; i < MAXCPU; i += 4) { if ((tmp & (0xf << i)) && !(tmp & (0x1 << i))) { /* * Oopps.. thread 0 is not available. Disable whole * core */ tmp = tmp & ~(0xf << i); printf("WARNING: Core %d is disabled because thread 0" " of this core is not enabled.\n", i / 4); } } xlr_boot1_info.cpu_online_map = tmp; /* Wakeup Other cpus, and put them in bsd park code. */ for (i = 1, j = 1; i < 32; i++) { /* Allocate stack for all other cpus from fbsd kseg0 memory. */ if ((1U << i) & xlr_boot1_info.cpu_online_map) { xlr_secondary_gp[i] = pmap_steal_memory(PAGE_SIZE); if (!xlr_secondary_gp[i]) panic("Allocation failed for secondary cpu stacks"); xlr_secondary_sp[i] = xlr_secondary_gp[i] + PAGE_SIZE - CALLFRAME_SIZ; xlr_secondary_gp[i] = (unsigned long)&_gp; /* Build ltop and ptol cpu map. */ cpu_ltop_map[j] = i; cpu_ptol_map[i] = j; if ((i & 0x3) == 0) /* store thread0 of each core */ xlr_core_cpu_mask |= (1 << j); mips_cpu_logical_mask |= (1 << j); j++; } } mips_cpu_online_mask |= xlr_boot1_info.cpu_online_map; wakeup = ((void (*) (void *, void *, unsigned int)) (unsigned long)(xlr_boot1_info.wakeup)); printf("Waking up CPUs 0x%llx.\n", xlr_boot1_info.cpu_online_map & ~(0x1U)); if (xlr_boot1_info.cpu_online_map & ~(0x1U)) wakeup(xlr_secondary_entry, 0, (unsigned int)xlr_boot1_info.cpu_online_map); #endif /* xlr specific post initialization */ /* * The expectation is that mutex_init() is already done in * mips_init() XXX NOTE: We may need to move this to SMP based init * code for each CPU, later. */ rmi_spin_mutex_safe = 1; on_chip_init(); mips_timer_init_params(platform_get_frequency(), 0); printf("Platform specific startup now completes\n"); } void platform_identify(void) { printf("Board [%d:%d], processor 0x%08x\n", (int)xlr_boot1_info.board_major_version, (int)xlr_boot1_info.board_minor_version, mips_rd_prid()); } /* * XXX Maybe return the state of the watchdog in enter, and pass it to * exit? Like spl(). */ void platform_trap_enter(void) { } void platform_trap_exit(void) { } /* void platform_update_intrmask(int intr) { write_c0_eimr64(read_c0_eimr64() | (1ULL<i_thread; p = td->td_proc; /* * Interrupt thread will enable the interrupts after processing all * messages */ disable_msgring_int(NULL); it->i_pending = 1; if (TD_AWAITING_INTR(td)) { thread_lock(td); CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, p->p_comm); TD_CLR_IWAIT(td); sched_add(td, SRQ_INTR); thread_unlock(td); } else { CTR4(KTR_INTR, "%s: pid %d (%s): state %d", __func__, p->p_pid, p->p_comm, td->td_state); } } #define MIT_DEAD 4 static void msgring_process(void *arg) { volatile struct msgring_ithread *ithd; struct thread *td; struct proc *p; td = curthread; p = td->td_proc; ithd = (volatile struct msgring_ithread *)arg; KASSERT(ithd->i_thread == td, ("%s:msg_ithread and proc linkage out of sync", __func__)); /* First bind this thread to the right CPU */ thread_lock(td); sched_bind(td, ithd->i_cpu); thread_unlock(td); //printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); while (1) { if (ithd->i_flags & MIT_DEAD) { CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, p->p_pid, p->p_comm); kthread_exit(); } while (ithd->i_pending) { /* * This might need a full read and write barrier to * make sure that this write posts before any of the * memory or device accesses in the handlers. */ atomic_store_rel_int(&ithd->i_pending, 0); xlr_msgring_handler(NULL); } if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) { thread_lock(td); sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); thread_unlock(td); enable_msgring_int(NULL); mi_switch(SW_VOL, NULL); } } } void platform_prep_smp_launch(void) { int cpu; uint32_t cpu_mask; struct msgring_ithread *ithd; struct thread *td; struct proc *p; int error; cpu_mask = PCPU_GET(cpumask) | PCPU_GET(other_cpus); /* Create kernel threads for message ring interrupt processing */ /* Currently create one task for thread 0 of each core */ for (cpu = 0; cpu < MAXCPU; cpu += 1) { if (!((1 << cpu) & cpu_mask)) continue; if ((cpu_ltop_map[cpu] % 4) != 0) continue; ithd = &msgring_ithreads[cpu]; sprintf(ithd_name[cpu], "msg_intr%d", cpu); error = kproc_create(msgring_process, (void *)ithd, &p, (RFSTOPPED | RFHIGHPID), 2, ithd_name[cpu]); if (error) panic("kproc_create() failed with %d", error); td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ thread_lock(td); sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); thread_unlock(td); ithd->i_thread = td; ithd->i_pending = 0; ithd->i_cpu = cpu; CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]); } } Index: projects/mips/sys/mips/sentry5/s5_machdep.c =================================================================== --- projects/mips/sys/mips/sentry5/s5_machdep.c (revision 201880) +++ projects/mips/sys/mips/sentry5/s5_machdep.c (revision 201881) @@ -1,245 +1,245 @@ /*- * Copyright (c) 2007 Bruce M. Simpson. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CFE #include #endif extern int *edata; extern int *end; void platform_cpu_init() { /* Nothing special */ } static void mips_init(void) { int i; printf("entry: mips_init()\n"); #ifdef CFE /* * Query DRAM memory map from CFE. */ physmem = 0; for (i = 0; i < 10; i += 2) { int result; uint64_t addr, len, type; result = cfe_enummem(i, 0, &addr, &len, &type); if (result < 0) { phys_avail[i] = phys_avail[i + 1] = 0; break; } if (type != CFE_MI_AVAILABLE) continue; phys_avail[i] = addr; if (i == 0 && addr == 0) { /* * If this is the first physical memory segment probed * from CFE, omit the region at the start of physical * memory where the kernel has been loaded. */ phys_avail[i] += MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); } phys_avail[i + 1] = addr + len; physmem += len; } realmem = btoc(physmem); #endif physmem = realmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); #endif } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { #if defined(CFE) cfe_exit(0, 0); #else *((volatile uint8_t *)MIPS_PHYS_TO_KSEG1(SENTRY5_EXTIFADR)) = 0x80; #endif } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); #ifdef CFE /* * Initialize CFE firmware trampolines before * we initialize the low-level console. * * CFE passes the following values in registers: * a0: firmware handle * a2: firmware entry point * a3: entry point seal */ if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif cninit(); mips_init(); # if 0 /* * Probe the Broadcom Sentry5's on-chip PLL clock registers * and discover the CPU pipeline clock and bus clock * multipliers from this. * XXX: Wrong place. You have to ask the ChipCommon * or External Interface cores on the SiBa. */ uint32_t busmult, cpumult, refclock, clkcfg1; #define S5_CLKCFG1_REFCLOCK_MASK 0x0000001F #define S5_CLKCFG1_BUSMULT_MASK 0x000003E0 #define S5_CLKCFG1_BUSMULT_SHIFT 5 #define S5_CLKCFG1_CPUMULT_MASK 0xFFFFFC00 #define S5_CLKCFG1_CPUMULT_SHIFT 10 counter_freq = 100000000; /* XXX */ clkcfg1 = s5_rd_clkcfg1(); printf("clkcfg1 = 0x%08x\n", clkcfg1); refclock = clkcfg1 & 0x1F; busmult = ((clkcfg1 & 0x000003E0) >> 5) + 1; cpumult = ((clkcfg1 & 0xFFFFFC00) >> 10) + 1; printf("refclock = %u\n", refclock); printf("busmult = %u\n", busmult); printf("cpumult = %u\n", cpumult); counter_freq = cpumult * refclock; # else platform_counter_freq = 200 * 1000 * 1000; /* Sentry5 is 200MHz */ # endif mips_timer_init_params(platform_counter_freq, 0); } Index: projects/mips/sys/mips/sibyte/sb_machdep.c =================================================================== --- projects/mips/sys/mips/sibyte/sb_machdep.c (revision 201880) +++ projects/mips/sys/mips/sibyte/sb_machdep.c (revision 201881) @@ -1,264 +1,264 @@ /*- * Copyright (c) 2007 Bruce M. Simpson. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include "opt_ddb.h" #include "opt_kdb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CFE #include #endif #include "sb_scd.h" #ifdef DDB #ifndef KDB #error KDB must be enabled in order for DDB to work! #endif #endif #ifdef CFE_ENV extern void cfe_env_init(void); #endif extern int *edata; extern int *end; void platform_cpu_init() { /* Nothing special */ } static void mips_init(void) { int i, cfe_mem_idx, tmp; uint64_t maxmem; #ifdef CFE_ENV cfe_env_init(); #endif TUNABLE_INT_FETCH("boothowto", &boothowto); if (boothowto & RB_VERBOSE) bootverbose++; #ifdef MAXMEM tmp = MAXMEM; #else tmp = 0; #endif TUNABLE_INT_FETCH("hw.physmem", &tmp); maxmem = (uint64_t)tmp * 1024; #ifdef CFE /* * Query DRAM memory map from CFE. */ physmem = 0; cfe_mem_idx = 0; for (i = 0; i < 10; i += 2) { int result; uint64_t addr, len, type; result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); if (result < 0) { phys_avail[i] = phys_avail[i + 1] = 0; break; } KASSERT(type == CFE_MI_AVAILABLE, ("CFE DRAM region is not available?")); if (bootverbose) printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len); if (maxmem != 0) { if (addr >= maxmem) { printf("Ignoring %llu bytes of memory at 0x%jx " "that is above maxmem %dMB\n", len, addr, (int)(maxmem / (1024 * 1024))); continue; } if (addr + len > maxmem) { printf("Ignoring %llu bytes of memory " "that is above maxmem %dMB\n", (addr + len) - maxmem, (int)(maxmem / (1024 * 1024))); len = maxmem - addr; } } phys_avail[i] = addr; if (i == 0 && addr == 0) { /* * If this is the first physical memory segment probed * from CFE, omit the region at the start of physical * memory where the kernel has been loaded. */ phys_avail[i] += MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); } phys_avail[i + 1] = addr + len; physmem += len; } realmem = btoc(physmem); #endif physmem = realmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); kdb_init(); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif } void platform_halt(void) { } void platform_identify(void) { } void platform_reset(void) { /* * XXX SMP * XXX flush data caches */ sb_system_reset(); } void platform_trap_enter(void) { } void platform_trap_exit(void) { } void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) { vm_offset_t kernend; /* clear the BSS and SBSS segments */ memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); kernend = round_page((vm_offset_t)&end); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); #ifdef CFE /* * Initialize CFE firmware trampolines before * we initialize the low-level console. * * CFE passes the following values in registers: * a0: firmware handle * a2: firmware entry point * a3: entry point seal */ if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif cninit(); mips_init(); mips_timer_init_params(sb_cpu_speed(), 0); }