/* $NetBSD: obs600_machdep.c,v 1.17 2022/01/15 10:55:06 msaitoh Exp $ */ /* Original: md_machdep.c,v 1.3 2005/01/24 18:47:37 shige Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. * All rights reserved. * * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC * 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. */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. * Copyright (C) 1995, 1996 TooLs GmbH. * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by TooLs GmbH. * 4. The name of TooLs GmbH may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 __KERNEL_RCSID(0, "$NetBSD: obs600_machdep.c,v 1.17 2022/01/15 10:55:06 msaitoh Exp $"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "com.h" #if (NCOM > 0) #include #include #include #ifndef CONADDR #define CONADDR AMCC405EX_UART0_BASE #endif #ifndef CONSPEED #define CONSPEED B115200 #endif #ifndef CONMODE /* 8N1 */ #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) #endif #endif /* NCOM */ /* * XXXX: * It is very troublesome though we can calculate from various registers. X-< */ #define OBS600_CPU_FREQ (600 * 1000 * 1000) #define OBS600_MEM_SIZE (1 * 1024 * 1024 * 1024) #define TLB_PG_SIZE (16 * 1024 * 1024) void initppc(vaddr_t, vaddr_t, int, char *[], char *); static int read_eeprom(int, char *); void initppc(vaddr_t startkernel, vaddr_t endkernel, int argc, char *argv[], char *argstr) { vaddr_t va; u_int memsize; memsize = OBS600_MEM_SIZE; /* Linear map kernel memory */ for (va = 0; va < endkernel; va += TLB_PG_SIZE) ppc4xx_tlb_reserve(va, va, TLB_PG_SIZE, TLB_EX); /* * Map console and I2C after RAM. (see pmap_tlbmiss()) * All peripherals mapped on a page. */ ppc4xx_tlb_reserve(AMCC405EX_OPB_BASE, roundup(memsize, TLB_PG_SIZE), TLB_PG_SIZE, TLB_I | TLB_G); /* Initialize AMCC 405EX CPU */ ibm40x_memsize_init(memsize, startkernel); ibm4xx_init(startkernel, endkernel, pic_ext_intr); #ifdef DDB if (boothowto & RB_KDB) Debugger(); #endif } void consinit(void) { #if (NCOM > 0) com_opb_cnattach(OBS600_COM_FREQ, CONADDR, CONSPEED, CONMODE); #endif /* NCOM */ } /* * Machine dependent startup code. */ void cpu_startup(void) { prop_number_t pn; prop_data_t pd; u_char *macaddr, *macaddr1; static u_char buf[16]; /* MAC address x2 buffer */ /* * cpu common startup */ ibm4xx_cpu_startup("OpenBlockS600 AMCC PowerPC 405EX Board"); /* * Set up the board properties database. */ board_info_init(); pn = prop_number_create_integer(OBS600_CPU_FREQ); KASSERT(pn != NULL); if (prop_dictionary_set(board_properties, "processor-frequency", pn) == false) panic("setting processor-frequency"); prop_object_release(pn); pn = prop_number_create_integer(OBS600_MEM_SIZE); KASSERT(pn != NULL); if (prop_dictionary_set(board_properties, "mem-size", pn) == false) panic("setting mem-size"); prop_object_release(pn); calc_delayconst(); /* required by read_eeprom() */ #define ETHER_ADDR_LEN 6 read_eeprom(sizeof(buf), buf); macaddr = &buf[0]; macaddr1 = &buf[8]; pd = prop_data_create_data_nocopy(macaddr, ETHER_ADDR_LEN); KASSERT(pd != NULL); if (prop_dictionary_set(board_properties, "emac0-mac-addr", pd) == false) panic("setting emac0-mac-addr"); prop_object_release(pd); pd = prop_data_create_data_nocopy(macaddr1, ETHER_ADDR_LEN); KASSERT(pd != NULL); if (prop_dictionary_set(board_properties, "emac1-mac-addr", pd) == false) panic("setting emac1-mac-addr"); prop_object_release(pd); /* emac0 connects to phy 2 and emac1 to phy 3 via RGMII. */ pn = prop_number_create_integer(2); KASSERT(pn != NULL); if (prop_dictionary_set(board_properties, "emac0-mii-phy", pn) == false) panic("setting emac0-mii-phy"); prop_object_release(pn); pn = prop_number_create_integer(3); KASSERT(pn != NULL); if (prop_dictionary_set(board_properties, "emac1-mii-phy", pn) == false) panic("setting emac1-mii-phy"); prop_object_release(pn); /* * Now that we have VM, malloc()s are OK in bus_space. */ bus_space_mallocok(); /* * no fake mapiodev */ fake_mapiodev = 0; splraise(-1); } /* * Read EEPROM via I2C. We don't use bus_space(9) here. This is MD-part and, * don't support bus_space_unmap() to a space on reserved space? X-< * * XXXX: Also this function assume already initialized for I2C... */ static int read_eeprom(int len, char *buf) { volatile uint8_t *iic0; #define IIC0_READ(r) (*(iic0 + (r))) #define IIC0_WRITE(r, v) (*(iic0 + (r)) = (v)) uint8_t sts; int cnt, i = 0; #define I2C_EEPROM_ADDR 0x52 if ((iic0 = ppc4xx_tlb_mapiodev(AMCC405EX_IIC0_BASE, IIC_NREG)) == NULL) return ENOMEM; /* ??? */ /* Clear Stop Complete Bit */ IIC0_WRITE(IIC_STS, IIC_STS_SCMP); /* Check init */ do { /* Get status */ sts = IIC0_READ(IIC_STS); } while ((sts & IIC_STS_PT)); IIC0_WRITE(IIC_MDCNTL, IIC0_READ(IIC_MDCNTL) | IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB); /* 7-bit addressing */ IIC0_WRITE(IIC_HMADR, 0); IIC0_WRITE(IIC_LMADR, I2C_EEPROM_ADDR << 1); IIC0_WRITE(IIC_MDBUF, 0); IIC0_WRITE(IIC_CNTL, IIC_CNTL_PT); do { /* Get status */ sts = IIC0_READ(IIC_STS); } while ((sts & IIC_STS_PT) && !(sts & IIC_STS_ERR)); cnt = 0; while (cnt < len) { /* always read 4byte */ IIC0_WRITE(IIC_CNTL, IIC_CNTL_PT | IIC_CNTL_RW | ((cnt == 0) ? IIC_CNTL_RPST : 0) | IIC_CNTL_TCT); do { /* Get status */ sts = IIC0_READ(IIC_STS); } while ((sts & IIC_STS_PT) && !(sts & IIC_STS_ERR)); if ((sts & IIC_STS_PT) || (sts & IIC_STS_ERR)) break; if (sts & IIC_STS_MDBS) { delay(1); /* read 4byte */ for (i = 0; i < 4 && cnt < len; i++, cnt++) buf[cnt] = IIC0_READ(IIC_MDBUF); } } for ( ; i < 4; i++) (void) IIC0_READ(IIC_MDBUF); return (cnt == len) ? 0 : EINVAL; }