Beispiel #1
0
Datei: ucode.c Projekt: glankk/gz
Gfx *load_l3dex2(Gfx **pgdl)
{
  if (have_l3dex2()) {
    gSPLoadUcode((*pgdl)++,
                 MIPS_KSEG0_TO_PHYS(gspL3DEX2_fifoTextStart),
                 MIPS_KSEG0_TO_PHYS(gspL3DEX2_fifoDataStart));
  }
  return *pgdl;
}
Beispiel #2
0
Datei: ucode.c Projekt: glankk/gz
Gfx *unload_l3dex2(Gfx **pgdl, _Bool set_lights)
{
  if (have_l3dex2()) {
    gSPLoadUcode((*pgdl)++,
                 MIPS_KSEG0_TO_PHYS(gspF3DEX2_NoN_fifoTextStart),
                 MIPS_KSEG0_TO_PHYS(gspF3DEX2_NoN_fifoDataStart));
    if (set_lights) {
      Lights0 lites;
      lites.a.l.col[0] = lites.a.l.colc[0] = z64_game.lighting.ambient[0];
      lites.a.l.col[1] = lites.a.l.colc[1] = z64_game.lighting.ambient[1];
      lites.a.l.col[2] = lites.a.l.colc[2] = z64_game.lighting.ambient[2];
      gSPSetLights0((*pgdl)++, lites);
    }
  }
  return *pgdl;
}
Beispiel #3
0
static void
mips_init(void)
{
	int i;

	printf("entry: mips_init()\n");

	bootverbose = 1;
	realmem = btoc(32 << 20);

	for (i = 0; i < 10; i++) {
		phys_avail[i] = 0;
	}

	/* phys_avail regions are in bytes */
	dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
	dump_avail[1] = phys_avail[1] = ctob(realmem);

	physmem = realmem;

	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
/*
 * Return true if we freed it, false if we didn't.
 */
bool
cpu_uarea_free(void *va)
{
#ifdef _LP64
	if (!MIPS_XKPHYS_P(va))
		return false;
	paddr_t pa = MIPS_XKPHYS_TO_PHYS(va);
#else
	if (!MIPS_KSEG0_P(va))
		return false;
	paddr_t pa = MIPS_KSEG0_TO_PHYS(va);
#endif

#ifdef MIPS3_PLUS
	if (MIPS_CACHE_VIRTUAL_ALIAS)
		mips_dcache_inv_range((vaddr_t)va, USPACE);
#endif

	for (const paddr_t epa = pa + USPACE; pa < epa; pa += PAGE_SIZE) {
		struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
		KASSERT(pg != NULL);
		uvm_pagefree(pg);
	}
	return true;
}
Beispiel #5
0
static int
vrdmaau_phy_addr(struct vrdmaau_softc *sc, void *addr, u_int32_t *phy)
{
	DPRINTFN(1, ("vrdmaau_phy_addr\n"));

	if (addr >= (void *)MIPS_KSEG0_START &&
	    addr < (void *)MIPS_KSEG1_START)
		*phy = MIPS_KSEG0_TO_PHYS(addr);
	else if (addr >= (void *)MIPS_KSEG1_START &&
		 addr < (void *)MIPS_KSEG2_START)
		*phy = MIPS_KSEG1_TO_PHYS(addr);
	else {
		DPRINTFN(0, ("vrdmaau_map_addr: invalid address %p\n", addr));
		return EFAULT;
	}

#ifdef DIAGNOSTIC
	if ((*phy & (VRDMAAU_ALIGNMENT - 1)) ||
	    *phy >= VRDMAAU_BOUNCE_THRESHOLD ) {
		printf("%s: vrdmaau_phy_addr: invalid address %p\n",
		       sc->sc_dev.dv_xname, addr);
		return EINVAL;
	}
#endif
	return 0;
}
static void
mips_init(void)
{
	int i;

	for (i = 0; i < 10; i++) {
		phys_avail[i] = 0;
	}

	/* phys_avail regions are in bytes */
	phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end);
	phys_avail[1] = ctob(realmem);

	physmem = realmem;

	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
#ifdef DDB
	kdb_init();
#endif
}
Beispiel #7
0
static void
mips_init(void)
{
	int i;
#ifdef FDT
	struct mem_region mr[FDT_MEM_REGIONS];
	uint64_t val;
	int mr_cnt;
	int j;
#endif

	for (i = 0; i < 10; i++) {
		phys_avail[i] = 0;
	}

	/* phys_avail regions are in bytes */
	phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
	phys_avail[1] = ctob(realmem);

	dump_avail[0] = phys_avail[0];
	dump_avail[1] = phys_avail[1];

	physmem = realmem;

#ifdef FDT
	if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) {

		physmem = btoc(val);

		KASSERT((phys_avail[0] >= mr[0].mr_start) && \
			(phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)),
			("First region is not within FDT memory range"));

		/* Limit size of the first region */
		phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem)));
		dump_avail[1] = phys_avail[1];

		/* Add the rest of regions */
		for (i = 1, j = 2; i < mr_cnt; i++, j+=2) {
			phys_avail[j] = mr[i].mr_start;
			phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size);
			dump_avail[j] = phys_avail[j];
			dump_avail[j+1] = phys_avail[j+1];
		}
	}
#endif

	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #8
0
int
arc_bus_space_paddr(bus_space_tag_t bst, bus_space_handle_t bsh, paddr_t *pap)
{

	if (bsh < MIPS_KSEG0_START) /* KUSEG */
		panic("arc_bus_space_paddr(0x%qx): bad address",
		    (unsigned long long) bsh);
	else if (bsh < MIPS_KSEG1_START) /* KSEG0 */
		*pap = MIPS_KSEG0_TO_PHYS(bsh);
	else if (bsh < MIPS_KSEG2_START) /* KSEG1 */
		*pap = MIPS_KSEG1_TO_PHYS(bsh);
	else { /* KSEG2 */
		/*
		 * Since this region may be mapped by wired TLB,
		 * kvtophys() is not always available.
		 */
		*pap = bst->bs_pbase + (bsh - bst->bs_vbase);
	}
	return 0;
}
Beispiel #9
0
int
_kvm_minidump_kvatop(kvm_t *kd, u_long va, off_t *pa)
{
	struct vmstate *vm;
	pt_entry_t pte;
	u_long offset, pteindex, a;
	off_t ofs;
	pt_entry_t *ptemap;

	if (ISALIVE(kd)) {
		_kvm_err(kd, 0, "kvm_kvatop called in live kernel!");
		return (0);
	}

 	offset = va & PAGE_MASK;
	/* Operate with page-aligned address */
	va &= ~PAGE_MASK;

	vm = kd->vmst;
	ptemap = vm->ptemap;

#if defined(__mips_n64)
	if (va >= MIPS_XKPHYS_START && va < MIPS_XKPHYS_END)
		a = (MIPS_XKPHYS_TO_PHYS(va));
	else
#endif
	if (va >= (u_long)MIPS_KSEG0_START && va < (u_long)MIPS_KSEG0_END)
		a = (MIPS_KSEG0_TO_PHYS(va));
	else if (va >= (u_long)MIPS_KSEG1_START && va < (u_long)MIPS_KSEG1_END)
		a = (MIPS_KSEG1_TO_PHYS(va));
	else if (va >= vm->hdr.kernbase) {
		pteindex = (va - vm->hdr.kernbase) >> PAGE_SHIFT;
		pte = ptemap[pteindex];
		if (!pte) {
			_kvm_err(kd, kd->program, "_kvm_vatop: pte not valid");
			goto invalid;
		}

		a = TLBLO_PTE_TO_PA(pte);

	} else {
Beispiel #10
0
/*----------------------------------------------------------------------------
 *
 * mips3_ConfigCache --
 *
 *	Size the caches.
 *	NOTE: should only be called from mach_init().
 *
 * Results:
 *     	None.
 *
 * Side effects:
 *	The size of the data cache is stored into mips_L1DCacheSize.
 *	The size of instruction cache is stored into mips_L1ICacheSize.
 *	Alignment mask for cache aliasing test is stored in mips_CacheAliasMask.
 *
 * XXX: method to retrieve mips_L2CacheSize is port dependent.
 *
 *----------------------------------------------------------------------------
 */
void
mips3_ConfigCache()
{
    u_int32_t config = mips3_read_config();
    static int snoop_check = 0;
    register int i;

    mips_L1ICacheSize = MIPS3_CONFIG_CACHE_SIZE(config,
                        MIPS3_CONFIG_IC_MASK, MIPS3_CONFIG_IC_SHIFT);
    mips_L1ICacheLSize = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
                         MIPS3_CONFIG_IB);
    mips_L1DCacheSize = MIPS3_CONFIG_CACHE_SIZE(config,
                        MIPS3_CONFIG_DC_MASK, MIPS3_CONFIG_DC_SHIFT);
    mips_L1DCacheLSize = MIPS3_CONFIG_CACHE_L1_LSIZE(config,
                         MIPS3_CONFIG_DB);

    mips_CacheAliasMask = (mips_L1DCacheLSize - 1) & ~(NBPG - 1);

    /*
     * Clear out the I and D caches.
     */
    mips_L2CacheSize = 0; /* kluge to skip L2 cache flush */
    mips3_FlushCache();

    i = *(volatile int *)&snoop_check;	/* Read and cache */
    mips3_FlushCache();			/* Flush */
    *(volatile int *)MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(&snoop_check))
        = ~i;				/* Write uncached */
    mips_L2CacheIsSnooping = *(volatile int *)&snoop_check == ~i;
    *(volatile int *)&snoop_check = i;	/* Write uncached */
    mips3_FlushCache();			/* Flush */


    mips_L2CachePresent = (config & MIPS3_CONFIG_SC) == 0;
    mips_L2CacheLSize = MIPS3_CONFIG_CACHE_L2_LSIZE(config);
    if (!mips_L2CachePresent) {
        mips_L2CacheSize = 0;
    }
    mips_L2CacheMixed = (config & MIPS3_CONFIG_SS) == 0;
}
/*
 * Map a (kernel) virtual address to a physical address.
 *
 * MIPS processor has 3 distinct kernel address ranges:
 *
 * - kseg0 kernel "virtual address" for the   cached physical address space.
 * - kseg1 kernel "virtual address" for the uncached physical address space.
 * - kseg2 normal kernel "virtual address" mapped via the TLB.
 */
paddr_t
kvtophys(vaddr_t kva)
{
	pt_entry_t *pte;
	paddr_t phys;

	if (kva >= VM_MIN_KERNEL_ADDRESS) {
		if (kva >= VM_MAX_KERNEL_ADDRESS)
			goto overrun;

		pte = kvtopte(kva);
		if ((size_t) (pte - Sysmap) >= Sysmapsize)  {
			printf("oops: Sysmap overrun, max %d index %zd\n",
			       Sysmapsize, pte - Sysmap);
		}
		if (!mips_pg_v(pte->pt_entry)) {
			printf("kvtophys: pte not valid for %#"PRIxVADDR"\n",
			    kva);
		}
		phys = mips_tlbpfn_to_paddr(pte->pt_entry) | (kva & PGOFSET);
		return phys;
	}
	if (MIPS_KSEG1_P(kva))
		return MIPS_KSEG1_TO_PHYS(kva);

	if (MIPS_KSEG0_P(kva))
		return MIPS_KSEG0_TO_PHYS(kva);
#ifdef _LP64
	if (MIPS_XKPHYS_P(kva))
		return MIPS_XKPHYS_TO_PHYS(kva);
#endif
overrun:
	printf("Virtual address %#"PRIxVADDR": cannot map to physical\n", kva);
#ifdef DDB
	Debugger();
	return 0;	/* XXX */
#endif
	panic("kvtophys");
}
Beispiel #12
0
/*
 * Map a (kernel) virtual address to a physical address.
 *
 * MIPS processor has 3 distinct kernel address ranges:
 *
 * - kseg0 kernel "virtual address" for the   cached physical address space.
 * - kseg1 kernel "virtual address" for the uncached physical address space.
 * - kseg2 normal kernel "virtual address" mapped via the TLB.
 */
paddr_t
kvtophys(vaddr_t kva)
{
	paddr_t phys;

	if (MIPS_KSEG1_P(kva))
		return MIPS_KSEG1_TO_PHYS(kva);

	if (MIPS_KSEG0_P(kva))
		return MIPS_KSEG0_TO_PHYS(kva);

	if (kva >= VM_MIN_KERNEL_ADDRESS) {
		if (kva >= VM_MAX_KERNEL_ADDRESS)
			goto overrun;

		pt_entry_t * const ptep = pmap_pte_lookup(pmap_kernel(), kva);
		if (ptep == NULL)
			goto overrun;
		if (!pte_valid_p(*ptep)) {
			printf("kvtophys: pte not valid for %#"PRIxVADDR"\n",
			    kva);
		}
		phys = pte_to_paddr(*ptep) | (kva & PGOFSET);
		return phys;
	}
#ifdef _LP64
	if (MIPS_XKPHYS_P(kva))
		return MIPS_XKPHYS_TO_PHYS(kva);
#endif
overrun:
	printf("Virtual address %#"PRIxVADDR": cannot map to physical\n", kva);
#ifdef DDB
	Debugger();
	return 0;	/* XXX */
#endif
	panic("kvtophys");
}
Beispiel #13
0
/*
 * Spin up the second code. The code is roughly modeled after
 * similar routine in Linux.
 */
int
platform_start_ap(int cpuid)
{
	uint32_t reg, addr;

	if (cpuid >= JZ4780_MAXCPU)
		return (EINVAL);

	/* Figure out address of mpentry in KSEG1 */
	addr = MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(jz4780_mpentry));
	KASSERT((addr & ~JZ_REIM_ENTRY_MASK) == 0,
	    ("Unaligned mpentry"));

	/* Configure core alternative entry point */
	reg = mips_rd_xburst_reim();
	reg &= ~JZ_REIM_ENTRY_MASK;
	reg |= addr & JZ_REIM_ENTRY_MASK;

	/* Allow this core to get IPIs from one being started */
	reg |= JZ_REIM_MIRQ0M;
	mips_wr_xburst_reim(reg);

	/* Force core into reset and enable use of alternate entry point */
	reg = mips_rd_xburst_core_ctl();
	reg |= (JZ_CORECTL_SWRST0 << cpuid) | (JZ_CORECTL_RPC0 << cpuid);
	mips_wr_xburst_core_ctl(reg);

	/* Power the core up */
	jz4780_core_powerup();

	/* Take the core out of reset */
	reg &= ~(JZ_CORECTL_SWRST0 << cpuid);
	mips_wr_xburst_core_ctl(reg);

	return (0);
}
void
__BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct)
{
#ifdef CHIP_EXTENT
	bus_addr_t addr;
	int error;

	if (acct == 0)
		return;

#ifdef EXTENT_DEBUG
	printf("xxx: freeing handle 0x%lx for 0x%lx\n", h, size);
#endif

	if (h >= MIPS_KSEG0_START && h < MIPS_KSEG1_START)
		h = MIPS_KSEG0_TO_PHYS(h);
	else
		h = MIPS_KSEG1_TO_PHYS(h);

#ifdef CHIP_W1_BUS_START
	if (h >= CHIP_W1_SYS_START(v) && h <= CHIP_W1_SYS_END(v)) {
		addr = CHIP_W1_BUS_START(v) + (h - CHIP_W1_SYS_START(v));
	} else
#endif
#ifdef CHIP_W2_BUS_START
	if (h >= CHIP_W2_SYS_START(v) && h <= CHIP_W2_SYS_END(v)) {
		addr = CHIP_W2_BUS_START(v) + (h - CHIP_W2_SYS_START(v));
	} else
#endif
#ifdef CHIP_W3_BUS_START
	if (h >= CHIP_W3_SYS_START(v) && h <= CHIP_W3_SYS_END(v)) {
		addr = CHIP_W3_BUS_START(v) + (h - CHIP_W3_SYS_START(v));
	} else
#endif
	{
		printf("\n");
#ifdef CHIP_W1_BUS_START
		printf("%s: sys window[1]=0x%lx-0x%lx\n",
		    __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v),
		    (u_long)CHIP_W1_SYS_END(v));
#endif
#ifdef CHIP_W2_BUS_START
		printf("%s: sys window[2]=0x%lx-0x%lx\n",
		    __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v),
		    (u_long)CHIP_W2_SYS_END(v));
#endif
#ifdef CHIP_W3_BUS_START
		printf("%s: sys window[3]=0x%lx-0x%lx\n",
		    __S(__BS(map)), (u_long)CHIP_W3_SYS_START(v),
		    (u_long)CHIP_W3_SYS_END(v));
#endif
		panic("%s: don't know how to unmap %lx", __S(__BS(unmap)), h);
	}

#ifdef EXTENT_DEBUG
	printf("xxx: freeing 0x%lx to 0x%lx\n", addr, addr + size - 1);
#endif
        error = extent_free(CHIP_EXTENT(v), addr, size,
            EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
	if (error) {
		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
		    __S(__BS(unmap)), addr, addr + size - 1,
		    error);
#ifdef EXTENT_DEBUG
		extent_print(CHIP_EXTENT(v));
#endif
	}	
#endif /* CHIP_EXTENT */
}
Beispiel #15
0
/*
 * Do all the stuff that locore normally does before calling main().
 */
void
mach_init(int32_t memsize32, u_int bim, int32_t bip32)
{
	intptr_t memsize = (int32_t)memsize32;
	char *kernend;
	char *bip = (char *)(intptr_t)(int32_t)bip32;
	u_long first, last;
	extern char edata[], end[];
	const char *bi_msg;
#if NKSYMS || defined(DDB) || defined(MODULAR)
	char *ssym = 0;
	struct btinfo_symtab *bi_syms;
#endif
	struct btinfo_howto *bi_howto;

	/*
	 * Clear the BSS segment (if needed).
	 */
	if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 &&
	    ((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) {
		esym = end;
#if NKSYMS || defined(DDB) || defined(MODULAR)
		esym += ((Elf_Ehdr *)end)->e_entry;
#endif
		kernend = (char *)mips_round_page(esym);
		/*
		 * We don't have to clear BSS here
		 * since our bootloader already does it.
		 */
#if 0
		memset(edata, 0, end - edata);
#endif
	} else {
		kernend = (void *)mips_round_page(end);
		/*
		 * No symbol table, so assume we are loaded by
		 * the firmware directly with "bfd" command.
		 * The firmware loader doesn't clear BSS of
		 * a loaded kernel, so do it here.
		 */
		memset(edata, 0, kernend - edata);

	}

	/*
	 * Copy exception-dispatch code down to exception vector.
	 * Initialize locore-function vector.
	 * Clear out the I and D caches.
	 */
	mips_vector_init(NULL, false);

	/* Check for valid bootinfo passed from bootstrap */
	if (bim == BOOTINFO_MAGIC) {
		struct btinfo_magic *bi_magic;

		bootinfo = bip;
		bi_magic = lookup_bootinfo(BTINFO_MAGIC);
		if (bi_magic == NULL) {
			bi_msg = "missing bootinfo structure";
			bim = (uintptr_t)bip;
		} else if (bi_magic->magic != BOOTINFO_MAGIC) {
			bi_msg = "invalid bootinfo structure";
			bim = bi_magic->magic;
		} else
			bi_msg = NULL;
	} else {
		bi_msg = "invalid bootinfo (standalone boot?)";
	}

#if NKSYMS || defined(DDB) || defined(MODULAR)
	bi_syms = lookup_bootinfo(BTINFO_SYMTAB);

	/* Load symbol table if present */
	if (bi_syms != NULL) {
		ssym = (void *)(intptr_t)bi_syms->ssym;
		esym = (void *)(intptr_t)bi_syms->esym;
		kernend = (void *)mips_round_page(esym);
	}
#endif

	bi_howto = lookup_bootinfo(BTINFO_HOWTO);
	if (bi_howto != NULL)
		boothowto = bi_howto->bi_howto;

	cobalt_id = read_board_id();
	if (cobalt_id >= COBALT_MODELS || cobalt_model[cobalt_id] == NULL)
		cpu_setmodel("Cobalt unknown model (board ID %u)",
		    cobalt_id);
	else
		cpu_setmodel("%s", cobalt_model[cobalt_id]);

	switch (cobalt_id) {
	case COBALT_ID_QUBE2700:
	case COBALT_ID_RAQ:
		cpuspeed = 150; /* MHz */
		break;
	case COBALT_ID_QUBE2:
	case COBALT_ID_RAQ2:
		cpuspeed = 250; /* MHz */
		break;
	default:
		/* assume the fastest, so that delay(9) works */
		cpuspeed = 250;
		break;
	}
	curcpu()->ci_cpu_freq = cpuspeed * 1000 * 1000;
	curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz;
	curcpu()->ci_divisor_delay =
	    ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000);
	/* all models have Rm5200, which is CPU_MIPS_DOUBLE_COUNT */
	curcpu()->ci_cycles_per_hz /= 2;
	curcpu()->ci_divisor_delay /= 2;

	physmem = btoc(memsize - MIPS_KSEG0_START);

	consinit();

	KASSERT(&lwp0 == curlwp);
	if (bi_msg != NULL)
		printf("%s: magic=%#x bip=%p\n", bi_msg, bim, bip);

	uvm_setpagesize();

	/*
	 * The boot command is passed in the top 512 bytes,
	 * so don't clobber that.
	 */
	mem_clusters[0].start = 0;
	mem_clusters[0].size = ctob(physmem) - 512;
	mem_cluster_cnt = 1;

	memcpy(bootstring, (char *)(memsize - 512), 512);
	memset((char *)(memsize - 512), 0, 512);
	bootstring[511] = '\0';

	decode_bootstring();

#if NKSYMS || defined(DDB) || defined(MODULAR)
	/* init symbols if present */
	if ((bi_syms != NULL) && (esym != NULL))
		ksyms_addsyms_elf(esym - ssym, ssym, esym);
#endif
	KASSERT(&lwp0 == curlwp);
#ifdef DDB
	if (boothowto & RB_KDB)
		Debugger();
#endif
#ifdef KGDB
	if (boothowto & RB_KDB)
		kgdb_connect(0);
#endif

	/*
	 * Load the rest of the available pages into the VM system.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
	    VM_FREELIST_DEFAULT);

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	pmap_bootstrap();

	/*
	 * Allocate space for proc0's USPACE.
	 */
	mips_init_lwp0_uarea();
}
Beispiel #16
0
/*
 * Do all the stuff that locore normally does before calling main().
 */
void
mach_init(long fwhandle, long magic, long bootdata, long reserved)
{
	void *kernend, *p0;
	u_long first, last;
	extern char edata[], end[];
	int i;
	uint32_t config;

	/* XXX this code must run on the target CPU */
	config = mips3_cp0_config_read();
	config &= ~MIPS3_CONFIG_K0_MASK;
	config |= 0x05;				/* XXX.  cacheable coherent */
	mips3_cp0_config_write(config);

	/* Zero BSS.  XXXCGD: uh, is this really necessary still?  */
	memset(edata, 0, end - edata);

	/*
	 * Copy the bootinfo structure from the boot loader.
	 * this has to be done before mips_vector_init is
	 * called because we may need CFE's TLB handler
	 */

	if (magic == BOOTINFO_MAGIC)
		memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata,
		    sizeof bootinfo);
	else if (reserved == CFE_EPTSEAL) {
		magic = BOOTINFO_MAGIC;
		bzero(&bootinfo, sizeof bootinfo);
		bootinfo.version = BOOTINFO_VERSION;
		bootinfo.fwhandle = fwhandle;
		bootinfo.fwentry = bootdata;
		bootinfo.ssym = (vaddr_t)end;
		bootinfo.esym = (vaddr_t)end;
	}

	kernend = (void *)mips_round_page(end);
#if NKSYMS || defined(DDB) || defined(LKM)
	if (magic == BOOTINFO_MAGIC) {
		ksym_start = (void *)bootinfo.ssym;
		ksym_end   = (void *)bootinfo.esym;
		kernend = (void *)mips_round_page((vaddr_t)ksym_end);
	}
#endif

	consinit();

	uvm_setpagesize();

	/*
	 * Copy exception-dispatch code down to exception vector.
	 * Initialize locore-function vector.
	 * Clear out the I and D caches.
	 */
	mips_vector_init();

#ifdef DEBUG
	printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n",
	    (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved);
#endif

	strcpy(cpu_model, "sb1250");

	if (magic == BOOTINFO_MAGIC) {
		int idx;
		int added;
		uint64_t start, len, type;

		cfe_init(bootinfo.fwhandle, bootinfo.fwentry);
		cfe_present = 1;

		idx = 0;
		physmem = 0;
		mem_cluster_cnt = 0;
		while (cfe_enummem(idx, 0, &start, &len, &type) == 0) {
			added = 0;
			printf("Memory Block #%d start %08"PRIx64"X len %08"PRIx64"X: %s: ",
			    idx, start, len, (type == CFE_MI_AVAILABLE) ?
			    "Available" : "Reserved");
			if ((type == CFE_MI_AVAILABLE) &&
			    (mem_cluster_cnt < VM_PHYSSEG_MAX)) {
				/*
				 * XXX Ignore memory above 256MB for now, it
				 * XXX needs special handling.
				 */
				if (start < (256*1024*1024)) {
				    physmem += btoc(((int) len));
				    mem_clusters[mem_cluster_cnt].start =
					(long) start;
				    mem_clusters[mem_cluster_cnt].size =
					(long) len;
				    mem_cluster_cnt++;
				    added = 1;
				}
			}
			if (added)
				printf("added to map\n");
			else
				printf("not added to map\n");
			idx++;
		}

	} else {
		/*
		 * Handle the case of not being called from the firmware.
		 */
		/* XXX hardwire to 32MB; should be kernel config option */
		physmem = 32 * 1024 * 1024 / 4096;
		mem_clusters[0].start = 0;
		mem_clusters[0].size = ctob(physmem);
		mem_cluster_cnt = 1;
	}


	for (i = 0; i < sizeof(bootinfo.boot_flags); i++) {
		switch (bootinfo.boot_flags[i]) {
		case '\0':
			break;
		case ' ':
			continue;
		case '-':
			while (bootinfo.boot_flags[i] != ' ' &&
			    bootinfo.boot_flags[i] != '\0') {
				switch (bootinfo.boot_flags[i]) {
				case 'a':
					boothowto |= RB_ASKNAME;
					break;
				case 'd':
					boothowto |= RB_KDB;
					break;
				case 's':
					boothowto |= RB_SINGLE;
					break;
				}
				i++;
			}
		}
	}

	/*
	 * Load the rest of the available pages into the VM system.
	 * The first chunk is tricky because we have to avoid the
	 * kernel, but the rest are easy.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
		VM_FREELIST_DEFAULT);

	for (i = 1; i < mem_cluster_cnt; i++) {
		first = round_page(mem_clusters[i].start);
		last = mem_clusters[i].start + mem_clusters[i].size;
		uvm_page_physload(atop(first), atop(last), atop(first),
		    atop(last), VM_FREELIST_DEFAULT);
	}

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Allocate space for proc0's USPACE
	 */
	p0 = (void *)pmap_steal_memory(USPACE, NULL, NULL);
	lwp0.l_addr = proc0paddr = (struct user *)p0;
	lwp0.l_md.md_regs = (struct frame *)((char *)p0 + USPACE) - 1;
	proc0paddr->u_pcb.pcb_context[11] =
	    MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */

	pmap_bootstrap();

	/*
	 * Initialize debuggers, and break into them, if appropriate.
	 */
#if NKSYMS || defined(DDB) || defined(LKM)
	ksyms_init(((uintptr_t)ksym_end - (uintptr_t)ksym_start),
	    ksym_start, ksym_end);
#endif

	if (boothowto & RB_KDB) {
#if defined(DDB)
		Debugger();
#endif
	}
}
Beispiel #17
0
/*
 * Do all the stuff that locore normally does before calling main().
 */
void
mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize)
{
	struct malta_config *mcp = &malta_configuration;
	bus_space_handle_t sh;
	caddr_t kernend, v;
        u_long first, last;
	vsize_t size;
	char *cp;
	int i, howto;
	uint8_t *brkres = (uint8_t *)MIPS_PHYS_TO_KSEG1(MALTA_BRKRES);

	extern char edata[], end[];

	*brkres = 0;	/* Disable BREAK==reset on console */

	/* Get the propaganda in early! */
	led_display_str("NetBSD");

	/*
	 * Clear the BSS segment.
	 */
	kernend = (caddr_t)mips_round_page(end);
	memset(edata, 0, kernend - edata);

	/* save the yamon environment pointer */
	yamon_envp = envp;

	/* Use YAMON callbacks for early console I/O */
	cn_tab = &yamon_promcd;

	/*
	 * Set up the exception vectors and cpu-specific function
	 * vectors early on.  We need the wbflush() vector set up
	 * before comcnattach() is called (or at least before the
	 * first printf() after that is called).
	 * Also clears the I+D caches.
	 */
	mips_vector_init();

	uvm_setpagesize();

	physmem = btoc(memsize);

	gt_pci_init(&mcp->mc_pc, &mcp->mc_gt);
	malta_bus_io_init(&mcp->mc_iot, mcp);
	malta_bus_mem_init(&mcp->mc_memt, mcp);
	malta_dma_init(mcp);

	/*
	 * Calibrate the timer, delay() relies on this.
	 */
	bus_space_map(&mcp->mc_iot, MALTA_RTCADR, 2, 0, &sh);
	malta_cal_timer(&mcp->mc_iot, sh);
	bus_space_unmap(&mcp->mc_iot, sh, 2);


#if NCOM > 0
	/*
	 * Delay to allow firmware putchars to complete.
	 * FIFO depth * character time.
	 * character time = (1000000 / (defaultrate / 10))
	 */
	delay(160000000 / comcnrate);
	if (comcnattach(&mcp->mc_iot, MALTA_UART0ADR, comcnrate, COM_FREQ,
	    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0)
		panic("malta: unable to initialize serial console");
#else
	panic("malta: not configured to use serial console");
#endif /* NCOM > 0 */

	consinit();

	mem_clusters[0].start = 0;
	mem_clusters[0].size = ctob(physmem);
	mem_cluster_cnt = 1;

	/*
	 * XXX: check argv[0] - do something if "gdb"???
	 */

	/*
	 * Look at arguments passed to us and compute boothowto.
	 */
	boothowto = RB_AUTOBOOT;
	for (i = 1; i < argc; i++) {
		for (cp = argv[i]; *cp; cp++) {
			/* Ignore superfluous '-', if there is one */
			if (*cp == '-')
				continue;

			howto = 0;
			BOOT_FLAG(*cp, howto);
			if (! howto)
				printf("bootflag '%c' not recognised\n", *cp);
			else
				boothowto |= howto;
		}
	}

	/*
	 * Load the rest of the available pages into the VM system.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
		VM_FREELIST_DEFAULT);

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Compute the size of system data structures.  pmap_bootstrap()
	 * needs some of this information.
	 */
	size = (vsize_t)allocsys(NULL, NULL);

	pmap_bootstrap();

	/*
	 * Allocate space for proc0's USPACE.
	 */
	v = (caddr_t)uvm_pageboot_alloc(USPACE); 
	proc0.p_addr = proc0paddr = (struct user *)v;
	proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1;
	curpcb = &proc0.p_addr->u_pcb;
	curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */

	/*
	 * Allocate space for system data structures.  These data structures
	 * are allocated here instead of cpu_startup() because physical
	 * memory is directly addressable.  We don't have to map these into
	 * virtual address space.
	 */
	v = (caddr_t)uvm_pageboot_alloc(size); 
	if ((allocsys(v, NULL) - v) != size)
		panic("mach_init: table size inconsistency");

	/*
	 * Initialize debuggers, and break into them, if appropriate.
	 */
#ifdef DDB
	ddb_init(0, 0, 0);
#endif

	if (boothowto & RB_KDB)
#if defined(DDB)
		Debugger();
#endif
}
Beispiel #18
0
static int draw_proc(struct menu_item *item,
                     struct menu_draw_params *draw_params)
{
  static Gfx null_dl = gsSPEndDisplayList();
  struct item_data *data = item->data;
  /* handle input */
  if (!input_bind_held(COMMAND_PREVROOM) &&
      !input_bind_held(COMMAND_NEXTROOM))
  {
    uint16_t pad = input_pad();
    if (pad & BUTTON_Z) {
      if (pad & BUTTON_D_UP)
        data->y += 50.f;
      if (pad & BUTTON_D_DOWN)
        data->y += -50.f;
      if (pad & BUTTON_D_LEFT) {
        data->x -= cos(data->yaw) * 50.f;
        data->z += sin(data->yaw) * 50.f;
      }
      if (pad & BUTTON_D_RIGHT) {
        data->x -= cos(data->yaw) * -50.f;
        data->z += sin(data->yaw) * -50.f;
      }
    }
    else {
      if (pad & BUTTON_D_UP) {
        data->x -= sin(data->yaw) * 50.f;
        data->z -= cos(data->yaw) * 50.f;
      }
      if (pad & BUTTON_D_DOWN) {
        data->x -= sin(data->yaw) * -50.f;
        data->z -= cos(data->yaw) * -50.f;
      }
      if (pad & BUTTON_D_LEFT)
        data->yaw += .2f;
      if (pad & BUTTON_D_RIGHT)
        data->yaw -= .2f;
    }
  }
  /* load resources */
  if (data->state == STATE_LOAD) {
    /* initialize segment table */
    z64_stab_t stab = z64_stab;
    /* load scene */
    if (data->scene_index != data->scene_next || !data->scene_file) {
      if (data->scene_file)
        free(data->scene_file);
      data->scene_index = data->scene_next;
      data->room_index = -1;
      z64_scene_table_t *scene_entry = &z64_scene_table[data->scene_index];
      uint32_t scene_vrom_start = scene_entry->scene_vrom_start;
      uint32_t scene_vrom_end = scene_entry->scene_vrom_end;
      uint32_t scene_vrom_size = scene_vrom_end - scene_vrom_start;
      data->scene_file = malloc(scene_vrom_size);
      zu_getfile(scene_vrom_start, data->scene_file, scene_vrom_size);
    }
    stab.seg[Z64_SEG_SCENE] = MIPS_KSEG0_TO_PHYS(data->scene_file);
    /* populate room list */
    struct zu_file room_files[0x100];
    zu_scene_rooms(zu_sr_header(data->scene_file,
                                z64_file.scene_setup_index, &stab),
                   room_files, 0x100, &data->n_rooms, &stab);
    /* load room */
    if (data->room_index != data->room_next || !data->room_file) {
      if (data->room_file) {
        free(data->room_file);
        zu_mesh_destroy(&data->room_mesh);
      }
      data->room_index = data->room_next;
      uint32_t room_vrom_start = room_files[data->room_index].vrom_start;
      uint32_t room_vrom_end = room_files[data->room_index].vrom_end;
      uint32_t room_vrom_size = room_vrom_end - room_vrom_start;
      data->room_file = malloc(room_vrom_size);
      zu_getfile(room_vrom_start, data->room_file, room_vrom_size);
      stab.seg[Z64_SEG_ROOM] = MIPS_KSEG0_TO_PHYS(data->room_file);
      /* populate mesh */
      zu_room_mesh(zu_sr_header(data->room_file,
                                z64_file.scene_setup_index, &stab),
                   &data->room_mesh, &stab);
      /* populate vertex list */
      struct zu_vlist vlist;
      zu_vlist_init(&vlist);
      stab.seg[0x08] = MIPS_KSEG0_TO_PHYS(&null_dl);
      stab.seg[0x09] = MIPS_KSEG0_TO_PHYS(&null_dl);
      stab.seg[0x0A] = MIPS_KSEG0_TO_PHYS(&null_dl);
      stab.seg[0x0B] = MIPS_KSEG0_TO_PHYS(&null_dl);
      stab.seg[0x0C] = MIPS_KSEG0_TO_PHYS(&null_dl);
      stab.seg[0x0D] = MIPS_KSEG0_TO_PHYS(&null_dl);
      for (int i = 0; i < ZU_MESH_TYPES; ++i)
        for (int j = 0; j < data->room_mesh.all[i].size; ++j)
          zu_vlist_add_dl(&vlist, &stab,
                          zu_seg_locate(&stab,
                                        data->room_mesh.all[i].dlists[j]));
      /* compute bounding box */
      struct zu_bbox bbox;
      zu_vlist_bbox(&vlist, &bbox);
      /* set orientation */
      {
        data->x = (bbox.x1 + bbox.x2) / 2.f;
        data->y = (bbox.y1 + bbox.y2) / 2.f;
        data->z = (bbox.z1 + bbox.z2) / 2.f;
        data->yaw = 0.f;
      }
      zu_vlist_destroy(&vlist);
    }
    /* proceed to rendering */
    data->state = STATE_RENDER;
  }
  /* render room */
  if (data->state == STATE_RENDER && data->room_file) {
    /* initialize rcp for rendering rooms */
    static void *zbuf = NULL;
    if (!zbuf)
      zbuf = memalign(64, 2 * Z64_SCREEN_WIDTH * Z64_SCREEN_HEIGHT);
    gDisplayListAppend(&data->gfx.poly_opa.p,
      /* clear z buffer */
      gsDPPipeSync(),
      gsDPSetCycleType(G_CYC_FILL),
      gsDPSetRenderMode(G_RM_NOOP, G_RM_NOOP2),
      gsDPSetColorImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, Z64_SCREEN_WIDTH, zbuf),
      gsDPSetFillColor((GPACK_ZDZ(G_MAXFBZ, 0) << 16) |
                       GPACK_ZDZ(G_MAXFBZ, 0)),
      gsDPFillRectangle(0, 0, Z64_SCREEN_WIDTH - 1, Z64_SCREEN_HEIGHT - 1),
      gsDPPipeSync(),
      gsDPSetColorImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, Z64_SCREEN_WIDTH,
                        ZU_MAKE_SEG(Z64_SEG_CIMG, 0)),
      gsDPSetDepthImage(zbuf),
      /* rsp settings */
      gsSPSegment(Z64_SEG_SCENE, data->scene_file),
      gsSPSegment(Z64_SEG_ROOM, data->room_file),
      gsSPSegment(0x08, &null_dl),
      gsSPSegment(0x09, &null_dl),
      gsSPSegment(0x0A, &null_dl),
      gsSPSegment(0x0B, &null_dl),
      gsSPSegment(0x0C, &null_dl),
      gsSPSegment(0x0D, &null_dl),
      gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING |
                           G_SHADING_SMOOTH),
      /* rdp settings */
      gsDPSetAlphaCompare(G_AC_NONE),
      gsDPSetDepthSource(G_ZS_PIXEL),
      gsDPSetAlphaDither(G_AD_DISABLE),
      gsDPSetColorDither(G_CD_DISABLE),
      gsDPSetCombineKey(G_OFF),
      gsDPSetTextureConvert(G_TC_FILT),
      gsDPSetTextureFilter(G_TF_BILERP),
      gsDPSetTextureLOD(G_TL_TILE),
      gsDPSetTexturePersp(G_TP_PERSP),
      gsDPSetCycleType(G_CYC_2CYCLE),
      gsDPPipelineMode(G_PM_NPRIMITIVE),
      gsDPSetEnvColor(0xFF, 0xFF, 0xFF, 0xFF),
      gsDPSetFogColor(0x00, 0x00, 0x00, 0x00),
      gsDPSetScissor(G_SC_NON_INTERLACE, 32, 32,
                     Z64_SCREEN_WIDTH - 32, Z64_SCREEN_HEIGHT - 32),
    );
    /* create projection matrix */
    {
      Mtx m;
      MtxF mf;
      MtxF mt;
      guPerspectiveF(&mf, NULL, atanf(2.f),
                     (float)Z64_SCREEN_WIDTH / (float)Z64_SCREEN_HEIGHT,
                     50.f, 5000.f, 1.f);
      {
        guScaleF(&mt, data->scale, data->scale, data->scale);
        guMtxCatF(&mt, &mf, &mf);
      }
      {
        guRotateF(&mt, M_PI / 6.f, 1.f, 0.f, 0.f);
        guMtxCatF(&mt, &mf, &mf);
      }
      {
        guTranslateF(&mt, 0.f, -100.f, -200.f);
        guMtxCatF(&mt, &mf, &mf);
      }
      {
        guRotateF(&mt, -data->yaw, 0.f, 1.f, 0.f);
        guMtxCatF(&mt, &mf, &mf);
      }
      {
        guTranslateF(&mt, -data->x, -data->y, -data->z);
        guMtxCatF(&mt, &mf, &mf);
      }
      guMtxF2L(&mf, &m);
      gSPMatrix(data->gfx.poly_opa.p++,
                gDisplayListData(&data->gfx.poly_opa.d, m),
                G_MTX_PROJECTION | G_MTX_LOAD);
      gSPMatrix(data->gfx.poly_xlu.p++,
                gDisplayListData(&data->gfx.poly_xlu.d, m),
                G_MTX_PROJECTION | G_MTX_LOAD);
    }
    /* create modelview matrix */
    {
      Mtx m;
      guMtxIdent(&m);
      gSPMatrix(data->gfx.poly_opa.p++,
                gDisplayListData(&data->gfx.poly_opa.d, m),
                G_MTX_MODELVIEW | G_MTX_LOAD);
      gSPMatrix(data->gfx.poly_xlu.p++,
                gDisplayListData(&data->gfx.poly_xlu.d, m),
                G_MTX_MODELVIEW | G_MTX_LOAD);
    }
    /* configure lights */
    zu_gfx_inject(&data->gfx);
    set_lighting();
    /* execute scene config */
    z64_scene_config_table[z64_scene_table[
                           z64_game.scene_index].scene_config](&z64_game);
    zu_gfx_restore(&data->gfx);
    /* draw scene */
    for (int i = 0; i < ZU_MESH_TYPES; ++i)
      for (int j = 0; j < data->room_mesh.all[i].size; ++j) {
        if (i == ZU_MESH_OPA || i == ZU_MESH_NEAR) {
          gSPDisplayList(data->gfx.poly_opa.p++,
                         data->room_mesh.all[i].dlists[j]);
        }
        else if (i == ZU_MESH_XLU || i == ZU_MESH_FAR) {
          gSPDisplayList(data->gfx.poly_xlu.p++,
                         data->room_mesh.all[i].dlists[j]);
        }
      }
    /* draw actors */
    if (z64_game.pause_state == 0) {
      zu_gfx_inject(&data->gfx);
      z64_DrawActors(&z64_game, &z64_game.actor_ctxt);
      zu_gfx_restore(&data->gfx);
    }
    /* draw additional stuff */
    draw_crosshair(item);
    /* flush */
    gfx_disp(gsSPDisplayList(zu_gfx_flush(&data->gfx)));
    /* restore rcp modes */
    gfx_mode_init();
    /* draw info */
    gfx_mode_set(GFX_MODE_COLOR, GPACK_RGBA8888(0xC0, 0xC0, 0xC0,
                                                draw_params->alpha));
    gfx_printf(draw_params->font, 36, 44, "scene %i", data->scene_index);
    gfx_printf(draw_params->font, 36, 44 + menu_get_cell_height(item->owner, 1),
               "room  %i", data->room_index);
  }
  /* wait for rendering to finish before unloading */
  if (data->state == STATE_UNLOAD)
    data->state = STATE_LOAD;
  return 1;
}
Beispiel #19
0
static void
mips_init(void)
{
	int i, j;

	printf("entry: mips_init()\n");

#ifdef CFE
	/*
	 * Query DRAM memory map from CFE.
	 */
	physmem = 0;
	for (i = 0; i < 10; i += 2) {
		int result;
		uint64_t addr, len, type;

		result = cfe_enummem(i / 2, 0, &addr, &len, &type);
		if (result < 0) {
			BCM_TRACE("There is no phys memory for: %d\n", i);
			phys_avail[i] = phys_avail[i + 1] = 0;
			break;
		}
		if (type != CFE_MI_AVAILABLE) {
			BCM_TRACE("phys memory is not available: %d\n", i);
			continue;
		}

		phys_avail[i] = addr;
		if (i == 0 && addr == 0) {
			/*
			 * If this is the first physical memory segment probed
			 * from CFE, omit the region at the start of physical
			 * memory where the kernel has been loaded.
			 */
			phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
		}
		
		BCM_TRACE("phys memory is available for: %d\n", i);
		BCM_TRACE(" => addr =  %jx\n", addr);
		BCM_TRACE(" => len =  %jd\n", len);

		phys_avail[i + 1] = addr + len;
		physmem += len;
	}

	BCM_TRACE("Total phys memory is : %ld\n", physmem);
	realmem = btoc(physmem);
#endif

	for (j = 0; j < i; j++)
		dump_avail[j] = phys_avail[j];

	physmem = realmem;

	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
static void
__BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct)
{
#if !defined(_LP64) || defined(CHIP_EXTENT)
	bus_addr_t addr = 0;	/* initialize to appease gcc */
#endif
#ifndef _LP64
	bool handle_is_km;

	/* determine if h is addr obtained from uvm_km_alloc */
	handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h));
#ifdef __mips_n32
	if (handle_is_km == true)
		handle_is_km = !MIPS_XKPHYS_P(h);
#endif
	if (handle_is_km == true) {
		paddr_t pa;
		vaddr_t va = (vaddr_t)trunc_page(h);
		vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size);
		int s;

		s = splhigh();

		if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false)
			panic("%s: pmap_extract failed", __func__);
		addr = (bus_addr_t)pa;
#if 0
		printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n",
			__func__, __LINE__, addr, sz);
#endif
		/* sanity check: this is why we couldn't map w/ kseg[0,1] */
		KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0);

		pmap_kremove(va, sz);
		pmap_update(pmap_kernel());
		uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);

		splx(s);
	}
#endif	/* _LP64 */

#ifdef CHIP_EXTENT

	if (acct == 0)
		return;

#ifdef EXTENT_DEBUG
	printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n",
		__S(__BS(unmap)), h, size);
#endif

#ifdef _LP64
	KASSERT(MIPS_XKPHYS_P(h));
	addr = MIPS_XKPHYS_TO_PHYS(h);
#else
	if (handle_is_km == false) {
		if (MIPS_KSEG0_P(h))
			addr = MIPS_KSEG0_TO_PHYS(h);
#ifdef __mips_n32
		else if (MIPS_XKPHYS_P(h))
			addr = MIPS_XKPHYS_TO_PHYS(h);
#endif
		else
			addr = MIPS_KSEG1_TO_PHYS(h);
	}
#endif

#ifdef CHIP_W1_BUS_START
	if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) {
		addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v));
	} else
#endif
#ifdef CHIP_W2_BUS_START
	if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) {
		addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v));
	} else
#endif
#ifdef CHIP_W3_BUS_START
	if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) {
		addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v));
	} else
#endif
	{
		printf("\n");
#ifdef CHIP_W1_BUS_START
		printf("%s: sys window[1]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W1_SYS_START(v),
		    (u_long)CHIP_W1_SYS_END(v));
#endif
#ifdef CHIP_W2_BUS_START
		printf("%s: sys window[2]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W2_SYS_START(v),
		    (u_long)CHIP_W2_SYS_END(v));
#endif
#ifdef CHIP_W3_BUS_START
		printf("%s: sys window[3]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v),
		    (u_long)CHIP_W3_SYS_END(v));
#endif
		panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h);
	}

#ifdef EXTENT_DEBUG
	printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
	    __S(__BS(unmap)), addr, addr + size - 1);
#endif
	int error = extent_free(CHIP_EXTENT(v), addr, size,
	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
	if (error) {
		printf("%s: WARNING: could not unmap"
		    " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n",
		    __S(__BS(unmap)), addr, addr + size - 1, error);
#ifdef EXTENT_DEBUG
		extent_print(CHIP_EXTENT(v));
#endif
	}
#endif /* CHIP_EXTENT */
#if !defined(_LP64) || defined(CHIP_EXTENT)
	__USE(addr);
#endif
}
Beispiel #21
0
static void
mips_init(void)
{
    int i, j, cfe_mem_idx, tmp;
    uint64_t maxmem;

#ifdef CFE_ENV
    cfe_env_init();
#endif

    TUNABLE_INT_FETCH("boothowto", &boothowto);

    if (boothowto & RB_VERBOSE)
        bootverbose++;

#ifdef MAXMEM
    tmp = MAXMEM;
#else
    tmp = 0;
#endif
    TUNABLE_INT_FETCH("hw.physmem", &tmp);
    maxmem = (uint64_t)tmp * 1024;

    /*
     * XXX
     * If we used vm_paddr_t consistently in pmap, etc., we could
     * use 64-bit page numbers on !n64 systems, too, like i386
     * does with PAE.
     */
#if !defined(__mips_n64)
    if (maxmem == 0 || maxmem > 0xffffffff)
        maxmem = 0xffffffff;
#endif

#ifdef CFE
    /*
     * Query DRAM memory map from CFE.
     */
    physmem = 0;
    cfe_mem_idx = 0;
    for (i = 0; i < 10; i += 2) {
        int result;
        uint64_t addr, len, type;

        result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type);
        if (result < 0) {
            phys_avail[i] = phys_avail[i + 1] = 0;
            break;
        }

        KASSERT(type == CFE_MI_AVAILABLE,
                ("CFE DRAM region is not available?"));

        if (bootverbose)
            printf("cfe_enummem: 0x%016jx/%ju.\n", addr, len);

        if (maxmem != 0) {
            if (addr >= maxmem) {
                printf("Ignoring %ju bytes of memory at 0x%jx "
                       "that is above maxmem %dMB\n",
                       len, addr,
                       (int)(maxmem / (1024 * 1024)));
                continue;
            }

            if (addr + len > maxmem) {
                printf("Ignoring %ju bytes of memory "
                       "that is above maxmem %dMB\n",
                       (addr + len) - maxmem,
                       (int)(maxmem / (1024 * 1024)));
                len = maxmem - addr;
            }
        }

        phys_avail[i] = addr;
        if (i == 0 && addr == 0) {
            /*
             * If this is the first physical memory segment probed
             * from CFE, omit the region at the start of physical
             * memory where the kernel has been loaded.
             */
            phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
        }
        phys_avail[i + 1] = addr + len;
        physmem += len;
    }

    realmem = btoc(physmem);
#endif

    for (j = 0; j < i; j++)
        dump_avail[j] = phys_avail[j];

    physmem = realmem;

    init_param1();
    init_param2(physmem);
    mips_cpu_init();

    /*
     * Sibyte has a L1 data cache coherent with DMA. This includes
     * on-chip network interfaces as well as PCI/HyperTransport bus
     * masters.
     */
    cpuinfo.cache_coherent_dma = TRUE;

    /*
     * XXX
     * The kernel is running in 32-bit mode but the CFE is running in
     * 64-bit mode. So the SR_KX bit in the status register is turned
     * on by the CFE every time we call into it - for e.g. CFE_CONSOLE.
     *
     * This means that if get a TLB miss for any address above 0xc0000000
     * and the SR_KX bit is set then we will end up in the XTLB exception
     * vector.
     *
     * For now work around this by copying the TLB exception handling
     * code to the XTLB exception vector.
     */
    {
        bcopy(MipsTLBMiss, (void *)MIPS3_XTLB_MISS_EXC_VEC,
              MipsTLBMissEnd - MipsTLBMiss);

        mips_icache_sync_all();
        mips_dcache_wbinv_all();
    }

    pmap_bootstrap();
    mips_proc0_init();
    mutex_init();

    kdb_init();
#ifdef KDB
    if (boothowto & RB_KDB)
        kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #22
0
void
platform_start(__register_t a0 __unused, __register_t a1 __unused, 
    __register_t a2 __unused, __register_t a3 __unused)
{
	uint64_t platform_counter_freq;
	uint32_t reg;
	int argc, i, count = 0;
	char **argv, **envp;
	vm_offset_t kernend;

	/* 
	 * clear the BSS and SBSS segments, this should be first call in
	 * the function
	 */
	kernend = (vm_offset_t)&end;
	memset(&edata, 0, kernend - (vm_offset_t)(&edata));

	mips_postboot_fixup();

	/* Initialize pcpu stuff */
	mips_pcpu0_init();

	argc = a0;
	argv = (char**)a1;
	envp = (char**)a2;
	/* 
	 * Protect ourselves from garbage in registers 
	 */
	if (MIPS_IS_VALID_PTR(envp)) {
		for (i = 0; envp[i]; i += 2)
		{
			if (strcmp(envp[i], "memsize") == 0)
				realmem = btoc(strtoul(envp[i+1], NULL, 16));
			else if (strcmp(envp[i], "ethaddr") == 0) {
				count = sscanf(envp[i+1], "%x.%x.%x.%x.%x.%x", 
				    &ar711_base_mac[0], &ar711_base_mac[1],
				    &ar711_base_mac[2], &ar711_base_mac[3],
				    &ar711_base_mac[4], &ar711_base_mac[5]);
				if (count < 6)
					memset(ar711_base_mac, 0,
					    sizeof(ar711_base_mac));
			}
		}
	}

	/*
	 * Just wild guess. RedBoot let us down and didn't reported 
	 * memory size
	 */
	if (realmem == 0)
		realmem = btoc(32*1024*1024);

	/* phys_avail regions are in bytes */
	phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
	phys_avail[1] = ctob(realmem);

	physmem = realmem;

	/*
	 * ns8250 uart code uses DELAY so ticker should be inititalized 
	 * before cninit. And tick_init_params refers to hz, so * init_param1 
	 * should be called first.
	 */
	init_param1();
	platform_counter_freq = ar71xx_cpu_freq();
	mips_timer_init_params(platform_counter_freq, 1);
	cninit();
	init_static_kenv(boot1_env, sizeof(boot1_env));

	printf("platform frequency: %lld\n", platform_counter_freq);
	printf("arguments: \n");
	printf("  a0 = %08x\n", a0);
	printf("  a1 = %08x\n", a1);
	printf("  a2 = %08x\n", a2);
	printf("  a3 = %08x\n", a3);

	printf("Cmd line:");
	if (MIPS_IS_VALID_PTR(argv)) {
		for (i = 0; i < argc; i++) {
			printf(" %s", argv[i]);
			parse_argv(argv[i]);
		}
	}
	else
		printf ("argv is invalid");
	printf("\n");

	printf("Environment:\n");
	if (MIPS_IS_VALID_PTR(envp)) {
		for (i = 0; envp[i]; i+=2) {
			printf("  %s = %s\n", envp[i], envp[i+1]);
			setenv(envp[i], envp[i+1]);
		}
	}
	else 
		printf ("envp is invalid\n");

	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();

	/*
	 * Reset USB devices 
	 */
	reg = ATH_READ_REG(AR71XX_RST_RESET);
	reg |= 
	    RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY;
	ATH_WRITE_REG(AR71XX_RST_RESET, reg);
	DELAY(1000);
	reg &= 
	    ~(RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY);
	ATH_WRITE_REG(AR71XX_RST_RESET, reg);
	
	ATH_WRITE_REG(AR71XX_USB_CTRL_CONFIG,
	    USB_CTRL_CONFIG_OHCI_DES_SWAP | USB_CTRL_CONFIG_OHCI_BUF_SWAP |
	    USB_CTRL_CONFIG_EHCI_DES_SWAP | USB_CTRL_CONFIG_EHCI_BUF_SWAP);

	ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, 
	    (32 << USB_CTRL_FLADJ_HOST_SHIFT) | (3 << USB_CTRL_FLADJ_A5_SHIFT));
	DELAY(1000);

	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #23
0
static void
octeon_memory_init(void)
{
	vm_paddr_t phys_end;
	int64_t addr;
	unsigned i, j;

	phys_end = round_page(MIPS_KSEG0_TO_PHYS((vm_offset_t)&end));

	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
		/* Simulator we limit to 96 meg */
		phys_avail[0] = phys_end;
		phys_avail[1] = 96 << 20;

		dump_avail[0] = phys_avail[0];
		dump_avail[1] = phys_avail[1];

		realmem = physmem = btoc(phys_avail[1] - phys_avail[0]);
		return;
	}

	/*
	 * Allocate memory from bootmem 1MB at a time and merge
	 * adjacent entries.
	 */
	i = 0;
	while (i < PHYS_AVAIL_ENTRIES) {
		/*
		 * If there is less than 2MB of memory available in 128-byte
		 * blocks, do not steal any more memory.  We need to leave some
		 * memory for the command queues to be allocated out of.
		 */
		if (cvmx_bootmem_available_mem(128) < 2 << 20)
			break;

		addr = cvmx_bootmem_phy_alloc(1 << 20, phys_end,
					      ~(vm_paddr_t)0, PAGE_SIZE, 0);
		if (addr == -1)
			break;

		/*
		 * The SDK needs to be able to easily map any memory that might
		 * come to it e.g. in the form of an mbuf.  Because on !n64 we
		 * can't direct-map some addresses and we don't want to manage
		 * temporary mappings within the SDK, don't feed memory that
		 * can't be direct-mapped to the kernel.
		 */
#if !defined(__mips_n64)
		if (!MIPS_DIRECT_MAPPABLE(addr + (1 << 20) - 1))
			continue;
#endif

		physmem += btoc(1 << 20);

		if (i > 0 && phys_avail[i - 1] == addr) {
			phys_avail[i - 1] += 1 << 20;
			continue;
		}

		phys_avail[i + 0] = addr;
		phys_avail[i + 1] = addr + (1 << 20);

		i += 2;
	}

	for (j = 0; j < i; j++)
		dump_avail[j] = phys_avail[j];

	realmem = physmem;
}
Beispiel #24
0
void
platform_start(__register_t a0, __register_t a1,
    __register_t a2 __unused, __register_t a3 __unused)
{
	uint64_t platform_counter_freq;
	vm_offset_t kernend;
	int argc = a0;
	char **argv = (char **)a1;
	int i, mem;


	/* clear the BSS and SBSS segments */
	kernend = (vm_offset_t)&end;
	memset(&edata, 0, kernend - (vm_offset_t)(&edata));

	mips_postboot_fixup();

	/* Initialize pcpu stuff */
	mips_pcpu0_init();

	/*
	 * Looking for mem=XXM argument
	 */
	mem = 0; /* Just something to start with */
	for (i=0; i < argc; i++) {
		if (strncmp(argv[i], "mem=", 4) == 0) {
			mem = strtol(argv[i] + 4, NULL, 0);
			break;
		}
	}

	bootverbose = 1;
	if (mem > 0)
		realmem = btoc(mem << 20);
	else
		realmem = btoc(32 << 20);

	for (i = 0; i < 10; i++) {
		phys_avail[i] = 0;
	}

	/* phys_avail regions are in bytes */
	phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
	phys_avail[1] = ctob(realmem);

	dump_avail[0] = phys_avail[0];
	dump_avail[1] = phys_avail[1];

	physmem = realmem;

	/* 
	 * ns8250 uart code uses DELAY so ticker should be inititalized 
	 * before cninit. And tick_init_params refers to hz, so * init_param1 
	 * should be called first.
	 */
	init_param1();
	/* TODO: parse argc,argv */
	platform_counter_freq = 330000000UL;
	mips_timer_init_params(platform_counter_freq, 1);
	cninit();
	/* Panic here, after cninit */ 
	if (mem == 0)
		panic("No mem=XX parameter in arguments");

	printf("cmd line: ");
	for (i=0; i < argc; i++)
		printf("%s ", argv[i]);
	printf("\n");

	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #25
0
/*
 * Do all the stuff that locore normally does before calling main().
 * Process arguments passed to us by the prom monitor.
 * Return the first page address following the system.
 */
void
mach_init(int x_boothowto, int x_bootdev, int x_bootname, int x_maxmem)
{
	u_long first, last;
	char *kernend;
	struct btinfo_magic *bi_magic;
	struct btinfo_bootarg *bi_arg;
	struct btinfo_systype *bi_systype;
#if NKSYMS || defined(DDB) || defined(MODULAR)
	struct btinfo_symtab *bi_sym;
	int nsym = 0;
	char *ssym, *esym;

	ssym = esym = NULL;	/* XXX: gcc */
#endif
	bi_arg = NULL;

	bootinfo = (void *)BOOTINFO_ADDR;	/* XXX */
	bi_magic = lookup_bootinfo(BTINFO_MAGIC);
	if (bi_magic && bi_magic->magic == BOOTINFO_MAGIC) {
		bi_arg = lookup_bootinfo(BTINFO_BOOTARG);
		if (bi_arg) {
			x_boothowto = bi_arg->howto;
			x_bootdev = bi_arg->bootdev;
			x_maxmem = bi_arg->maxmem;
		}
#if NKSYMS || defined(DDB) || defined(MODULAR)
		bi_sym = lookup_bootinfo(BTINFO_SYMTAB);
		if (bi_sym) {
			nsym = bi_sym->nsym;
			ssym = (void *)bi_sym->ssym;
			esym = (void *)bi_sym->esym;
		}
#endif

		bi_systype = lookup_bootinfo(BTINFO_SYSTYPE);
		if (bi_systype)
			systype = bi_systype->type;
	} else {
		/*
		 * Running kernel is loaded by non-native loader;
		 * clear the BSS segment here.
		 */
		memset(edata, 0, end - edata);
	}

	if (systype == 0) 
		systype = NEWS3400;	/* XXX compatibility for old boot */

#ifdef news5000
	if (systype == NEWS5000) {
		int i;
		char *bootspec = (char *)x_bootdev;

		if (bi_arg == NULL)
			panic("news5000 requires BTINFO_BOOTARG to boot");

		_sip = (void *)bi_arg->sip;
		x_maxmem = _sip->apbsi_memsize;
		x_maxmem -= 0x00100000;	/* reserve 1MB for ROM monitor */
		if (strncmp(bootspec, "scsi", 4) == 0) {
			x_bootdev = (5 << 28) | 0;	 /* magic, sd */
			bootspec += 4;
			if (*bootspec != '(' /*)*/)
				goto bootspec_end;
			i = strtoul(bootspec + 1, &bootspec, 10);
			x_bootdev |= (i << 24);		/* bus */
			if (*bootspec != ',')
				goto bootspec_end;
			i = strtoul(bootspec + 1, &bootspec, 10);
			x_bootdev |= (i / 10) << 20;	/* controller */
			x_bootdev |= (i % 10) << 16;	/* unit */
			if (*bootspec != ',')
				goto bootspec_end;
			i = strtoul(bootspec + 1, &bootspec, 10);
			x_bootdev |= (i << 8);		/* partition */
		}
 bootspec_end:
		consinit();
	}
#endif

	/*
	 * Save parameters into kernel work area.
	 */
	*(int *)(MIPS_PHYS_TO_KSEG1(MACH_MAXMEMSIZE_ADDR)) = x_maxmem;
	*(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTDEV_ADDR)) = x_bootdev;
	*(int *)(MIPS_PHYS_TO_KSEG1(MACH_BOOTSW_ADDR)) = x_boothowto;

	kernend = (char *)mips_round_page(end);
#if NKSYMS || defined(DDB) || defined(MODULAR)
	if (nsym)
		kernend = (char *)mips_round_page(esym);
#endif

	/*
	 * Set the VM page size.
	 */
	uvm_setpagesize();

	boothowto = x_boothowto;
	bootdev = x_bootdev;
	physmem = btoc(x_maxmem);

	/*
	 * Now that we know how much memory we have, initialize the
	 * mem cluster array.
	 */
	mem_clusters[0].start = 0;		/* XXX is this correct? */
	mem_clusters[0].size  = ctob(physmem);
	mem_cluster_cnt = 1;

	/*
	 * Copy exception-dispatch code down to exception vector.
	 * Initialize locore-function vector.
	 * Clear out the I and D caches.
	 */
	mips_vector_init(NULL, false);

	/*
	 * We know the CPU type now.  Initialize our DMA tags (might
	 * need this early).
	 */
	newsmips_bus_dma_init();

#if NKSYMS || defined(DDB) || defined(MODULAR)
	if (nsym)
		ksyms_addsyms_elf(esym - ssym, ssym, esym);
#endif

#ifdef KADB
	boothowto |= RB_KDB;
#endif

	/*
	 * Check to see if a mini-root was loaded into memory. It resides
	 * at the start of the next page just after the end of BSS.
	 */
	if (boothowto & RB_MINIROOT)
		kernend += round_page(mfs_initminiroot(kernend));

	/*
	 * Load the rest of the available pages into the VM system.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
	    VM_FREELIST_DEFAULT);

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Initialize the virtual memory system.
	 */
	pmap_bootstrap();

	/*
	 * Allocate uarea page for lwp0 and set it.
	 */
	mips_init_lwp0_uarea();

	/*
	 * Determine what model of computer we are running on.
	 */
	switch (systype) {
#ifdef news3400
	case NEWS3400:
		news3400_init();
		strcpy(cpu_model, idrom.id_machine);
		if (strcmp(cpu_model, "news3400") == 0 ||
		    strcmp(cpu_model, "news3200") == 0 ||
		    strcmp(cpu_model, "news3700") == 0) {
			/*
			 * Set up interrupt handling and I/O addresses.
			 */
			hardware_intr = news3400_intr;
			cpuspeed = 10;
		} else {
			printf("kernel not configured for machine %s\n",
			    cpu_model);
		}
		break;
#endif

#ifdef news5000
	case NEWS5000:
		news5000_init();
		strcpy(cpu_model, idrom.id_machine);
		if (strcmp(cpu_model, "news5000") == 0 ||
		    strcmp(cpu_model, "news5900") == 0) {
			/*
			 * Set up interrupt handling and I/O addresses.
			 */
			hardware_intr = news5000_intr;
			cpuspeed = 50;	/* ??? XXX */
		} else {
			printf("kernel not configured for machine %s\n",
			    cpu_model);
		}
		break;
#endif

	default:
		printf("kernel not configured for systype %d\n", systype);
		break;
	}
}
Beispiel #26
0
void
platform_start(__register_t a0 __unused, __register_t a1 __unused, 
    __register_t a2 __unused, __register_t a3 __unused)
{
	uint64_t platform_counter_freq;
	int argc = 0, i;
	char **argv = NULL, **envp = NULL;
	vm_offset_t kernend;

	/* 
	 * clear the BSS and SBSS segments, this should be first call in
	 * the function
	 */
	kernend = (vm_offset_t)&end;
	memset(&edata, 0, kernend - (vm_offset_t)(&edata));

	mips_postboot_fixup();

	/* Initialize pcpu stuff */
	mips_pcpu0_init();

	/*
	 * Until some more sensible abstractions for uboot/redboot
	 * environment handling, we have to make this a compile-time
	 * hack.  The existing code handles the uboot environment
	 * very incorrectly so we should just ignore initialising
	 * the relevant pointers.
	 */
#ifndef	AR71XX_ENV_UBOOT
	argc = a0;
	argv = (char**)a1;
	envp = (char**)a2;
#endif
	/* 
	 * Protect ourselves from garbage in registers 
	 */
	if (MIPS_IS_VALID_PTR(envp)) {
		for (i = 0; envp[i]; i += 2) {
			if (strcmp(envp[i], "memsize") == 0)
				realmem = btoc(strtoul(envp[i+1], NULL, 16));
		}
	}

	/*
	 * Just wild guess. RedBoot let us down and didn't reported 
	 * memory size
	 */
	if (realmem == 0)
		realmem = btoc(32*1024*1024);

	/*
	 * Allow build-time override in case Redboot lies
	 * or in other situations (eg where there's u-boot)
	 * where there isn't (yet) a convienent method of
	 * being told how much RAM is available.
	 *
	 * This happens on at least the Ubiquiti LS-SR71A
	 * board, where redboot says there's 16mb of RAM
	 * but in fact there's 32mb.
	 */
#if	defined(AR71XX_REALMEM)
		realmem = btoc(AR71XX_REALMEM);
#endif

	/* phys_avail regions are in bytes */
	phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
	phys_avail[1] = ctob(realmem);

	dump_avail[0] = phys_avail[0];
	dump_avail[1] = phys_avail[1] - phys_avail[0];

	physmem = realmem;

	/*
	 * ns8250 uart code uses DELAY so ticker should be inititalized 
	 * before cninit. And tick_init_params refers to hz, so * init_param1 
	 * should be called first.
	 */
	init_param1();

	/* Detect the system type - this is needed for subsequent chipset-specific calls */
	ar71xx_detect_sys_type();
	ar71xx_detect_sys_frequency();

	platform_counter_freq = ar71xx_cpu_freq();
	mips_timer_init_params(platform_counter_freq, 1);
	cninit();
	init_static_kenv(boot1_env, sizeof(boot1_env));

	printf("CPU platform: %s\n", ar71xx_get_system_type());
	printf("CPU Frequency=%d MHz\n", u_ar71xx_cpu_freq / 1000000);
	printf("CPU DDR Frequency=%d MHz\n", u_ar71xx_ddr_freq / 1000000);
	printf("CPU AHB Frequency=%d MHz\n", u_ar71xx_ahb_freq / 1000000);
	printf("platform frequency: %lld\n", platform_counter_freq);
	printf("CPU reference clock: %d MHz\n", u_ar71xx_refclk / 1000000);
	printf("arguments: \n");
	printf("  a0 = %08x\n", a0);
	printf("  a1 = %08x\n", a1);
	printf("  a2 = %08x\n", a2);
	printf("  a3 = %08x\n", a3);

	/*
	 * XXX this code is very redboot specific.
	 */
	printf("Cmd line:");
	if (MIPS_IS_VALID_PTR(argv)) {
		for (i = 0; i < argc; i++) {
			printf(" %s", argv[i]);
			parse_argv(argv[i]);
		}
	}
	else
		printf ("argv is invalid");
	printf("\n");

	printf("Environment:\n");
	if (MIPS_IS_VALID_PTR(envp)) {
		for (i = 0; envp[i]; i+=2) {
			printf("  %s = %s\n", envp[i], envp[i+1]);
			setenv(envp[i], envp[i+1]);
		}
	}
	else 
		printf ("envp is invalid\n");

	/* Redboot if_arge MAC address is in the environment */
	ar71xx_redboot_get_macaddr();

	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();

	/*
	 * Reset USB devices 
	 */
	ar71xx_init_usb_peripheral();

	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #27
0
void
mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize)
{
	bus_space_handle_t sh;
	void *kernend;
	const char *cp;
	u_long first, last;
	void *v;
	int freqok, howto, i;
	const struct alchemy_board *board;

	extern char edata[], end[];	/* XXX */

	board = board_info();
	KASSERT(board != NULL);

	/* clear the BSS segment */
	kernend = (void *)mips_round_page(end);
	memset(edata, 0, (char *)kernend - edata);

	/* set CPU model info for sysctl_hw */
	strcpy(cpu_model, board->ab_name);

	/* save the yamon environment pointer */
	yamon_envp = envp;

	/* Use YAMON callbacks for early console I/O */
	cn_tab = &yamon_promcd;

	/*
	 * Set up the exception vectors and CPU-specific function
	 * vectors early on.  We need the wbflush() vector set up
	 * before comcnattach() is called (or at least before the
	 * first printf() after that is called).
	 * Sets up mips_cpu_flags that may be queried by other
	 * functions called during startup.
	 * Also clears the I+D caches.
	 */
	mips_vector_init();

	/*
	 * Set the VM page size.
	 */
	uvm_setpagesize();

	/*
	 * Use YAMON's CPU frequency if available.
	 */
	freqok = yamon_setcpufreq(1);

	/*
	 * Initialize bus space tags.
	 */
	au_cpureg_bus_mem_init(&alchemy_cpuregt, &alchemy_cpuregt);
	aubus_st = &alchemy_cpuregt;

	/*
	 * Calibrate the timer if YAMON failed to tell us.
	 */
	if (!freqok) {
		bus_space_map(aubus_st, PC_BASE, PC_SIZE, 0, &sh);
		au_cal_timers(aubus_st, sh);
		bus_space_unmap(aubus_st, sh, PC_SIZE);
	}

	/*
	 * Perform board-specific initialization.
	 */
	board->ab_init();

	/*
	 * Bring up the console.
	 */
#if NCOM > 0
#ifdef CONSPEED
	if (aucomcnrate == 0)
		aucomcnrate = CONSPEED;
#else /* !CONSPEED */
	/*
	 * Learn default console speed.  We use the YAMON environment,
	 * though we could probably also figure it out by checking the
	 * aucom registers directly.
	 */
	if ((aucomcnrate == 0) && ((cp = yamon_getenv("modetty0")) != NULL))
		aucomcnrate = strtoul(cp, NULL, 0);

	if (aucomcnrate == 0) {
		printf("FATAL: `modetty0' YAMON variable not set.  Set it\n");
		printf("       to the speed of the console and try again.\n");
		printf("       Or, build a kernel with the `CONSPEED' "
		    "option.\n");
		panic("mach_init");
	}
#endif /* CONSPEED */

	/*
	 * Delay to allow firmware putchars to complete.
	 * FIFO depth * character time.
	 * character time = (1000000 / (defaultrate / 10))
	 */
	delay(160000000 / aucomcnrate);
	if (com_aubus_cnattach(UART0_BASE, aucomcnrate) != 0)
		panic("mach_init: unable to initialize serial console");

#else /* NCOM > 0 */
	panic("mach_init: not configured to use serial console");
#endif /* NAUCOM > 0 */

	/*
	 * Look at arguments passed to us and compute boothowto.
	 */
	boothowto = RB_AUTOBOOT;
#ifdef KADB
	boothowto |= RB_KDB;
#endif
	for (i = 1; i < argc; i++) {
		for (cp = argv[i]; *cp; cp++) {
			/* Ignore superfluous '-', if there is one */
			if (*cp == '-')
				continue;

			howto = 0;
			BOOT_FLAG(*cp, howto);
			if (! howto)
				printf("bootflag '%c' not recognised\n", *cp);
			else
				boothowto |= howto;
		}
	}

	/*
	 * Determine the memory size.  Use the `memsize' PMON
	 * variable.  If that's not available, panic.
	 *
	 * Note: Reserve the first page!  That's where the trap
	 * vectors are located.
	 */

#if defined(MEMSIZE)
	memsize = MEMSIZE;
#else
	if (memsize == 0) {
		if ((cp = yamon_getenv("memsize")) != NULL)
			memsize = strtoul(cp, NULL, 0);
		else {
			printf("FATAL: `memsize' YAMON variable not set.  Set it to\n");
			printf("       the amount of memory (in MB) and try again.\n");
			printf("       Or, build a kernel with the `MEMSIZE' "
			    "option.\n");
			panic("mach_init");
		}
	}
#endif /* MEMSIZE */
	printf("Memory size: 0x%08lx\n", memsize);
	physmem = btoc(memsize);

	mem_clusters[mem_cluster_cnt].start = PAGE_SIZE;
	mem_clusters[mem_cluster_cnt].size =
	    memsize - mem_clusters[mem_cluster_cnt].start;
	mem_cluster_cnt++;

	/*
	 * Load the rest of the available pages into the VM system.
	 */
	first = round_page(MIPS_KSEG0_TO_PHYS(kernend));
	last = mem_clusters[0].start + mem_clusters[0].size;
	uvm_page_physload(atop(first), atop(last), atop(first), atop(last),
	    VM_FREELIST_DEFAULT);

	/*
	 * Initialize message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Initialize the virtual memory system.
	 */
	pmap_bootstrap();

	/*
	 * Init mapping for u page(s) for proc0.
	 */
	v = (void *) uvm_pageboot_alloc(USPACE);
	lwp0.l_addr = proc0paddr = (struct user *)v;
	lwp0.l_md.md_regs = (struct frame *)((char *)v + USPACE) - 1;
	proc0paddr->u_pcb.pcb_context[11] =
	    MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */

	/*
	 * Initialize debuggers, and break into them, if appropriate.
	 */
#if NKSYMS || defined(DDB) || defined(LKM)
	ksyms_init(0, 0, 0);
#endif
#ifdef DDB
	if (boothowto & RB_KDB)
		Debugger();
#endif
}
Beispiel #28
0
static void
mips_init(void)
{
	struct mem_region mr[FDT_MEM_REGIONS];
	uint64_t val;
	int i, j, mr_cnt;
	char *memsize;

	printf("entry: mips_init()\n");

	bootverbose = 1;

	for (i = 0; i < 10; i++)
		phys_avail[i] = 0;

	dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);

	/*
	 * The most low memory MT7621 can have. Currently MT7621 is the chip
	 * that supports the most memory, so that seems reasonable.
	 */
	realmem = btoc(448 * 1024 * 1024);

	if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) {
		physmem = btoc(val);

		printf("RAM size: %ldMB (from FDT)\n",
		    ctob(physmem) / (1024 * 1024));

		KASSERT((phys_avail[0] >= mr[0].mr_start) && \
			(phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)),
			("First region is not within FDT memory range"));

		/* Limit size of the first region */
		phys_avail[1] = (mr[0].mr_start +
		    MIN(mr[0].mr_size, ctob(realmem)));
		dump_avail[1] = phys_avail[1];

		/* Add the rest of the regions */
		for (i = 1, j = 2; i < mr_cnt; i++, j+=2) {
			phys_avail[j] = mr[i].mr_start;
			phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size);
			dump_avail[j] = phys_avail[j];
			dump_avail[j+1] = phys_avail[j+1];
		}
	} else {
		if ((memsize = kern_getenv("memsize")) != NULL) {
			physmem = btoc(strtol(memsize, NULL, 0) << 20);
			printf("RAM size: %ldMB (from memsize)\n",
			    ctob(physmem) / (1024 * 1024));
		} else { /* All else failed, assume 32MB */
			physmem = btoc(32 * 1024 * 1024);
			printf("RAM size: %ldMB (assumed)\n",
			    ctob(physmem) / (1024 * 1024));
		}

		if (ctob(physmem) < (448 * 1024 * 1024)) {
			/*
			 * Anything up to 448MB is assumed to be directly
			 * mappable as low memory...
			 */
			dump_avail[1] = phys_avail[1] = ctob(physmem);
		} else if (mtk_soc_get_socid() == MTK_SOC_MT7621) {
			/*
			 * On MT7621 the low memory is limited to 448MB, the
			 * rest is high memory, mapped at 0x20000000
			 */
			phys_avail[1] = 448 * 1024 * 1024;
			phys_avail[2] = 0x20000000;
			phys_avail[3] = phys_avail[2] + ctob(physmem) -
			    phys_avail[1];
			dump_avail[1] = phys_avail[1] - phys_avail[0];
			dump_avail[2] = phys_avail[2];
			dump_avail[3] = phys_avail[3] - phys_avail[2];
		} else {
			/*
			 * We have > 448MB RAM and we're not MT7621? Currently
			 * there is no such chip, so we'll just limit the RAM to
			 * 32MB and let the user know...
			 */
			printf("Unknown chip, assuming 32MB RAM\n");
			physmem = btoc(32 * 1024 * 1024);
			dump_avail[1] = phys_avail[1] = ctob(physmem);
		}
	}

	if (physmem < realmem)
		realmem = physmem;

	init_param1();
	init_param2(physmem);
	mips_cpu_init();
	pmap_bootstrap();
	mips_proc0_init();
	mutex_init();
	kdb_init();
#ifdef KDB
	if (boothowto & RB_KDB)
		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
#endif
}
Beispiel #29
0
/*
 * Do all the stuff that locore normally does before calling main().
 */
void
mach_init()
{
	extern char kernel_text[], edata[], end[];
	extern struct user *proc0paddr;
	caddr_t kernend, v;
	paddr_t start;
	size_t size;

	/*
	 * Clear the BSS segment.
	 */
	kernend = (caddr_t)mips_round_page(end);
	memset(edata, 0, kernend - edata);

	/* disable all interrupt */
	interrupt_init_bootstrap();

	/* enable SIF BIOS */
	sifbios_init();

	consinit();

	printf("kernel_text=%p edata=%p end=%p\n", kernel_text, edata, end);

#ifdef DEBUG
	bootinfo_dump();
#endif
	uvm_setpagesize();
	physmem = atop(PS2_MEMORY_SIZE);

	/*
	 * Copy exception-dispatch code down to exception vector.
	 * Initialize locore-function vector.
	 * Clear out the I and D caches.
	 */
	mips_vector_init();

	/*
	 * Load the rest of the available pages into the VM system.
	 */
	start = (paddr_t)round_page(MIPS_KSEG0_TO_PHYS(kernend));
	size = PS2_MEMORY_SIZE - start - BOOTINFO_BLOCK_SIZE;
	memset((void *)MIPS_PHYS_TO_KSEG1(start), 0, size);
	    
	/* kernel itself */
	mem_clusters[0].start = trunc_page(MIPS_KSEG0_TO_PHYS(kernel_text));
	mem_clusters[0].size = start - mem_clusters[0].start;
	/* heap */
	mem_clusters[1].start = start;
	mem_clusters[1].size = size;
	/* load */
	printf("load memory %#lx, %#x\n", start, size);
	uvm_page_physload(atop(start), atop(start + size),
	    atop(start), atop(start + size), VM_FREELIST_DEFAULT);

	/*
	 * Initialize error message buffer (at end of core).
	 */
	mips_init_msgbuf();

	/*
	 * Compute the size of system data structures.  pmap_bootstrap()
	 * needs some of this information.
	 */
	size = (vsize_t)allocsys(NULL, NULL);

	pmap_bootstrap();

	/*
	 * Allocate space for proc0's USPACE.
	 */
	v = (caddr_t)uvm_pageboot_alloc(USPACE); 
	proc0.p_addr = proc0paddr = (struct user *)v;
	proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1;
	curpcb = &proc0.p_addr->u_pcb;
	curpcb->pcb_context[11] = PSL_LOWIPL;	/* SR */
#ifdef IPL_ICU_MASK
	curpcb->pcb_ppl = 0;
#endif

	/*
	 * Allocate space for system data structures.  These data structures
	 * are allocated here instead of cpu_startup() because physical
	 * memory is directly addressable.  We don't have to map these into
	 * virtual address space.
	 */
	v = (caddr_t)uvm_pageboot_alloc(size); 
	if ((allocsys(v, NULL) - v) != size)
		panic("mach_init: table size inconsistency");
}