If you received this File from Marvell, you may opt to use, redistribute and/or
modify this File under the following licensing terms.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of Marvell nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
/*
* Address to call from cpu_reset() to reset the machine.
* This is machine architecture dependent as it varies depending
* on where the ROM appears when you turn the MMU off.
*/
/*
* Put some bogus settings of the MEMSTART and MEMSIZE
* if they are not defined in kernel configuration file.
*/
#ifndef MEMSTART
#define MEMSTART 0x00000000UL
#endif
#ifndef MEMSIZE
#define MEMSIZE 0x40000000UL
#endif
/*
* Static device mappings. These peripheral registers are mapped at
* fixed virtual addresses very early in initarm() so that we can use
* them while booting the kernel, and stay at the same address
* throughout whole kernel's life time.
*
* We use this table twice; once with bootstrap page table, and once
* with kernel's page table which we build up in initarm().
*
* Since we map these registers into the bootstrap page table using
* pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
* registers segment-aligned and segment-rounded in order to avoid
* using the 2nd page tables.
*/
static int
axp_pcie_free_win(void)
{
/* Find first disabled window */
for (size_t i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
MVSOC_MLMB_WCR_WINEN) == 0) {
return i;
}
}
/* If there is no free window, return erroneous value */
return (-1);
}
/* Reset PCI-Express space to window register. */
window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
/* Find free window if we've got spurious one */
if (window >= nwindow) {
window = axp_pcie_free_win();
/* Just break if there is no free windows left */
if (window < 0) {
aprint_error(": no free windows for PEX MEM\n");
break;
}
}
write_mlmbreg(MVSOC_MLMB_WCR(window),
MVSOC_MLMB_WCR_WINEN |
MVSOC_MLMB_WCR_TARGET(target) |
MVSOC_MLMB_WCR_ATTR(attr) |
MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
write_mlmbreg(MVSOC_MLMB_WBR(window),
membase & MVSOC_MLMB_WBR_BASE_MASK);
#ifdef PCI_NETBSD_CONFIGURE
if (window < nremap) {
write_mlmbreg(MVSOC_MLMB_WRLR(window),
membase & MVSOC_MLMB_WRLR_REMAP_MASK);
write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
}
#endif
window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
/* Find free window if we've got spurious one */
if (window >= nwindow) {
window = axp_pcie_free_win();
/* Just break if there is no free windows left */
if (window < 0) {
aprint_error(": no free windows for PEX I/O\n");
break;
}
}
write_mlmbreg(MVSOC_MLMB_WCR(window),
MVSOC_MLMB_WCR_WINEN |
MVSOC_MLMB_WCR_TARGET(target) |
MVSOC_MLMB_WCR_ATTR(attr) |
MVSOC_MLMB_WCR_SIZE(MARVELL_PEXIO_SIZE));
write_mlmbreg(MVSOC_MLMB_WBR(window),
iobase & MVSOC_MLMB_WBR_BASE_MASK);
#ifdef PCI_NETBSD_CONFIGURE
if (window < nremap) {
write_mlmbreg(MVSOC_MLMB_WRLR(window),
iobase & MVSOC_MLMB_WRLR_REMAP_MASK);
write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
}
#endif
membase += MARVELL_PEXMEM_SIZE;
iobase += MARVELL_PEXIO_SIZE;
}
}
/*
* vaddr_t initarm(...)
*
* Initial entry point on startup. This gets called before main() is
* entered.
* It should be responsible for setting up everything that must be
* in place when main is called.
* This includes
* Taking a copy of the boot configuration structure.
* Initialising the physical console so characters can be printed.
* Setting up page tables for the kernel
* Relocating the kernel to the bottom of physical memory
*/
vaddr_t
initarm(void *arg)
{
cpu_reset_address = axp_system_reset;
mvsoc_bootstrap(MARVELL_INTERREGS_VBASE);
/* Set CPU functions */
if (set_cpufuncs())
panic("cpu not recognized!");
/*
* Map devices into the initial page table
* in order to use early console during initialization process.
* consinit is going to use this mapping.
*/
pmap_devmap_bootstrap((vaddr_t)read_ttb(), devmap);
/* Initialize system console */
consinit();
/* Reset PCI-Express space to window register. */
reset_axp_pcie_win();
/* Get CPU, system and timebase frequencies */
armadaxp_bootstrap(
MARVELL_INTERREGS_VBASE,
MARVELL_INTERREGS_PBASE);
#ifdef KGDB
kgdb_port_init();
#endif
#ifdef VERBOSE_INIT_ARM
/* Talk to the user */
#define BDSTR(s) _BDSTR(s)
#define _BDSTR(s) #s
printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
#endif
if (mvuart_cnattach(&mvsoc_bs_tag, comcnaddr, comcnspeed,
comcnfreq ? comcnfreq : mvTclk , comcnmode))
panic("Serial console can not be initialized.");
#endif
}
#ifdef KGDB
#ifndef KGDB_DEVADDR
#error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
#endif
#ifndef KGDB_DEVRATE
#define KGDB_DEVRATE B115200
#endif
#define MVUART_SIZE 0x20
void
static kgdb_port_init(void)
{
static int kgdbsinit_called = 0;
if (kgdbsinit_called != 0)
return;
kgdbsinit_called = 1;
if (com_kgdb_attach(&mvsoc_bs_tag, comkgdbaddr, comkgdbspeed,
MVUART_SIZE, COM_TYPE_16550_NOERS, comkgdbmode))
panic("KGDB uart can not be initialized.");
}
#endif