1/* $NetBSD: obs600_machdep.c,v 1.7 2011/06/20 17:44:33 matt Exp $ */ 2/* Original: md_machdep.c,v 1.3 2005/01/24 18:47:37 shige Exp $ */ 3 4/* 5 * Copyright 2001, 2002 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 41 * Copyright (C) 1995, 1996 TooLs GmbH. 42 * All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by TooLs GmbH. 55 * 4. The name of TooLs GmbH may not be used to endorse or promote products 56 * derived from this software without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 62 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 63 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 64 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 65 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 66 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 67 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70#include <sys/cdefs.h> 71__KERNEL_RCSID(0, "$NetBSD: obs600_machdep.c,v 1.7 2011/06/20 17:44:33 matt Exp $"); 72 73#include "opt_compat_netbsd.h" 74#include "opt_ddb.h" 75#include "opt_ipkdb.h" 76#include "opt_modular.h" 77 78#include <sys/param.h> 79#include <sys/bus.h> 80#include <sys/errno.h> 81#include <sys/kernel.h> 82#include <sys/ksyms.h> 83#include <sys/mount.h> 84#include <sys/reboot.h> 85#include <sys/systm.h> 86#include <sys/device.h> 87#include <sys/module.h> 88#include <sys/bus.h> 89#include <sys/cpu.h> 90 91#include <uvm/uvm_extern.h> 92 93#include <machine/obs600.h> 94 95#include <powerpc/ibm4xx/amcc405ex.h> 96#include <powerpc/ibm4xx/cpu.h> 97#include <powerpc/ibm4xx/dcr4xx.h> 98#include <powerpc/ibm4xx/dev/comopbvar.h> 99#include <powerpc/ibm4xx/dev/gpiicreg.h> 100#include <powerpc/ibm4xx/dev/opbvar.h> 101 102#include <powerpc/spr.h> 103#include <powerpc/ibm4xx/spr.h> 104 105#include <dev/ic/comreg.h> 106 107#include "ksyms.h" 108 109#include "com.h" 110#if (NCOM > 0) 111#include <sys/termios.h> 112 113#ifndef CONADDR 114#define CONADDR AMCC405EX_UART0_BASE 115#endif 116#ifndef CONSPEED 117#define CONSPEED B115200 118#endif 119#ifndef CONMODE 120 /* 8N1 */ 121#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) 122#endif 123#endif /* NCOM */ 124 125/* 126 * XXXX: 127 * It is very troublesome though we can calculate from various registers. X-< 128 */ 129#define OBS600_CPU_FREQ (600 * 1000 * 1000) 130#define OBS600_MEM_SIZE (1 * 1024 * 1024 * 1024) 131 132#define TLB_PG_SIZE (16 * 1024 * 1024) 133 134/* 135 * Global variables used here and there 136 */ 137char bootpath[256]; 138 139extern paddr_t msgbuf_paddr; 140 141void initppc(vaddr_t, vaddr_t, int, char *[], char *); 142static int read_eeprom(int, char *); 143 144 145void 146initppc(vaddr_t startkernel, vaddr_t endkernel, int argc, char *argv[], 147 char *argstr) 148{ 149 vaddr_t va; 150 u_int memsize; 151 152 memsize = OBS600_MEM_SIZE; 153 154 /* Linear map kernel memory */ 155 for (va = 0; va < endkernel; va += TLB_PG_SIZE) 156 ppc4xx_tlb_reserve(va, va, TLB_PG_SIZE, TLB_EX); 157 158 /* 159 * Map console and I2C after RAM. (see pmap_tlbmiss()) 160 * All peripherals mapped on a page. 161 */ 162 ppc4xx_tlb_reserve(AMCC405EX_OPB_BASE, roundup(memsize, TLB_PG_SIZE), 163 TLB_PG_SIZE, TLB_I | TLB_G); 164 165 /* Initialize AMCC 405EX CPU */ 166 ibm40x_memsize_init(memsize, startkernel); 167 ibm4xx_init(startkernel, endkernel, pic_ext_intr); 168 169#ifdef DDB 170 if (boothowto & RB_KDB) 171 Debugger(); 172#endif 173#ifdef IPKDB 174 /* 175 * Now trap to IPKDB 176 */ 177 ipkdb_init(); 178 if (boothowto & RB_KDB) 179 ipkdb_connect(0); 180#endif 181 182 /* 183 * Look for the ibm4xx modules in the right place. 184 */ 185 module_machine = module_machine_ibm4xx; 186} 187 188void 189consinit(void) 190{ 191 192#if (NCOM > 0) 193 com_opb_cnattach(OBS600_COM_FREQ, CONADDR, CONSPEED, CONMODE); 194#endif /* NCOM */ 195} 196 197/* 198 * Machine dependent startup code. 199 */ 200void 201cpu_startup(void) 202{ 203 prop_number_t pn; 204 prop_data_t pd; 205 u_char *macaddr, *macaddr1; 206 static u_char buf[16]; /* MAC address x2 buffer */ 207 208 /* 209 * cpu common startup 210 */ 211 ibm4xx_cpu_startup("OpenBlockS600 AMCC PowerPC 405EX Board"); 212 213 /* 214 * Set up the board properties database. 215 */ 216 board_info_init(); 217 218 /* 219 * Now that we have VM, malloc()s are OK in bus_space. 220 */ 221 bus_space_mallocok(); 222 223 read_eeprom(sizeof(buf), buf); 224 macaddr = &buf[0]; 225 macaddr1 = &buf[8]; 226 227 pn = prop_number_create_integer(OBS600_CPU_FREQ); 228 KASSERT(pn != NULL); 229 if (prop_dictionary_set(board_properties, "processor-frequency", pn) == 230 false) 231 panic("setting processor-frequency"); 232 prop_object_release(pn); 233 234 pn = prop_number_create_integer(OBS600_MEM_SIZE); 235 KASSERT(pn != NULL); 236 if (prop_dictionary_set(board_properties, "mem-size", pn) == false) 237 panic("setting mem-size"); 238 prop_object_release(pn); 239 240#define ETHER_ADDR_LEN 6 241 242 pd = prop_data_create_data_nocopy(macaddr, ETHER_ADDR_LEN); 243 KASSERT(pd != NULL); 244 if (prop_dictionary_set(board_properties, "emac0-mac-addr", pd) == 245 false) 246 panic("setting emac0-mac-addr"); 247 prop_object_release(pd); 248 pd = prop_data_create_data_nocopy(macaddr1, ETHER_ADDR_LEN); 249 KASSERT(pd != NULL); 250 if (prop_dictionary_set(board_properties, "emac1-mac-addr", pd) == 251 false) 252 panic("setting emac1-mac-addr"); 253 prop_object_release(pd); 254 255 /* emac0 connects to phy 2 and emac1 to phy 3 via RGMII. */ 256 pn = prop_number_create_integer(2); 257 KASSERT(pn != NULL); 258 if (prop_dictionary_set(board_properties, "emac0-mii-phy", pn) == false) 259 panic("setting emac0-mii-phy"); 260 prop_object_release(pn); 261 pn = prop_number_create_integer(3); 262 KASSERT(pn != NULL); 263 if (prop_dictionary_set(board_properties, "emac1-mii-phy", pn) == false) 264 panic("setting emac1-mii-phy"); 265 prop_object_release(pn); 266 267 /* 268 * no fake mapiodev 269 */ 270 fake_mapiodev = 0; 271 272 splraise(-1); 273} 274 275/* 276 * Halt or reboot the machine after syncing/dumping according to howto. 277 */ 278void 279cpu_reboot(int howto, char *what) 280{ 281 static int syncing; 282 static char str[256]; 283 char *ap = str, *ap1 = ap; 284 285 boothowto = howto; 286 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 287 syncing = 1; 288 vfs_shutdown(); /* sync */ 289 resettodr(); /* set wall clock */ 290 } 291 292 splhigh(); 293 294 if (!cold && (howto & RB_DUMP)) 295 ibm4xx_dumpsys(); 296 297 doshutdownhooks(); 298 299 pmf_system_shutdown(boothowto); 300 301 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 302 /* Power off here if we know how...*/ 303 } 304 305 if (howto & RB_HALT) { 306 printf("halted\n\n"); 307 308#if 0 309 goto reboot; /* XXX for now... */ 310#endif 311 312#ifdef DDB 313 printf("dropping to debugger\n"); 314 while(1) 315 Debugger(); 316#endif 317 } 318 319 printf("rebooting\n\n"); 320 if (what && *what) { 321 if (strlen(what) > sizeof str - 5) 322 printf("boot string too large, ignored\n"); 323 else { 324 strcpy(str, what); 325 ap1 = ap = str + strlen(str); 326 *ap++ = ' '; 327 } 328 } 329 *ap++ = '-'; 330 if (howto & RB_SINGLE) 331 *ap++ = 's'; 332 if (howto & RB_KDB) 333 *ap++ = 'd'; 334 *ap++ = 0; 335 if (ap[-2] == '-') 336 *ap1 = 0; 337 338 /* flush cache for msgbuf */ 339 __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); 340 341#if 0 342 reboot: 343#endif 344 ppc4xx_reset(); 345 346 printf("ppc4xx_reset() failed!\n"); 347#ifdef DDB 348 while(1) 349 Debugger(); 350#else 351 while (1) 352 /* nothing */; 353#endif 354} 355 356/* This function assume already initialized for I2C... */ 357static int 358read_eeprom(int len, char *buf) 359{ 360 bus_space_tag_t bst = opb_get_bus_space_tag(); 361 bus_space_handle_t bsh; 362 uint8_t mdcntl, sts; 363 int cnt, i = 0; 364 365#define I2C_EEPROM_ADDR 0x52 366 367 if (bus_space_map(bst, AMCC405EX_IIC0_BASE, IIC_NREG, 0, &bsh)) 368 return ENOMEM; /* ??? */ 369 370 /* Clear Stop Complete Bit */ 371 bus_space_write_1(bst, bsh, IIC_STS, IIC_STS_SCMP); 372 /* Check init */ 373 do { 374 /* Get status */ 375 sts = bus_space_read_1(bst, bsh, IIC_STS); 376 } while ((sts & IIC_STS_PT)); 377 378 mdcntl = bus_space_read_1(bst, bsh, IIC_MDCNTL); 379 bus_space_write_1(bst, bsh, IIC_MDCNTL, 380 mdcntl | IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB); 381 382 /* 7-bit adressing */ 383 bus_space_write_1(bst, bsh, IIC_HMADR, 0); 384 bus_space_write_1(bst, bsh, IIC_LMADR, I2C_EEPROM_ADDR << 1); 385 386 bus_space_write_1(bst, bsh, IIC_MDBUF, 0); 387 bus_space_write_1(bst, bsh, IIC_CNTL, IIC_CNTL_PT); 388 do { 389 /* Get status */ 390 sts = bus_space_read_1(bst, bsh, IIC_STS); 391 } while ((sts & IIC_STS_PT) && !(sts & IIC_STS_ERR)); 392 393 cnt = 0; 394 while (cnt < len) { 395 /* always read 4byte */ 396 bus_space_write_1(bst, bsh, IIC_CNTL, 397 IIC_CNTL_PT | IIC_CNTL_RW | IIC_CNTL_TCT); 398 do { 399 /* Get status */ 400 sts = bus_space_read_1(bst, bsh, IIC_STS); 401 } while ((sts & IIC_STS_PT) && !(sts & IIC_STS_ERR)); 402 403 if ((sts & IIC_STS_PT) || (sts & IIC_STS_ERR)) 404 break; 405 if (sts & IIC_STS_MDBS) { 406 delay(1); 407 /* read 4byte */ 408 for (i = 0; i < 4 && cnt < len; i++, cnt++) 409 buf[cnt] = 410 bus_space_read_1(bst, bsh, IIC_MDBUF); 411 } 412 } 413 for ( ; i < 4; i++) 414 (void) bus_space_read_1(bst, bsh, IIC_MDBUF); 415 416#if 0 /* Ooops, can't unmap here... */ 417 bus_space_unmap(bst, bsh, IIC_NREG); 418#endif 419 420 return (cnt == len) ? 0 : EINVAL; 421} 422