1/* 2 * Copyright 2002 Momentum Computer Inc. 3 * Author: Matthew Dharm <mdharm@momenco.com> 4 * 5 * Louis Hamilton, Red Hat, Inc. 6 * hamilton@redhat.com [MIPS64 modifications] 7 * 8 * Based on Ocelot Linux port, which is 9 * Copyright 2001 MontaVista Software Inc. 10 * Author: jsun@mvista.com or jsun@junsun.net 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the 14 * Free Software Foundation; either version 2 of the License, or (at your 15 * option) any later version. 16 */ 17#include <linux/init.h> 18#include <linux/mm.h> 19#include <linux/sched.h> 20#include <linux/bootmem.h> 21#include <linux/mv643xx.h> 22 23#include <asm/addrspace.h> 24#include <asm/bootinfo.h> 25#include <asm/pmon.h> 26 27#include "ocelot_c_fpga.h" 28 29struct callvectors* debug_vectors; 30 31extern unsigned long marvell_base; 32extern unsigned int cpu_clock; 33 34const char *get_system_type(void) 35{ 36#ifdef CONFIG_CPU_SR71000 37 return "Momentum Ocelot-CS"; 38#else 39 return "Momentum Ocelot-C"; 40#endif 41} 42 43#ifdef CONFIG_64BIT 44 45unsigned long signext(unsigned long addr) 46{ 47 addr &= 0xffffffff; 48 return (unsigned long)((int)addr); 49} 50 51void *get_arg(unsigned long args, int arc) 52{ 53 unsigned long ul; 54 unsigned char *puc, uc; 55 56 args += (arc * 4); 57 ul = (unsigned long)signext(args); 58 puc = (unsigned char *)ul; 59 if (puc == 0) 60 return (void *)0; 61 62#ifdef CONFIG_CPU_LITTLE_ENDIAN 63 uc = *puc++; 64 ul = (unsigned long)uc; 65 uc = *puc++; 66 ul |= (((unsigned long)uc) << 8); 67 uc = *puc++; 68 ul |= (((unsigned long)uc) << 16); 69 uc = *puc++; 70 ul |= (((unsigned long)uc) << 24); 71#else /* CONFIG_CPU_LITTLE_ENDIAN */ 72 uc = *puc++; 73 ul = ((unsigned long)uc) << 24; 74 uc = *puc++; 75 ul |= (((unsigned long)uc) << 16); 76 uc = *puc++; 77 ul |= (((unsigned long)uc) << 8); 78 uc = *puc++; 79 ul |= ((unsigned long)uc); 80#endif /* CONFIG_CPU_LITTLE_ENDIAN */ 81 ul = signext(ul); 82 return (void *)ul; 83} 84 85char *arg64(unsigned long addrin, int arg_index) 86{ 87 unsigned long args; 88 char *p; 89 args = signext(addrin); 90 p = (char *)get_arg(args, arg_index); 91 return p; 92} 93#endif /* CONFIG_64BIT */ 94 95 96void __init prom_init(void) 97{ 98 int argc = fw_arg0; 99 char **arg = (char **) fw_arg1; 100 char **env = (char **) fw_arg2; 101 struct callvectors *cv = (struct callvectors *) fw_arg3; 102 int i; 103 104#ifdef CONFIG_64BIT 105 char *ptr; 106 107 printk("prom_init - MIPS64\n"); 108 /* save the PROM vectors for debugging use */ 109 debug_vectors = (struct callvectors *)signext((unsigned long)cv); 110 111 /* arg[0] is "g", the rest is boot parameters */ 112 arcs_cmdline[0] = '\0'; 113 114 for (i = 1; i < argc; i++) { 115 ptr = (char *)arg64((unsigned long)arg, i); 116 if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >= 117 sizeof(arcs_cmdline)) 118 break; 119 strcat(arcs_cmdline, ptr); 120 strcat(arcs_cmdline, " "); 121 } 122 i = 0; 123 while (1) { 124 ptr = (char *)arg64((unsigned long)env, i); 125 if (! ptr) 126 break; 127 128 if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) { 129 marvell_base = simple_strtol(ptr + strlen("gtbase="), 130 NULL, 16); 131 132 if ((marvell_base & 0xffffffff00000000) == 0) 133 marvell_base |= 0xffffffff00000000; 134 135 printk("marvell_base set to 0x%016lx\n", marvell_base); 136 } 137 if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) { 138 cpu_clock = simple_strtol(ptr + strlen("cpuclock="), 139 NULL, 10); 140 printk("cpu_clock set to %d\n", cpu_clock); 141 } 142 i++; 143 } 144 printk("arcs_cmdline: %s\n", arcs_cmdline); 145 146#else /* CONFIG_64BIT */ 147 /* save the PROM vectors for debugging use */ 148 debug_vectors = cv; 149 150 /* arg[0] is "g", the rest is boot parameters */ 151 arcs_cmdline[0] = '\0'; 152 for (i = 1; i < argc; i++) { 153 if (strlen(arcs_cmdline) + strlen(arg[i] + 1) 154 >= sizeof(arcs_cmdline)) 155 break; 156 strcat(arcs_cmdline, arg[i]); 157 strcat(arcs_cmdline, " "); 158 } 159 160 while (*env) { 161 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { 162 marvell_base = simple_strtol(*env + strlen("gtbase="), 163 NULL, 16); 164 } 165 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { 166 cpu_clock = simple_strtol(*env + strlen("cpuclock="), 167 NULL, 10); 168 } 169 env++; 170 } 171#endif /* CONFIG_64BIT */ 172 173 mips_machgroup = MACH_GROUP_MOMENCO; 174 mips_machtype = MACH_MOMENCO_OCELOT_C; 175 176#ifndef CONFIG_64BIT 177 debug_vectors->printf("Booting Linux kernel...\n"); 178#endif 179} 180 181void __init prom_free_prom_memory(void) 182{ 183} 184