From b1f46e3ee287f994242aa18de6d18d927e42501d Mon Sep 17 00:00:00 2001 From: skrll Date: Fri, 4 Apr 2014 06:04:54 +0000 Subject: [PATCH] Revert previous - it wasn't complete. --- sys/arch/cats/cats/cats_machdep.c | 421 +++++++++++++++++++++++++----- sys/arch/cats/conf/files.cats | 6 +- 2 files changed, 357 insertions(+), 70 deletions(-) diff --git a/sys/arch/cats/cats/cats_machdep.c b/sys/arch/cats/cats/cats_machdep.c index 851df2a4d4a9..fc74a0f39a7c 100644 --- a/sys/arch/cats/cats/cats_machdep.c +++ b/sys/arch/cats/cats/cats_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: cats_machdep.c,v 1.79 2014/04/02 17:36:05 skrll Exp $ */ +/* $NetBSD: cats_machdep.c,v 1.80 2014/04/04 06:04:54 skrll Exp $ */ /* * Copyright (c) 1997,1998 Mark Brinicombe. @@ -40,7 +40,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cats_machdep.c,v 1.79 2014/04/02 17:36:05 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cats_machdep.c,v 1.80 2014/04/04 06:04:54 skrll Exp $"); #include "opt_ddb.h" #include "opt_modular.h" @@ -74,8 +74,6 @@ __KERNEL_RCSID(0, "$NetBSD: cats_machdep.c,v 1.79 2014/04/02 17:36:05 skrll Exp #include #include #include - -#include #include #include @@ -118,11 +116,30 @@ static char bootargs[MAX_BOOT_STRING + 1]; char *boot_args = NULL; char *boot_file = NULL; +vm_offset_t physical_start; +vm_offset_t physical_freestart; +vm_offset_t physical_freeend; +vm_offset_t physical_end; +u_int free_pages; +vm_offset_t pagetables_start; + +vm_offset_t msgbufphys; #ifdef PMAP_DEBUG extern int pmap_debug_level; #endif +#define KERNEL_PT_SYS 0 /* L2 table for mapping zero page */ +#define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel */ +#define KERNEL_PT_KERNEL_NUM 2 + +/* now this could move into something more generic */ + /* L2 tables for mapping kernel VM */ +#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM) +#define KERNEL_PT_VMDATA_NUM 4 /* 16MB kernel VM !*/ +#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) + +pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; /* Prototypes */ @@ -173,7 +190,88 @@ extern void configure(void); int comcnspeed = CONSPEED; int comcnmode = CONMODE; -static const struct pmap_devmap cats_devmap[] = { + +/* + * void cpu_reboot(int howto, char *bootstr) + * + * Reboots the system + * + * Deal with any syncing, unmounting, dumping and shutdown hooks, + * then reset the CPU. + */ + +void +cpu_reboot(int howto, char *bootstr) +{ +#ifdef DIAGNOSTIC + /* info */ + printf("boot: howto=%08x curlwp=%p\n", howto, curlwp); +#endif + + /* + * If we are still cold then hit the air brakes + * and crash to earth fast + */ + if (cold) { + doshutdownhooks(); + pmf_system_shutdown(boothowto); + printf("The operating system has halted.\n"); + printf("Please press any key to reboot.\n\n"); + cngetc(); + printf("rebooting...\n"); + cpu_reset(); + /*NOTREACHED*/ + } + + /* Disable console buffering */ +/* cnpollc(1);*/ + + /* + * If RB_NOSYNC was not specified sync the discs. + * Note: Unless cold is set to 1 here, syslogd will die during the unmount. + * It looks like syslogd is getting woken up only to find that it cannot + * page part of the binary in as the filesystem has been unmounted. + */ + if (!(howto & RB_NOSYNC)) + bootsync(); + + /* Say NO to interrupts */ + splhigh(); + + /* Do a dump if requested. */ + if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) + dumpsys(); + + /* Run any shutdown hooks */ + doshutdownhooks(); + + pmf_system_shutdown(boothowto); + + /* Make sure IRQ's are disabled */ + IRQdisable; + + if (howto & RB_HALT) { + printf("The operating system has halted.\n"); + printf("Please press any key to reboot.\n\n"); + cngetc(); + } + + printf("rebooting...\n"); + cpu_reset(); + /*NOTREACHED*/ +} + +/* + * Mapping table for core kernel memory. This memory is mapped at init + * time with section mappings. + */ +struct l1_sec_map { + vm_offset_t va; + vm_offset_t pa; + vm_size_t size; + vm_prot_t prot; + int cache; +} l1_sec_table[] = { /* Map 1MB for CSR space */ { DC21285_ARMCSR_VBASE, DC21285_ARMCSR_BASE, DC21285_ARMCSR_VSIZE, VM_PROT_READ|VM_PROT_WRITE, @@ -212,14 +310,6 @@ static const struct pmap_devmap cats_devmap[] = { { 0, 0, 0, 0, 0 } }; -#define MAX_PHYSMEM 4 -static struct boot_physmem cats_physmem[MAX_PHYSMEM]; -int ncats_physmem = 0; - -extern struct bus_space footbridge_pci_io_bs_tag; -extern struct bus_space footbridge_pci_mem_bs_tag; -void footbridge_pci_bs_tag_init(void); - /* * u_int initarm(struct ebsaboot *bootinfo) * @@ -238,6 +328,9 @@ u_int initarm(void *arm_bootargs) { struct ebsaboot *bootinfo = arm_bootargs; + int loop; + int loop1; + u_int l1pagetable; extern u_int cpu_get_control(void); /* @@ -265,10 +358,8 @@ initarm(void *arm_bootargs) * Once all the memory map changes are complete we can call consinit() * and not have to worry about things moving. */ - pmap_devmap_bootstrap((vaddr_t)ebsabootinfo.bt_l1, cats_devmap); - #ifdef FCOM_INIT_ARM - fcomcnattach(DC21285_ARMCSR_VBASE, comcnspeed, comcnmode); + fcomcnattach(DC21285_ARMCSR_BASE, comcnspeed, comcnmode); #endif /* Talk to the user */ @@ -296,6 +387,37 @@ initarm(void *arm_bootargs) printf("bt_vers = 0x%08x\n", ebsabootinfo.bt_vers); printf("bt_features = 0x%08x\n", ebsabootinfo.bt_features); #endif +/* { + int loop; + for (loop = 0; loop < 8; ++loop) { + printf("%08x\n", *(((int *)bootinfo)+loop)); + } + }*/ + + /* + * Ok we have the following memory map + * + * virtual address == physical address apart from the areas: + * 0x00000000 -> 0x000fffff which is mapped to + * top 1MB of physical memory + * 0x00100000 -> 0x0fffffff which is mapped to + * physical addresses 0x00100000 -> 0x0fffffff + * 0x10000000 -> 0x1fffffff which is mapped to + * physical addresses 0x00000000 -> 0x0fffffff + * 0x20000000 -> 0xefffffff which is mapped to + * physical addresses 0x20000000 -> 0xefffffff + * 0xf0000000 -> 0xf03fffff which is mapped to + * physical addresses 0x00000000 -> 0x003fffff + * + * This means that the kernel is mapped suitably for continuing + * execution, all I/O is mapped 1:1 virtual to physical and + * physical memory is accessible. + * + * The initarm() has the responsibility for creating the kernel + * page tables. + * It must also set up various memory pointers that are used + * by pmap etc. + */ /* * Examine the boot args string for options we need to know about @@ -303,17 +425,186 @@ initarm(void *arm_bootargs) */ process_kernel_args(ebsabootinfo.bt_args); - arm32_bootmem_init(ebsabootinfo.bt_memstart, - ebsabootinfo.bt_memend - ebsabootinfo.bt_memstart, - ebsabootinfo.bt_memstart); + printf("initarm: Configuring system ...\n"); - arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, cats_devmap, - false); + /* + * Set up the variables that define the availablilty of + * physical memory + */ + physical_start = ebsabootinfo.bt_memstart; + physical_freestart = physical_start; + physical_end = ebsabootinfo.bt_memend; + physical_freeend = physical_end; + free_pages = (physical_end - physical_start) / PAGE_SIZE; + + physmem = (physical_end - physical_start) / PAGE_SIZE; + /* Tell the user about the memory */ + printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem, + physical_start, physical_end - 1); + + /* + * Ok the kernel occupies the bottom of physical memory. + * The first free page after the kernel can be found in + * ebsabootinfo->bt_memavail + * We now need to allocate some fixed page tables to get the kernel + * going. + * We allocate one page directory and a number page tables and store + * the physical addresses in the kernel_pt_table array. + * + * Ok the next bit of physical allocation may look complex but it is + * simple really. I have done it like this so that no memory gets + * wasted during the allocation of various pages and tables that are + * all different sizes. + * The start addresses will be page aligned. + * We allocate the kernel page directory on the first free 16KB boundry + * we find. + * We allocate the kernel page tables on the first 4KB boundry we find. + * Since we allocate at least 3 L2 pagetables we know that we must + * encounter at least one 16KB aligned address. + */ + +#ifdef VERBOSE_INIT_ARM + printf("Allocating page tables"); +#endif + + /* Update the address of the first free page of physical memory */ + physical_freestart = ebsabootinfo.bt_memavail; + free_pages -= (physical_freestart - physical_start) / PAGE_SIZE; + +#ifdef VERBOSE_INIT_ARM + printf(" above %p\n", (void *)physical_freestart); +#endif + /* Define a macro to simplify memory allocation */ +#define valloc_pages(var, np) \ + alloc_pages((var).pv_pa, (np)); \ + (var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; + +#define alloc_pages(var, np) \ + (var) = physical_freestart; \ + physical_freestart += ((np) * PAGE_SIZE);\ + free_pages -= (np); \ + memset((char *)(var), 0, ((np) * PAGE_SIZE)); + + loop1 = 0; + for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { + /* Are we 16KB aligned for an L1 ? */ + if ((physical_freestart & (L1_TABLE_SIZE - 1)) == 0 + && kernel_l1pt.pv_pa == 0) { + valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); + } else { + valloc_pages(kernel_pt_table[loop1], + L2_TABLE_SIZE / PAGE_SIZE); + ++loop1; + } + } + +#ifdef DIAGNOSTIC + /* This should never be able to happen but better confirm that. */ + if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) + panic("initarm: Failed to align the kernel page directory"); +#endif + + /* + * Allocate a page for the system page mapped to V0x00000000 + * This page will just contain the system vectors and can be + * shared by all processes. + */ + alloc_pages(systempage.pv_pa, 1); + + /* 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, UPAGES); + +#ifdef VERBOSE_INIT_ARM + printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, irqstack.pv_va); + printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, abtstack.pv_va); + printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, undstack.pv_va); + printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, kernelstack.pv_va); +#endif + + alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE); + + /* + * Ok we have allocated physical pages for the primary kernel + * page tables + */ + +#ifdef VERBOSE_INIT_ARM + printf("Creating L1 page table\n"); +#endif + + /* + * Now we start consturction of the L1 page table + * We start by mapping the L2 page tables into the L1. + * This means that we can replace L1 mappings later on if necessary + */ + l1pagetable = kernel_l1pt.pv_pa; + + /* Map the L2 pages tables in the L1 page table */ + pmap_link_l2pt(l1pagetable, 0x00000000, + &kernel_pt_table[KERNEL_PT_SYS]); + + for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) + pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, + &kernel_pt_table[KERNEL_PT_KERNEL + loop]); + + for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) + pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, + &kernel_pt_table[KERNEL_PT_VMDATA + loop]); + + /* update the top of the kernel VM */ + pmap_curmaxkvaddr = + KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); + +#ifdef VERBOSE_INIT_ARM + printf("Mapping kernel\n"); +#endif + + /* Now we fill in the L2 pagetable for the kernel static code/data */ struct exec *kernexec = (struct exec *)KERNEL_TEXT_BASE; - bool isaout = (N_GETMAGIC(kernexec[0]) == ZMAGIC); + if (N_GETMAGIC(kernexec[0]) != ZMAGIC) { + /* + * If it's not a.out, assume ELF. + */ + extern char etext[], _end[]; + size_t textsize = (uintptr_t) etext - KERNEL_BASE; + size_t totalsize = (uintptr_t) _end - KERNEL_BASE; + u_int logical; + + textsize = round_page(textsize); + totalsize = round_page(totalsize); - printf("init subsystems: patch "); + logical = pmap_map_chunk(l1pagetable, KERNEL_BASE, + physical_start, textsize, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + (void) pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, + physical_start + logical, totalsize - textsize, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + } else { + extern int end; + u_int logical; + + logical = pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, + physical_start, kernexec->a_text, + VM_PROT_READ, PTE_CACHE); + logical += pmap_map_chunk(l1pagetable, + KERNEL_TEXT_BASE + logical, + physical_start + logical, kernexec->a_data, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + logical += pmap_map_chunk(l1pagetable, + KERNEL_TEXT_BASE + logical, + physical_start + logical, kernexec->a_bss, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + logical += pmap_map_chunk(l1pagetable, + KERNEL_TEXT_BASE + logical, + physical_start + logical, kernexec->a_syms + sizeof(int) + + *(u_int *)((int)&end + kernexec->a_syms + sizeof(int)), + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + } /* * PATCH PATCH ... @@ -520,11 +811,9 @@ initarm(void *arm_bootargs) printf(" ISADMA 0x%lx -> 0x%lx\n", istart, istart + isize - 1); #endif - bp = &cats_physmem[ncats_physmem++]; - KASSERT(ncats_physmem < MAX_PHYSMEM); - bp->bp_start = atop(istart); - bp->bp_pages = atop(isize); - bp->bp_freelist = VM_FREELIST_ISADMA; + uvm_page_physload(atop(istart), + atop(istart + isize), atop(istart), + atop(istart + isize), VM_FREELIST_ISADMA); /* * Load the pieces that come before the @@ -535,11 +824,9 @@ initarm(void *arm_bootargs) printf(" BEFORE 0x%lx -> 0x%lx\n", start, istart - 1); #endif - bp = &cats_physmem[ncats_physmem++]; - KASSERT(ncats_physmem < MAX_PHYSMEM); - bp->bp_start = atop(start); - bp->bp_pages = atop(istart - start); - bp->bp_freelist = VM_FREELIST_DEFAULT; + uvm_page_physload(atop(start), + atop(istart), atop(start), + atop(istart), VM_FREELIST_DEFAULT); } /* @@ -551,57 +838,50 @@ initarm(void *arm_bootargs) printf(" AFTER 0x%lx -> 0x%lx\n", (istart + isize), end - 1); #endif - bp = &cats_physmem[ncats_physmem++]; - KASSERT(ncats_physmem < MAX_PHYSMEM); - bp->bp_start = atop(istart + isize); - bp->bp_pages = atop(end - (istart + isize)); - bp->bp_freelist = VM_FREELIST_DEFAULT; + uvm_page_physload(atop(istart + isize), + atop(end), atop(istart + isize), + atop(end), VM_FREELIST_DEFAULT); } } else { - bp = &cats_physmem[ncats_physmem++]; - KASSERT(ncats_physmem < MAX_PHYSMEM); - bp->bp_start = atop(start); - bp->bp_pages = atop(end - start); - bp->bp_freelist = VM_FREELIST_DEFAULT; + uvm_page_physload(atop(start), atop(end), + atop(start), atop(end), VM_FREELIST_DEFAULT); } #else /* NISADMA > 0 */ - bp = &cats_physmem[ncats_physmem++]; - KASSERT(ncats_physmem < MAX_PHYSMEM); - bp->bp_start = atop(start); - bp->bp_pages = atop(end - start); - bp->bp_freelist = VM_FREELIST_DEFAULT; + uvm_page_physload(atop(start), atop(end), + atop(start), atop(end), VM_FREELIST_DEFAULT); #endif /* NISADMA > 0 */ } + /* Boot strap pmap telling it where the kernel page table is */ + printf("pmap "); + pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); + cpu_reset_address_paddr = DC21285_ROM_BASE; - /* initarm_common returns the new stack pointer address */ - u_int sp; - sp = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, cats_physmem, - ncats_physmem); - /* Setup the IRQ system */ - printf("init subsystems: irq "); + printf("irq "); footbridge_intr_init(); printf("done.\n"); -#ifdef FCOM_INIT_ARM - fcomcndetach(); -#endif - if (isaout) { +#if NKSYMS || defined(DDB) || defined(MODULAR) +#ifndef __ELF__ /* XXX */ + { extern int end; - extern int esym[]; + extern int *esym; ksyms_addsyms_elf(*(int *)&end, ((int *)&end) + 1, esym); } +#endif /* __ELF__ */ +#endif - /* - * XXX this should only be done in main() but it useful to - * have output earlier ... - */ - consinit(); +#ifdef DDB + db_machine_init(); + if (boothowto & RB_KDB) + Debugger(); +#endif - return sp; + /* We return the new stack pointer address */ + return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); } static void @@ -634,6 +914,10 @@ process_kernel_args(const char *loader_args) parse_mi_bootargs(boot_args); } +extern struct bus_space footbridge_pci_io_bs_tag; +extern struct bus_space footbridge_pci_mem_bs_tag; +void footbridge_pci_bs_tag_init(void); + void consinit(void) { @@ -645,6 +929,13 @@ consinit(void) consinit_called = 1; +#if NISA > 0 + /* Initialise the ISA subsystem early ... */ + isa_footbridge_init(DC21285_PCI_IO_VBASE, DC21285_PCI_ISA_MEM_VBASE); +#endif + + footbridge_pci_bs_tag_init(); + get_bootconf_option(boot_args, "console", BOOTOPT_TYPE_STRING, &console); diff --git a/sys/arch/cats/conf/files.cats b/sys/arch/cats/conf/files.cats index c71c3b9a3918..d7af6d1d92ce 100644 --- a/sys/arch/cats/conf/files.cats +++ b/sys/arch/cats/conf/files.cats @@ -1,4 +1,4 @@ -# $NetBSD: files.cats,v 1.36 2014/04/02 17:36:05 skrll Exp $ +# $NetBSD: files.cats,v 1.37 2014/04/04 06:04:54 skrll Exp $ # # CATS-specific configuration info # @@ -6,10 +6,6 @@ maxpartitions 8 maxusers 2 8 64 -file arch/arm/arm32/arm32_boot.c -file arch/arm/arm32/arm32_kvminit.c -file arch/arm/arm32/arm32_reboot.c - # Maintain Interrupt statistics defflag IRQSTATS