version 1.4, 2001/11/09 07:21:39 |
version 1.4.2.7, 2002/08/01 02:41:35 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/* |
/* |
* Copyright (c) 2001 ARM Ltd |
* Copyright (c) 2001,2002 ARM Ltd |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
* products derived from this software without specific prior written |
* products derived from this software without specific prior written |
* permission. |
* permission. |
* |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARM LTD |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* SUCH DAMAGE. |
* POSSIBILITY OF SUCH DAMAGE. |
* |
*/ |
|
|
|
/* |
* Copyright (c) 1997,1998 Mark Brinicombe. |
* Copyright (c) 1997,1998 Mark Brinicombe. |
* Copyright (c) 1997,1998 Causality Limited. |
* Copyright (c) 1997,1998 Causality Limited. |
* All rights reserved. |
* All rights reserved. |
|
|
#include <machine/cpu.h> |
#include <machine/cpu.h> |
#include <machine/frame.h> |
#include <machine/frame.h> |
#include <machine/intr.h> |
#include <machine/intr.h> |
#include <machine/pte.h> |
#include <evbarm/ifpga/irqhandler.h> /* XXX XXX XXX */ |
#include <machine/undefined.h> |
#include <arm/undefined.h> |
|
|
|
#include <arm/arm32/machdep.h> |
|
|
#include <evbarm/integrator/integrator_boot.h> |
#include <evbarm/integrator/integrator_boot.h> |
|
|
Line 115 u_int cpu_reset_address = (u_int) ifpga_ |
|
Line 119 u_int cpu_reset_address = (u_int) ifpga_ |
|
#define UND_STACK_SIZE 1 |
#define UND_STACK_SIZE 1 |
#endif |
#endif |
|
|
struct intbootinfo intbootinfo; |
|
BootConfig bootconfig; /* Boot config storage */ |
BootConfig bootconfig; /* Boot config storage */ |
static char bootargs[MAX_BOOT_STRING + 1]; |
|
char *boot_args = NULL; |
char *boot_args = NULL; |
char *boot_file = NULL; |
char *boot_file = NULL; |
|
|
Line 151 extern u_int undefined_handler_address; |
|
Line 153 extern u_int undefined_handler_address; |
|
extern int pmap_debug_level; |
extern int pmap_debug_level; |
#endif |
#endif |
|
|
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */ |
#define KERNEL_PT_SYS 0 /* L2 table for mapping zero page */ |
#define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */ |
|
#define KERNEL_PT_VMDATA 2 /* Page tables for mapping kernel VM */ |
#define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel */ |
#define KERNEL_PT_VMDATA_NUM (KERNEL_VM_SIZE >> (PDSHIFT + 2)) |
#define KERNEL_PT_KERNEL_NUM 2 |
|
/* L2 tables for mapping kernel VM */ |
|
#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM) |
|
#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ |
#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) |
#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) |
|
|
pt_entry_t kernel_pt_table[NUM_KERNEL_PTS]; |
pv_addr_t kernel_pt_table[NUM_KERNEL_PTS]; |
|
|
struct user *proc0paddr; |
struct user *proc0paddr; |
|
|
/* Prototypes */ |
/* Prototypes */ |
|
|
void consinit __P((void)); |
static void integrator_sdram_bounds (paddr_t *, psize_t *); |
|
|
void map_section __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa, |
void consinit(void); |
int cacheable)); |
|
void map_pagetable __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa)); |
|
void map_entry __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa)); |
|
void map_entry_nc __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa)); |
|
void map_entry_ro __P((vm_offset_t pt, vm_offset_t va, vm_offset_t pa)); |
|
vm_size_t map_chunk __P((vm_offset_t pd, vm_offset_t pt, vm_offset_t va, |
|
vm_offset_t pa, vm_size_t size, u_int acc, |
|
u_int flg)); |
|
|
|
void process_kernel_args __P((char *)); |
|
void data_abort_handler __P((trapframe_t *frame)); |
|
void prefetch_abort_handler __P((trapframe_t *frame)); |
|
void undefinedinstruction_bounce __P((trapframe_t *frame)); |
|
extern void configure __P((void)); |
|
extern void parse_mi_bootargs __P((char *args)); |
|
extern void dumpsys __P((void)); |
|
|
|
/* A load of console goo. */ |
/* A load of console goo. */ |
#include "vga.h" |
#include "vga.h" |
#if (NVGA > 0) |
#if NVGA > 0 |
#include <dev/ic/mc6845reg.h> |
#include <dev/ic/mc6845reg.h> |
#include <dev/ic/pcdisplayvar.h> |
#include <dev/ic/pcdisplayvar.h> |
#include <dev/ic/vgareg.h> |
#include <dev/ic/vgareg.h> |
Line 193 extern void dumpsys __P((void)); |
|
Line 182 extern void dumpsys __P((void)); |
|
#endif |
#endif |
|
|
#include "pckbc.h" |
#include "pckbc.h" |
#if (NPCKBC > 0) |
#if NPCKBC > 0 |
#include <dev/ic/i8042reg.h> |
#include <dev/ic/i8042reg.h> |
#include <dev/ic/pckbcvar.h> |
#include <dev/ic/pckbcvar.h> |
#endif |
#endif |
|
|
#include "com.h" |
#include "com.h" |
#if (NCOM > 0) |
#if NCOM > 0 |
#include <dev/ic/comreg.h> |
#include <dev/ic/comreg.h> |
#include <dev/ic/comvar.h> |
#include <dev/ic/comvar.h> |
#ifndef CONCOMADDR |
#ifndef CONCOMADDR |
Line 207 extern void dumpsys __P((void)); |
|
Line 196 extern void dumpsys __P((void)); |
|
#endif |
#endif |
#endif |
#endif |
|
|
|
/* |
|
* Define the default console speed for the board. This is generally |
|
* what the firmware provided with the board defaults to. |
|
*/ |
#define CONSPEED B115200 |
#define CONSPEED B115200 |
#ifndef CONSPEED |
#ifndef CONSPEED |
#define CONSPEED B9600 /* TTYDEF_SPEED */ |
#define CONSPEED B9600 /* TTYDEF_SPEED */ |
Line 258 static void kcomcnputc(dev_t, int); |
|
Line 251 static void kcomcnputc(dev_t, int); |
|
* Deal with any syncing, unmounting, dumping and shutdown hooks, |
* Deal with any syncing, unmounting, dumping and shutdown hooks, |
* then reset the CPU. |
* then reset the CPU. |
*/ |
*/ |
|
|
void |
void |
cpu_reboot(howto, bootstr) |
cpu_reboot(int howto, char *bootstr) |
int howto; |
|
char *bootstr; |
|
{ |
{ |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
/* info */ |
/* info */ |
printf("boot: howto=%08x curproc=%p\n", howto, curproc); |
printf("boot: howto=%08x curlwp=%p\n", howto, curlwp); |
#endif |
#endif |
|
|
/* |
/* |
Line 284 cpu_reboot(howto, bootstr) |
|
Line 274 cpu_reboot(howto, bootstr) |
|
} |
} |
|
|
/* Disable console buffering */ |
/* Disable console buffering */ |
/* cnpollc(1);*/ |
|
|
|
/* |
/* |
* If RB_NOSYNC was not specified sync the discs. |
* If RB_NOSYNC was not specified sync the discs. |
* Note: Unless cold is set to 1 here, syslogd will die during the unmount. |
* Note: Unless cold is set to 1 here, syslogd will die during the |
* It looks like syslogd is getting woken up only to find that it cannot |
* unmount. It looks like syslogd is getting woken up only to find |
* page part of the binary in as the filesystem has been unmounted. |
* that it cannot page part of the binary in as the filesystem has |
|
* been unmounted. |
*/ |
*/ |
if (!(howto & RB_NOSYNC)) |
if (!(howto & RB_NOSYNC)) |
bootsync(); |
bootsync(); |
Line 324 cpu_reboot(howto, bootstr) |
|
Line 314 cpu_reboot(howto, bootstr) |
|
* time with section mappings. |
* time with section mappings. |
*/ |
*/ |
struct l1_sec_map { |
struct l1_sec_map { |
vm_offset_t va; |
vaddr_t va; |
vm_offset_t pa; |
vaddr_t pa; |
vm_size_t size; |
vsize_t size; |
int flags; |
vm_prot_t prot; |
|
int cache; |
} l1_sec_table[] = { |
} l1_sec_table[] = { |
#if NPLCOM > 0 && defined(PLCONSOLE) |
#if NPLCOM > 0 && defined(PLCONSOLE) |
{ UART0_BOOT_BASE, IFPGA_IO_BASE + IFPGA_UART0, 1024 * 1024, 0}, |
{ |
{ UART1_BOOT_BASE, IFPGA_IO_BASE + IFPGA_UART1, 1024 * 1024, 0}, |
UART0_BOOT_BASE, |
|
IFPGA_IO_BASE + IFPGA_UART0, |
|
1024 * 1024, |
|
VM_PROT_READ|VM_PROT_WRITE, |
|
PTE_NOCACHE |
|
}, |
|
|
|
{ |
|
UART1_BOOT_BASE, |
|
IFPGA_IO_BASE + IFPGA_UART1, |
|
1024 * 1024, |
|
VM_PROT_READ|VM_PROT_WRITE, |
|
PTE_NOCACHE |
|
}, |
#endif |
#endif |
#if NPCI > 0 |
#if NPCI > 0 |
{ IFPGA_PCI_IO_VBASE, IFPGA_PCI_IO_BASE, IFPGA_PCI_IO_VSIZE, 0}, |
{ |
{ IFPGA_PCI_CONF_VBASE, IFPGA_PCI_CONF_BASE, IFPGA_PCI_CONF_VSIZE, 0}, |
IFPGA_PCI_IO_VBASE, |
|
IFPGA_PCI_IO_BASE, |
|
IFPGA_PCI_IO_VSIZE, |
|
VM_PROT_READ|VM_PROT_WRITE, |
|
PTE_NOCACHE |
|
}, |
|
|
|
{ |
|
IFPGA_PCI_CONF_VBASE, |
|
IFPGA_PCI_CONF_BASE, |
|
IFPGA_PCI_CONF_VSIZE, |
|
VM_PROT_READ|VM_PROT_WRITE, |
|
PTE_NOCACHE }, |
#endif |
#endif |
|
|
{ 0, 0, 0, 0 } |
{ |
|
0, |
|
0, |
|
0, |
|
0, |
|
0 |
|
} |
}; |
}; |
|
|
/* |
/* |
* u_int initarm(struct ebsaboot *bootinfo) |
* u_int initarm(...) |
* |
* |
* Initial entry point on startup. This gets called before main() is |
* Initial entry point on startup. This gets called before main() is |
* entered. |
* entered. |
Line 356 struct l1_sec_map { |
|
Line 378 struct l1_sec_map { |
|
*/ |
*/ |
|
|
u_int |
u_int |
initarm(bootinfo) |
initarm(void *arg) |
struct intbootinfo *bootinfo; |
|
{ |
{ |
int loop; |
int loop; |
int loop1; |
int loop1; |
u_int l1pagetable; |
u_int l1pagetable; |
u_int l2pagetable; |
|
extern char page0[], page0_end[]; |
|
extern int etext asm ("_etext"); |
extern int etext asm ("_etext"); |
extern int end asm ("_end"); |
extern int end asm ("_end"); |
pv_addr_t kernel_l1pt; |
pv_addr_t kernel_l1pt; |
pv_addr_t kernel_ptpt; |
pv_addr_t kernel_ptpt; |
|
paddr_t memstart; |
|
psize_t memsize; |
#if NPLCOM > 0 && defined(PLCONSOLE) |
#if NPLCOM > 0 && defined(PLCONSOLE) |
static struct bus_space plcom_bus_space; |
static struct bus_space plcom_bus_space; |
#endif |
#endif |
|
|
|
|
#if 0 |
|
cn_tab = &kcomcons; |
|
#endif |
|
/* |
/* |
* Heads up ... Setup the CPU / MMU / TLB functions |
* Heads up ... Setup the CPU / MMU / TLB functions |
*/ |
*/ |
if (set_cpufuncs()) |
if (set_cpufuncs()) |
panic("cpu not recognized!"); |
panic("cpu not recognized!"); |
|
|
/* - intbootinfo.bt_memstart) / NBPG */; |
|
|
|
#if NPLCOM > 0 && defined(PLCONSOLE) |
#if NPLCOM > 0 && defined(PLCONSOLE) |
/* |
/* |
* Initialise the diagnostic serial console |
* Initialise the diagnostic serial console |
Line 404 initarm(bootinfo) |
|
Line 419 initarm(bootinfo) |
|
#endif |
#endif |
|
|
/* Talk to the user */ |
/* Talk to the user */ |
printf("\nNetBSD/integrator booting ...\n"); |
printf("\nNetBSD/evbarm (Integrator) booting ...\n"); |
|
|
#if 0 |
|
if (intbootinfo.bt_magic != BT_MAGIC_NUMBER_EBSA |
|
&& intbootinfo.bt_magic != BT_MAGIC_NUMBER_CATS) |
|
panic("Incompatible magic number passed in boot args\n"); |
|
#endif |
|
|
|
/* { |
|
int loop; |
|
for (loop = 0; loop < 8; ++loop) { |
|
printf("%08x\n", *(((int *)bootinfo)+loop)); |
|
} |
|
}*/ |
|
|
|
/* |
/* |
* Ok we have the following memory map |
* Ok we have the following memory map |
* |
* |
|
* XXX NO WE DON'T |
|
* |
* virtual address == physical address apart from the areas: |
* virtual address == physical address apart from the areas: |
* 0x00000000 -> 0x000fffff which is mapped to |
* 0x00000000 -> 0x000fffff which is mapped to |
* top 1MB of physical memory |
* top 1MB of physical memory |
Line 445 initarm(bootinfo) |
|
Line 449 initarm(bootinfo) |
|
*/ |
*/ |
|
|
/* |
/* |
* Examine the boot args string for options we need to know about |
* Fetch the SDRAM start/size from the CM configuration registers. |
* now. |
|
*/ |
*/ |
#if 0 |
integrator_sdram_bounds(&memstart, &memsize); |
process_kernel_args((char *)intbootinfo.bt_args); |
|
#endif |
|
|
|
printf("initarm: Configuring system ...\n"); |
printf("initarm: Configuring system ...\n"); |
|
|
|
/* Fake bootconfig structure for the benefit of pmap.c */ |
|
/* XXX must make the memory description h/w independent */ |
|
bootconfig.dramblocks = 1; |
|
bootconfig.dram[0].address = memstart; |
|
bootconfig.dram[0].pages = memsize / NBPG; |
|
|
/* |
/* |
* Set up the variables that define the availablilty of |
* Set up the variables that define the availablilty of |
* physical memory |
* physical memory. For now, we're going to set |
|
* physical_freestart to 0x00200000 (where the kernel |
|
* was loaded), and allocate the memory we need downwards. |
|
* If we get too close to the L1 table that we set up, we |
|
* will panic. We will update physical_freestart and |
|
* physical_freeend later to reflect what pmap_bootstrap() |
|
* wants to see. |
|
* |
|
* XXX pmap_bootstrap() needs an enema. |
*/ |
*/ |
physical_start = 0 /*intbootinfo.bt_memstart*/; |
physical_start = bootconfig.dram[0].address; |
physical_freestart = physical_start; |
physical_end = physical_start + (bootconfig.dram[0].pages * NBPG); |
|
|
#if 0 |
|
physical_end = /*intbootinfo.bt_memend*/ /*intbootinfo.bi_nrpages * NBPG */ 32*1024*1024; |
|
#else |
|
{ |
|
volatile unsigned long *cm_sdram |
|
= (volatile unsigned long *)0x10000020; |
|
|
|
switch ((*cm_sdram >> 2) & 0x7) |
|
{ |
|
case 0: |
|
physical_end = 16 * 1024 * 1024; |
|
break; |
|
case 1: |
|
physical_end = 32 * 1024 * 1024; |
|
break; |
|
case 2: |
|
physical_end = 64 * 1024 * 1024; |
|
break; |
|
case 3: |
|
physical_end = 128 * 1024 * 1024; |
|
break; |
|
case 4: |
|
physical_end = 256 * 1024 * 1024; |
|
break; |
|
default: |
|
printf("CM_SDRAM retuns unknown value, using 16M\n"); |
|
physical_end = 16 * 1024 * 1024; |
|
break; |
|
} |
|
} |
|
#endif |
|
|
|
physical_freeend = physical_end; |
physical_freestart = 0x00009000UL; |
free_pages = (physical_end - physical_start) / NBPG; |
physical_freeend = 0x00200000UL; |
|
|
/* Set up the bootconfig structure for the benefit of pmap.c */ |
|
bootconfig.dramblocks = 1; |
|
bootconfig.dram[0].address = physical_start; |
|
bootconfig.dram[0].pages = free_pages; |
|
|
|
physmem = (physical_end - physical_start) / NBPG; |
physmem = (physical_end - physical_start) / NBPG; |
|
|
/* Tell the user about the memory */ |
/* Tell the user about the memory */ |
Line 508 initarm(bootinfo) |
|
Line 486 initarm(bootinfo) |
|
physical_start, physical_end - 1); |
physical_start, physical_end - 1); |
|
|
/* |
/* |
* Ok the kernel occupies the bottom of physical memory. |
* Okay, the kernel starts 2MB in from the bottom of physical |
* The first free page after the kernel can be found in |
* memory. We are going to allocate our bootstrap pages downwards |
* intbootinfo->bt_memavail |
* from there. |
* 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 |
* We need to allocate some fixed page tables to get the kernel |
* simple really. I have done it like this so that no memory gets |
* going. We allocate one page directory and a number of page |
* wasted during the allocation of various pages and tables that are |
* tables and store the physical addresses in the kernel_pt_table |
* all different sizes. |
* array. |
* The start addresses will be page aligned. |
* |
* We allocate the kernel page directory on the first free 16KB boundry |
* The kernel page directory must be on a 16K boundary. The page |
* we find. |
* tables must be on 4K bounaries. What we do is allocate the |
* We allocate the kernel page tables on the first 4KB boundry we find. |
* page directory on the first 16K boundary that we encounter, and |
* Since we allocate at least 3 L2 pagetables we know that we must |
* the page tables on 4K boundaries otherwise. Since we allocate |
* encounter at least one 16KB aligned address. |
* at least 3 L2 page tables, we are guaranteed to encounter at |
|
* least one 16K aligned region. |
*/ |
*/ |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("Allocating page tables\n"); |
printf("Allocating page tables\n"); |
#endif |
#endif |
|
|
/* Update the address of the first free 16KB chunk of physical memory */ |
free_pages = (physical_freeend - physical_freestart) / NBPG; |
physical_freestart = ((uintptr_t) &end - KERNEL_TEXT_BASE + PGOFSET) |
|
& ~PGOFSET; |
|
#if 0 |
|
physical_freestart += (kernexec->a_syms + sizeof(int) |
|
+ *(u_int *)((int)end + kernexec->a_syms + sizeof(int)) |
|
+ (NBPG - 1)) & ~(NBPG - 1); |
|
#endif |
|
|
|
free_pages -= (physical_freestart - physical_start) / NBPG; |
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("freestart = %#lx, free_pages = %d (%#x)\n", |
printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n", |
physical_freestart, free_pages, free_pages); |
physical_freestart, free_pages, free_pages); |
#endif |
#endif |
|
|
/* Define a macro to simplify memory allocation */ |
/* Define a macro to simplify memory allocation */ |
#define valloc_pages(var, np) \ |
#define valloc_pages(var, np) \ |
alloc_pages((var).pv_pa, (np)); \ |
alloc_pages((var).pv_pa, (np)); \ |
(var).pv_va = KERNEL_TEXT_BASE + (var).pv_pa - physical_start; |
(var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start; |
|
|
#define alloc_pages(var, np) \ |
#define alloc_pages(var, np) \ |
(var) = physical_freestart; \ |
physical_freeend -= ((np) * NBPG); \ |
physical_freestart += ((np) * NBPG); \ |
if (physical_freeend < physical_freestart) \ |
free_pages -= (np); \ |
panic("initarm: out of memory"); \ |
|
(var) = physical_freeend; \ |
|
free_pages -= (np); \ |
memset((char *)(var), 0, ((np) * NBPG)); |
memset((char *)(var), 0, ((np) * NBPG)); |
|
|
loop1 = 0; |
loop1 = 0; |
kernel_l1pt.pv_pa = 0; |
kernel_l1pt.pv_pa = 0; |
for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { |
for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) { |
/* Are we 16KB aligned for an L1 ? */ |
/* Are we 16KB aligned for an L1 ? */ |
if ((physical_freestart & (PD_SIZE - 1)) == 0 |
if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0 |
&& kernel_l1pt.pv_pa == 0) { |
&& kernel_l1pt.pv_pa == 0) { |
valloc_pages(kernel_l1pt, PD_SIZE / NBPG); |
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / NBPG); |
} else { |
} else { |
alloc_pages(kernel_pt_table[loop1], PT_SIZE / NBPG); |
alloc_pages(kernel_pt_table[loop1].pv_pa, |
|
L2_TABLE_SIZE / NBPG); |
|
kernel_pt_table[loop1].pv_va = |
|
kernel_pt_table[loop1].pv_pa; |
++loop1; |
++loop1; |
} |
} |
} |
} |
|
|
/* This should never be able to happen but better confirm that. */ |
/* This should never be able to happen but better confirm that. */ |
if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (PD_SIZE-1)) != 0) |
if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0) |
panic("initarm: Failed to align the kernel page directory\n"); |
panic("initarm: Failed to align the kernel page directory\n"); |
|
|
/* |
/* |
Line 582 initarm(bootinfo) |
|
Line 554 initarm(bootinfo) |
|
*/ |
*/ |
alloc_pages(systempage.pv_pa, 1); |
alloc_pages(systempage.pv_pa, 1); |
|
|
/* Allocate a page for the page table to map kernel page tables*/ |
/* Allocate a page for the page table to map kernel page tables. */ |
valloc_pages(kernel_ptpt, PT_SIZE / NBPG); |
valloc_pages(kernel_ptpt, L2_TABLE_SIZE / NBPG); |
|
|
/* Allocate stacks for all modes */ |
/* Allocate stacks for all modes */ |
valloc_pages(irqstack, IRQ_STACK_SIZE); |
valloc_pages(irqstack, IRQ_STACK_SIZE); |
Line 592 initarm(bootinfo) |
|
Line 564 initarm(bootinfo) |
|
valloc_pages(kernelstack, UPAGES); |
valloc_pages(kernelstack, UPAGES); |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, irqstack.pv_va); |
printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa, |
printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, abtstack.pv_va); |
irqstack.pv_va); |
printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa, undstack.pv_va); |
printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa, |
printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa, kernelstack.pv_va); |
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 |
#endif |
|
|
alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG); |
alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / NBPG); |
Line 606 initarm(bootinfo) |
|
Line 582 initarm(bootinfo) |
|
*/ |
*/ |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("Creating L1 page table at %#lx\n", kernel_l1pt.pv_pa); |
printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa); |
#endif |
#endif |
|
|
/* |
/* |
* Now we start consturction of the L1 page table |
* Now we start construction of the L1 page table |
* We start by mapping the L2 page tables into the L1. |
* We start by mapping the L2 page tables into the L1. |
* This means that we can replace L1 mappings later on if necessary |
* This means that we can replace L1 mappings later on if necessary |
*/ |
*/ |
l1pagetable = kernel_l1pt.pv_pa; |
l1pagetable = kernel_l1pt.pv_pa; |
|
|
/* Map the L2 pages tables in the L1 page table */ |
/* Map the L2 pages tables in the L1 page table */ |
map_pagetable(l1pagetable, 0x00000000, |
pmap_link_l2pt(l1pagetable, 0x00000000, |
kernel_pt_table[KERNEL_PT_SYS]); |
&kernel_pt_table[KERNEL_PT_SYS]); |
map_pagetable(l1pagetable, KERNEL_BASE, |
for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) |
kernel_pt_table[KERNEL_PT_KERNEL]); |
pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000, |
for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) |
&kernel_pt_table[KERNEL_PT_KERNEL + loop]); |
map_pagetable(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, |
for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) |
kernel_pt_table[KERNEL_PT_VMDATA + loop]); |
pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, |
map_pagetable(l1pagetable, PROCESS_PAGE_TBLS_BASE, |
&kernel_pt_table[KERNEL_PT_VMDATA + loop]); |
kernel_ptpt.pv_pa); |
pmap_link_l2pt(l1pagetable, PTE_BASE, &kernel_ptpt); |
|
|
|
/* update the top of the kernel VM */ |
|
pmap_curmaxkvaddr = |
|
KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000); |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("Mapping kernel\n"); |
printf("Mapping kernel\n"); |
#endif |
#endif |
|
|
/* Now we fill in the L2 pagetable for the kernel static code/data */ |
/* Now we fill in the L2 pagetable for the kernel static code/data */ |
l2pagetable = kernel_pt_table[KERNEL_PT_KERNEL]; |
|
|
|
{ |
{ |
u_int logical; |
|
size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE; |
size_t textsize = (uintptr_t) &etext - KERNEL_TEXT_BASE; |
size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE; |
size_t totalsize = (uintptr_t) &end - KERNEL_TEXT_BASE; |
|
u_int logical; |
|
|
/* Round down text size and round up total size |
textsize = (textsize + PGOFSET) & ~PGOFSET; |
*/ |
|
textsize = textsize & ~PGOFSET; |
|
totalsize = (totalsize + PGOFSET) & ~PGOFSET; |
totalsize = (totalsize + PGOFSET) & ~PGOFSET; |
/* logical = map_chunk(l1pagetable, l2pagetable, KERNEL_BASE, |
|
physical_start, KERNEL_TEXT_BASE - KERNEL_BASE, |
logical = 0x00200000; /* offset of kernel in RAM */ |
AP_KRW, PT_CACHEABLE); */ |
|
logical = map_chunk(l1pagetable, l2pagetable, |
logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, |
KERNEL_TEXT_BASE, physical_start, textsize, |
physical_start + logical, textsize, |
AP_KRW, PT_CACHEABLE); |
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
logical += map_chunk(l1pagetable, l2pagetable, |
logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical, |
KERNEL_TEXT_BASE + logical, physical_start + logical, |
physical_start + logical, totalsize - textsize, |
totalsize - textsize, AP_KRW, PT_CACHEABLE); |
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
#if 0 |
|
logical += map_chunk(0, l2pagetable, KERNEL_BASE + logical, |
|
physical_start + logical, kernexec->a_syms + sizeof(int) |
|
+ *(u_int *)((int)end + kernexec->a_syms + sizeof(int)), |
|
AP_KRW, PT_CACHEABLE); |
|
#endif |
|
} |
} |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("Constructing L2 page tables\n"); |
printf("Constructing L2 page tables\n"); |
#endif |
#endif |
|
|
/* Map the boot arguments page */ |
|
#if 0 |
|
map_entry_ro(l2pagetable, intbootinfo.bt_vargp, intbootinfo.bt_pargp); |
|
#endif |
|
|
|
/* Map the stack pages */ |
/* Map the stack pages */ |
map_chunk(0, l2pagetable, irqstack.pv_va, irqstack.pv_pa, |
pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, |
IRQ_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE); |
IRQ_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
map_chunk(0, l2pagetable, abtstack.pv_va, abtstack.pv_pa, |
pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa, |
ABT_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE); |
ABT_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
map_chunk(0, l2pagetable, undstack.pv_va, undstack.pv_pa, |
pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa, |
UND_STACK_SIZE * NBPG, AP_KRW, PT_CACHEABLE); |
UND_STACK_SIZE * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
map_chunk(0, l2pagetable, kernelstack.pv_va, kernelstack.pv_pa, |
pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa, |
UPAGES * NBPG, AP_KRW, PT_CACHEABLE); |
UPAGES * NBPG, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
map_chunk(0, l2pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, |
|
PD_SIZE, AP_KRW, 0); |
pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, |
|
L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
|
/* Map the page table that maps the kernel pages */ |
/* Map the page table that maps the kernel pages */ |
map_entry_nc(l2pagetable, kernel_ptpt.pv_pa, kernel_ptpt.pv_pa); |
pmap_map_entry(l1pagetable, kernel_ptpt.pv_va, kernel_ptpt.pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
|
/* |
/* |
* Map entries in the page table used to map PTE's |
* Map entries in the page table used to map PTE's |
* Basically every kernel page table gets mapped here |
* Basically every kernel page table gets mapped here |
*/ |
*/ |
/* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */ |
/* The -2 is slightly bogus, it should be -log2(sizeof(pt_entry_t)) */ |
l2pagetable = kernel_ptpt.pv_pa; |
for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++) { |
map_entry_nc(l2pagetable, (KERNEL_BASE >> (PGSHIFT-2)), |
pmap_map_entry(l1pagetable, |
kernel_pt_table[KERNEL_PT_KERNEL]); |
PTE_BASE + ((KERNEL_BASE + |
map_entry_nc(l2pagetable, (PROCESS_PAGE_TBLS_BASE >> (PGSHIFT-2)), |
|
kernel_ptpt.pv_pa); |
|
map_entry_nc(l2pagetable, (0x00000000 >> (PGSHIFT-2)), |
|
kernel_pt_table[KERNEL_PT_SYS]); |
|
for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) |
|
map_entry_nc(l2pagetable, ((KERNEL_VM_BASE + |
|
(loop * 0x00400000)) >> (PGSHIFT-2)), |
(loop * 0x00400000)) >> (PGSHIFT-2)), |
kernel_pt_table[KERNEL_PT_VMDATA + loop]); |
kernel_pt_table[KERNEL_PT_KERNEL + loop].pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
} |
|
pmap_map_entry(l1pagetable, |
|
PTE_BASE + (PTE_BASE >> (PGSHIFT-2)), |
|
kernel_ptpt.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
pmap_map_entry(l1pagetable, |
|
PTE_BASE + (0x00000000 >> (PGSHIFT-2)), |
|
kernel_pt_table[KERNEL_PT_SYS].pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++) |
|
pmap_map_entry(l1pagetable, |
|
PTE_BASE + ((KERNEL_VM_BASE + |
|
(loop * 0x00400000)) >> (PGSHIFT-2)), |
|
kernel_pt_table[KERNEL_PT_VMDATA + loop].pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
|
|
/* |
/* Map the vector page. */ |
* Map the system page in the kernel page table for the bottom 1Meg |
|
* of the virtual memory map. |
|
*/ |
|
l2pagetable = kernel_pt_table[KERNEL_PT_SYS]; |
|
#if 1 |
#if 1 |
/* MULTI-ICE requires that page 0 is NC/NB so that it can download |
/* MULTI-ICE requires that page 0 is NC/NB so that it can download |
the cache-clean code there. */ |
the cache-clean code there. */ |
map_entry_nc(l2pagetable, 0x00000000, systempage.pv_pa); |
pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); |
#else |
#else |
map_entry_nc(l2pagetable, 0x00000000, systempage.pv_pa); |
pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, |
|
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); |
#endif |
#endif |
/* Map the core memory needed before autoconfig */ |
/* Map the core memory needed before autoconfig */ |
loop = 0; |
loop = 0; |
Line 723 initarm(bootinfo) |
|
Line 697 initarm(bootinfo) |
|
l1_sec_table[loop].pa + l1_sec_table[loop].size - 1, |
l1_sec_table[loop].pa + l1_sec_table[loop].size - 1, |
l1_sec_table[loop].va); |
l1_sec_table[loop].va); |
#endif |
#endif |
for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_SEC_SIZE) |
for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE) |
map_section(l1pagetable, l1_sec_table[loop].va + sz, |
pmap_map_section(l1pagetable, |
|
l1_sec_table[loop].va + sz, |
l1_sec_table[loop].pa + sz, |
l1_sec_table[loop].pa + sz, |
l1_sec_table[loop].flags); |
l1_sec_table[loop].prot, |
|
l1_sec_table[loop].cache); |
++loop; |
++loop; |
} |
} |
|
|
/* |
/* |
* Now we have the real page tables in place so we can switch to them. |
* Now we have the real page tables in place so we can switch to them. |
* Once this is done we will be running with the REAL kernel page tables. |
* Once this is done we will be running with the REAL kernel page |
|
* tables. |
*/ |
*/ |
|
|
|
/* |
|
* Update the physical_freestart/physical_freeend/free_pages |
|
* variables. |
|
*/ |
|
{ |
|
physical_freestart = physical_start + |
|
(((((uintptr_t) &end) + PGOFSET) & ~PGOFSET) - |
|
KERNEL_BASE); |
|
physical_freeend = physical_end; |
|
free_pages = (physical_freeend - physical_freestart) / NBPG; |
|
} |
|
|
/* Switch tables */ |
/* Switch tables */ |
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("freestart = %#lx, free_pages = %d (%#x)\n", |
printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n", |
physical_freestart, free_pages, free_pages); |
physical_freestart, free_pages, free_pages); |
printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); |
printf("switching to new L1 page table @%#lx...", kernel_l1pt.pv_pa); |
#endif |
#endif |
|
|
setttb(kernel_l1pt.pv_pa); |
setttb(kernel_l1pt.pv_pa); |
|
cpu_tlb_flushID(); |
|
|
#ifdef VERBOSE_INIT_ARM |
#ifdef VERBOSE_INIT_ARM |
printf("done!\n"); |
printf("done!\n"); |
Line 766 initarm(bootinfo) |
|
Line 755 initarm(bootinfo) |
|
printf("bootstrap done.\n"); |
printf("bootstrap done.\n"); |
#endif |
#endif |
|
|
/* Right set up the vectors at the bottom of page 0 */ |
arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); |
memcpy((char *)0x00000000, page0, page0_end - page0); |
|
|
|
/* We have modified a text page so sync the icache */ |
|
cpu_cache_syncI(); |
|
|
|
/* |
/* |
* Pages were allocated during the secondary bootstrap for the |
* Pages were allocated during the secondary bootstrap for the |
Line 788 initarm(bootinfo) |
|
Line 773 initarm(bootinfo) |
|
|
|
/* |
/* |
* Well we should set a data abort handler. |
* Well we should set a data abort handler. |
* Once things get going this will change as we will need a proper handler. |
* Once things get going this will change as we will need a proper |
|
* handler. |
* Until then we will use a handler that just panics but tells us |
* Until then we will use a handler that just panics but tells us |
* why. |
* why. |
* Initialisation of the vectors will just panic on a data abort. |
* Initialisation of the vectors will just panic on a data abort. |
Line 799 initarm(bootinfo) |
|
Line 785 initarm(bootinfo) |
|
prefetch_abort_handler_address = (u_int)prefetch_abort_handler; |
prefetch_abort_handler_address = (u_int)prefetch_abort_handler; |
undefined_handler_address = (u_int)undefinedinstruction_bounce; |
undefined_handler_address = (u_int)undefinedinstruction_bounce; |
|
|
/* At last ! |
|
* We now have the kernel in physical memory from the bottom upwards. |
|
* Kernel page tables are physically above this. |
|
* The kernel is mapped to KERNEL_TEXT_BASE |
|
* The kernel data PTs will handle the mapping of 0xf1000000-0xf3ffffff |
|
* The page tables are mapped to 0xefc00000 |
|
*/ |
|
|
|
/* Initialise the undefined instruction handlers */ |
/* Initialise the undefined instruction handlers */ |
printf("undefined "); |
printf("undefined "); |
undefined_init(); |
undefined_init(); |
|
|
|
/* Load memory into UVM. */ |
|
printf("page "); |
|
uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ |
|
uvm_page_physload(atop(physical_freestart), atop(physical_freeend), |
|
atop(physical_freestart), atop(physical_freeend), |
|
VM_FREELIST_DEFAULT); |
|
|
/* Boot strap pmap telling it where the kernel page table is */ |
/* Boot strap pmap telling it where the kernel page table is */ |
printf("pmap "); |
printf("pmap "); |
pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt); |
pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, kernel_ptpt); |
Line 843 initarm(bootinfo) |
|
Line 828 initarm(bootinfo) |
|
} |
} |
|
|
void |
void |
process_kernel_args(args) |
|
char *args; |
|
{ |
|
|
|
boothowto = 0; |
|
|
|
/* Make a local copy of the bootargs */ |
|
strncpy(bootargs, args, MAX_BOOT_STRING); |
|
|
|
args = bootargs; |
|
boot_file = bootargs; |
|
|
|
/* Skip the kernel image filename */ |
|
while (*args != ' ' && *args != 0) |
|
++args; |
|
|
|
if (*args != 0) |
|
*args++ = 0; |
|
|
|
while (*args == ' ') |
|
++args; |
|
|
|
boot_args = args; |
|
|
|
printf("bootfile: %s\n", boot_file); |
|
printf("bootargs: %s\n", boot_args); |
|
|
|
parse_mi_bootargs(boot_args); |
|
} |
|
|
|
void |
|
consinit(void) |
consinit(void) |
{ |
{ |
static int consinit_called = 0; |
static int consinit_called = 0; |
|
|
panic("No serial console configured"); |
panic("No serial console configured"); |
} |
} |
|
|
#if 0 |
|
static bus_space_handle_t kcom_base = (bus_space_handle_t) (DC21285_PCI_IO_VBASE + CONCOMADDR); |
|
|
|
u_int8_t footbridge_bs_r_1(void *, bus_space_handle_t, bus_size_t); |
|
void footbridge_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t); |
|
|
|
#define KCOM_GETBYTE(r) footbridge_bs_r_1(0, kcom_base, (r)) |
|
#define KCOM_PUTBYTE(r,v) footbridge_bs_w_1(0, kcom_base, (r), (v)) |
|
|
|
static int |
|
kcomcngetc(dev_t dev) |
|
{ |
|
int stat, c; |
|
|
|
/* block until a character becomes available */ |
|
while (!ISSET(stat = KCOM_GETBYTE(com_lsr), LSR_RXRDY)) |
|
; |
|
|
|
c = KCOM_GETBYTE(com_data); |
|
stat = KCOM_GETBYTE(com_iir); |
|
return c; |
|
} |
|
|
|
/* |
|
* Console kernel output character routine. |
|
*/ |
|
static void |
static void |
kcomcnputc(dev_t dev, int c) |
integrator_sdram_bounds(paddr_t *memstart, psize_t *memsize) |
{ |
{ |
int timo; |
volatile unsigned long *cm_sdram |
|
= (volatile unsigned long *)0x10000020; |
|
|
/* wait for any pending transmission to finish */ |
*memstart = 0; |
timo = 150000; |
|
while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo) |
|
continue; |
|
|
|
KCOM_PUTBYTE(com_data, c); |
|
|
|
/* wait for this transmission to complete */ |
|
timo = 1500000; |
|
while (!ISSET(KCOM_GETBYTE(com_lsr), LSR_TXRDY) && --timo) |
|
continue; |
|
} |
|
|
|
static void |
switch ((*cm_sdram >> 2) & 0x7) |
kcomcnpollc(dev_t dev, int on) |
{ |
{ |
case 0: |
|
*memsize = 16 * 1024 * 1024; |
|
break; |
|
case 1: |
|
*memsize = 32 * 1024 * 1024; |
|
break; |
|
case 2: |
|
*memsize = 64 * 1024 * 1024; |
|
break; |
|
case 3: |
|
*memsize = 128 * 1024 * 1024; |
|
break; |
|
case 4: |
|
*memsize = 256 * 1024 * 1024; |
|
break; |
|
default: |
|
printf("CM_SDRAM retuns unknown value, using 16M\n"); |
|
*memsize = 16 * 1024 * 1024; |
|
break; |
|
} |
} |
} |
|
|
struct consdev kcomcons = { |
|
NULL, NULL, kcomcngetc, kcomcnputc, kcomcnpollc, NULL, |
|
NODEV, CN_NORMAL |
|
}; |
|
|
|
#endif |
|