1 /* $NetBSD: sbd.c,v 1.4 2015/06/23 21:00:23 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: sbd.c,v 1.4 2015/06/23 21:00:23 matt Exp $"); 34 35 /* System board */ 36 #include "opt_sbd.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 41 #include <uvm/uvm_extern.h> 42 43 #include <mips/locore.h> 44 45 #include <machine/sbdvar.h> 46 #include <machine/sbd.h> 47 48 struct sbd platform; /* System board itself */ 49 50 void 51 sbd_init(void) 52 { 53 54 switch (SBD_INFO->machine) { /* Get model information from ROM */ 55 default: 56 printf("This model is not supported.\n"); 57 printf("machine [0x%04x] model [0x%04x]\n", 58 SBD_INFO->machine, SBD_INFO->model); 59 for (;;) 60 ; 61 /* NOTREACHED */ 62 break; 63 #ifdef EWS4800_TR2 64 case MACHINE_TR2: /* EWS4800/350 */ 65 tr2_init(); 66 break; 67 #endif 68 #ifdef EWS4800_TR2A 69 case MACHINE_TR2A: 70 tr2a_init(); /* EWS4800/360 */ 71 break; 72 #endif 73 } 74 } 75 76 void 77 sbd_memcluster_init(uint32_t m) 78 { 79 /* Initialize memory_cluster *** mainfo_type2 only *** */ 80 size_t size, total = 0; 81 int i, j, k, n; 82 uint32_t start_addr[] = { 83 __M0_BANK0_ADDR, 84 __M0_BANK1_ADDR, 85 __M1_BANK0_ADDR, 86 __M1_BANK1_ADDR, 87 __M2_BANK0_ADDR, 88 __M2_BANK1_ADDR, 89 }; 90 n = sizeof start_addr / sizeof start_addr[0]; 91 92 for (i = 0, k = 0, j = 1; i < 8; i++, m >>= 4) { 93 size = m & 0xf ? ((m & 0xf) << 4) : 0; 94 if (size == 0) 95 continue; 96 if (k == n) { 97 /* don't load over 0x20000000 memory */ 98 printf("M%d=%dMB(reserved)\n", i, size); 99 continue; 100 } 101 102 switch (size) { 103 case 128: /* oooooooo */ 104 case 16: /* o....... */ 105 mem_clusters[j].size = size * 1024 * 1024; 106 mem_clusters[j].start = start_addr[k]; 107 j += 1; 108 k += 2; 109 break; 110 case 32: /* o...o... */ 111 mem_clusters[j].size = 16 * 1024 * 1024; 112 mem_clusters[j].start = start_addr[k++]; 113 j++; 114 mem_clusters[j].size = 16 * 1024 * 1024; 115 mem_clusters[j].start = start_addr[k++]; 116 j++; 117 break; 118 default: 119 printf("UNKNOWN MEMORY CLUSTER SIZE%d\n", size); 120 for (;;) 121 ; 122 } 123 total += size; 124 printf("M%d=%dMB ", i, size); 125 } 126 printf(" total %dMB\n", total); 127 mem_cluster_cnt = j; 128 mem_clusters[0].size = total << 20; 129 } 130 131 void 132 sbd_memcluster_setup(void *kernstart, void *kernend) 133 { 134 paddr_t start; 135 size_t size; 136 137 physmem = atop(mem_clusters[0].size); 138 139 start = (paddr_t)round_page(MIPS_KSEG0_TO_PHYS(kernend)); 140 size = mem_clusters[1].size - start; 141 142 /* kernel itself */ 143 mem_clusters[0].start = trunc_page(MIPS_KSEG0_TO_PHYS(kernstart)); 144 mem_clusters[0].size = start - mem_clusters[0].start; 145 146 /* heap start */ 147 mem_clusters[1].start = start; 148 mem_clusters[1].size = size; 149 } 150 151 void 152 sbd_memcluster_check(void) 153 { 154 uint32_t *m, *mend; 155 phys_ram_seg_t *p; 156 paddr_t start; 157 size_t size; 158 size_t i, j; 159 160 /* Very slow */ 161 for (i = 1; i < mem_cluster_cnt; i++) { 162 p = &mem_clusters[i]; 163 start = p->start; 164 size = p->size; 165 printf("[%u] %#"PRIxPADDR"-%#"PRIxPADDR", %#x (%uMB)\n", 166 i, start, start + size, size, size >>20); 167 m = (uint32_t *)MIPS_PHYS_TO_KSEG1(start); 168 mend = (uint32_t *)MIPS_PHYS_TO_KSEG1(start + size); 169 for (; m < mend; m++) { 170 uint32_t pattern[4] = 171 { 0xffffffff, 0xa5a5a5a5, 0x5a5a5a5a, 0x00000000 }; 172 for (j = 0; j < 4; j++) { 173 *m = pattern[j]; 174 if (*m != pattern[j]) 175 panic("memory error %p\n", m); 176 } 177 } 178 printf("checked.\r"); 179 memset((void *)MIPS_PHYS_TO_KSEG0(start), 0, size); 180 printf("cleared.\r"); 181 } 182 } 183