1 /* $NetBSD: arm_pxa2x0.cpp,v 1.1 2008/03/08 02:26:03 rafal Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <arm/arm_arch.h> 40 #include <console.h> 41 #include <memory.h> 42 #include <arm/arm_pxa2x0.h> 43 44 /* 45 * Intel XScale PXA 2x0 46 */ 47 48 #define PAGE_SIZE 0x1000 49 #define DRAM_BANK_NUM 4 /* total 256MByte */ 50 #define DRAM_BANK_SIZE 0x04000000 /* 64Mbyte */ 51 52 #define DRAM_BANK0_START 0xa0000000 53 #define DRAM_BANK0_SIZE DRAM_BANK_SIZE 54 #define DRAM_BANK1_START 0xa4000000 55 #define DRAM_BANK1_SIZE DRAM_BANK_SIZE 56 #define DRAM_BANK2_START 0xa8000000 57 #define DRAM_BANK2_SIZE DRAM_BANK_SIZE 58 #define DRAM_BANK3_START 0xac000000 59 #define DRAM_BANK3_SIZE DRAM_BANK_SIZE 60 #define ZERO_BANK_START 0xe0000000 61 #define ZERO_BANK_SIZE DRAM_BANK_SIZE 62 63 __BEGIN_DECLS 64 65 // 2nd bootloader 66 void boot_func(kaddr_t, kaddr_t, kaddr_t, kaddr_t); 67 extern char boot_func_end[]; 68 #define BOOT_FUNC_START reinterpret_cast <vaddr_t>(boot_func) 69 #define BOOT_FUNC_END reinterpret_cast <vaddr_t>(boot_func_end) 70 71 /* jump to 2nd loader */ 72 void FlatJump(kaddr_t, kaddr_t, kaddr_t, kaddr_t); 73 74 __END_DECLS 75 76 PXA2X0Architecture::PXA2X0Architecture(Console *&cons, MemoryManager *&mem) 77 : ARMArchitecture(cons, mem) 78 { 79 DPRINTF((TEXT("PXA-2x0 CPU.\n"))); 80 } 81 82 PXA2X0Architecture::~PXA2X0Architecture(void) 83 { 84 } 85 86 BOOL 87 PXA2X0Architecture::init(void) 88 { 89 if (!_mem->init()) { 90 DPRINTF((TEXT("can't initialize memory manager.\n"))); 91 return FALSE; 92 } 93 // set D-RAM information 94 _mem->loadBank(DRAM_BANK0_START, DRAM_BANK_SIZE); 95 _mem->loadBank(DRAM_BANK1_START, DRAM_BANK_SIZE); 96 _mem->loadBank(DRAM_BANK2_START, DRAM_BANK_SIZE); 97 _mem->loadBank(DRAM_BANK3_START, DRAM_BANK_SIZE); 98 99 #ifdef HW_TEST 100 DPRINTF((TEXT("Testing framebuffer.\n"))); 101 testFramebuffer(); 102 103 DPRINTF((TEXT("Testing UART.\n"))); 104 testUART(); 105 #endif 106 107 return TRUE; 108 } 109 110 void 111 PXA2X0Architecture::testFramebuffer(void) 112 { 113 DPRINTF((TEXT("No framebuffer test yet.\n"))); 114 } 115 116 void 117 PXA2X0Architecture::testUART(void) 118 { 119 #define COM_DATA VOLATILE_REF8(uart + 0x00) 120 #define COM_IIR VOLATILE_REF8(uart + 0x08) 121 #define COM_LSR VOLATILE_REF8(uart + 0x14) 122 #define LSR_TXRDY 0x20 123 #define COM_TX_CHECK while (!(COM_LSR & LSR_TXRDY)) 124 #define COM_PUTCHAR(c) (COM_DATA = (c)) 125 #define COM_CLR_INTS ((void)COM_IIR) 126 #define _(c) \ 127 __BEGIN_MACRO \ 128 COM_TX_CHECK; \ 129 COM_PUTCHAR(c); \ 130 COM_TX_CHECK; \ 131 COM_CLR_INTS; \ 132 __END_MACRO 133 134 vaddr_t uart = 135 _mem->mapPhysicalPage(0x40100000, 0x100, PAGE_READWRITE); 136 137 // Don't turn on the enable-UART bit in the IER; this seems to 138 // result in WinCE losing the port (and nothing working later). 139 // All that should be taken care of by using WinCE to open the 140 // port before we actually use it. 141 142 _('H');_('e');_('l');_('l');_('o');_(' '); 143 _('W');_('o');_('r');_('l');_('d');_('\r');_('\n'); 144 145 _mem->unmapPhysicalPage(uart); 146 } 147 148 BOOL 149 PXA2X0Architecture::setupLoader(void) 150 { 151 vaddr_t v; 152 vsize_t sz = BOOT_FUNC_END - BOOT_FUNC_START; 153 154 // check 2nd bootloader size. 155 if (sz > _mem->getPageSize()) { 156 DPRINTF((TEXT("2nd bootloader size(%dbyte) is larger than page size(%d).\n"), 157 sz, _mem->getPageSize())); 158 return FALSE; 159 } 160 161 // get physical mapped page and copy loader to there. 162 // don't writeback D-cache here. make sure to writeback before jump. 163 if (!_mem->getPage(v , _loader_addr)) { 164 DPRINTF((TEXT("can't get page for 2nd loader.\n"))); 165 return FALSE; 166 } 167 DPRINTF((TEXT("2nd bootloader vaddr=0x%08x paddr=0x%08x\n"), 168 (unsigned)v,(unsigned)_loader_addr)); 169 170 memcpy(reinterpret_cast <LPVOID>(v), 171 reinterpret_cast <LPVOID>(BOOT_FUNC_START), sz); 172 DPRINTF((TEXT("2nd bootloader copy done.\n"))); 173 174 return TRUE; 175 } 176 177 void 178 PXA2X0Architecture::jump(paddr_t info, paddr_t pvec) 179 { 180 kaddr_t sp; 181 vaddr_t v; 182 paddr_t p; 183 184 // stack for bootloader 185 _mem->getPage(v, p); 186 sp = ptokv(p) + _mem->getPageSize(); 187 DPRINTF((TEXT("sp for bootloader = %08x + %08x = %08x\n"), 188 ptokv(p), _mem->getPageSize(), sp)); 189 190 // writeback whole D-cache 191 WritebackDCache(); 192 193 SetKMode(1); 194 FlatJump(info, pvec, sp, _loader_addr); 195 // NOTREACHED 196 } 197