Home | History | Annotate | Line # | Download | only in booke
booke_machdep.c revision 1.5.2.1
      1      1.2    matt /*-
      2      1.2    matt  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
      3      1.2    matt  * All rights reserved.
      4      1.2    matt  *
      5      1.2    matt  * This code is derived from software contributed to The NetBSD Foundation
      6      1.2    matt  * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
      7      1.2    matt  * Agency and which was developed by Matt Thomas of 3am Software Foundry.
      8      1.2    matt  *
      9      1.2    matt  * This material is based upon work supported by the Defense Advanced Research
     10      1.2    matt  * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
     11      1.2    matt  * Contract No. N66001-09-C-2073.
     12      1.2    matt  * Approved for Public Release, Distribution Unlimited
     13      1.2    matt  *
     14      1.2    matt  * Redistribution and use in source and binary forms, with or without
     15      1.2    matt  * modification, are permitted provided that the following conditions
     16      1.2    matt  * are met:
     17      1.2    matt  * 1. Redistributions of source code must retain the above copyright
     18      1.2    matt  *    notice, this list of conditions and the following disclaimer.
     19      1.2    matt  * 2. Redistributions in binary form must reproduce the above copyright
     20      1.2    matt  *    notice, this list of conditions and the following disclaimer in the
     21      1.2    matt  *    documentation and/or other materials provided with the distribution.
     22      1.2    matt  *
     23      1.2    matt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     24      1.2    matt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     25      1.2    matt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     26      1.2    matt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     27      1.2    matt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28      1.2    matt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29      1.2    matt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30      1.2    matt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31      1.2    matt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32      1.2    matt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33      1.2    matt  * POSSIBILITY OF SUCH DAMAGE.
     34      1.2    matt  */
     35      1.2    matt 
     36      1.2    matt #define	__INTR_PRIVATE
     37      1.2    matt #define	_POWERPC_BUS_DMA_PRIVATE
     38      1.2    matt 
     39      1.2    matt #include <sys/cdefs.h>
     40      1.2    matt 
     41  1.5.2.1  cherry #include "opt_modular.h"
     42  1.5.2.1  cherry 
     43      1.2    matt #include <sys/param.h>
     44      1.2    matt #include <sys/cpu.h>
     45      1.2    matt #include <sys/device.h>
     46      1.2    matt #include <sys/intr.h>
     47      1.2    matt #include <sys/mount.h>
     48      1.2    matt #include <sys/msgbuf.h>
     49      1.2    matt #include <sys/kernel.h>
     50      1.2    matt #include <sys/reboot.h>
     51      1.2    matt #include <sys/bus.h>
     52      1.2    matt 
     53      1.2    matt #include <uvm/uvm_extern.h>
     54      1.2    matt 
     55      1.4    matt #include <powerpc/spr.h>
     56      1.4    matt #include <powerpc/booke/spr.h>
     57      1.4    matt #include <powerpc/booke/cpuvar.h>
     58      1.2    matt 
     59      1.2    matt /*
     60      1.2    matt  * Global variables used here and there
     61      1.2    matt  */
     62      1.2    matt paddr_t msgbuf_paddr;
     63      1.2    matt psize_t pmemsize;
     64      1.2    matt struct vm_map *phys_map;
     65      1.2    matt 
     66  1.5.2.1  cherry #ifdef MODULAR
     67  1.5.2.1  cherry register_t cpu_psluserset = PSL_USERSET;
     68  1.5.2.1  cherry register_t cpu_pslusermod = PSL_USERMOD;
     69  1.5.2.1  cherry register_t cpu_pslusermask = PSL_USERMASK;
     70  1.5.2.1  cherry #endif
     71  1.5.2.1  cherry 
     72      1.2    matt static bus_addr_t booke_dma_phys_to_bus_mem(bus_dma_tag_t, bus_addr_t);
     73      1.2    matt static bus_addr_t booke_dma_bus_mem_to_phys(bus_dma_tag_t, bus_addr_t);
     74      1.2    matt 
     75      1.2    matt 
     76      1.2    matt struct powerpc_bus_dma_tag booke_bus_dma_tag = {
     77      1.2    matt 	._dmamap_create = _bus_dmamap_create,
     78      1.2    matt 	._dmamap_destroy = _bus_dmamap_destroy,
     79      1.2    matt 	._dmamap_load = _bus_dmamap_load,
     80      1.2    matt 	._dmamap_load_mbuf = _bus_dmamap_load_mbuf,
     81      1.2    matt 	._dmamap_load_uio = _bus_dmamap_load_uio,
     82      1.2    matt 	._dmamap_load_raw = _bus_dmamap_load_raw,
     83      1.2    matt 	._dmamap_unload = _bus_dmamap_unload,
     84      1.2    matt 	._dmamap_sync = _bus_dmamap_sync,
     85      1.2    matt 	._dmamem_alloc = _bus_dmamem_alloc,
     86      1.2    matt 	._dmamem_free = _bus_dmamem_free,
     87      1.2    matt 	._dmamem_map = _bus_dmamem_map,
     88      1.2    matt 	._dmamem_unmap = _bus_dmamem_unmap,
     89      1.2    matt 	._dmamem_mmap = _bus_dmamem_mmap,
     90      1.2    matt 	._dma_phys_to_bus_mem = booke_dma_phys_to_bus_mem,
     91      1.2    matt 	._dma_bus_mem_to_phys = booke_dma_bus_mem_to_phys,
     92      1.2    matt };
     93      1.2    matt 
     94      1.2    matt static bus_addr_t
     95      1.2    matt booke_dma_phys_to_bus_mem(bus_dma_tag_t t, bus_addr_t a)
     96      1.2    matt {
     97      1.2    matt 	return a;
     98      1.2    matt }
     99      1.2    matt 
    100      1.2    matt static bus_addr_t
    101      1.2    matt booke_dma_bus_mem_to_phys(bus_dma_tag_t t, bus_addr_t a)
    102      1.2    matt {
    103      1.2    matt 	return a;
    104      1.2    matt }
    105      1.2    matt 
    106      1.2    matt struct cpu_md_ops cpu_md_ops;
    107      1.2    matt 
    108  1.5.2.1  cherry struct cpu_softc cpu_softc[] = {
    109      1.2    matt 	[0] = {
    110  1.5.2.1  cherry 		.cpu_ci = &cpu_info[0],
    111      1.2    matt 	},
    112  1.5.2.1  cherry #ifdef MULTIPROCESSOR
    113  1.5.2.1  cherry 	[CPU_MAXNUM-1] = {
    114  1.5.2.1  cherry 		.cpu_ci = &cpu_info[CPU_MAXNUM-1],
    115  1.5.2.1  cherry 	},
    116  1.5.2.1  cherry #endif
    117      1.2    matt };
    118  1.5.2.1  cherry struct cpu_info cpu_info[] = {
    119      1.2    matt 	[0] = {
    120      1.2    matt 		.ci_curlwp = &lwp0,
    121      1.2    matt 		.ci_tlb_info = &pmap_tlb0_info,
    122  1.5.2.1  cherry 		.ci_softc = &cpu_softc[0],
    123  1.5.2.1  cherry 		.ci_cpl = IPL_HIGH,
    124  1.5.2.1  cherry 	},
    125  1.5.2.1  cherry #ifdef MULTIPROCESSOR
    126  1.5.2.1  cherry 	[CPU_MAXNUM-1] = {
    127  1.5.2.1  cherry 		.ci_curlwp = NULL,
    128  1.5.2.1  cherry 		.ci_tlb_info = &pmap_tlb0_info,
    129  1.5.2.1  cherry 		.ci_softc = &cpu_softc[CPU_MAXNUM-1],
    130      1.2    matt 		.ci_cpl = IPL_HIGH,
    131      1.2    matt 	},
    132  1.5.2.1  cherry #endif
    133      1.2    matt };
    134      1.2    matt 
    135      1.2    matt /*
    136      1.2    matt  * This should probably be in autoconf!				XXX
    137      1.2    matt  */
    138      1.2    matt char cpu_model[80];
    139      1.2    matt char machine[] = MACHINE;		/* from <machine/param.h> */
    140      1.2    matt char machine_arch[] = MACHINE_ARCH;	/* from <machine/param.h> */
    141      1.2    matt 
    142      1.2    matt char bootpath[256];
    143      1.2    matt 
    144      1.2    matt #if NKSYMS || defined(DDB) || defined(MODULAR)
    145      1.2    matt void *startsym, *endsym;
    146      1.2    matt #endif
    147      1.2    matt 
    148      1.2    matt int fake_mapiodev = 1;
    149      1.2    matt 
    150      1.2    matt void
    151      1.2    matt booke_cpu_startup(const char *model)
    152      1.2    matt {
    153      1.2    matt 	vaddr_t 	minaddr, maxaddr;
    154      1.2    matt 	char 		pbuf[9];
    155      1.2    matt 
    156      1.2    matt 	strlcpy(cpu_model, model, sizeof(cpu_model));
    157      1.2    matt 
    158      1.2    matt 	printf("%s%s", copyright, version);
    159      1.2    matt 
    160      1.5    matt 	format_bytes(pbuf, sizeof(pbuf), ctob((uint64_t)physmem));
    161      1.2    matt 	printf("total memory = %s\n", pbuf);
    162      1.2    matt 
    163      1.2    matt 	minaddr = 0;
    164      1.2    matt 	/*
    165      1.2    matt 	 * Allocate a submap for physio
    166      1.2    matt 	 */
    167      1.2    matt 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
    168      1.2    matt 				 VM_PHYS_SIZE, 0, false, NULL);
    169      1.2    matt 
    170      1.2    matt 	/*
    171      1.2    matt 	 * No need to allocate an mbuf cluster submap.  Mbuf clusters
    172      1.2    matt 	 * are allocated via the pool allocator, and we use direct-mapped
    173      1.2    matt 	 * pool pages.
    174      1.2    matt 	 */
    175      1.2    matt 
    176      1.2    matt 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
    177      1.2    matt 	printf("avail memory = %s\n", pbuf);
    178      1.2    matt 
    179      1.2    matt 	/*
    180      1.2    matt 	 * Set up the board properties database.
    181      1.2    matt 	 */
    182      1.2    matt 	board_info_init();
    183      1.2    matt 
    184      1.2    matt 	/*
    185      1.2    matt 	 * Now that we have VM, malloc()s are OK in bus_space.
    186      1.2    matt 	 */
    187      1.2    matt 	bus_space_mallocok();
    188      1.2    matt 	fake_mapiodev = 0;
    189      1.2    matt }
    190      1.2    matt 
    191      1.2    matt static void
    192      1.2    matt dumpsys(void)
    193      1.2    matt {
    194      1.2    matt 
    195      1.2    matt 	printf("dumpsys: TBD\n");
    196      1.2    matt }
    197      1.2    matt 
    198      1.2    matt /*
    199      1.2    matt  * Halt or reboot the machine after syncing/dumping according to howto.
    200      1.2    matt  */
    201      1.2    matt void
    202      1.2    matt cpu_reboot(int howto, char *what)
    203      1.2    matt {
    204      1.2    matt 	static int syncing;
    205      1.2    matt 	static char str[256];
    206      1.2    matt 	char *ap = str, *ap1 = ap;
    207      1.2    matt 
    208      1.2    matt 	boothowto = howto;
    209      1.2    matt 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
    210      1.2    matt 		syncing = 1;
    211      1.2    matt 		vfs_shutdown();		/* sync */
    212      1.2    matt 		resettodr();		/* set wall clock */
    213      1.2    matt 	}
    214      1.2    matt 
    215      1.2    matt 	splhigh();
    216      1.2    matt 
    217      1.2    matt 	if (!cold && (howto & RB_DUMP))
    218      1.2    matt 		dumpsys();
    219      1.2    matt 
    220      1.2    matt 	doshutdownhooks();
    221      1.2    matt 
    222      1.2    matt 	pmf_system_shutdown(boothowto);
    223      1.2    matt 
    224      1.2    matt 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
    225      1.2    matt 	  /* Power off here if we know how...*/
    226      1.2    matt 	}
    227      1.2    matt 
    228      1.2    matt 	if (howto & RB_HALT) {
    229      1.2    matt 		printf("halted\n\n");
    230      1.2    matt 
    231      1.2    matt 		goto reboot;	/* XXX for now... */
    232      1.2    matt 
    233      1.2    matt #ifdef DDB
    234      1.2    matt 		printf("dropping to debugger\n");
    235      1.2    matt 		while(1)
    236      1.2    matt 			Debugger();
    237      1.2    matt #endif
    238      1.2    matt 	}
    239      1.2    matt 
    240      1.2    matt 	printf("rebooting\n\n");
    241      1.2    matt 	if (what && *what) {
    242      1.2    matt 		if (strlen(what) > sizeof str - 5)
    243      1.2    matt 			printf("boot string too large, ignored\n");
    244      1.2    matt 		else {
    245      1.2    matt 			strcpy(str, what);
    246      1.2    matt 			ap1 = ap = str + strlen(str);
    247      1.2    matt 			*ap++ = ' ';
    248      1.2    matt 		}
    249      1.2    matt 	}
    250      1.2    matt 	*ap++ = '-';
    251      1.2    matt 	if (howto & RB_SINGLE)
    252      1.2    matt 		*ap++ = 's';
    253      1.2    matt 	if (howto & RB_KDB)
    254      1.2    matt 		*ap++ = 'd';
    255      1.2    matt 	*ap++ = 0;
    256      1.2    matt 	if (ap[-2] == '-')
    257      1.2    matt 		*ap1 = 0;
    258      1.2    matt 
    259      1.2    matt 	/* flush cache for msgbuf */
    260      1.2    matt 	dcache_wb(msgbuf_paddr, round_page(MSGBUFSIZE));
    261      1.2    matt 
    262      1.2    matt  reboot:
    263      1.2    matt 	__asm volatile("msync; isync");
    264      1.2    matt 	(*cpu_md_ops.md_cpu_reset)();
    265      1.2    matt 
    266      1.2    matt 	printf("%s: md_cpu_reset() failed!\n", __func__);
    267      1.2    matt #ifdef DDB
    268      1.2    matt 	for (;;)
    269      1.2    matt 		Debugger();
    270      1.2    matt #else
    271      1.2    matt 	for (;;)
    272      1.2    matt 		/* nothing */;
    273      1.2    matt #endif
    274      1.2    matt }
    275      1.2    matt 
    276      1.2    matt /*
    277      1.2    matt  * mapiodev:
    278      1.2    matt  *
    279      1.2    matt  * 	Allocate vm space and mapin the I/O address. Use reserved TLB
    280      1.2    matt  * 	mapping if one is found.
    281      1.2    matt  */
    282      1.2    matt void *
    283      1.2    matt mapiodev(paddr_t pa, psize_t len)
    284      1.2    matt {
    285      1.2    matt 	const vsize_t off = pa & PAGE_MASK;
    286      1.2    matt 
    287      1.2    matt 	/*
    288      1.2    matt 	 * See if we have reserved TLB entry for the pa. This needs to be
    289      1.2    matt 	 * true for console as we can't use uvm during early bootstrap.
    290      1.2    matt 	 */
    291      1.2    matt 	void * const p = tlb_mapiodev(pa, len);
    292      1.2    matt 	if (p != NULL)
    293      1.2    matt 		return p;
    294      1.2    matt 
    295      1.2    matt 	if (fake_mapiodev)
    296      1.2    matt 		panic("mapiodev: no TLB entry reserved for %llx+%llx",
    297      1.2    matt 		    (long long)pa, (long long)len);
    298      1.2    matt 
    299      1.2    matt 	pa = trunc_page(pa);
    300      1.2    matt 	len = round_page(off + len);
    301      1.2    matt 	vaddr_t va = uvm_km_alloc(kernel_map, len, 0, UVM_KMF_VAONLY);
    302      1.2    matt 
    303      1.2    matt 	if (va == 0)
    304      1.2    matt 		return NULL;
    305      1.2    matt 
    306      1.2    matt 	for (va += len, pa += len; len > 0; len -= PAGE_SIZE) {
    307      1.2    matt 		va -= PAGE_SIZE;
    308      1.2    matt 		pa -= PAGE_SIZE;
    309      1.2    matt 		pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE,
    310      1.2    matt 		    PMAP_NOCACHE);
    311      1.2    matt 	}
    312      1.2    matt 	pmap_update(pmap_kernel());
    313      1.2    matt 	return (void *)(va + off);
    314      1.2    matt }
    315      1.2    matt 
    316      1.2    matt void
    317      1.2    matt unmapiodev(vaddr_t va, vsize_t len)
    318      1.2    matt {
    319      1.2    matt 	/* Nothing to do for reserved (ie. not uvm_km_alloc'd) mappings. */
    320      1.2    matt 	if (va < VM_MIN_KERNEL_ADDRESS || va > VM_MAX_KERNEL_ADDRESS) {
    321      1.2    matt 		tlb_unmapiodev(va, len);
    322      1.2    matt 		return;
    323      1.2    matt 	}
    324      1.2    matt 
    325      1.2    matt 	len = round_page((va & PAGE_MASK) + len);
    326      1.2    matt 	va = trunc_page(va);
    327      1.2    matt 
    328      1.2    matt 	pmap_kremove(va, len);
    329      1.2    matt 	uvm_km_free(kernel_map, va, len, UVM_KMF_VAONLY);
    330      1.2    matt }
    331      1.2    matt 
    332      1.2    matt void
    333      1.2    matt cpu_evcnt_attach(struct cpu_info *ci)
    334      1.2    matt {
    335      1.2    matt 	struct cpu_softc * const cpu = ci->ci_softc;
    336      1.2    matt 	const char * const xname = device_xname(ci->ci_dev);
    337      1.2    matt 
    338      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_clock, EVCNT_TYPE_INTR,
    339      1.2    matt 		NULL, xname, "clock");
    340      1.2    matt 	evcnt_attach_dynamic_nozero(&cpu->cpu_ev_late_clock, EVCNT_TYPE_INTR,
    341      1.2    matt 		NULL, xname, "late clock");
    342      1.2    matt 	evcnt_attach_dynamic_nozero(&cpu->cpu_ev_exec_trap_sync, EVCNT_TYPE_TRAP,
    343      1.2    matt 		NULL, xname, "exec pages synced (trap)");
    344      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_traps, EVCNT_TYPE_TRAP,
    345      1.2    matt 		NULL, xname, "traps");
    346      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_kdsi, EVCNT_TYPE_TRAP,
    347      1.2    matt 		&ci->ci_ev_traps, xname, "kernel DSI traps");
    348      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_udsi, EVCNT_TYPE_TRAP,
    349      1.2    matt 		&ci->ci_ev_traps, xname, "user DSI traps");
    350      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_udsi_fatal, EVCNT_TYPE_TRAP,
    351      1.2    matt 		&ci->ci_ev_udsi, xname, "user DSI failures");
    352      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_kisi, EVCNT_TYPE_TRAP,
    353      1.2    matt 		&ci->ci_ev_traps, xname, "kernel ISI traps");
    354      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_isi, EVCNT_TYPE_TRAP,
    355      1.2    matt 		&ci->ci_ev_traps, xname, "user ISI traps");
    356      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_isi_fatal, EVCNT_TYPE_TRAP,
    357      1.2    matt 		&ci->ci_ev_isi, xname, "user ISI failures");
    358      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_scalls, EVCNT_TYPE_TRAP,
    359      1.2    matt 		&ci->ci_ev_traps, xname, "system call traps");
    360      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_pgm, EVCNT_TYPE_TRAP,
    361      1.2    matt 		&ci->ci_ev_traps, xname, "PGM traps");
    362      1.3    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_debug, EVCNT_TYPE_TRAP,
    363      1.3    matt 		&ci->ci_ev_traps, xname, "debug traps");
    364      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_fpu, EVCNT_TYPE_TRAP,
    365      1.2    matt 		&ci->ci_ev_traps, xname, "FPU unavailable traps");
    366      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_fpusw, EVCNT_TYPE_MISC,
    367      1.2    matt 		&ci->ci_ev_fpu, xname, "FPU context switches");
    368      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_ali, EVCNT_TYPE_TRAP,
    369      1.2    matt 		&ci->ci_ev_traps, xname, "user alignment traps");
    370      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_ali_fatal, EVCNT_TYPE_TRAP,
    371      1.2    matt 		&ci->ci_ev_ali, xname, "user alignment traps");
    372      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_umchk, EVCNT_TYPE_TRAP,
    373      1.2    matt 		&ci->ci_ev_umchk, xname, "user MCHK failures");
    374      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_vec, EVCNT_TYPE_TRAP,
    375      1.2    matt 		&ci->ci_ev_traps, xname, "SPE unavailable");
    376      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_vecsw, EVCNT_TYPE_MISC,
    377      1.2    matt 	    &ci->ci_ev_vec, xname, "SPE context switches");
    378      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_ipi, EVCNT_TYPE_INTR,
    379      1.2    matt 		NULL, xname, "IPIs");
    380      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_tlbmiss_soft, EVCNT_TYPE_TRAP,
    381      1.2    matt 		&ci->ci_ev_traps, xname, "soft tlb misses");
    382      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_dtlbmiss_hard, EVCNT_TYPE_TRAP,
    383      1.2    matt 		&ci->ci_ev_traps, xname, "data tlb misses");
    384      1.2    matt 	evcnt_attach_dynamic_nozero(&ci->ci_ev_itlbmiss_hard, EVCNT_TYPE_TRAP,
    385      1.2    matt 		&ci->ci_ev_traps, xname, "inst tlb misses");
    386      1.2    matt }
    387      1.2    matt 
    388      1.2    matt uint32_t
    389      1.2    matt cpu_read_4(bus_addr_t a)
    390      1.2    matt {
    391      1.2    matt 	struct cpu_softc * const cpu = curcpu()->ci_softc;
    392      1.2    matt //	printf(" %s(%p, %x, %x)", __func__, cpu->cpu_bst, cpu->cpu_bsh, a);
    393      1.2    matt 	return bus_space_read_4(cpu->cpu_bst, cpu->cpu_bsh, a);
    394      1.2    matt }
    395      1.2    matt 
    396      1.2    matt uint8_t
    397      1.2    matt cpu_read_1(bus_addr_t a)
    398      1.2    matt {
    399      1.2    matt 	struct cpu_softc * const cpu = curcpu()->ci_softc;
    400      1.2    matt //	printf(" %s(%p, %x, %x)", __func__, cpu->cpu_bst, cpu->cpu_bsh, a);
    401      1.2    matt 	return bus_space_read_1(cpu->cpu_bst, cpu->cpu_bsh, a);
    402      1.2    matt }
    403      1.2    matt 
    404      1.2    matt void
    405      1.2    matt cpu_write_4(bus_addr_t a, uint32_t v)
    406      1.2    matt {
    407      1.2    matt 	struct cpu_softc * const cpu = curcpu()->ci_softc;
    408      1.2    matt 	bus_space_write_4(cpu->cpu_bst, cpu->cpu_bsh, a, v);
    409      1.2    matt }
    410      1.2    matt 
    411      1.2    matt void
    412      1.2    matt cpu_write_1(bus_addr_t a, uint8_t v)
    413      1.2    matt {
    414      1.2    matt 	struct cpu_softc * const cpu = curcpu()->ci_softc;
    415      1.2    matt 	bus_space_write_1(cpu->cpu_bst, cpu->cpu_bsh, a, v);
    416      1.2    matt }
    417      1.4    matt 
    418      1.4    matt void
    419      1.4    matt booke_sstep(struct trapframe *tf)
    420      1.4    matt {
    421      1.4    matt 	KASSERT(tf->tf_srr1 & PSL_DE);
    422      1.4    matt 	const uint32_t insn = ufetch_32((const void *)tf->tf_srr0);
    423      1.4    matt 	register_t dbcr0 = DBCR0_IAC1 | DBCR0_IDM;
    424      1.4    matt 	register_t dbcr1 = DBCR1_IAC1US_USER | DBCR1_IAC1ER_DS1;
    425      1.4    matt 	if ((insn >> 28) == 4) {
    426      1.4    matt 		uint32_t iac2 = 0;
    427      1.4    matt 		if ((insn >> 26) == 0x12) {
    428      1.4    matt 			const int32_t off = (((int32_t)insn << 6) >> 6) & ~3;
    429      1.4    matt 			iac2 = ((insn & 2) ? 0 : tf->tf_srr0) + off;
    430      1.4    matt 			dbcr0 |= DBCR0_IAC2;
    431      1.4    matt 		} else if ((insn >> 26) == 0x10) {
    432      1.4    matt 			const int16_t off = insn & ~3;
    433      1.4    matt 			iac2 = ((insn & 2) ? 0 : tf->tf_srr0) + off;
    434      1.4    matt 			dbcr0 |= DBCR0_IAC2;
    435      1.4    matt 		} else if ((insn & 0xfc00ffde) == 0x4c000420) {
    436      1.4    matt 			iac2 = tf->tf_ctr;
    437      1.4    matt 			dbcr0 |= DBCR0_IAC2;
    438      1.4    matt 		} else if ((insn & 0xfc00ffde) == 0x4c000020) {
    439      1.4    matt 			iac2 = tf->tf_lr;
    440      1.4    matt 			dbcr0 |= DBCR0_IAC2;
    441      1.4    matt 		}
    442      1.4    matt 		if (dbcr0 & DBCR0_IAC2) {
    443      1.4    matt 			dbcr1 |= DBCR1_IAC2US_USER | DBCR1_IAC2ER_DS1;
    444      1.4    matt 			mtspr(SPR_IAC2, iac2);
    445      1.4    matt 		}
    446      1.4    matt 	}
    447      1.4    matt 	mtspr(SPR_IAC1, tf->tf_srr0 + 4);
    448      1.4    matt 	mtspr(SPR_DBCR1, dbcr1);
    449      1.4    matt 	mtspr(SPR_DBCR0, dbcr0);
    450      1.4    matt }
    451