1/*- 2 * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 19 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 22 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25/*- 26 * Copyright (C) 2001 Benno Rice 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 1. Redistributions of source code must retain the above copyright 33 * notice, this list of conditions and the following disclaimer. 34 * 2. Redistributions in binary form must reproduce the above copyright 35 * notice, this list of conditions and the following disclaimer in the 36 * documentation and/or other materials provided with the distribution. 37 * 38 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 43 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 44 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 49 */ 50/*- 51 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 52 * Copyright (C) 1995, 1996 TooLs GmbH. 53 * All rights reserved. 54 * 55 * Redistribution and use in source and binary forms, with or without 56 * modification, are permitted provided that the following conditions 57 * are met: 58 * 1. Redistributions of source code must retain the above copyright 59 * notice, this list of conditions and the following disclaimer. 60 * 2. Redistributions in binary form must reproduce the above copyright 61 * notice, this list of conditions and the following disclaimer in the 62 * documentation and/or other materials provided with the distribution. 63 * 3. All advertising materials mentioning features or use of this software 64 * must display the following acknowledgement: 65 * This product includes software developed by TooLs GmbH. 66 * 4. The name of TooLs GmbH may not be used to endorse or promote products 67 * derived from this software without specific prior written permission. 68 * 69 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 70 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 71 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 72 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 73 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 74 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 75 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 76 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 77 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 78 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 79 */ 80 81#include <sys/cdefs.h>
| 1/*- 2 * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 19 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 22 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25/*- 26 * Copyright (C) 2001 Benno Rice 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 1. Redistributions of source code must retain the above copyright 33 * notice, this list of conditions and the following disclaimer. 34 * 2. Redistributions in binary form must reproduce the above copyright 35 * notice, this list of conditions and the following disclaimer in the 36 * documentation and/or other materials provided with the distribution. 37 * 38 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 43 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 44 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 49 */ 50/*- 51 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 52 * Copyright (C) 1995, 1996 TooLs GmbH. 53 * All rights reserved. 54 * 55 * Redistribution and use in source and binary forms, with or without 56 * modification, are permitted provided that the following conditions 57 * are met: 58 * 1. Redistributions of source code must retain the above copyright 59 * notice, this list of conditions and the following disclaimer. 60 * 2. Redistributions in binary form must reproduce the above copyright 61 * notice, this list of conditions and the following disclaimer in the 62 * documentation and/or other materials provided with the distribution. 63 * 3. All advertising materials mentioning features or use of this software 64 * must display the following acknowledgement: 65 * This product includes software developed by TooLs GmbH. 66 * 4. The name of TooLs GmbH may not be used to endorse or promote products 67 * derived from this software without specific prior written permission. 68 * 69 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 70 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 71 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 72 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 73 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 74 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 75 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 76 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 77 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 78 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 79 */ 80 81#include <sys/cdefs.h>
|
82__FBSDID("$FreeBSD: head/sys/powerpc/booke/machdep.c 209613 2010-06-30 18:03:42Z jhb $");
| 82__FBSDID("$FreeBSD: head/sys/powerpc/booke/machdep.c 209908 2010-07-11 21:08:29Z raj $");
|
83 84#include "opt_compat.h" 85#include "opt_ddb.h" 86#include "opt_kstack_pages.h" 87#include "opt_msgbuf.h" 88 89#include <sys/cdefs.h> 90#include <sys/types.h> 91#include <sys/param.h> 92#include <sys/proc.h> 93#include <sys/systm.h> 94#include <sys/time.h> 95#include <sys/bio.h> 96#include <sys/buf.h> 97#include <sys/bus.h> 98#include <sys/cons.h> 99#include <sys/cpu.h> 100#include <sys/kdb.h> 101#include <sys/kernel.h> 102#include <sys/lock.h> 103#include <sys/mutex.h> 104#include <sys/sysctl.h> 105#include <sys/exec.h> 106#include <sys/ktr.h> 107#include <sys/syscallsubr.h> 108#include <sys/sysproto.h> 109#include <sys/signalvar.h> 110#include <sys/sysent.h> 111#include <sys/imgact.h> 112#include <sys/msgbuf.h> 113#include <sys/ptrace.h> 114 115#include <vm/vm.h> 116#include <vm/pmap.h> 117#include <vm/vm_page.h> 118#include <vm/vm_object.h> 119#include <vm/vm_pager.h> 120 121#include <machine/cpu.h> 122#include <machine/kdb.h> 123#include <machine/reg.h> 124#include <machine/vmparam.h> 125#include <machine/spr.h> 126#include <machine/hid.h> 127#include <machine/psl.h> 128#include <machine/trap.h> 129#include <machine/md_var.h> 130#include <machine/mmuvar.h> 131#include <machine/sigframe.h> 132#include <machine/metadata.h>
| 83 84#include "opt_compat.h" 85#include "opt_ddb.h" 86#include "opt_kstack_pages.h" 87#include "opt_msgbuf.h" 88 89#include <sys/cdefs.h> 90#include <sys/types.h> 91#include <sys/param.h> 92#include <sys/proc.h> 93#include <sys/systm.h> 94#include <sys/time.h> 95#include <sys/bio.h> 96#include <sys/buf.h> 97#include <sys/bus.h> 98#include <sys/cons.h> 99#include <sys/cpu.h> 100#include <sys/kdb.h> 101#include <sys/kernel.h> 102#include <sys/lock.h> 103#include <sys/mutex.h> 104#include <sys/sysctl.h> 105#include <sys/exec.h> 106#include <sys/ktr.h> 107#include <sys/syscallsubr.h> 108#include <sys/sysproto.h> 109#include <sys/signalvar.h> 110#include <sys/sysent.h> 111#include <sys/imgact.h> 112#include <sys/msgbuf.h> 113#include <sys/ptrace.h> 114 115#include <vm/vm.h> 116#include <vm/pmap.h> 117#include <vm/vm_page.h> 118#include <vm/vm_object.h> 119#include <vm/vm_pager.h> 120 121#include <machine/cpu.h> 122#include <machine/kdb.h> 123#include <machine/reg.h> 124#include <machine/vmparam.h> 125#include <machine/spr.h> 126#include <machine/hid.h> 127#include <machine/psl.h> 128#include <machine/trap.h> 129#include <machine/md_var.h> 130#include <machine/mmuvar.h> 131#include <machine/sigframe.h> 132#include <machine/metadata.h>
|
133#include <machine/bootinfo.h>
| |
134#include <machine/platform.h> 135 136#include <sys/linker.h> 137#include <sys/reboot.h> 138
| 133#include <machine/platform.h> 134 135#include <sys/linker.h> 136#include <sys/reboot.h> 137
|
139#include <powerpc/mpc85xx/ocpbus.h>
| 138#include <dev/fdt/fdt_common.h> 139#include <dev/ofw/openfirm.h> 140
|
140#include <powerpc/mpc85xx/mpc85xx.h> 141 142#ifdef DDB 143extern vm_offset_t ksym_start, ksym_end; 144#endif 145 146#ifdef DEBUG 147#define debugf(fmt, args...) printf(fmt, ##args) 148#else 149#define debugf(fmt, args...) 150#endif 151 152extern unsigned char kernel_text[]; 153extern unsigned char _etext[]; 154extern unsigned char _edata[]; 155extern unsigned char __bss_start[]; 156extern unsigned char __sbss_start[]; 157extern unsigned char __sbss_end[]; 158extern unsigned char _end[]; 159 160extern void dcache_enable(void); 161extern void dcache_inval(void); 162extern void icache_enable(void); 163extern void icache_inval(void); 164 165struct kva_md_info kmi; 166struct pcpu __pcpu[MAXCPU]; 167struct trapframe frame0; 168int cold = 1; 169long realmem = 0; 170long Maxmem = 0; 171
| 141#include <powerpc/mpc85xx/mpc85xx.h> 142 143#ifdef DDB 144extern vm_offset_t ksym_start, ksym_end; 145#endif 146 147#ifdef DEBUG 148#define debugf(fmt, args...) printf(fmt, ##args) 149#else 150#define debugf(fmt, args...) 151#endif 152 153extern unsigned char kernel_text[]; 154extern unsigned char _etext[]; 155extern unsigned char _edata[]; 156extern unsigned char __bss_start[]; 157extern unsigned char __sbss_start[]; 158extern unsigned char __sbss_end[]; 159extern unsigned char _end[]; 160 161extern void dcache_enable(void); 162extern void dcache_inval(void); 163extern void icache_enable(void); 164extern void icache_inval(void); 165 166struct kva_md_info kmi; 167struct pcpu __pcpu[MAXCPU]; 168struct trapframe frame0; 169int cold = 1; 170long realmem = 0; 171long Maxmem = 0; 172
|
172struct bootinfo *bootinfo; 173
| |
174char machine[] = "powerpc"; 175SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 176 177int cacheline_size = 32; 178 179SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 180 CTLFLAG_RD, &cacheline_size, 0, ""); 181 182int hw_direct_map = 0; 183 184static void cpu_e500_startup(void *); 185SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL); 186 187void print_kernel_section_addr(void);
| 173char machine[] = "powerpc"; 174SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 175 176int cacheline_size = 32; 177 178SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 179 CTLFLAG_RD, &cacheline_size, 0, ""); 180 181int hw_direct_map = 0; 182 183static void cpu_e500_startup(void *); 184SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL); 185 186void print_kernel_section_addr(void);
|
188void print_bootinfo(void);
| |
189void print_kenv(void); 190u_int e500_init(u_int32_t, u_int32_t, void *); 191 192static void 193cpu_e500_startup(void *dummy) 194{ 195 int indx, size; 196 197 /* Initialise the decrementer-based clock. */ 198 decr_init(); 199 200 /* Good {morning,afternoon,evening,night}. */ 201 cpu_setup(PCPU_GET(cpuid)); 202 203 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 204 ptoa(physmem) / 1048576); 205 realmem = physmem; 206 207 /* Display any holes after the first chunk of extended memory. */ 208 if (bootverbose) { 209 printf("Physical memory chunk(s):\n"); 210 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 211 size = phys_avail[indx + 1] - phys_avail[indx]; 212 213 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 214 phys_avail[indx], phys_avail[indx + 1] - 1, 215 size, size / PAGE_SIZE); 216 } 217 } 218 219 vm_ksubmap_init(&kmi); 220 221 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 222 ptoa(cnt.v_free_count) / 1048576); 223 224 /* Set up buffers, so they can be used to read disk labels. */ 225 bufinit(); 226 vm_pager_bufferinit(); 227} 228 229static char * 230kenv_next(char *cp) 231{ 232 233 if (cp != NULL) { 234 while (*cp != 0) 235 cp++; 236 cp++; 237 if (*cp == 0) 238 cp = NULL; 239 } 240 return (cp); 241} 242 243void 244print_kenv(void) 245{ 246 int len; 247 char *cp; 248 249 debugf("loader passed (static) kenv:\n"); 250 if (kern_envp == NULL) { 251 debugf(" no env, null ptr\n"); 252 return; 253 } 254 debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp); 255 256 len = 0; 257 for (cp = kern_envp; cp != NULL; cp = kenv_next(cp)) 258 debugf(" %x %s\n", (u_int32_t)cp, cp); 259} 260 261void
| 187void print_kenv(void); 188u_int e500_init(u_int32_t, u_int32_t, void *); 189 190static void 191cpu_e500_startup(void *dummy) 192{ 193 int indx, size; 194 195 /* Initialise the decrementer-based clock. */ 196 decr_init(); 197 198 /* Good {morning,afternoon,evening,night}. */ 199 cpu_setup(PCPU_GET(cpuid)); 200 201 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 202 ptoa(physmem) / 1048576); 203 realmem = physmem; 204 205 /* Display any holes after the first chunk of extended memory. */ 206 if (bootverbose) { 207 printf("Physical memory chunk(s):\n"); 208 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 209 size = phys_avail[indx + 1] - phys_avail[indx]; 210 211 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 212 phys_avail[indx], phys_avail[indx + 1] - 1, 213 size, size / PAGE_SIZE); 214 } 215 } 216 217 vm_ksubmap_init(&kmi); 218 219 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 220 ptoa(cnt.v_free_count) / 1048576); 221 222 /* Set up buffers, so they can be used to read disk labels. */ 223 bufinit(); 224 vm_pager_bufferinit(); 225} 226 227static char * 228kenv_next(char *cp) 229{ 230 231 if (cp != NULL) { 232 while (*cp != 0) 233 cp++; 234 cp++; 235 if (*cp == 0) 236 cp = NULL; 237 } 238 return (cp); 239} 240 241void 242print_kenv(void) 243{ 244 int len; 245 char *cp; 246 247 debugf("loader passed (static) kenv:\n"); 248 if (kern_envp == NULL) { 249 debugf(" no env, null ptr\n"); 250 return; 251 } 252 debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp); 253 254 len = 0; 255 for (cp = kern_envp; cp != NULL; cp = kenv_next(cp)) 256 debugf(" %x %s\n", (u_int32_t)cp, cp); 257} 258 259void
|
262print_bootinfo(void) 263{ 264 struct bi_mem_region *mr; 265 struct bi_eth_addr *eth; 266 int i, j; 267 268 debugf("bootinfo:\n"); 269 if (bootinfo == NULL) { 270 debugf(" no bootinfo, null ptr\n"); 271 return; 272 } 273 274 debugf(" version = 0x%08x\n", bootinfo->bi_version); 275 debugf(" ccsrbar = 0x%08x\n", bootinfo->bi_bar_base); 276 debugf(" cpu_clk = 0x%08x\n", bootinfo->bi_cpu_clk); 277 debugf(" bus_clk = 0x%08x\n", bootinfo->bi_bus_clk); 278 279 debugf(" mem regions:\n"); 280 mr = (struct bi_mem_region *)bootinfo->bi_data; 281 for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) 282 debugf(" #%d, base = 0x%08x, size = 0x%08x\n", i, 283 mr->mem_base, mr->mem_size); 284 285 debugf(" eth addresses:\n"); 286 eth = (struct bi_eth_addr *)mr; 287 for (i = 0; i < bootinfo->bi_eth_addr_no; i++, eth++) { 288 debugf(" #%d, addr = ", i); 289 for (j = 0; j < 6; j++) 290 debugf("%02x ", eth->mac_addr[j]); 291 debugf("\n"); 292 } 293} 294 295void
| |
296print_kernel_section_addr(void) 297{ 298 299 debugf("kernel image addresses:\n"); 300 debugf(" kernel_text = 0x%08x\n", (uint32_t)kernel_text); 301 debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); 302 debugf(" _edata = 0x%08x\n", (uint32_t)_edata); 303 debugf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start); 304 debugf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end); 305 debugf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start); 306 debugf(" _end = 0x%08x\n", (uint32_t)_end); 307} 308
| 260print_kernel_section_addr(void) 261{ 262 263 debugf("kernel image addresses:\n"); 264 debugf(" kernel_text = 0x%08x\n", (uint32_t)kernel_text); 265 debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); 266 debugf(" _edata = 0x%08x\n", (uint32_t)_edata); 267 debugf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start); 268 debugf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end); 269 debugf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start); 270 debugf(" _end = 0x%08x\n", (uint32_t)_end); 271} 272
|
309struct bi_mem_region * 310bootinfo_mr(void) 311{ 312 313 return ((struct bi_mem_region *)bootinfo->bi_data); 314} 315 316struct bi_eth_addr * 317bootinfo_eth(void) 318{ 319 struct bi_mem_region *mr; 320 struct bi_eth_addr *eth; 321 int i; 322 323 /* Advance to the eth section */ 324 mr = bootinfo_mr(); 325 for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) 326 ; 327 328 eth = (struct bi_eth_addr *)mr; 329 return (eth); 330} 331
| |
332u_int 333e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) 334{ 335 struct pcpu *pc; 336 void *kmdp;
| 273u_int 274e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) 275{ 276 struct pcpu *pc; 277 void *kmdp;
|
337 vm_offset_t end;
| 278 vm_offset_t dtbp, end;
|
338 uint32_t csr; 339 340 kmdp = NULL; 341 342 end = endkernel;
| 279 uint32_t csr; 280 281 kmdp = NULL; 282 283 end = endkernel;
|
| 284 dtbp = (vm_offset_t)NULL;
|
343 344 /*
| 285 286 /*
|
345 * Parse metadata and fetch parameters. This must be done as the first 346 * step as we need bootinfo data to at least init the console
| 287 * Parse metadata and fetch parameters.
|
347 */ 348 if (mdp != NULL) { 349 preload_metadata = mdp; 350 kmdp = preload_search_by_type("elf kernel"); 351 if (kmdp != NULL) {
| 288 */ 289 if (mdp != NULL) { 290 preload_metadata = mdp; 291 kmdp = preload_search_by_type("elf kernel"); 292 if (kmdp != NULL) {
|
352 bootinfo = (struct bootinfo *)preload_search_info(kmdp, 353 MODINFO_METADATA | MODINFOMD_BOOTINFO); 354
| |
355 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 356 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
| 293 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 294 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
|
| 295 dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
|
357 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 358#ifdef DDB 359 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 360 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 361#endif 362 } 363 } else { 364 /*
| 296 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 297#ifdef DDB 298 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 299 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 300#endif 301 } 302 } else { 303 /*
|
365 * We should scream but how? - without CCSR bar (in bootinfo) 366 * cannot even output anything...
| 304 * We should scream but how? Cannot even output anything...
|
367 */ 368 369 /* 370 * FIXME add return value and handle in the locore so we can 371 * return to the loader maybe? (this seems not very easy to 372 * restore everything as the TLB have all been reprogrammed 373 * in the locore etc...) 374 */
| 305 */ 306 307 /* 308 * FIXME add return value and handle in the locore so we can 309 * return to the loader maybe? (this seems not very easy to 310 * restore everything as the TLB have all been reprogrammed 311 * in the locore etc...) 312 */
|
375 while(1);
| 313 while (1);
|
376 } 377
| 314 } 315
|
| 316 if (OF_install(OFW_FDT, 0) == FALSE) 317 while (1); 318 319 if (OF_init((void *)dtbp) != 0) 320 while (1); 321 322 if (fdt_immr_addr() != 0) 323 while (1); 324 325 OF_interpret("perform-fixup", 0); 326
|
378 /* Initialize TLB1 handling */
| 327 /* Initialize TLB1 handling */
|
379 tlb1_init(bootinfo->bi_bar_base);
| 328 tlb1_init(fdt_immr_pa);
|
380 381 /* Reset Time Base */ 382 mttb(0); 383 384 /* Init params/tunables that can be overridden by the loader. */ 385 init_param1(); 386 387 /* Start initializing proc0 and thread0. */ 388 proc_linkup0(&proc0, &thread0); 389 thread0.td_frame = &frame0; 390 391 /* Set up per-cpu data and store the pointer in SPR general 0. */ 392 pc = &__pcpu[0]; 393 pcpu_init(pc, 0, sizeof(struct pcpu)); 394 pc->pc_curthread = &thread0; 395 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 396 397 /* Initialize system mutexes. */ 398 mutex_init(); 399 400 /* Initialize the console before printing anything. */ 401 cninit(); 402 403 /* Print out some debug info... */ 404 debugf("e500_init: console initialized\n"); 405 debugf(" arg1 startkernel = 0x%08x\n", startkernel); 406 debugf(" arg2 endkernel = 0x%08x\n", endkernel); 407 debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp); 408 debugf(" end = 0x%08x\n", (u_int32_t)end); 409 debugf(" boothowto = 0x%08x\n", boothowto); 410 debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA); 411 debugf(" MSR = 0x%08x\n", mfmsr()); 412 debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0)); 413 debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1)); 414 debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR)); 415 416 __asm __volatile("msync; isync"); 417 csr = ccsr_read4(OCP85XX_L2CTL); 418 debugf(" L2CTL = 0x%08x\n", csr); 419
| 329 330 /* Reset Time Base */ 331 mttb(0); 332 333 /* Init params/tunables that can be overridden by the loader. */ 334 init_param1(); 335 336 /* Start initializing proc0 and thread0. */ 337 proc_linkup0(&proc0, &thread0); 338 thread0.td_frame = &frame0; 339 340 /* Set up per-cpu data and store the pointer in SPR general 0. */ 341 pc = &__pcpu[0]; 342 pcpu_init(pc, 0, sizeof(struct pcpu)); 343 pc->pc_curthread = &thread0; 344 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 345 346 /* Initialize system mutexes. */ 347 mutex_init(); 348 349 /* Initialize the console before printing anything. */ 350 cninit(); 351 352 /* Print out some debug info... */ 353 debugf("e500_init: console initialized\n"); 354 debugf(" arg1 startkernel = 0x%08x\n", startkernel); 355 debugf(" arg2 endkernel = 0x%08x\n", endkernel); 356 debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp); 357 debugf(" end = 0x%08x\n", (u_int32_t)end); 358 debugf(" boothowto = 0x%08x\n", boothowto); 359 debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA); 360 debugf(" MSR = 0x%08x\n", mfmsr()); 361 debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0)); 362 debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1)); 363 debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR)); 364 365 __asm __volatile("msync; isync"); 366 csr = ccsr_read4(OCP85XX_L2CTL); 367 debugf(" L2CTL = 0x%08x\n", csr); 368
|
420 print_bootinfo();
| 369 debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp); 370
|
421 print_kernel_section_addr(); 422 print_kenv(); 423 //tlb1_print_entries(); 424 //tlb1_print_tlbentries(); 425 426 kdb_init(); 427 428#ifdef KDB 429 if (boothowto & RB_KDB) 430 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 431#endif 432 433 /* Initialise platform module */ 434 platform_probe_and_attach(); 435 436 /* Initialise virtual memory. */ 437 pmap_mmu_install(MMU_TYPE_BOOKE, 0); 438 pmap_bootstrap(startkernel, end); 439 debugf("MSR = 0x%08x\n", mfmsr()); 440 //tlb1_print_entries(); 441 //tlb1_print_tlbentries(); 442 443 /* Initialize params/tunables that are derived from memsize. */ 444 init_param2(physmem); 445 446 /* Finish setting up thread0. */ 447 thread0.td_pcb = (struct pcb *) 448 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 449 sizeof(struct pcb)) & ~15); 450 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 451 pc->pc_curpcb = thread0.td_pcb; 452 453 /* Initialise the message buffer. */ 454 msgbufinit(msgbufp, MSGBUF_SIZE); 455 456 /* Enable Machine Check interrupt. */ 457 mtmsr(mfmsr() | PSL_ME); 458 isync(); 459 460 /* Enable D-cache if applicable */ 461 csr = mfspr(SPR_L1CSR0); 462 if ((csr & L1CSR0_DCE) == 0) { 463 dcache_inval(); 464 dcache_enable(); 465 } 466 467 csr = mfspr(SPR_L1CSR0); 468 if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR0_DCE) == 0) 469 printf("L1 D-cache %sabled\n", 470 (csr & L1CSR0_DCE) ? "en" : "dis"); 471 472 /* Enable L1 I-cache if applicable. */ 473 csr = mfspr(SPR_L1CSR1); 474 if ((csr & L1CSR1_ICE) == 0) { 475 icache_inval(); 476 icache_enable(); 477 } 478 479 csr = mfspr(SPR_L1CSR1); 480 if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR1_ICE) == 0) 481 printf("L1 I-cache %sabled\n", 482 (csr & L1CSR1_ICE) ? "en" : "dis"); 483 484 debugf("e500_init: SP = 0x%08x\n", ((uintptr_t)thread0.td_pcb - 16) & ~15); 485 debugf("e500_init: e\n"); 486 487 return (((uintptr_t)thread0.td_pcb - 16) & ~15); 488} 489 490#define RES_GRANULE 32 491extern uint32_t tlb0_miss_locks[]; 492 493/* Initialise a struct pcpu. */ 494void 495cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 496{ 497 498 pcpu->pc_tid_next = TID_MIN; 499 500#ifdef SMP 501 uint32_t *ptr; 502 int words_per_gran = RES_GRANULE / sizeof(uint32_t); 503 504 ptr = &tlb0_miss_locks[cpuid * words_per_gran]; 505 pcpu->pc_booke_tlb_lock = ptr; 506 *ptr = MTX_UNOWNED; 507 *(ptr + 1) = 0; /* recurse counter */ 508#endif 509} 510 511/* Set set up registers on exec. */ 512void 513exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 514{ 515 struct trapframe *tf; 516 struct ps_strings arginfo; 517 518 tf = trapframe(td); 519 bzero(tf, sizeof *tf); 520 tf->fixreg[1] = -roundup(-stack + 8, 16); 521 522 /* 523 * XXX Machine-independent code has already copied arguments and 524 * XXX environment to userland. Get them back here. 525 */ 526 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 527 528 /* 529 * Set up arguments for _start(): 530 * _start(argc, argv, envp, obj, cleanup, ps_strings); 531 * 532 * Notes: 533 * - obj and cleanup are the auxilliary and termination 534 * vectors. They are fixed up by ld.elf_so. 535 * - ps_strings is a NetBSD extention, and will be 536 * ignored by executables which are strictly 537 * compliant with the SVR4 ABI. 538 * 539 * XXX We have to set both regs and retval here due to different 540 * XXX calling convention in trap.c and init_main.c. 541 */ 542 /* 543 * XXX PG: these get overwritten in the syscall return code. 544 * execve() should return EJUSTRETURN, like it does on NetBSD. 545 * Emulate by setting the syscall return value cells. The 546 * registers still have to be set for init's fork trampoline. 547 */ 548 td->td_retval[0] = arginfo.ps_nargvstr; 549 td->td_retval[1] = (register_t)arginfo.ps_argvstr; 550 tf->fixreg[3] = arginfo.ps_nargvstr; 551 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 552 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 553 tf->fixreg[6] = 0; /* auxillary vector */ 554 tf->fixreg[7] = 0; /* termination vector */ 555 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 556 557 tf->srr0 = imgp->entry_addr; 558 tf->srr1 = PSL_USERSET; 559 td->td_pcb->pcb_flags = 0; 560} 561 562int 563fill_regs(struct thread *td, struct reg *regs) 564{ 565 struct trapframe *tf; 566 567 tf = td->td_frame; 568 memcpy(regs, tf, sizeof(struct reg)); 569 570 return (0); 571} 572 573int 574fill_fpregs(struct thread *td, struct fpreg *fpregs) 575{ 576 577 return (0); 578} 579 580/* 581 * Flush the D-cache for non-DMA I/O so that the I-cache can 582 * be made coherent later. 583 */ 584void 585cpu_flush_dcache(void *ptr, size_t len) 586{ 587 /* TBD */ 588} 589 590/* 591 * Construct a PCB from a trapframe. This is called from kdb_trap() where 592 * we want to start a backtrace from the function that caused us to enter 593 * the debugger. We have the context in the trapframe, but base the trace 594 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 595 * enough for a backtrace. 596 */ 597void 598makectx(struct trapframe *tf, struct pcb *pcb) 599{ 600 601 pcb->pcb_lr = tf->srr0; 602 pcb->pcb_sp = tf->fixreg[1]; 603} 604 605/* 606 * get_mcontext/sendsig helper routine that doesn't touch the 607 * proc lock. 608 */ 609static int 610grab_mcontext(struct thread *td, mcontext_t *mcp, int flags) 611{ 612 struct pcb *pcb; 613 614 pcb = td->td_pcb; 615 memset(mcp, 0, sizeof(mcontext_t)); 616 617 mcp->mc_vers = _MC_VERSION; 618 mcp->mc_flags = 0; 619 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe)); 620 if (flags & GET_MC_CLEAR_RET) { 621 mcp->mc_gpr[3] = 0; 622 mcp->mc_gpr[4] = 0; 623 } 624 625 /* XXX Altivec context ? */ 626 627 mcp->mc_len = sizeof(*mcp); 628 return (0); 629} 630 631int 632get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 633{ 634 int error; 635 636 error = grab_mcontext(td, mcp, flags); 637 if (error == 0) { 638 PROC_LOCK(curthread->td_proc); 639 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 640 PROC_UNLOCK(curthread->td_proc); 641 } 642 643 return (error); 644} 645 646int 647set_mcontext(struct thread *td, const mcontext_t *mcp) 648{ 649 struct pcb *pcb; 650 struct trapframe *tf; 651 652 pcb = td->td_pcb; 653 tf = td->td_frame; 654 655 if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp)) 656 return (EINVAL); 657 658 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame)); 659 660 /* XXX Altivec context? */ 661 662 return (0); 663} 664 665int 666sigreturn(struct thread *td, struct sigreturn_args *uap) 667{ 668 ucontext_t uc; 669 int error; 670 671 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 672 673 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 674 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 675 return (EFAULT); 676 } 677 678 error = set_mcontext(td, &uc.uc_mcontext); 679 if (error != 0) 680 return (error); 681 682 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 683 684 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 685 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 686 687 return (EJUSTRETURN); 688} 689 690#ifdef COMPAT_FREEBSD4 691int 692freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 693{ 694 695 return sigreturn(td, (struct sigreturn_args *)uap); 696} 697#endif 698 699/* 700 * cpu_idle 701 * 702 * Set Wait state enable. 703 */ 704void 705cpu_idle (int busy) 706{ 707 register_t msr; 708 709 msr = mfmsr(); 710 711#ifdef INVARIANTS 712 if ((msr & PSL_EE) != PSL_EE) { 713 struct thread *td = curthread; 714 printf("td msr %x\n", td->td_md.md_saved_msr); 715 panic("ints disabled in idleproc!"); 716 } 717#endif 718 719 /* Freescale E500 core RM section 6.4.1. */ 720 msr = msr | PSL_WE; 721 __asm __volatile("msync; mtmsr %0; isync" :: "r" (msr)); 722} 723 724int 725cpu_idle_wakeup(int cpu) 726{ 727 728 return (0); 729} 730 731void 732spinlock_enter(void) 733{ 734 struct thread *td; 735 736 td = curthread; 737 if (td->td_md.md_spinlock_count == 0) 738 td->td_md.md_saved_msr = intr_disable(); 739 td->td_md.md_spinlock_count++; 740 critical_enter(); 741} 742 743void 744spinlock_exit(void) 745{ 746 struct thread *td; 747 748 td = curthread; 749 critical_exit(); 750 td->td_md.md_spinlock_count--; 751 if (td->td_md.md_spinlock_count == 0) 752 intr_restore(td->td_md.md_saved_msr); 753} 754 755/* Shutdown the CPU as much as possible. */ 756void 757cpu_halt(void) 758{ 759 760 mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE)); 761 while (1); 762} 763 764int 765set_regs(struct thread *td, struct reg *regs) 766{ 767 struct trapframe *tf; 768 769 tf = td->td_frame; 770 memcpy(tf, regs, sizeof(struct reg)); 771 return (0); 772} 773 774int 775fill_dbregs(struct thread *td, struct dbreg *dbregs) 776{ 777 778 /* No debug registers on PowerPC */ 779 return (ENOSYS); 780} 781 782int 783set_dbregs(struct thread *td, struct dbreg *dbregs) 784{ 785 786 /* No debug registers on PowerPC */ 787 return (ENOSYS); 788} 789 790int 791set_fpregs(struct thread *td, struct fpreg *fpregs) 792{ 793 794 return (0); 795} 796 797int 798ptrace_set_pc(struct thread *td, unsigned long addr) 799{ 800 struct trapframe *tf; 801 802 tf = td->td_frame; 803 tf->srr0 = (register_t)addr; 804 805 return (0); 806} 807 808int 809ptrace_single_step(struct thread *td) 810{ 811 struct trapframe *tf; 812 813 tf = td->td_frame; 814 tf->srr1 |= PSL_DE; 815 tf->cpu.booke.dbcr0 |= (DBCR0_IDM | DBCR0_IC); 816 return (0); 817} 818 819int 820ptrace_clear_single_step(struct thread *td) 821{ 822 struct trapframe *tf; 823 824 tf = td->td_frame; 825 tf->srr1 &= ~PSL_DE; 826 tf->cpu.booke.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC); 827 return (0); 828} 829 830void 831kdb_cpu_clear_singlestep(void) 832{ 833 register_t r; 834 835 r = mfspr(SPR_DBCR0); 836 mtspr(SPR_DBCR0, r & ~DBCR0_IC); 837 kdb_frame->srr1 &= ~PSL_DE; 838} 839 840void 841kdb_cpu_set_singlestep(void) 842{ 843 register_t r; 844 845 r = mfspr(SPR_DBCR0); 846 mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM); 847 kdb_frame->srr1 |= PSL_DE; 848} 849 850void 851sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 852{ 853 struct trapframe *tf; 854 struct sigframe *sfp; 855 struct sigacts *psp; 856 struct sigframe sf; 857 struct thread *td; 858 struct proc *p; 859 int oonstack, rndfsize; 860 int sig, code; 861 862 td = curthread; 863 p = td->td_proc; 864 PROC_LOCK_ASSERT(p, MA_OWNED); 865 sig = ksi->ksi_signo; 866 code = ksi->ksi_code; 867 psp = p->p_sigacts; 868 mtx_assert(&psp->ps_mtx, MA_OWNED); 869 tf = td->td_frame; 870 oonstack = sigonstack(tf->fixreg[1]); 871 872 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 873 874 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 875 catcher, sig); 876 877 /* 878 * Save user context 879 */ 880 memset(&sf, 0, sizeof(sf)); 881 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 882 sf.sf_uc.uc_sigmask = *mask; 883 sf.sf_uc.uc_stack = td->td_sigstk; 884 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 885 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 886 887 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 888 889 /* 890 * Allocate and validate space for the signal handler context. 891 */ 892 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 893 SIGISMEMBER(psp->ps_sigonstack, sig)) { 894 sfp = (struct sigframe *)((caddr_t)td->td_sigstk.ss_sp + 895 td->td_sigstk.ss_size - rndfsize); 896 } else { 897 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); 898 } 899 900 /* 901 * Translate the signal if appropriate (Linux emu ?) 902 */ 903 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 904 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 905 906 /* 907 * Save the floating-point state, if necessary, then copy it. 908 */ 909 /* XXX */ 910 911 /* 912 * Set up the registers to return to sigcode. 913 * 914 * r1/sp - sigframe ptr 915 * lr - sig function, dispatched to by blrl in trampoline 916 * r3 - sig number 917 * r4 - SIGINFO ? &siginfo : exception code 918 * r5 - user context 919 * srr0 - trampoline function addr 920 */ 921 tf->lr = (register_t)catcher; 922 tf->fixreg[1] = (register_t)sfp; 923 tf->fixreg[FIRSTARG] = sig; 924 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; 925 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 926 /* 927 * Signal handler installed with SA_SIGINFO. 928 */ 929 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si; 930 931 /* 932 * Fill siginfo structure. 933 */ 934 sf.sf_si = ksi->ksi_info; 935 sf.sf_si.si_signo = sig; 936 sf.sf_si.si_addr = (void *) ((tf->exc == EXC_DSI) ? 937 tf->cpu.booke.dear : tf->srr0); 938 } else { 939 /* Old FreeBSD-style arguments. */ 940 tf->fixreg[FIRSTARG+1] = code; 941 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ? 942 tf->cpu.booke.dear : tf->srr0; 943 } 944 mtx_unlock(&psp->ps_mtx); 945 PROC_UNLOCK(p); 946 947 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); 948 949 /* 950 * copy the frame out to userland. 951 */ 952 if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) { 953 /* 954 * Process has trashed its stack. Kill it. 955 */ 956 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 957 PROC_LOCK(p); 958 sigexit(td, SIGILL); 959 } 960 961 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 962 tf->srr0, tf->fixreg[1]); 963 964 PROC_LOCK(p); 965 mtx_lock(&psp->ps_mtx); 966} 967 968void 969bzero(void *buf, size_t len) 970{ 971 caddr_t p; 972 973 p = buf; 974 975 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 976 *p++ = 0; 977 len--; 978 } 979 980 while (len >= sizeof(u_long) * 8) { 981 *(u_long*) p = 0; 982 *((u_long*) p + 1) = 0; 983 *((u_long*) p + 2) = 0; 984 *((u_long*) p + 3) = 0; 985 len -= sizeof(u_long) * 8; 986 *((u_long*) p + 4) = 0; 987 *((u_long*) p + 5) = 0; 988 *((u_long*) p + 6) = 0; 989 *((u_long*) p + 7) = 0; 990 p += sizeof(u_long) * 8; 991 } 992 993 while (len >= sizeof(u_long)) { 994 *(u_long*) p = 0; 995 len -= sizeof(u_long); 996 p += sizeof(u_long); 997 } 998 999 while (len) { 1000 *p++ = 0; 1001 len--; 1002 } 1003} 1004 1005/* 1006 * XXX what is the better/proper place for this routine? 1007 */ 1008int 1009mem_valid(vm_offset_t addr, int len) 1010{ 1011 1012 return (1); 1013}
| 371 print_kernel_section_addr(); 372 print_kenv(); 373 //tlb1_print_entries(); 374 //tlb1_print_tlbentries(); 375 376 kdb_init(); 377 378#ifdef KDB 379 if (boothowto & RB_KDB) 380 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 381#endif 382 383 /* Initialise platform module */ 384 platform_probe_and_attach(); 385 386 /* Initialise virtual memory. */ 387 pmap_mmu_install(MMU_TYPE_BOOKE, 0); 388 pmap_bootstrap(startkernel, end); 389 debugf("MSR = 0x%08x\n", mfmsr()); 390 //tlb1_print_entries(); 391 //tlb1_print_tlbentries(); 392 393 /* Initialize params/tunables that are derived from memsize. */ 394 init_param2(physmem); 395 396 /* Finish setting up thread0. */ 397 thread0.td_pcb = (struct pcb *) 398 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 399 sizeof(struct pcb)) & ~15); 400 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 401 pc->pc_curpcb = thread0.td_pcb; 402 403 /* Initialise the message buffer. */ 404 msgbufinit(msgbufp, MSGBUF_SIZE); 405 406 /* Enable Machine Check interrupt. */ 407 mtmsr(mfmsr() | PSL_ME); 408 isync(); 409 410 /* Enable D-cache if applicable */ 411 csr = mfspr(SPR_L1CSR0); 412 if ((csr & L1CSR0_DCE) == 0) { 413 dcache_inval(); 414 dcache_enable(); 415 } 416 417 csr = mfspr(SPR_L1CSR0); 418 if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR0_DCE) == 0) 419 printf("L1 D-cache %sabled\n", 420 (csr & L1CSR0_DCE) ? "en" : "dis"); 421 422 /* Enable L1 I-cache if applicable. */ 423 csr = mfspr(SPR_L1CSR1); 424 if ((csr & L1CSR1_ICE) == 0) { 425 icache_inval(); 426 icache_enable(); 427 } 428 429 csr = mfspr(SPR_L1CSR1); 430 if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR1_ICE) == 0) 431 printf("L1 I-cache %sabled\n", 432 (csr & L1CSR1_ICE) ? "en" : "dis"); 433 434 debugf("e500_init: SP = 0x%08x\n", ((uintptr_t)thread0.td_pcb - 16) & ~15); 435 debugf("e500_init: e\n"); 436 437 return (((uintptr_t)thread0.td_pcb - 16) & ~15); 438} 439 440#define RES_GRANULE 32 441extern uint32_t tlb0_miss_locks[]; 442 443/* Initialise a struct pcpu. */ 444void 445cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 446{ 447 448 pcpu->pc_tid_next = TID_MIN; 449 450#ifdef SMP 451 uint32_t *ptr; 452 int words_per_gran = RES_GRANULE / sizeof(uint32_t); 453 454 ptr = &tlb0_miss_locks[cpuid * words_per_gran]; 455 pcpu->pc_booke_tlb_lock = ptr; 456 *ptr = MTX_UNOWNED; 457 *(ptr + 1) = 0; /* recurse counter */ 458#endif 459} 460 461/* Set set up registers on exec. */ 462void 463exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 464{ 465 struct trapframe *tf; 466 struct ps_strings arginfo; 467 468 tf = trapframe(td); 469 bzero(tf, sizeof *tf); 470 tf->fixreg[1] = -roundup(-stack + 8, 16); 471 472 /* 473 * XXX Machine-independent code has already copied arguments and 474 * XXX environment to userland. Get them back here. 475 */ 476 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 477 478 /* 479 * Set up arguments for _start(): 480 * _start(argc, argv, envp, obj, cleanup, ps_strings); 481 * 482 * Notes: 483 * - obj and cleanup are the auxilliary and termination 484 * vectors. They are fixed up by ld.elf_so. 485 * - ps_strings is a NetBSD extention, and will be 486 * ignored by executables which are strictly 487 * compliant with the SVR4 ABI. 488 * 489 * XXX We have to set both regs and retval here due to different 490 * XXX calling convention in trap.c and init_main.c. 491 */ 492 /* 493 * XXX PG: these get overwritten in the syscall return code. 494 * execve() should return EJUSTRETURN, like it does on NetBSD. 495 * Emulate by setting the syscall return value cells. The 496 * registers still have to be set for init's fork trampoline. 497 */ 498 td->td_retval[0] = arginfo.ps_nargvstr; 499 td->td_retval[1] = (register_t)arginfo.ps_argvstr; 500 tf->fixreg[3] = arginfo.ps_nargvstr; 501 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 502 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 503 tf->fixreg[6] = 0; /* auxillary vector */ 504 tf->fixreg[7] = 0; /* termination vector */ 505 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 506 507 tf->srr0 = imgp->entry_addr; 508 tf->srr1 = PSL_USERSET; 509 td->td_pcb->pcb_flags = 0; 510} 511 512int 513fill_regs(struct thread *td, struct reg *regs) 514{ 515 struct trapframe *tf; 516 517 tf = td->td_frame; 518 memcpy(regs, tf, sizeof(struct reg)); 519 520 return (0); 521} 522 523int 524fill_fpregs(struct thread *td, struct fpreg *fpregs) 525{ 526 527 return (0); 528} 529 530/* 531 * Flush the D-cache for non-DMA I/O so that the I-cache can 532 * be made coherent later. 533 */ 534void 535cpu_flush_dcache(void *ptr, size_t len) 536{ 537 /* TBD */ 538} 539 540/* 541 * Construct a PCB from a trapframe. This is called from kdb_trap() where 542 * we want to start a backtrace from the function that caused us to enter 543 * the debugger. We have the context in the trapframe, but base the trace 544 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 545 * enough for a backtrace. 546 */ 547void 548makectx(struct trapframe *tf, struct pcb *pcb) 549{ 550 551 pcb->pcb_lr = tf->srr0; 552 pcb->pcb_sp = tf->fixreg[1]; 553} 554 555/* 556 * get_mcontext/sendsig helper routine that doesn't touch the 557 * proc lock. 558 */ 559static int 560grab_mcontext(struct thread *td, mcontext_t *mcp, int flags) 561{ 562 struct pcb *pcb; 563 564 pcb = td->td_pcb; 565 memset(mcp, 0, sizeof(mcontext_t)); 566 567 mcp->mc_vers = _MC_VERSION; 568 mcp->mc_flags = 0; 569 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe)); 570 if (flags & GET_MC_CLEAR_RET) { 571 mcp->mc_gpr[3] = 0; 572 mcp->mc_gpr[4] = 0; 573 } 574 575 /* XXX Altivec context ? */ 576 577 mcp->mc_len = sizeof(*mcp); 578 return (0); 579} 580 581int 582get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 583{ 584 int error; 585 586 error = grab_mcontext(td, mcp, flags); 587 if (error == 0) { 588 PROC_LOCK(curthread->td_proc); 589 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 590 PROC_UNLOCK(curthread->td_proc); 591 } 592 593 return (error); 594} 595 596int 597set_mcontext(struct thread *td, const mcontext_t *mcp) 598{ 599 struct pcb *pcb; 600 struct trapframe *tf; 601 602 pcb = td->td_pcb; 603 tf = td->td_frame; 604 605 if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp)) 606 return (EINVAL); 607 608 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame)); 609 610 /* XXX Altivec context? */ 611 612 return (0); 613} 614 615int 616sigreturn(struct thread *td, struct sigreturn_args *uap) 617{ 618 ucontext_t uc; 619 int error; 620 621 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 622 623 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 624 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 625 return (EFAULT); 626 } 627 628 error = set_mcontext(td, &uc.uc_mcontext); 629 if (error != 0) 630 return (error); 631 632 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 633 634 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 635 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 636 637 return (EJUSTRETURN); 638} 639 640#ifdef COMPAT_FREEBSD4 641int 642freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 643{ 644 645 return sigreturn(td, (struct sigreturn_args *)uap); 646} 647#endif 648 649/* 650 * cpu_idle 651 * 652 * Set Wait state enable. 653 */ 654void 655cpu_idle (int busy) 656{ 657 register_t msr; 658 659 msr = mfmsr(); 660 661#ifdef INVARIANTS 662 if ((msr & PSL_EE) != PSL_EE) { 663 struct thread *td = curthread; 664 printf("td msr %x\n", td->td_md.md_saved_msr); 665 panic("ints disabled in idleproc!"); 666 } 667#endif 668 669 /* Freescale E500 core RM section 6.4.1. */ 670 msr = msr | PSL_WE; 671 __asm __volatile("msync; mtmsr %0; isync" :: "r" (msr)); 672} 673 674int 675cpu_idle_wakeup(int cpu) 676{ 677 678 return (0); 679} 680 681void 682spinlock_enter(void) 683{ 684 struct thread *td; 685 686 td = curthread; 687 if (td->td_md.md_spinlock_count == 0) 688 td->td_md.md_saved_msr = intr_disable(); 689 td->td_md.md_spinlock_count++; 690 critical_enter(); 691} 692 693void 694spinlock_exit(void) 695{ 696 struct thread *td; 697 698 td = curthread; 699 critical_exit(); 700 td->td_md.md_spinlock_count--; 701 if (td->td_md.md_spinlock_count == 0) 702 intr_restore(td->td_md.md_saved_msr); 703} 704 705/* Shutdown the CPU as much as possible. */ 706void 707cpu_halt(void) 708{ 709 710 mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE)); 711 while (1); 712} 713 714int 715set_regs(struct thread *td, struct reg *regs) 716{ 717 struct trapframe *tf; 718 719 tf = td->td_frame; 720 memcpy(tf, regs, sizeof(struct reg)); 721 return (0); 722} 723 724int 725fill_dbregs(struct thread *td, struct dbreg *dbregs) 726{ 727 728 /* No debug registers on PowerPC */ 729 return (ENOSYS); 730} 731 732int 733set_dbregs(struct thread *td, struct dbreg *dbregs) 734{ 735 736 /* No debug registers on PowerPC */ 737 return (ENOSYS); 738} 739 740int 741set_fpregs(struct thread *td, struct fpreg *fpregs) 742{ 743 744 return (0); 745} 746 747int 748ptrace_set_pc(struct thread *td, unsigned long addr) 749{ 750 struct trapframe *tf; 751 752 tf = td->td_frame; 753 tf->srr0 = (register_t)addr; 754 755 return (0); 756} 757 758int 759ptrace_single_step(struct thread *td) 760{ 761 struct trapframe *tf; 762 763 tf = td->td_frame; 764 tf->srr1 |= PSL_DE; 765 tf->cpu.booke.dbcr0 |= (DBCR0_IDM | DBCR0_IC); 766 return (0); 767} 768 769int 770ptrace_clear_single_step(struct thread *td) 771{ 772 struct trapframe *tf; 773 774 tf = td->td_frame; 775 tf->srr1 &= ~PSL_DE; 776 tf->cpu.booke.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC); 777 return (0); 778} 779 780void 781kdb_cpu_clear_singlestep(void) 782{ 783 register_t r; 784 785 r = mfspr(SPR_DBCR0); 786 mtspr(SPR_DBCR0, r & ~DBCR0_IC); 787 kdb_frame->srr1 &= ~PSL_DE; 788} 789 790void 791kdb_cpu_set_singlestep(void) 792{ 793 register_t r; 794 795 r = mfspr(SPR_DBCR0); 796 mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM); 797 kdb_frame->srr1 |= PSL_DE; 798} 799 800void 801sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 802{ 803 struct trapframe *tf; 804 struct sigframe *sfp; 805 struct sigacts *psp; 806 struct sigframe sf; 807 struct thread *td; 808 struct proc *p; 809 int oonstack, rndfsize; 810 int sig, code; 811 812 td = curthread; 813 p = td->td_proc; 814 PROC_LOCK_ASSERT(p, MA_OWNED); 815 sig = ksi->ksi_signo; 816 code = ksi->ksi_code; 817 psp = p->p_sigacts; 818 mtx_assert(&psp->ps_mtx, MA_OWNED); 819 tf = td->td_frame; 820 oonstack = sigonstack(tf->fixreg[1]); 821 822 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 823 824 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 825 catcher, sig); 826 827 /* 828 * Save user context 829 */ 830 memset(&sf, 0, sizeof(sf)); 831 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 832 sf.sf_uc.uc_sigmask = *mask; 833 sf.sf_uc.uc_stack = td->td_sigstk; 834 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 835 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 836 837 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 838 839 /* 840 * Allocate and validate space for the signal handler context. 841 */ 842 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 843 SIGISMEMBER(psp->ps_sigonstack, sig)) { 844 sfp = (struct sigframe *)((caddr_t)td->td_sigstk.ss_sp + 845 td->td_sigstk.ss_size - rndfsize); 846 } else { 847 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); 848 } 849 850 /* 851 * Translate the signal if appropriate (Linux emu ?) 852 */ 853 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 854 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 855 856 /* 857 * Save the floating-point state, if necessary, then copy it. 858 */ 859 /* XXX */ 860 861 /* 862 * Set up the registers to return to sigcode. 863 * 864 * r1/sp - sigframe ptr 865 * lr - sig function, dispatched to by blrl in trampoline 866 * r3 - sig number 867 * r4 - SIGINFO ? &siginfo : exception code 868 * r5 - user context 869 * srr0 - trampoline function addr 870 */ 871 tf->lr = (register_t)catcher; 872 tf->fixreg[1] = (register_t)sfp; 873 tf->fixreg[FIRSTARG] = sig; 874 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; 875 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 876 /* 877 * Signal handler installed with SA_SIGINFO. 878 */ 879 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si; 880 881 /* 882 * Fill siginfo structure. 883 */ 884 sf.sf_si = ksi->ksi_info; 885 sf.sf_si.si_signo = sig; 886 sf.sf_si.si_addr = (void *) ((tf->exc == EXC_DSI) ? 887 tf->cpu.booke.dear : tf->srr0); 888 } else { 889 /* Old FreeBSD-style arguments. */ 890 tf->fixreg[FIRSTARG+1] = code; 891 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ? 892 tf->cpu.booke.dear : tf->srr0; 893 } 894 mtx_unlock(&psp->ps_mtx); 895 PROC_UNLOCK(p); 896 897 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); 898 899 /* 900 * copy the frame out to userland. 901 */ 902 if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) { 903 /* 904 * Process has trashed its stack. Kill it. 905 */ 906 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 907 PROC_LOCK(p); 908 sigexit(td, SIGILL); 909 } 910 911 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 912 tf->srr0, tf->fixreg[1]); 913 914 PROC_LOCK(p); 915 mtx_lock(&psp->ps_mtx); 916} 917 918void 919bzero(void *buf, size_t len) 920{ 921 caddr_t p; 922 923 p = buf; 924 925 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 926 *p++ = 0; 927 len--; 928 } 929 930 while (len >= sizeof(u_long) * 8) { 931 *(u_long*) p = 0; 932 *((u_long*) p + 1) = 0; 933 *((u_long*) p + 2) = 0; 934 *((u_long*) p + 3) = 0; 935 len -= sizeof(u_long) * 8; 936 *((u_long*) p + 4) = 0; 937 *((u_long*) p + 5) = 0; 938 *((u_long*) p + 6) = 0; 939 *((u_long*) p + 7) = 0; 940 p += sizeof(u_long) * 8; 941 } 942 943 while (len >= sizeof(u_long)) { 944 *(u_long*) p = 0; 945 len -= sizeof(u_long); 946 p += sizeof(u_long); 947 } 948 949 while (len) { 950 *p++ = 0; 951 len--; 952 } 953} 954 955/* 956 * XXX what is the better/proper place for this routine? 957 */ 958int 959mem_valid(vm_offset_t addr, int len) 960{ 961 962 return (1); 963}
|