/* $NetBSD: memcreg.h,v 1.4 2012/05/11 15:39:17 skrll Exp $ */ /*- * Copyright (c) 1997, 1998 Ben Harris * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. */ /* * memcreg.h - Acorn/ARM MEMC (Anna/VC2304/VL2304/MEMC1A/VL2304A/VL86C110/VY86C110) * registers */ #ifndef _ARM26_MEMCREG_H #define _ARM26_MEMCREG_H /* * Accessing the MEMC is a little odd. It's not connected to the data * bus, so the register and the new value are coded into an address. * Thus, to set a register, OR together the register specifier and the * new value, and write any word to the resultant address. */ #define MEMC_WRITE(value) *(volatile uint32_t *)value = 0 /* * This information is mostly derived from: * MEMC Datasheet * Published by Acorn Computers Limited. * Part no 0460,019 * Issue No 1.0 * 30 September 1986 * ISBN 1 85250 025 6 * * Thanks must go to Jeanette Draper at ARM Ltd * for finding it for me. * * Information on master/slave MEMCs came from Tony Duell * , who has a copy of the MEMC1A data * sheet and might photocopy it for me one day. */ /* General memory-map layout provided by MEMC */ #define MEMC_PHYS_BASE ((void *)0x02000000) #define MEMC_IO_BASE ((void *)0x03000000) #define MEMC_VIDC_BASE ((void *)0x03400000) #define MEMC_ROM_LOW_BASE ((void *)0x03400000) #define MEMC_ROM_HIGH_BASE ((void *)0x03800000) /* * Each MEMC can manage 4Mb in 128 pages. The memory map only has * space for 16Mb of physical RAM. */ #define MEMC_MAX_PHYSPAGES 512 /* * DMA address generator control registers. Addresses (>>4) go in * bits 2-16, and must thus be in the bottom 512k of physical RAM. */ #define MEMC_DMA_MAX 0x00080000 /* Video */ #define MEMC_VINIT 0x03600000 #define MEMC_VSTART 0x03620000 #define MEMC_VEND 0x03640000 /* Cursor */ #define MEMC_CINIT 0x03660000 /* Sound */ #define MEMC_SSTARTN 0x03680000 #define MEMC_SENDN 0x036A0000 #define MEMC_SPTR 0x036C0000 #define MEMC_SET_PTR(reg,addr) (reg | (addr >> 2)) /* MEMC control register (sec 6.5) */ #define MEMC_CONTROL 0x036E0000 /* Page size */ #define MEMC_CTL_PGSZ_MASK 0x0000000C #define MEMC_CTL_PGSZ_4K 0x00000000 #define MEMC_CTL_PGSZ_8K 0x00000004 #define MEMC_CTL_PGSZ_16K 0x00000008 #define MEMC_CTL_PGSZ_32K 0x0000000C /* ROM speeds; low and high banks, relative to RAM speed */ #define MEMC_CTL_LROMSPD_MASK 0x00000030 #define MEMC_CTL_LROMSPD_4N 0x00000000 #define MEMC_CTL_LROMSPD_3N 0x00000010 #define MEMC_CTL_LROMSPD_2N 0x00000020 #define MEMC_CTL_LROMSPD_PAGED 0x00000030 #define MEMC_CTL_HROMSPD_MASK 0x000000C0 #define MEMC_CTL_HROMSPD_4N 0x00000000 #define MEMC_CTL_HROMSPD_3N 0x00000040 #define MEMC_CTL_HROMSPD_2N 0x00000080 #define MEMC_CTL_HROMSPD_PAGED 0x000000C0 /* DRAM refresh control */ #define MEMC_CTL_RFRSH_MASK 0x00000300 #define MEMC_CTL_RFRSH_NONE 0x00000000 #define MEMC_CTL_RFRSH_FLYBACK 0x00000100 #define MEMC_CTL_RFRSH_CONTIN 0x00000300 /* Enable video DMA */ #define MEMC_CTL_VIDEODMA 0x00000400 /* Enable sound DMA */ #define MEMC_CTL_SOUNDDMA 0x00000800 /* Operating System Mode Select */ #define MEMC_CTL_OSMODE 0x00001000 /* Test mode */ /* This should never be set in a running system */ #define MEMC_CTL_TESTMODE 0x00002000 /* * Address translation control */ /* Absolute address of translation table */ #define MEMC_TRANS_BASE 0x03800000 /* * MEMC translation entries are painful, and vary with the page size * in use. Here, ppn is the physical page number, lpn is the logical * page number and ppl is the page protection level. * * The list of transformations at the start of each macro is copied * verbatim from the MEMC datasheet (Figure 5) with the exception of * the entries for PPN[7] and PPN[8]. In dual-MEMC situations, PPN[7] * selects between master and slave MEMCs, and is mapped to A[7] whatever * the page size (though Acorn machines always use 32k pages with dual * MEMCs). The Archimedes 540 can have up to 16Mb of RAM, and arranges * this by having several address lines go through PALs on their way to the * MEMCs. The upshot of this is that for the purposes of setting the * translation tables, PPN[8] maps to A[12]. The A540 always has 32kb pages. */ /* Page protection levels (data sheet section 6.6) */ /*- * PPL * Mode 00 01 10 11 * SVC R/W R/W R/W R/W * OS R/W R/W R R * User R/W R - - */ #define MEMC_PPL_RDWR 0 #define MEMC_PPL_RDONLY 1 #define MEMC_PPL_NOACCESS 2 /*- * 4k pages: * PPN[7] -> A[7] (MEMC1a) * PPN[6:0] -> A[6:0] * PPL[1:0] -> A[9:8] * LPN[12:11] -> A[11:10] * LPN[10:0] -> A[22:12] */ #define MEMC_TRANS_ENTRY_4K(ppn, lpn, ppl) \ (MEMC_TRANS_BASE | \ ((ppn) & 0xff) | \ ((ppl) & 0x3) << 8 | \ ((lpn) & 0x7ff) << 12 | \ ((lpn) & 0x1800) >> 1) /*- * 8k pages: * PPN[7] -> A[7] (MEMC1a) * PPN[6] -> A[0] * PPN[5:0] -> A[6:1] * PPL[1:0] -> A[9:8] * LPN[11:10] -> A[11:10] * LPN[9:0] -> A[22:13] */ #define MEMC_TRANS_ENTRY_8K(ppn, lpn, ppl) \ (MEMC_TRANS_BASE | \ ((ppn) & 0x80) | \ ((ppn) & 0x40) >> 6 | \ ((ppn) & 0x3f) << 1 | \ ((ppl) & 0x3) << 8 | \ ((lpn) & 0xc00)) | \ ((lpn) & 0x3ff) << 13) /*- * 16k pages: * PPN[7] -> A[7] (MEMC1a) * PPN[6:5] -> A[1:0] * PPN[4:0] -> A[6:2] * PPL[1:0] -> A[9:8] * LPN[10:9] -> A[11:10] * LPN[9:0] -> A[22:14] */ #define MEMC_TRANS_ENTRY_16K(ppn, lpn, ppl) \ (MEMC_TRANS_BASE | \ ((ppn) & 0x80) | \ ((ppn) & 0x60) >> 5 | \ ((ppn) & 0x1f) << 2 | \ ((ppl) & 0x3) << 8 | \ ((lpn) & 0x600) << 1 | \ ((lpn) & 0x1ff) << 14) /*- * 32k pages (here, the MEMC descends into madness...): * PPN[8] -> A[12] (A540) * PPN[7] -> A[7] (MEMC1a) * PPN[6] -> A[1] * PPN[5] -> A[2] * PPN[4] -> A[0] * PPN[3:0] -> A[6:3] * PPL[1:0] -> A[9:8] * LPN[9:8] -> A[11:10] * LPN[7:0] -> A[22:15] */ #define MEMC_TRANS_ENTRY_32K(ppn, lpn, ppl) \ (MEMC_TRANS_BASE | \ ((ppn) & 0x100) << 4 | \ ((ppn) & 0x80) | \ ((ppn) & 0x40) >> 5 | \ ((ppn) & 0x20) >> 3 | \ ((ppn) & 0x10) >> 4 | \ ((ppn) & 0x0f) << 3 | \ ((ppl) & 0x3) << 8 | \ ((lpn) & 0x300) << 2 | \ ((lpn) & 0x0ff) << 15) #endif