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
sbd_init(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
sbd_memcluster_init(uint32_t m)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
sbd_memcluster_setup(void * kernstart,void * kernend)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
sbd_memcluster_check(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