19d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/* 29d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * OpenRISC setup.c 39d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 49d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Linux architectural port borrowing liberally from similar works of 59d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * others. All original copyrights apply as per the original source 69d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * declaration. 79d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 89d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Modifications for the OpenRISC architecture: 99d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> 109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> 119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * This program is free software; you can redistribute it and/or 139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * modify it under the terms of the GNU General Public License 149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * as published by the Free Software Foundation; either version 159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 2 of the License, or (at your option) any later version. 169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * This file handles the architecture-dependent parts of initialization 189d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */ 199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/errno.h> 219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/sched.h> 229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/kernel.h> 239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/mm.h> 249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/stddef.h> 259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/unistd.h> 269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/ptrace.h> 279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/slab.h> 289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/tty.h> 299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/ioport.h> 309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/delay.h> 319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/console.h> 329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/init.h> 339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/bootmem.h> 349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/seq_file.h> 359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/serial.h> 369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/initrd.h> 379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of_fdt.h> 389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of.h> 399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/memblock.h> 409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/device.h> 419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of_platform.h> 429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 43be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven#include <asm/sections.h> 449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/segment.h> 459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/pgtable.h> 469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/types.h> 479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/setup.h> 489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/io.h> 499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/cpuinfo.h> 509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/delay.h> 519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include "vmlinux.h" 539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic unsigned long __init setup_memory(void) 559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long bootmap_size; 579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long ram_start_pfn; 589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long free_ram_start_pfn; 599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long ram_end_pfn; 609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn phys_addr_t memory_start, memory_end; 619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn struct memblock_region *region; 629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn memory_end = memory_start = 0; 649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* Find main memory where is the kernel */ 669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn for_each_memblock(memory, region) { 679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn memory_start = region->base; 689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn memory_end = region->base + region->size; 699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__, 709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn memory_start, memory_end); 719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (!memory_end) { 749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn panic("No memory!"); 759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn ram_start_pfn = PFN_UP(memory_start); 789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* free_ram_start_pfn is first page after kernel */ 79be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven free_ram_start_pfn = PFN_UP(__pa(_end)); 809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM()); 819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn max_pfn = ram_end_pfn; 839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* 859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * initialize the boot-time allocator (with low memory only). 869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 879d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * This makes the memory from the end of the kernel to the end of 889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * RAM usable. 899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * init_bootmem sets the global values min_low_pfn, max_low_pfn. 909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */ 919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn bootmap_size = init_bootmem(free_ram_start_pfn, 929d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn ram_end_pfn - ram_start_pfn); 939d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn free_bootmem(PFN_PHYS(free_ram_start_pfn), 949d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT); 959d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size, 969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn BOOTMEM_DEFAULT); 979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn for_each_memblock(reserved, region) { 999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n", 1009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn (u32) region->base, (u32) region->size); 1019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT); 1029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 1039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return ram_end_pfn; 1059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 1069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstruct cpuinfo cpuinfo; 1089d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void print_cpuinfo(void) 1109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 1119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long upr = mfspr(SPR_UPR); 1129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long vr = mfspr(SPR_VR); 1139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned int version; 1149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned int revision; 1159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn version = (vr & SPR_VR_VER) >> 24; 1179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn revision = (vr & SPR_VR_REV); 1189d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "CPU: OpenRISC-%x (revision %d) @%d MHz\n", 1209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn version, revision, cpuinfo.clock_frequency / 1000000); 1219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (!(upr & SPR_UPR_UP)) { 1239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO 1249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "-- no UPR register... unable to detect configuration\n"); 1259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return; 1269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 1279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_DCP) 1299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO 1309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "-- dcache: %4d bytes total, %2d bytes/line, %d way(s)\n", 1319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.dcache_size, cpuinfo.dcache_block_size, 1); 1329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn else 1339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- dcache disabled\n"); 1349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_ICP) 1359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO 1369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "-- icache: %4d bytes total, %2d bytes/line, %d way(s)\n", 1379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.icache_size, cpuinfo.icache_block_size, 1); 1389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn else 1399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- icache disabled\n"); 1409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_DMP) 1429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n", 1439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), 1449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW)); 1459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_IMP) 1469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- immu: %4d entries, %lu way(s)\n", 1479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2), 1489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW)); 1499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- additional features:\n"); 1519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_DUP) 1529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- debug unit\n"); 1539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_PCUP) 1549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- performance counters\n"); 1559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_PMP) 1569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- power management\n"); 1579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_PICP) 1589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- PIC\n"); 1599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_TTP) 1609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- timer\n"); 1619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & SPR_UPR_CUP) 1629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "-- custom unit(s)\n"); 1639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 1649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init setup_cpuinfo(void) 1669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 1679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn struct device_node *cpu; 1689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long iccfgr, dccfgr; 1699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long cache_set_size, cache_ways; 1709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481"); 1729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (!cpu) 1739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn panic("No compatible CPU found in device tree...\n"); 1749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn iccfgr = mfspr(SPR_ICCFGR); 1769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW); 1779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); 1789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7); 1799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.icache_size = 1809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_set_size * cache_ways * cpuinfo.icache_block_size; 1819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn dccfgr = mfspr(SPR_DCCFGR); 1839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW); 1849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); 1859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7); 1869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.dcache_size = 1879d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cache_set_size * cache_ways * cpuinfo.dcache_block_size; 1889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (of_property_read_u32(cpu, "clock-frequency", 1909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn &cpuinfo.clock_frequency)) { 1919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_WARNING 1929d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "Device tree missing CPU 'clock-frequency' parameter." 1939d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "Assuming frequency 25MHZ" 1949d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "This is probably not what you want."); 1959d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 1969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn of_node_put(cpu); 1989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn print_cpuinfo(); 2009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/** 2039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * or32_early_setup 2049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 2059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Handles the pointer to the device tree that this kernel is to use 2069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * for establishing the available platform devices. 2079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 208dec830189e1e192a80f574243a2dc31bdc1c4fc5Stefan Kristiansson * Falls back on built-in device tree in case null pointer is passed. 2099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */ 2109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 211621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoevenvoid __init or32_early_setup(void *fdt) 2129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 213621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven if (fdt) 214621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven pr_info("FDT at %p\n", fdt); 215621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven else { 216621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven fdt = __dtb_start; 217621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven pr_info("Compiled-in FDT at %p\n", fdt); 218dec830189e1e192a80f574243a2dc31bdc1c4fc5Stefan Kristiansson } 219621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven early_init_devtree(fdt); 2209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic int __init openrisc_device_probe(void) 2239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn of_platform_populate(NULL, NULL, NULL, NULL); 2259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return 0; 2279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonndevice_initcall(openrisc_device_probe); 2309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic inline unsigned long extract_value_bits(unsigned long reg, 2329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn short bit_nr, short width) 2339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return (reg >> bit_nr) & (0 << width); 2359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic inline unsigned long extract_value(unsigned long reg, unsigned long mask) 2389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn while (!(mask & 0x1)) { 2409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn reg = reg >> 1; 2419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn mask = mask >> 1; 2429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 2439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return mask & reg; 2449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init detect_unit_config(unsigned long upr, unsigned long mask, 2479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn char *text, void (*func) (void)) 2489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (text != NULL) 2509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk("%s", text); 2519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (upr & mask) { 2539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (func != NULL) 2549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn func(); 2559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn else 2569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk("present\n"); 2579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } else 2589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk("not present\n"); 2599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/* 2629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * calibrate_delay 2639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 2649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Lightweight calibrate_delay implementation that calculates loops_per_jiffy 2659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * from the clock frequency passed in via the device tree 2669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * 2679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */ 2689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2698e8550ef01676829f4d4b175a1ce4fee30f7a778Paul Gortmakervoid calibrate_delay(void) 2709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn const int *val; 2729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn struct device_node *cpu = NULL; 2739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481"); 2749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn val = of_get_property(cpu, "clock-frequency", NULL); 2759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (!val) 2769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn panic("no cpu 'clock-frequency' parameter in device tree"); 2779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn loops_per_jiffy = *val / HZ; 2789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", 2799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn loops_per_jiffy / (500000 / HZ), 2809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy); 2819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 2829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init setup_arch(char **cmdline_p) 2849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 2859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long max_low_pfn; 2869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2873486892f998fea5b4f1a0a4d093f09b7d0024696Rob Herring unflatten_and_copy_device_tree(); 2889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn setup_cpuinfo(); 2909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* process 1's initial memory region is the kernel code/data */ 292be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven init_mm.start_code = (unsigned long)_stext; 293be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven init_mm.end_code = (unsigned long)_etext; 294be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven init_mm.end_data = (unsigned long)_edata; 295be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven init_mm.brk = (unsigned long)_end; 2969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 2979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#ifdef CONFIG_BLK_DEV_INITRD 2989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn initrd_start = (unsigned long)&__initrd_start; 2999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn initrd_end = (unsigned long)&__initrd_end; 3009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (initrd_start == initrd_end) { 3019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn initrd_start = 0; 3029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn initrd_end = 0; 3039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn } 3049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn initrd_below_start_ok = 1; 3059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#endif 3069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* setup bootmem allocator */ 3089d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn max_low_pfn = setup_memory(); 3099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* paging_init() sets up the MMU and marks all pages as reserved */ 3119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn paging_init(); 3129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) 3149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn if (!conswitchp) 3159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn conswitchp = &dummy_con; 3169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#endif 3179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 318bbf28b505ac2dd923b9051ca5031cf87bf7c40ccRob Herring *cmdline_p = boot_command_line; 3199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn printk(KERN_INFO "OpenRISC Linux -- http://openrisc.net\n"); 3219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 3229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic int show_cpuinfo(struct seq_file *m, void *v) 3249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 3259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn unsigned long vr; 3269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn int version, revision; 3279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn vr = mfspr(SPR_VR); 3299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn version = (vr & SPR_VR_VER) >> 24; 3309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn revision = vr & SPR_VR_REV; 3319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return seq_printf(m, 3339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "cpu\t\t: OpenRISC-%x\n" 3349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "revision\t: %d\n" 3359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "frequency\t: %ld\n" 3369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "dcache size\t: %d bytes\n" 3379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "dcache block size\t: %d bytes\n" 3389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "icache size\t: %d bytes\n" 3399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "icache block size\t: %d bytes\n" 3409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "immu\t\t: %d entries, %lu ways\n" 3419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "dmmu\t\t: %d entries, %lu ways\n" 3429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn "bogomips\t: %lu.%02lu\n", 3439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn version, 3449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn revision, 3459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn loops_per_jiffy * HZ, 3469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.dcache_size, 3479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.dcache_block_size, 3489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.icache_size, 3499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn cpuinfo.icache_block_size, 3509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2), 3519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW), 3529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2), 3539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW), 3549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn (loops_per_jiffy * HZ) / 500000, 3559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn ((loops_per_jiffy * HZ) / 5000) % 100); 3569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 3579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void *c_start(struct seq_file *m, loff_t * pos) 3599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 3609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn /* We only have one CPU... */ 3619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return *pos < 1 ? (void *)1 : NULL; 3629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 3639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void *c_next(struct seq_file *m, void *v, loff_t * pos) 3659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 3669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn ++*pos; 3679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn return NULL; 3689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 3699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void c_stop(struct seq_file *m, void *v) 3719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{ 3729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn} 3739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn 3749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnconst struct seq_operations cpuinfo_op = { 3759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn .start = c_start, 3769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn .next = c_next, 3779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn .stop = c_stop, 3789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn .show = show_cpuinfo, 3799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}; 380