/* 2007-03-27: File added by Sony Corporation */
/*
 *  Register description for ARMv6
 *
 *  Copyright 2003-2007 Sony Corporation.
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  version 2 of the  License.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``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   THE AUTHOR  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.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>

#define read_coprocessor(cp_num, crn, op1, crm, op2)			\
	({								\
		unsigned int __val;					\
		__asm__ __volatile__(					\
			"mrc	" __stringify(cp_num) ","		\
			__stringify(op1) ", %0," __stringify(crn) ","	\
			__stringify(crm) "," __stringify(op2)		\
			: "=r" (__val)					\
			:						\
			: "cc");					\
		__val;							\
	})

#define write_coprocessor(val, cp_num, crn, op1, crm, op2)		\
	({								\
		__asm__ __volatile__(					\
			"mcr	" __stringify(cp_num) ","		\
			__stringify(op1) ", %0," __stringify(crn) ","	\
			__stringify(crm) "," __stringify(op2)		\
			:						\
			: "r" (val)					\
			: "cc");					\
	})

u_int32_t
do_read_coprocessor(unsigned int func_offset)
{
	switch (func_offset) {
	case 0 :		/* Main ID */
		return read_coprocessor(p15, c0, 0, c0, 0);
	case 1 :		/* Cache Type */
		return read_coprocessor(p15, c0, 0, c0, 1);
	case 2 :		/* TCM Status */
		return read_coprocessor(p15, c0, 0, c0, 2);
	case 3 :		/* TLB Type */
		return read_coprocessor(p15, c0, 0, c0, 3);
	case 4 :		/* Control */
		return read_coprocessor(p15, c1, 0, c0, 0);
	case 5 :		/* Auxiliary Control */
		return read_coprocessor(p15, c1, 0, c0, 1);
	case 6 :		/* Coprocessor Access Control */
		return read_coprocessor(p15, c1, 0, c0, 2);
	case 7 :		/* Translation Table Base 0 */
		return read_coprocessor(p15, c2, 0, c0, 0);
	case 8 :		/* Translation Table Base 1 */
		return read_coprocessor(p15, c2, 0, c0, 1);
	case 9 :		/* Translation Table Base Control */
		return read_coprocessor(p15, c2, 0, c0, 2);
	case 10 :		/* Domain Access Control */
		return read_coprocessor(p15, c3, 0, c0, 0);
	case 11 :		/* Data Fault Status */
		return read_coprocessor(p15, c5, 0, c0, 0);
	case 12 :		/* Instruction Fault Status */
		return read_coprocessor(p15, c5, 0, c0, 1);
	case 13 :		/* Data Fault Address */
		return read_coprocessor(p15, c6, 0, c0, 0);
	case 14 :		/* Watchpoint Fault Address */
		return read_coprocessor(p15, c6, 0, c0, 1);
	case 31 :		/* Read Cache Dirty Status Register */
		return read_coprocessor(p15, c7, 0, c10, 6);
	case 32 :		/* Read Block Transfer Status Register */
		return read_coprocessor(p15, c7, 0, c12, 4);
	case 47 :		/* Data Cache Lockdown */
		return read_coprocessor(p15, c9, 0, c0, 0);
	case 48 :		/* Instruction Cache Lockdown */
		return read_coprocessor(p15, c9, 0, c0, 1);
	case 49 :		/* Data TCM Region */
		return read_coprocessor(p15, c9, 0, c1, 0);
	case 50 :		/* Instruction TCM Region */
		return read_coprocessor(p15, c9, 0, c1, 1);
	case 51 :		/* TLB Lockdown */
		return read_coprocessor(p15, c10, 0, c0, 0);
	case 52 :		/* DMA Ident. and Status (Present) */
		return read_coprocessor(p15, c11, 0, c0, 0);
	case 53 :		/* DMA Ident. and Status (Queued) */
		return read_coprocessor(p15, c11, 0, c0, 1);
	case 54 :		/* DMA Ident. and Status (Running) */
		return read_coprocessor(p15, c11, 0, c0, 2);
	case 55 :		/* DMA Ident. and Status (Interrupting) */
		return read_coprocessor(p15, c11, 0, c0, 3);
	case 56 :		/* DMA User Accessibility */
		return read_coprocessor(p15, c11, 0, c1, 0);
	case 57 :		/* DMA Channel Number */
		return read_coprocessor(p15, c11, 0, c2, 0);
	case 61 :		/* DMA Control */
		return read_coprocessor(p15, c11, 0, c4, 0);
	case 62 :		/* DMA Internal Start Address */
		return read_coprocessor(p15, c11, 0, c5, 0);
	case 63 :		/* DMA External Start Address */
		return read_coprocessor(p15, c11, 0, c6, 0);
	case 64 :		/* DMA Internal End Address */
		return read_coprocessor(p15, c11, 0, c7, 0);
	case 65 :		/* DMA Channel Status */
		return read_coprocessor(p15, c11, 0, c8, 0);
	case 66 :		/* DMA Context ID */
		return read_coprocessor(p15, c11, 0, c15, 0);
	case 67 :		/* FCSE PID */
		return read_coprocessor(p15, c13, 0, c0, 0);
	case 68 :		/* Context ID */
		return read_coprocessor(p15, c13, 0, c0, 1);
	case 69 :		/* Data Memory Remap */
		return read_coprocessor(p15, c15, 0, c2, 0);
	case 70 :		/* Instruction Memory Remap */
		return read_coprocessor(p15, c15, 0, c2, 1);
	case 71 :		/* DMA Memory Remap */
		return read_coprocessor(p15, c15, 0, c2, 2);
	case 72 :		/* Peripheral Port Memory Remap */
		return read_coprocessor(p15, c15, 0, c2, 4);
	case 73 :		/* Performance Monitor Control */
		return read_coprocessor(p15, c15, 0, c12, 0);
	case 74 :		/* Cycle Counter (CCNT) */
		return read_coprocessor(p15, c15, 0, c12, 1);
	case 75 :		/* Count 0 (PMN0) */
		return read_coprocessor(p15, c15, 0, c12, 2);
	case 76 :		/* Count 1 (PMN1) */
		return read_coprocessor(p15, c15, 0, c12, 3);
	case 77 :		/* Data Debug Cache */
		return read_coprocessor(p15, c15, 3, c0, 0);
	case 78 :		/* Instruction Debug Cache */
		return read_coprocessor(p15, c15, 3, c0, 1);
	case 82 :		/* Instruction Cache Master Valid0 */
		return read_coprocessor(p15, c15, 3, c8, 0);
	case 83 :		/* Instruction Cache Master Valid1 */
		return read_coprocessor(p15, c15, 3, c8, 1);
	case 84 :		/* Instruction Cache Master Valid2 */
		return read_coprocessor(p15, c15, 3, c8, 2);
	case 85 :		/* Instruction Cache Master Valid3 */
		return read_coprocessor(p15, c15, 3, c8, 3);
	case 86 :		/* Instruction Cache Master Valid4 */
		return read_coprocessor(p15, c15, 3, c8, 4);
	case 87 :		/* Instruction Cache Master Valid5 */
		return read_coprocessor(p15, c15, 3, c8, 5);
	case 88 :		/* Instruction Cache Master Valid6 */
		return read_coprocessor(p15, c15, 3, c8, 6);
	case 89 :		/* Instruction Cache Master Valid7 */
		return read_coprocessor(p15, c15, 3, c8, 7);
	case 90 :		/* Instruction SmartCache Master Valid0 */
		return read_coprocessor(p15, c15, 3, c10, 0);
	case 91 :		/* Instruction SmartCache Master Valid1 */
		return read_coprocessor(p15, c15, 3, c10, 1);
	case 92 :		/* Instruction SmartCache Master Valid2 */
		return read_coprocessor(p15, c15, 3, c10, 2);
	case 93 :		/* Instruction SmartCache Master Valid3 */
		return read_coprocessor(p15, c15, 3, c10, 3);
	case 94 :		/* Instruction SmartCache Master Valid4 */
		return read_coprocessor(p15, c15, 3, c10, 4);
	case 95 :		/* Instruction SmartCache Master Valid5 */
		return read_coprocessor(p15, c15, 3, c10, 5);
	case 96 :		/* Instruction SmartCache Master Valid6 */
		return read_coprocessor(p15, c15, 3, c10, 6);
	case 97 :		/* Instruction SmartCache Master Valid7 */
		return read_coprocessor(p15, c15, 3, c10, 7);
	case 98 :		/* Data Cache Master Valid0 */
		return read_coprocessor(p15, c15, 3, c12, 0);
	case 99 :		/* Data Cache Master Valid1 */
		return read_coprocessor(p15, c15, 3, c12, 1);
	case 100 :		/* Data Cache Master Valid2 */
		return read_coprocessor(p15, c15, 3, c12, 2);
	case 101 :		/* Data Cache Master Valid3 */
		return read_coprocessor(p15, c15, 3, c12, 3);
	case 102 :		/* Data Cache Master Valid4 */
		return read_coprocessor(p15, c15, 3, c12, 4);
	case 103 :		/* Data Cache Master Valid5 */
		return read_coprocessor(p15, c15, 3, c12, 5);
	case 104 :		/* Data Cache Master Valid6 */
		return read_coprocessor(p15, c15, 3, c12, 6);
	case 105 :		/* Data Cache Master Valid7 */
		return read_coprocessor(p15, c15, 3, c12, 7);
	case 106 :		/* Data SmartCache Master Valid0 */
		return read_coprocessor(p15, c15, 3, c14, 0);
	case 107 :		/* Data SmartCache Master Valid1 */
		return read_coprocessor(p15, c15, 3, c14, 1);
	case 108 :		/* Data SmartCache Master Valid2 */
		return read_coprocessor(p15, c15, 3, c14, 2);
	case 109 :		/* Data SmartCache Master Valid3 */
		return read_coprocessor(p15, c15, 3, c14, 3);
	case 110 :		/* Data SmartCache Master Valid4 */
		return read_coprocessor(p15, c15, 3, c14, 4);
	case 111 :		/* Data SmartCache Master Valid5 */
		return read_coprocessor(p15, c15, 3, c14, 5);
	case 112 :		/* Data SmartCache Master Valid6 */
		return read_coprocessor(p15, c15, 3, c14, 6);
	case 113 :		/* Data SmartCache Master Valid7 */
		return read_coprocessor(p15, c15, 3, c14, 7);
	case 114 :		/* Data MicroTLB Index */
		return read_coprocessor(p15, c15, 5, c4, 0);
	case 115 :		/* Instruction MicroTLB Index */
		return read_coprocessor(p15, c15, 5, c4, 1);
	case 118 :		/* Data MicroTLB VA */
		return read_coprocessor(p15, c15, 5, c5, 0);
	case 119 :		/* Instruction MicroTLB VA */
		return read_coprocessor(p15, c15, 5, c5, 1);
	case 120 :		/* Main TLB VA */
		return read_coprocessor(p15, c15, 5, c5, 2);
	case 121 :		/* Data MicroTLB PA */
		return read_coprocessor(p15, c15, 5, c6, 0);
	case 122 :		/* Instruction MicroTLB PA */
		return read_coprocessor(p15, c15, 5, c6, 1);
	case 123 :		/* Main TLB PA */
		return read_coprocessor(p15, c15, 5, c6, 2);
	case 124 :		/* Data MicroTLB Attribute */
		return read_coprocessor(p15, c15, 5, c7, 0);
	case 125 :		/* Instruction MicroTLB Attribute */
		return read_coprocessor(p15, c15, 5, c7, 1);
	case 126 :		/* Main TLB Attribute */
		return read_coprocessor(p15, c15, 5, c7, 2);
	case 127 :		/* Main TLB Master Valid0 */
		return read_coprocessor(p15, c15, 5, c14, 0);
	case 128 :		/* Main TLB Master Valid1 */
		return read_coprocessor(p15, c15, 5, c14, 1);
	case 129 :		/* Cache Debug Control */
		return read_coprocessor(p15, c15, 7, c0, 0);
	case 130 :		/* TLB Debug Control */
		return read_coprocessor(p15, c15, 7, c1, 0);
	}
	return 0;
}

void
do_write_coprocessor(unsigned int val, unsigned int func_offset)
{
	switch (func_offset) {
	case 4 :		/* Control */
		write_coprocessor(val, p15, c1, 0, c0, 0); break;
	case 5 :		/* Auxiliary Control */
		write_coprocessor(val, p15, c1, 0, c0, 1); break;
	case 6 :		/* Coprocessor Access Control */
		write_coprocessor(val, p15, c1, 0, c0, 2); break;
	case 7 :		/* Translation Table Base 0 */
		write_coprocessor(val, p15, c2, 0, c0, 0); break;
	case 8 :		/* Translation Table Base 1 */
		write_coprocessor(val, p15, c2, 0, c0, 1); break;
	case 9 :		/* Translation Table Base Control */
		write_coprocessor(val, p15, c2, 0, c0, 2); break;
	case 10 :		/* Domain Access Control */
		write_coprocessor(val, p15, c3, 0, c0, 0); break;
	case 11 :		/* Data Fault Status */
		write_coprocessor(val, p15, c5, 0, c0, 0); break;
	case 12 :		/* Instruction Fault Status */
		write_coprocessor(val, p15, c5, 0, c0, 1); break;
	case 13 :		/* Data Fault Address */
		write_coprocessor(val, p15, c6, 0, c0, 0); break;
	case 14 :		/* Watchpoint Fault Address */
		write_coprocessor(val, p15, c6, 0, c0, 1); break;
	case 15 :		/* Wait For Interrupt */
		write_coprocessor(val, p15, c7, 0, c0, 4); break;
	case 16 :		/* Invalidate Entire Instruction Cache */
		write_coprocessor(val, p15, c7, 0, c5, 0); break;
	case 17 :		/* Invalidate I-Cache, using MVA */
		write_coprocessor(val, p15, c7, 0, c5, 1); break;
	case 18 :		/* Invalidate I-Cache, using Set/Way */
		write_coprocessor(val, p15, c7, 0, c5, 2); break;
	case 19 :		/* Flush Prefetch Buffer */
		write_coprocessor(val, p15, c7, 0, c5, 4); break;
	case 20 :		/* Flush Entire Branch Target Cache */
		write_coprocessor(val, p15, c7, 0, c5, 6); break;
	case 21 :		/* Flush Branch Target Cache Entry */
		write_coprocessor(val, p15, c7, 0, c5, 7); break;
	case 22 :		/* Invalidate Entire Data Cache */
		write_coprocessor(val, p15, c7, 0, c6, 0); break;
	case 23 :		/* Invalidate D-Cache Line, using MVA */
		write_coprocessor(val, p15, c7, 0, c6, 1); break;
	case 24 :		/* Invalidate D-Cache Line, using Set/Way */
		write_coprocessor(val, p15, c7, 0, c6, 2); break;
	case 25 :		/* Invalidate Both Caches */
		write_coprocessor(val, p15, c7, 0, c7, 0); break;
	case 26 :		/* Clean Entire Data Cache */
		write_coprocessor(val, p15, c7, 0, c10, 0); break;
	case 27 :		/* Clean Data Cache Line, using MVA */
		write_coprocessor(val, p15, c7, 0, c10, 1); break;
	case 28 :		/* Clean Data Cache Line, using Set/Way */
		write_coprocessor(val, p15, c7, 0, c10, 2); break;
	case 29 :		/* Data Synchronization Barrier */
		write_coprocessor(val, p15, c7, 0, c10, 4); break;
	case 30 :		/* Data Memory Barrier */
		write_coprocessor(val, p15, c7, 0, c10, 5); break;
	case 33 :		/* Stop Prefetch Range */
		write_coprocessor(val, p15, c7, 0, c12, 5); break;
	case 34 :		/* Prefetch Instruction Cache Line */
		write_coprocessor(val, p15, c7, 0, c13, 1); break;
	case 35 :		/* Clean and Invalidate Entire Data Cache */
		write_coprocessor(val, p15, c7, 0, c14, 0); break;
	case 36 :		/* Clean and Invalidate D-Cache Line, using MVA */
		write_coprocessor(val, p15, c7, 0, c14, 1); break;
	case 37 :		/* Clean and Invalidate D-CacheLine, using Set/Way */
		write_coprocessor(val, p15, c7, 0, c14, 2); break;
	case 38 :		/* Invalidate Instruction TLB */
		write_coprocessor(val, p15, c8, 0, c5, 0); break;
	case 39 :		/* Invalidate Instruction TLB Single Entry */
		write_coprocessor(val, p15, c8, 0, c5, 1); break;
	case 40 :		/* Invalidate Instruction TLB Entry on ASID match */
		write_coprocessor(val, p15, c8, 0, c5, 2); break;
	case 41 :		/* Invalidate Data TLB */
		write_coprocessor(val, p15, c8, 0, c6, 0); break;
	case 42 :		/* Invalidate Data TLB Single Entry */
		write_coprocessor(val, p15, c8, 0, c6, 1); break;
	case 43 :		/* Invalidate Data TLB Entry on ASID match */
		write_coprocessor(val, p15, c8, 0, c6, 2); break;
	case 44 :		/* Invalidate Unified TLB */
		write_coprocessor(val, p15, c8, 0, c7, 0); break;
	case 45 :		/* Invalidate Unified TLB Single Entry */
		write_coprocessor(val, p15, c8, 0, c7, 1); break;
	case 46 :		/* Invalidate Unified TLB Entry on ASID match */
		write_coprocessor(val, p15, c8, 0, c7, 2); break;
	case 47 :		/* Data Cache Lockdown */
		write_coprocessor(val, p15, c9, 0, c0, 0); break;
	case 48 :		/* Instruction Cache Lockdown */
		write_coprocessor(val, p15, c9, 0, c0, 1); break;
	case 49 :		/* Data TCM Region */
		write_coprocessor(val, p15, c9, 0, c1, 0); break;
	case 50 :		/* Instruction TCM Region */
		write_coprocessor(val, p15, c9, 0, c1, 1); break;
	case 51 :		/* TLB Lockdown */
		write_coprocessor(val, p15, c10, 0, c0, 0); break;
	case 56 :		/* DMA User Accessibility */
		write_coprocessor(val, p15, c11, 0, c1, 0); break;
	case 57 :		/* DMA Channel Number */
		write_coprocessor(val, p15, c11, 0, c2, 0); break;
	case 58 :		/* DMA Enable (Stop) */
		write_coprocessor(val, p15, c11, 0, c3, 0); break;
	case 59 :		/* DMA Enable (Start) */
		write_coprocessor(val, p15, c11, 0, c3, 1); break;
	case 60 :		/* DMA Enable (Clear) */
		write_coprocessor(val, p15, c11, 0, c3, 2); break;
	case 61 :		/* DMA Control */
		write_coprocessor(val, p15, c11, 0, c4, 0); break;
	case 62 :		/* DMA Internal Start Address */
		write_coprocessor(val, p15, c11, 0, c5, 0); break;
	case 63 :		/* DMA External Start Address */
		write_coprocessor(val, p15, c11, 0, c6, 0); break;
	case 64 :		/* DMA Internal End Address */
		write_coprocessor(val, p15, c11, 0, c7, 0); break;
	case 66 :		/* DMA Context ID */
		write_coprocessor(val, p15, c11, 0, c15, 0); break;
	case 67 :		/* FCSE PID */
		write_coprocessor(val, p15, c13, 0, c0, 0); break;
	case 68 :		/* Context ID */
		write_coprocessor(val, p15, c13, 0, c0, 1); break;
	case 69 :		/* Data Memory Remap */
		write_coprocessor(val, p15, c15, 0, c2, 0); break;
	case 70 :		/* Instruction Memory Remap */
		write_coprocessor(val, p15, c15, 0, c2, 1); break;
	case 71 :		/* DMA Memory Remap */
		write_coprocessor(val, p15, c15, 0, c2, 2); break;
	case 72 :		/* Peripheral Port Memory Remap */
		write_coprocessor(val, p15, c15, 0, c2, 4); break;
	case 73 :		/* Performance Monitor Control */
		write_coprocessor(val, p15, c15, 0, c12, 0); break;
	case 74 :		/* Cycle Counter (CCNT) */
		write_coprocessor(val, p15, c15, 0, c12, 1); break;
	case 75 :		/* Count 0 (PMN0) */
		write_coprocessor(val, p15, c15, 0, c12, 2); break;
	case 76 :		/* Count 1 (PMN1) */
		write_coprocessor(val, p15, c15, 0, c12, 3); break;
	case 79 :		/* Data Tag RAM Read Operation */
		write_coprocessor(val, p15, c15, 3, c2, 0); break;
	case 80 :		/* Instruction Tag RAM Read Operation */
		write_coprocessor(val, p15, c15, 3, c2, 1); break;
	case 81 :		/* Instruction Cache Data RAM Read Operation */
		write_coprocessor(val, p15, c15, 3, c4, 1); break;
	case 82 :		/* Instruction Cache Master Valid0 */
		write_coprocessor(val, p15, c15, 3, c8, 0); break;
	case 83 :		/* Instruction Cache Master Valid1 */
		write_coprocessor(val, p15, c15, 3, c8, 1); break;
	case 84 :		/* Instruction Cache Master Valid2 */
		write_coprocessor(val, p15, c15, 3, c8, 2); break;
	case 85 :		/* Instruction Cache Master Valid3 */
		write_coprocessor(val, p15, c15, 3, c8, 3); break;
	case 86 :		/* Instruction Cache Master Valid4 */
		write_coprocessor(val, p15, c15, 3, c8, 4); break;
	case 87 :		/* Instruction Cache Master Valid5 */
		write_coprocessor(val, p15, c15, 3, c8, 5); break;
	case 88 :		/* Instruction Cache Master Valid6 */
		write_coprocessor(val, p15, c15, 3, c8, 6); break;
	case 89 :		/* Instruction Cache Master Valid7 */
		write_coprocessor(val, p15, c15, 3, c8, 7); break;
	case 90 :		/* Instruction SmartCache Master Valid0 */
		write_coprocessor(val, p15, c15, 3, c10, 0); break;
	case 91 :		/* Instruction SmartCache Master Valid1 */
		write_coprocessor(val, p15, c15, 3, c10, 1); break;
	case 92 :		/* Instruction SmartCache Master Valid2 */
		write_coprocessor(val, p15, c15, 3, c10, 2); break;
	case 93 :		/* Instruction SmartCache Master Valid3 */
		write_coprocessor(val, p15, c15, 3, c10, 3); break;
	case 94 :		/* Instruction SmartCache Master Valid4 */
		write_coprocessor(val, p15, c15, 3, c10, 4); break;
	case 95 :		/* Instruction SmartCache Master Valid5 */
		write_coprocessor(val, p15, c15, 3, c10, 5); break;
	case 96 :		/* Instruction SmartCache Master Valid6 */
		write_coprocessor(val, p15, c15, 3, c10, 6); break;
	case 97 :		/* Instruction SmartCache Master Valid7 */
		write_coprocessor(val, p15, c15, 3, c10, 7); break;
	case 98 :		/* Data Cache Master Valid0 */
		write_coprocessor(val, p15, c15, 3, c12, 0); break;
	case 99 :		/* Data Cache Master Valid1 */
		write_coprocessor(val, p15, c15, 3, c12, 1); break;
	case 100 :		/* Data Cache Master Valid2 */
		write_coprocessor(val, p15, c15, 3, c12, 2); break;
	case 101 :		/* Data Cache Master Valid3 */
		write_coprocessor(val, p15, c15, 3, c12, 3); break;
	case 102 :		/* Data Cache Master Valid4 */
		write_coprocessor(val, p15, c15, 3, c12, 4); break;
	case 103 :		/* Data Cache Master Valid5 */
		write_coprocessor(val, p15, c15, 3, c12, 5); break;
	case 104 :		/* Data Cache Master Valid6 */
		write_coprocessor(val, p15, c15, 3, c12, 6); break;
	case 105 :		/* Data Cache Master Valid7 */
		write_coprocessor(val, p15, c15, 3, c12, 7); break;
	case 106 :		/* Data SmartCache Master Valid0 */
		write_coprocessor(val, p15, c15, 3, c14, 0); break;
	case 107 :		/* Data SmartCache Master Valid1 */
		write_coprocessor(val, p15, c15, 3, c14, 1); break;
	case 108 :		/* Data SmartCache Master Valid2 */
		write_coprocessor(val, p15, c15, 3, c14, 2); break;
	case 109 :		/* Data SmartCache Master Valid3 */
		write_coprocessor(val, p15, c15, 3, c14, 3); break;
	case 110 :		/* Data SmartCache Master Valid4 */
		write_coprocessor(val, p15, c15, 3, c14, 4); break;
	case 111 :		/* Data SmartCache Master Valid5 */
		write_coprocessor(val, p15, c15, 3, c14, 5); break;
	case 112 :		/* Data SmartCache Master Valid6 */
		write_coprocessor(val, p15, c15, 3, c14, 6); break;
	case 113 :		/* Data SmartCache Master Valid7 */
		write_coprocessor(val, p15, c15, 3, c14, 7); break;
	case 114 :		/* Data MicroTLB Index */
		write_coprocessor(val, p15, c15, 5, c4, 0); break;
	case 115 :		/* Instruction MicroTLB Index */
		write_coprocessor(val, p15, c15, 5, c4, 1); break;
	case 116 :		/* Read Main TLB Entry */
		write_coprocessor(val, p15, c15, 5, c4, 2); break;
	case 117 :		/* Write Main TLB Entry */
		write_coprocessor(val, p15, c15, 5, c4, 4); break;
	case 120 :		/* Main TLB VA */
		write_coprocessor(val, p15, c15, 5, c5, 2); break;
	case 123 :		/* Main TLB PA */
		write_coprocessor(val, p15, c15, 5, c6, 2); break;
	case 126 :		/* Main TLB Attribute */
		write_coprocessor(val, p15, c15, 5, c7, 2); break;
	case 127 :		/* Main TLB Master Valid0 */
		write_coprocessor(val, p15, c15, 5, c14, 0); break;
	case 128 :		/* Main TLB Master Valid1 */
		write_coprocessor(val, p15, c15, 5, c14, 1); break;
	case 129 :		/* Cache Debug Control */
		write_coprocessor(val, p15, c15, 7, c0, 0); break;
	case 130 :		/* TLB Debug Control */
		write_coprocessor(val, p15, c15, 7, c1, 0); break;
	}
	return;
}

static regproc_reg_t cop15[] = {
	{.offset = 0,	.type = REG_COP_RO,	.name = "Main_ID"},
	{.offset = 1,	.type = REG_COP_RO,	.name = "Cache_Type"},
	{.offset = 2,	.type = REG_COP_RO,	.name = "TCM_Status"},
	{.offset = 3,	.type = REG_COP_RO,	.name = "TLB_Type"},
	{.offset = 4,	.type = REG_COP_RW,	.name = "Control"},
	{.offset = 5,	.type = REG_COP_RW,	.name = "Auxiliary_Control"},
	{.offset = 6,	.type = REG_COP_RW,	.name = "Coprocessor_Access_Control"},
	{.offset = 7,	.type = REG_COP_RW,	.name = "Translation_Table_Base_0"},
	{.offset = 8,	.type = REG_COP_RW,	.name = "Translation_Table_Base_1"},
	{.offset = 9,	.type = REG_COP_RW,	.name = "Translation_Table_Base_Control"},
	{.offset = 10,	.type = REG_COP_RW,	.name = "Domain_Access_Control"},
	{.offset = 11,	.type = REG_COP_RW,	.name = "Data_Fault_Status"},
	{.offset = 12,	.type = REG_COP_RW,	.name = "Instruction_Fault_Status"},
	{.offset = 13,	.type = REG_COP_RW,	.name = "Data_Fault_Address"},
	{.offset = 14,	.type = REG_COP_RW,	.name = "Watchpoint_Fault_Address"},
	{.offset = 15,	.type = REG_COP_WO,	.name = "Wait_For_Interrupt"},
	{.offset = 16,	.type = REG_COP_WO,	.name = "Invalidate_Entire_Instruction_Cache"},
	{.offset = 17,	.type = REG_COP_WO,	.name = "Invalidate_I-Cache_using_MVA"},
	{.offset = 18,	.type = REG_COP_WO,	.name = "Invalidate_I-Cache_using_SetWay"},
	{.offset = 19,	.type = REG_COP_WO,	.name = "Flush_Prefetch_Buffer"},
	{.offset = 20,	.type = REG_COP_WO,	.name = "Flush_Entire_Branch_Target_Cache"},
	{.offset = 21,	.type = REG_COP_WO,	.name = "Flush_Branch_Target_Cache_Entry"},
	{.offset = 22,	.type = REG_COP_WO,	.name = "Invalidate_Entire_Data_Cache"},
	{.offset = 23,	.type = REG_COP_WO,	.name = "Invalidate_D-Cache_Line_using_MVA"},
	{.offset = 24,	.type = REG_COP_WO,	.name = "Invalidate_D-Cache_Line_using_SetWay"},
	{.offset = 25,	.type = REG_COP_WO,	.name = "Invalidate_Both_Caches"},
	{.offset = 26,	.type = REG_COP_WO,	.name = "Clean_Entire_Data_Cache"},
	{.offset = 27,	.type = REG_COP_WO,	.name = "Clean_Data_Cache_Line_using_MVA"},
	{.offset = 28,	.type = REG_COP_WO,	.name = "Clean_Data_Cache_Line_using_SetWay"},
	{.offset = 29,	.type = REG_COP_WO,	.name = "Data_Synchronization_Barrier"},
	{.offset = 30,	.type = REG_COP_WO,	.name = "Data_Memory_Barrier"},
	{.offset = 31,	.type = REG_COP_RO,	.name = "Read_Cache_Dirty_Status_Register"},
	{.offset = 32,	.type = REG_COP_RO,	.name = "Read_Block_Transfer_Status_Register"},
	{.offset = 33,	.type = REG_COP_WO,	.name = "Stop_Prefetch_Range"},
	{.offset = 34,	.type = REG_COP_WO,	.name = "Prefetch_Instruction_Cache_Line"},
	{.offset = 35,	.type = REG_COP_WO,	.name = "Clean_and_Invalidate_Entire_Data_Cache"},
	{.offset = 36,	.type = REG_COP_WO,	.name = "Clean_and_Invalidate_D-Cache_Line_using_MVA"},
	{.offset = 37,	.type = REG_COP_WO,	.name = "Clean_and_Invalidate_D-CacheLine_using_SetWay"},
	{.offset = 38,	.type = REG_COP_WO,	.name = "Invalidate_Instruction_TLB"},
	{.offset = 39,	.type = REG_COP_WO,	.name = "Invalidate_Instruction_TLB_Single_Entry"},
	{.offset = 40,	.type = REG_COP_WO,	.name = "Invalidate_Instruction_TLB_Entry_on_ASID_match"},
	{.offset = 41,	.type = REG_COP_WO,	.name = "Invalidate_Data_TLB"},
	{.offset = 42,	.type = REG_COP_WO,	.name = "Invalidate_Data_TLB_Single_Entry"},
	{.offset = 43,	.type = REG_COP_WO,	.name = "Invalidate_Data_TLB_Entry_on_ASID_match"},
	{.offset = 44,	.type = REG_COP_WO,	.name = "Invalidate_Unified_TLB"},
	{.offset = 45,	.type = REG_COP_WO,	.name = "Invalidate_Unified_TLB_Single_Entry"},
	{.offset = 46,	.type = REG_COP_WO,	.name = "Invalidate_Unified_TLB_Entry_on_ASID_match"},
	{.offset = 47,	.type = REG_COP_RW,	.name = "Data_Cache_Lockdown"},
	{.offset = 48,	.type = REG_COP_RW,	.name = "Instruction_Cache_Lockdown"},
	{.offset = 49,	.type = REG_COP_RW,	.name = "Data_TCM_Region"},
	{.offset = 50,	.type = REG_COP_RW,	.name = "Instruction_TCM_Region"},
	{.offset = 51,	.type = REG_COP_RW,	.name = "TLB_Lockdown"},
	{.offset = 52,	.type = REG_COP_RO,	.name = "DMA_Ident_and_Status_(Present)"},
	{.offset = 53,	.type = REG_COP_RO,	.name = "DMA_Ident_and_Status_(Queued)"},
	{.offset = 54,	.type = REG_COP_RO,	.name = "DMA_Ident_and_Status_(Running)"},
	{.offset = 55,	.type = REG_COP_RO,	.name = "DMA_Ident_and_Status_(Interrupting)"},
	{.offset = 56,	.type = REG_COP_RW,	.name = "DMA_User_Accessibility"},
	{.offset = 57,	.type = REG_COP_RW,	.name = "DMA_Channel_Number"},
	{.offset = 58,	.type = REG_COP_WO,	.name = "DMA_Enable_(Stop)"},
	{.offset = 59,	.type = REG_COP_WO,	.name = "DMA_Enable_(Start)"},
	{.offset = 60,	.type = REG_COP_WO,	.name = "DMA_Enable_(Clear)"},
	{.offset = 61,	.type = REG_COP_RW,	.name = "DMA_Control"},
	{.offset = 62,	.type = REG_COP_RW,	.name = "DMA_Internal_Start_Address"},
	{.offset = 63,	.type = REG_COP_RW,	.name = "DMA_External_Start_Address"},
	{.offset = 64,	.type = REG_COP_RW,	.name = "DMA_Internal_End_Address"},
	{.offset = 65,	.type = REG_COP_RO,	.name = "DMA_Channel_Status"},
	{.offset = 66,	.type = REG_COP_RW,	.name = "DMA_Context_ID"},
	{.offset = 67,	.type = REG_COP_RW,	.name = "FCSE_PID"},
	{.offset = 68,	.type = REG_COP_RW,	.name = "Context_ID"},
	{.offset = 69,	.type = REG_COP_RW,	.name = "Data_Memory_Remap"},
	{.offset = 70,	.type = REG_COP_RW,	.name = "Instruction_Memory_Remap"},
	{.offset = 71,	.type = REG_COP_RW,	.name = "DMA_Memory_Remap"},
	{.offset = 72,	.type = REG_COP_RW,	.name = "Peripheral_Port_Memory_Remap"},
	{.offset = 73,	.type = REG_COP_RW,	.name = "Performance_Monitor_Control"},
	{.offset = 74,	.type = REG_COP_RW,	.name = "Cycle_Counter_(CCNT)"},
	{.offset = 75,	.type = REG_COP_RW,	.name = "Count_0_(PMN0)"},
	{.offset = 76,	.type = REG_COP_RW,	.name = "Count_1_(PMN1)"},
	{.offset = 77,	.type = REG_COP_RO,	.name = "Data_Debug_Cache"},
	{.offset = 78,	.type = REG_COP_RO,	.name = "Instruction_Debug_Cache"},
	{.offset = 79,	.type = REG_COP_WO,	.name = "Data_Tag_RAM_Read_Operation"},
	{.offset = 80,	.type = REG_COP_WO,	.name = "Instruction_Tag_RAM_Read_Operation"},
	{.offset = 81,	.type = REG_COP_WO,	.name = "Instruction_Cache_Data_RAM_Read_Operation"},
	{.offset = 82,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid0"},
	{.offset = 83,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid1"},
	{.offset = 84,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid2"},
	{.offset = 85,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid3"},
	{.offset = 86,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid4"},
	{.offset = 87,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid5"},
	{.offset = 88,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid6"},
	{.offset = 89,	.type = REG_COP_RW,	.name = "Instruction_Cache_Master_Valid7"},
	{.offset = 90,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid0"},
	{.offset = 91,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid1"},
	{.offset = 92,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid2"},
	{.offset = 93,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid3"},
	{.offset = 94,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid4"},
	{.offset = 95,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid5"},
	{.offset = 96,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid6"},
	{.offset = 97,	.type = REG_COP_RW,	.name = "Instruction_SmartCache_Master_Valid7"},
	{.offset = 98,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid0"},
	{.offset = 99,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid1"},
	{.offset = 100,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid2"},
	{.offset = 101,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid3"},
	{.offset = 102,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid4"},
	{.offset = 103,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid5"},
	{.offset = 104,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid6"},
	{.offset = 105,	.type = REG_COP_RW,	.name = "Data_Cache_Master_Valid7"},
	{.offset = 106,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid0"},
	{.offset = 107,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid1"},
	{.offset = 108,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid2"},
	{.offset = 109,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid3"},
	{.offset = 110,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid4"},
	{.offset = 111,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid5"},
	{.offset = 112,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid6"},
	{.offset = 113,	.type = REG_COP_RW,	.name = "Data_SmartCache_Master_Valid7"},
	{.offset = 114,	.type = REG_COP_RW,	.name = "Data_MicroTLB_Index"},
	{.offset = 115,	.type = REG_COP_RW,	.name = "Instruction_MicroTLB_Index"},
	{.offset = 116,	.type = REG_COP_WO,	.name = "Read_Main_TLB_Entry"},
	{.offset = 117,	.type = REG_COP_WO,	.name = "Write_Main_TLB_Entry"},
	{.offset = 118,	.type = REG_COP_RO,	.name = "Data_MicroTLB_VA"},
	{.offset = 119,	.type = REG_COP_RO,	.name = "Instruction_MicroTLB_VA"},
	{.offset = 120,	.type = REG_COP_RW,	.name = "Main_TLB_VA"},
	{.offset = 121,	.type = REG_COP_RO,	.name = "Data_MicroTLB_PA"},
	{.offset = 122,	.type = REG_COP_RO,	.name = "Instruction_MicroTLB_PA"},
	{.offset = 123,	.type = REG_COP_RW,	.name = "Main_TLB_PA"},
	{.offset = 124,	.type = REG_COP_RO,	.name = "Data_MicroTLB_Attribute"},
	{.offset = 125,	.type = REG_COP_RO,	.name = "Instruction_MicroTLB_Attribute"},
	{.offset = 126,	.type = REG_COP_RW,	.name = "Main_TLB_Attribute"},
	{.offset = 127,	.type = REG_COP_RW,	.name = "Main_TLB_Master_Valid0"},
	{.offset = 128,	.type = REG_COP_RW,	.name = "Main_TLB_Master_Valid1"},
	{.offset = 129,	.type = REG_COP_RW,	.name = "Cache_Debug_Control"},
	{.offset = 130,	.type = REG_COP_RW,	.name = "TLB_Debug_Control"},
	{NULL}
};

#define CPU_COPROCESSOR_MODULES				\
	{.name = "cp15",	.regs = cop15},
