summaryrefslogtreecommitdiffstats
path: root/sys/arm/mv/mv_machdep.c
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-08-15 05:15:49 +0000
committergonzo <gonzo@FreeBSD.org>2012-08-15 05:15:49 +0000
commit8b8633cc987a479a321d1f508e8cbed2e3b0907a (patch)
tree5d41b0c203c7eee2fd144c67899fe39cfcdef717 /sys/arm/mv/mv_machdep.c
parent08c3a17117fbf4a3289526d99ca74f9ccbc8c3b4 (diff)
downloadFreeBSD-src-8b8633cc987a479a321d1f508e8cbed2e3b0907a.zip
FreeBSD-src-8b8633cc987a479a321d1f508e8cbed2e3b0907a.tar.gz
Merging of projects/armv6, part 7
Add Marvell ARMADA XP support Obtained from: Marvell, Semihalf
Diffstat (limited to 'sys/arm/mv/mv_machdep.c')
-rw-r--r--sys/arm/mv/mv_machdep.c172
1 files changed, 146 insertions, 26 deletions
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index 0c12aea..07ca23d 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -122,14 +122,12 @@ extern u_int undefined_handler_address;
extern vm_offset_t pmap_bootstrap_lastaddr;
struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
-struct pcpu __pcpu;
-struct pcpu *pcpup = &__pcpu;
/* Physical and virtual addresses for some global pages */
-
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
vm_offset_t pmap_bootstrap_lastaddr;
+vm_paddr_t pmap_pa;
const struct pmap_devmap *pmap_devmap_bootstrap_table;
struct pv_addr systempage;
@@ -139,6 +137,8 @@ struct pv_addr undstack;
struct pv_addr abtstack;
struct pv_addr kernelstack;
+void set_stackptrs(int cpu);
+
static struct mem_region availmem_regions[FDT_MEM_REGIONS];
static int availmem_regions_sz;
@@ -348,8 +348,7 @@ initarm(struct arm_boot_params *abp)
/* Platform-specific initialisation */
pmap_bootstrap_lastaddr = fdt_immr_va - ARM_NOCACHE_KVA_SIZE;
- pcpu_init(pcpup, 0, sizeof(struct pcpu));
- PCPU_SET(curthread, &thread0);
+ pcpu0_init();
/* Calculate number of L2 tables needed for mapping vm_page_array */
l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page);
@@ -407,10 +406,10 @@ initarm(struct arm_boot_params *abp)
dpcpu_init((void *)dpcpu.pv_va, 0);
/* Allocate stacks for all modes */
- valloc_pages(irqstack, IRQ_STACK_SIZE);
- valloc_pages(abtstack, ABT_STACK_SIZE);
- valloc_pages(undstack, UND_STACK_SIZE);
- valloc_pages(kernelstack, KSTACK_PAGES);
+ valloc_pages(irqstack, (IRQ_STACK_SIZE * MAXCPU));
+ valloc_pages(abtstack, (ABT_STACK_SIZE * MAXCPU));
+ valloc_pages(undstack, (UND_STACK_SIZE * MAXCPU));
+ valloc_pages(kernelstack, (KSTACK_PAGES * MAXCPU));
init_param1();
@@ -462,7 +461,7 @@ initarm(struct arm_boot_params *abp)
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
&kernel_pt_table[l2size - 1]);
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE);
/* Map pmap_devmap[] entries */
err_devmap = platform_devmap_init();
@@ -470,6 +469,7 @@ initarm(struct arm_boot_params *abp)
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
DOMAIN_CLIENT);
+ pmap_pa = kernel_l1pt.pv_pa;
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
@@ -494,7 +494,7 @@ initarm(struct arm_boot_params *abp)
debugf("initarm: console initialized\n");
debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp);
debugf(" boothowto = 0x%08x\n", boothowto);
- printf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
+ debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
print_kernel_section_addr();
print_kenv();
@@ -505,9 +505,14 @@ initarm(struct arm_boot_params *abp)
/*
* Re-initialise decode windows
*/
+#if !defined(SOC_MV_FREY)
if (soc_decode_win() != 0)
printf("WARNING: could not re-initialise decode windows! "
"Running with existing settings...\n");
+#else
+ /* Disable watchdog and timers */
+ write_cpu_ctrl(CPU_TIMERS_BASE + CPU_TIMER_CONTROL, 0);
+#endif
/*
* Pages were allocated during the secondary bootstrap for the
@@ -518,12 +523,8 @@ initarm(struct arm_boot_params *abp)
* of the stack memory.
*/
cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
- set_stackptr(PSR_IRQ32_MODE,
- irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
- set_stackptr(PSR_ABT32_MODE,
- abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
- set_stackptr(PSR_UND32_MODE,
- undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
+
+ set_stackptrs(0);
/*
* We must now clean the cache again....
@@ -564,7 +565,19 @@ initarm(struct arm_boot_params *abp)
sizeof(struct pcb)));
}
-#define MPP_PIN_MAX 50
+void
+set_stackptrs(int cpu)
+{
+
+ set_stackptr(PSR_IRQ32_MODE,
+ irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+ set_stackptr(PSR_ABT32_MODE,
+ abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+ set_stackptr(PSR_UND32_MODE,
+ undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+}
+
+#define MPP_PIN_MAX 68
#define MPP_PIN_CELLS 2
#define MPP_PINS_PER_REG 8
#define MPP_SEL(pin,func) (((func) & 0xf) << \
@@ -601,7 +614,11 @@ platform_mpp_init(void)
return (ENXIO);
if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0)
- return (ENXIO);
+ /*
+ * No MPP node. Fall back to how MPP got set by the
+ * first-stage loader and try to continue booting.
+ */
+ return (0);
moveon:
/*
* Process 'reg' prop.
@@ -694,11 +711,49 @@ moveon:
return (0);
}
-#define FDT_DEVMAP_MAX (MV_WIN_CPU_MAX + 1)
+#define FDT_DEVMAP_MAX (MV_WIN_CPU_MAX + 2)
static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = {
{ 0, 0, 0, 0, 0, }
};
+static int
+platform_sram_devmap(struct pmap_devmap *map)
+{
+#if !defined(SOC_MV_ARMADAXP)
+ phandle_t child, root;
+ u_long base, size;
+ /*
+ * SRAM range.
+ */
+ if ((child = OF_finddevice("/sram")) != 0)
+ if (fdt_is_compatible(child, "mrvl,cesa-sram") ||
+ fdt_is_compatible(child, "mrvl,scratchpad"))
+ goto moveon;
+
+ if ((root = OF_finddevice("/")) == 0)
+ return (ENXIO);
+
+ if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0 &&
+ (child = fdt_find_compatible(root, "mrvl,scratchpad", 0)) == 0)
+ goto out;
+
+moveon:
+ if (fdt_regsize(child, &base, &size) != 0)
+ return (EINVAL);
+
+ map->pd_va = MV_CESA_SRAM_BASE; /* XXX */
+ map->pd_pa = base;
+ map->pd_size = size;
+ map->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+ map->pd_cache = PTE_NOCACHE;
+
+ return (0);
+out:
+#endif
+ return (ENOENT);
+
+}
+
/*
* XXX: When device entry in devmap has pd_size smaller than section size,
* system will freeze during initialization
@@ -730,27 +785,33 @@ platform_devmap_init(void)
i++;
/*
+ * SRAM range.
+ */
+ if (i < FDT_DEVMAP_MAX)
+ if (platform_sram_devmap(&fdt_devmap[i]) == 0)
+ i++;
+
+ /*
+ * PCI range(s).
* PCI range(s) and localbus.
*/
if ((root = OF_finddevice("/")) == -1)
return (ENXIO);
-
for (child = OF_child(root); child != 0; child = OF_peer(child)) {
- if (fdt_is_type(child, "pci")) {
+ if (fdt_is_type(child, "pci") || fdt_is_type(child, "pciep")) {
/*
* Check space: each PCI node will consume 2 devmap
* entries.
*/
- if (i + 1 >= FDT_DEVMAP_MAX) {
+ if (i + 1 >= FDT_DEVMAP_MAX)
return (ENOMEM);
- }
/*
* XXX this should account for PCI and multiple ranges
* of a given kind.
*/
- if (fdt_pci_devmap(child, &fdt_devmap[i],
- MV_PCIE_IO_BASE, MV_PCIE_MEM_BASE) != 0)
+ if (fdt_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE,
+ MV_PCI_VA_MEM_BASE) != 0)
return (ENXIO);
i += 2;
}
@@ -817,3 +878,62 @@ bus_dma_get_range_nb(void)
return (0);
}
+
+#if defined(CPU_MV_PJ4B)
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(cp15, db_show_cp15)
+{
+ u_int reg;
+
+ __asm __volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (reg));
+ db_printf("Cpu ID: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (reg));
+ db_printf("Current Cache Lvl ID: 0x%08x\n",reg);
+
+ __asm __volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (reg));
+ db_printf("Ctrl: 0x%08x\n",reg);
+ __asm __volatile("mrc p15, 0, %0, c1, c0, 1" : "=r" (reg));
+ db_printf("Aux Ctrl: 0x%08x\n",reg);
+
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (reg));
+ db_printf("Processor Feat 0: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 1" : "=r" (reg));
+ db_printf("Processor Feat 1: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (reg));
+ db_printf("Debug Feat 0: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 3" : "=r" (reg));
+ db_printf("Auxiliary Feat 0: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 4" : "=r" (reg));
+ db_printf("Memory Model Feat 0: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 5" : "=r" (reg));
+ db_printf("Memory Model Feat 1: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 6" : "=r" (reg));
+ db_printf("Memory Model Feat 2: 0x%08x\n", reg);
+ __asm __volatile("mrc p15, 0, %0, c0, c1, 7" : "=r" (reg));
+ db_printf("Memory Model Feat 3: 0x%08x\n", reg);
+
+ __asm __volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (reg));
+ db_printf("Aux Func Modes Ctrl 0: 0x%08x\n",reg);
+ __asm __volatile("mrc p15, 1, %0, c15, c2, 1" : "=r" (reg));
+ db_printf("Aux Func Modes Ctrl 1: 0x%08x\n",reg);
+
+ __asm __volatile("mrc p15, 1, %0, c15, c12, 0" : "=r" (reg));
+ db_printf("CPU ID code extension: 0x%08x\n",reg);
+}
+
+DB_SHOW_COMMAND(vtop, db_show_vtop)
+{
+ u_int reg;
+
+ if (have_addr) {
+ __asm __volatile("mcr p15, 0, %0, c7, c8, 0" : : "r" (addr));
+ __asm __volatile("mrc p15, 0, %0, c7, c4, 0" : "=r" (reg));
+ db_printf("Physical address reg: 0x%08x\n",reg);
+ } else
+ db_printf("show vtop <virt_addr>\n");
+}
+#endif /* DDB */
+#endif /* CPU_MV_PJ4B */
+
OpenPOWER on IntegriCloud