diff --git a/sys/arch/evbarm/iq80310/iq80310_machdep.c b/sys/arch/evbarm/iq80310/iq80310_machdep.c index ab5c70e99668..e30bec8c99b4 100644 --- a/sys/arch/evbarm/iq80310/iq80310_machdep.c +++ b/sys/arch/evbarm/iq80310/iq80310_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: iq80310_machdep.c,v 1.2 2001/11/07 00:33:24 thorpej Exp $ */ +/* $NetBSD: iq80310_machdep.c,v 1.3 2001/11/08 03:28:53 thorpej Exp $ */ /* * Copyright (c) 1997,1998 Mark Brinicombe. @@ -67,6 +67,8 @@ #include #include +#include + #include #include #include @@ -127,7 +129,8 @@ extern int pmap_debug_level; #define KERNEL_PT_SYS 0 /* Page table for mapping proc0 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_IOPXS 2 /* Page table for mapping i80312 */ +#define KERNEL_PT_VMDATA 3 /* Page tables for mapping kernel VM */ #define KERNEL_PT_VMDATA_NUM (KERNEL_VM_SIZE >> (PDSHIFT + 2)) #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) @@ -323,8 +326,32 @@ initarm(void) printf("\nNetBSD/evbarm (IQ80310) booting ...\n"); /* - * Okay, RedBoot has provided us with the following memory map: + * Reset the secondary PCI bus. RedBoot doesn't stop devices + * on the PCI bus before handing us control, so we have to + * do this. * + * XXX This is arguably a bug in RedBoot, and doing this reset + * XXX could be problematic in the future if we encounter an + * XXX application where the PPB in the i80312 is used as a + * XXX PPB. + */ + { + uint32_t reg; + + printf("Resetting secondary PCI bus...\n"); + reg = bus_space_read_4(&obio_bs_tag, + I80312_PMMR_BASE + I80312_PPB_BASE, PPB_REG_BRIDGECONTROL); + bus_space_write_4(&obio_bs_tag, + I80312_PMMR_BASE + I80312_PPB_BASE, PPB_REG_BRIDGECONTROL, + reg | PPB_BC_SECONDARY_RESET); + delay(10 * 1000); /* 10ms enough? */ + bus_space_write_4(&obio_bs_tag, + I80312_PMMR_BASE + I80312_PPB_BASE, PPB_REG_BRIDGECONTROL, + reg); + } + + /* + * Okay, RedBoot has provided us with the following memory map: * * Physical Address Range Description * ----------------------- ---------------------------------- @@ -380,8 +407,8 @@ initarm(void) * Fetch the SDRAM start/size from the i80312 SDRAM configration * registers. */ - i80312_sdram_bounds(&obio_bs_tag, I80312_MEM_BASE, &memstart, - &memsize); + i80312_sdram_bounds(&obio_bs_tag, I80312_PMMR_BASE + I80312_MEM_BASE, + &memstart, &memsize); printf("initarm: Configuring system ...\n"); @@ -528,6 +555,8 @@ initarm(void) kernel_pt_table[KERNEL_PT_SYS]); map_pagetable(l1pagetable, KERNEL_BASE, kernel_pt_table[KERNEL_PT_KERNEL]); + map_pagetable(l1pagetable, IQ80310_IOPXS_VBASE, + kernel_pt_table[KERNEL_PT_IOPXS]); for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) map_pagetable(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, kernel_pt_table[KERNEL_PT_VMDATA + loop]); @@ -614,7 +643,9 @@ initarm(void) l2pagetable = kernel_pt_table[KERNEL_PT_SYS]; map_entry(l2pagetable, 0x00000000, systempage.pv_pa); - /* Map the core memory needed before autoconfig */ + /* + * Map devices we can map w/ section mappings. + */ loop = 0; while (l1_sec_table[loop].size) { vm_size_t sz; @@ -631,6 +662,38 @@ initarm(void) ++loop; } + /* + * Map the PCI I/O spaces and i80312 registers. These are too + * small to be mapped w/ section mappings. + */ + l2pagetable = kernel_pt_table[KERNEL_PT_IOPXS]; +#ifdef VERBOSE_INIT_ARM + printf("Mapping PIOW 0x%08lx -> 0x%08lx @ 0x%08lx\n", + I80312_PCI_XLATE_PIOW_BASE, + I80312_PCI_XLATE_PIOW_BASE + I80312_PCI_XLATE_IOSIZE - 1, + IQ80310_PIOW_VBASE); +#endif + map_chunk(0, l2pagetable, IQ80310_PIOW_VBASE, + I80312_PCI_XLATE_PIOW_BASE, I80312_PCI_XLATE_IOSIZE, AP_KRW, 0); + +#ifdef VERBOSE_INIT_ARM + printf("Mapping SIOW 0x%08lx -> 0x%08lx @ 0x%08lx\n", + I80312_PCI_XLATE_SIOW_BASE, + I80312_PCI_XLATE_SIOW_BASE + I80312_PCI_XLATE_IOSIZE - 1, + IQ80310_SIOW_VBASE); +#endif + map_chunk(0, l2pagetable, IQ80310_SIOW_VBASE, + I80312_PCI_XLATE_SIOW_BASE, I80312_PCI_XLATE_IOSIZE, AP_KRW, 0); + +#ifdef VERBOSE_INIT_ARM + printf("Mapping SIOW 0x%08lx -> 0x%08lx @ 0x%08lx\n", + I80312_PMMR_BASE, + I80312_PMMR_BASE + I80312_PMMR_SIZE - 1, + IQ80310_80312_VBASE); +#endif + map_chunk(0, l2pagetable, IQ80310_80312_VBASE, + I80312_PMMR_BASE, I80312_PMMR_SIZE, AP_KRW, 0); + /* * 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 diff --git a/sys/arch/evbarm/iq80310/iq80310reg.h b/sys/arch/evbarm/iq80310/iq80310reg.h index 4b0f8e19afe9..84d18d367620 100644 --- a/sys/arch/evbarm/iq80310/iq80310reg.h +++ b/sys/arch/evbarm/iq80310/iq80310reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: iq80310reg.h,v 1.2 2001/11/07 02:24:18 thorpej Exp $ */ +/* $NetBSD: iq80310reg.h,v 1.3 2001/11/08 03:28:53 thorpej Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -79,8 +79,22 @@ #define CPLD_READ(x) *((__volatile uint8_t *)(x)) #define CPLD_WRITE(x, v) *((__volatile uint8_t *)(x)) = (v) +/* + * We allocate a page table for VA 0xfe400000 (4MB) and map the i80312 + * PCI I/O space (2 * 64L) and i80312 regisers (4K) there. + */ +#define IQ80310_IOPXS_VBASE 0xfe400000UL +#define IQ80310_PIOW_VBASE IQ80310_IOPXS_VBASE +#define IQ80310_SIOW_VBASE (IQ80310_PIOW_VBASE + I80312_PCI_XLATE_IOSIZE) +#define IQ80310_80312_VBASE (IQ80310_SIOW_VBASE + I80312_PCI_XLATE_IOSIZE) + +/* + * The IQ80310 on-board devices are mapped VA==PA during bootstrap. + * Conveniently, the size of the on-board register space is 1 section + * mapping. + */ #define IQ80310_OBIO_BASE 0xfe800000UL -#define IQ80310_OBIO_SIZE 0x00100000UL +#define IQ80310_OBIO_SIZE 0x00100000UL /* 1MB */ #define IQ80310_UART1 0xfe800000UL /* XR 16550 */