Ejemplo n.º 1
0
/*
 * Initialize PDC and related variables.
 */
void
pdc_init()
{
	int err;

	/*
	 * Initialize important global variables (defined above).
	 */
	pdc = (pdcio_t)(u_long)PAGE0->mem_pdc;

	err = pdc_call(pdc, PDC_STABLE, PDC_STABLE_SIZE, pdcbuf, 0, 0);
	if (err >= 0) {
		sstorsiz = min(pdcbuf[0],sizeof(sstor));
		err = (*pdc)(PDC_STABLE, PDC_STABLE_READ, 0, &sstor, sstorsiz);
	}

	/*
	 * Now that we (may) have an output device, if we encountered
	 * an error reading Stable Storage (above), let them know.
	 */
#ifdef DEBUG
	if (debug && err)
		printf("Stable storage PDC_STABLE Read Ret'd %d\n", err);
#endif

	/*
	 * Clear the FAULT light (so we know when we get a real one)
	 */
	pdc_call(pdc, PDC_CHASSIS, PDC_CHASSIS_DISP,
	    PDC_OSTAT(PDC_OSTAT_BOOT) | 0xCEC0);
}
Ejemplo n.º 2
0
struct pdc_pat_pci_rt *
pdc_getirt(int *pn)
{
	struct pdc_pat_pci_rt *rt;
	int i, num, err;
	long cell;

	cell = -1;
	if (!pdc_call((iodcio_t)pdc, 0, PDC_PAT_CELL, PDC_PAT_CELL_GETID,
	    &pdc_pat_cell_id, 0)) {
		cell = pdc_pat_cell_id.id;

		if ((err = pdc_call((iodcio_t)pdc, 0, PDC_PAT_IO,
		    PDC_PAT_IO_GET_PCI_RTSZ, &pdc_pat_io_num, cell))) {
			printf("irt size error %d\n", err);
			return (NULL);
		}
	} else if ((err = pdc_call((iodcio_t)pdc, 0, PDC_PCI_INDEX,
	    PDC_PCI_GET_INT_TBL_SZ, &pdc_pat_io_num, cpu_gethpa(0)))) {
		printf("irt size error %d\n", err);
		return (NULL);
	}

printf("num %ld ", pdc_pat_io_num.num);
	*pn = num = pdc_pat_io_num.num;
	if (num > sizeof(pdc_rt) / sizeof(*rt)) {
		printf("\nPCI IRT is too big %d\n", num);
		return (NULL);
	}

	if (!(rt = malloc(num * sizeof(*rt), M_DEVBUF, M_NOWAIT)))
		return (NULL);

	if (cell >= 0) {
		if ((err = pdc_call((iodcio_t)pdc, 0, PDC_PAT_IO,
		    PDC_PAT_IO_GET_PCI_RT, rt, cell))) {
			printf("irt fetch error %d\n", err);
			free(rt, M_DEVBUF);
			return (NULL);
		}
	} else if ((err = pdc_call((iodcio_t)pdc, 0, PDC_PCI_INDEX,
	    PDC_PCI_GET_INT_TBL, &pdc_pat_io_num, cpu_gethpa(0), pdc_rt))) {
		printf("irt fetch error %d\n", err);
		free(rt, M_DEVBUF);
		return (NULL);
	}
	bcopy(pdc_rt, rt, num * sizeof(*rt));

for (i = 0; i < num; i++)
printf("\n%d: ty 0x%02x it 0x%02x trig 0x%02x pin 0x%02x bus %d seg %d line %d addr 0x%llx",
i, rt[i].type, rt[i].itype, rt[i].trigger, rt[i].pin, rt[i].bus, rt[i].seg, rt[i].line, rt[i].addr);
	return rt;
}
Ejemplo n.º 3
0
void
cpu_startup()
{
	struct pdc_model pdc_model;
	register const struct hppa_board_info *bip;
	vm_offset_t minaddr, maxaddr;
	vm_size_t size;
	int base, residual;
	int err, i;
#ifdef DEBUG
	extern int pmapdebug;
	int opmapdebug = pmapdebug;

	pmapdebug = 0;
#endif

	/* good night */
	printf(version);

	/* identify system type */
	if ((err = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO,
			    &pdc_model)) < 0) {
#ifdef DEBUG
		printf("WARNING: PDC_MODEL failed (%d)\n", err);
#endif
	} else {
		i = pdc_model.hvers >> 4; /* board type */
		for (bip = hppa_knownboards;
		     bip->bi_id >= 0 && bip->bi_id != i; bip++);
		if (bip->bi_id >= 0) {
			char *p;
			switch(pdc_model.arch_rev) {
			case  0:  p = "1.0";	break;
			case  4:  p = "1.1";	break;
			case  8:  p = "2.0";	break;
			default:  p = "?.?";	break;
			}
			/* my babe said: 6010, 481, 0, 0, 77b657b1, 0, 4 */
			sprintf(cpu_model, "HP9000/%s PA-RISC %s",
				bip->bi_name, p);
		} else
			sprintf(cpu_model, "HP9000/(UNKNOWN %x)", i);
		printf("%s\n", cpu_model);
	}

	printf("real mem = %d (%d reserved for PROM, %d used by OpenBSD)\n",
	       ctob(totalphysmem), ctob(resvmem), ctob(physmem));

	/*
	 * Now allocate buffers proper.  They are different than the above
	 * in that they usually occupy more virtual memory than physical.
	 */
	size = MAXBSIZE * nbuf;
	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
				   &maxaddr, size, TRUE);
	minaddr = (vm_offset_t)buffers;
	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
			&minaddr, size, FALSE) != KERN_SUCCESS)
		panic("cpu_startup: cannot allocate buffers");

	base = bufpages / nbuf;
	residual = bufpages % nbuf;
	for (i = 0; i < nbuf; i++) {
		/*
		 * First <residual> buffers get (base+1) physical pages
		 * allocated for them.  The rest get (base) physical pages.
		 *
		 * The rest of each buffer occupies virtual space,
		 * but has no physical memory allocated for it.
		 */
		vm_map_pageable(buffer_map, minaddr, minaddr +
				CLBYTES * (base + (i < residual)), FALSE);
		vm_map_simplify(buffer_map, minaddr);
		minaddr += MAXBSIZE;
	}

	/*
	 * Allocate a submap for exec arguments.  This map effectively
	 * limits the number of processes exec'ing at any time.
	 */
	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
				 16*NCARGS, TRUE);

	/*
	 * Allocate a submap for physio
	 */
	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
				 VM_PHYS_SIZE, TRUE);

	/*
	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
	 * we use the more space efficient malloc in place of kmem_alloc.
	 */
	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
				   M_MBUF, M_NOWAIT);
	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
			       VM_MBUF_SIZE, FALSE);

	/*
	 * Initialize callouts
	 */
	callfree = callout;
	for (i = 1; i < ncallout; i++)
		callout[i-1].c_next = &callout[i];
	callout[i-1].c_next = NULL;

#ifdef DEBUG
	pmapdebug = opmapdebug;
#endif
	printf("avail mem = %ld\n", ptoa(cnt.v_free_count));
	printf("using %d buffers containing %d bytes of memory\n",
		nbuf, bufpages * CLBYTES);

	/*
	 * Set up buffers, so they can be used to read disk labels.
	 */
	bufinit();

	/*
	 * Configure the system.
	 */
	if (boothowto & RB_CONFIG) {
#ifdef BOOT_CONFIG
		user_config();
#else
		printf("kernel does not support -c; continuing..\n");
#endif
	}
	hppa_malloc_ok = 1;
	configure();
}
Ejemplo n.º 4
0
void
hppa_init()
{
	extern int kernel_text, end;
	struct pdc_hwtlb pdc_hwtlb PDC_ALIGNMENT;
	struct pdc_coproc pdc_coproc PDC_ALIGNMENT;
	vm_offset_t v, vstart, vend;
	register int pdcerr;
	int usehpt;

	/* init PDC iface, so we can call em easy */
	pdc_init();

	/* calculate cpu speed */
	cpu_hzticks = (PAGE0->mem_10msec * 100) / hz;
	delay_init();

	/*
	 * get cache parameters from the PDC
	 */
	if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT,
			       &pdc_cache)) < 0) {
#ifdef DIAGNOSTIC
                printf("Warning: PDC_CACHE call Ret'd %d\n", pdcerr);
#endif
	}

	dcache_line_mask = pdc_cache.dc_conf.cc_line * 16 - 1;
	dcache_size = pdc_cache.dc_size;
	dcache_stride = pdc_cache.dc_stride;
	icache_stride = pdc_cache.ic_stride;

	/*
	 * purge TLBs and flush caches
	 */
	if (pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_PURGE_ALL) < 0)
		printf("WARNING: BTLB purge failed\n");
	ptlball();
	fcacheall();

	/* calculate HPT size */
	hpt_hashsize = PAGE0->imm_max_mem / NBPG;
	mtctl(hpt_hashsize - 1, CR_HPTMASK);

	/*
	 * If we want to use the HW TLB support, ensure that it exists.
	 */
	if (pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_INFO, &pdc_hwtlb) &&
	    !pdc_hwtlb.min_size && !pdc_hwtlb.max_size) {
		printf("WARNING: no HW tlb walker\n");
		usehpt = 0;
	} else {
		usehpt = 1;
#ifdef DEBUG
		printf("hwtlb: %u-%u, %u/",
		       pdc_hwtlb.min_size, pdc_hwtlb.max_size, hpt_hashsize);
#endif
		if (hpt_hashsize > pdc_hwtlb.max_size)
			hpt_hashsize = pdc_hwtlb.max_size;
		else if (hpt_hashsize < pdc_hwtlb.min_size)
			hpt_hashsize = pdc_hwtlb.min_size;
#ifdef DEBUG
		printf("%u (0x%x)\n", hpt_hashsize,
		       hpt_hashsize * sizeof(struct hpt_entry));
#endif
	}
	
	totalphysmem = PAGE0->imm_max_mem / NBPG;
	resvmem = ((vm_offset_t)&kernel_text) / NBPG;

	vstart = hppa_round_page(&end);
	vend = VM_MAX_KERNEL_ADDRESS;

	/* we hope this won't fail */
	hppa_ex = extent_create("mem", 0x0, 0xffffffff, M_DEVBUF,
				(caddr_t)mem_ex_storage,
				sizeof(mem_ex_storage),
				EX_NOCOALESCE|EX_NOWAIT);
	if (extent_alloc_region(hppa_ex, 0, (vm_offset_t)PAGE0->imm_max_mem,
				EX_NOWAIT))
		panic("cannot reserve main memory");

	/*
	 * Allocate space for system data structures.  We are given
	 * a starting virtual address and we return a final virtual
	 * address; along the way we set each data structure pointer.
	 *
	 * We call allocsys() with 0 to find out how much space we want,
	 * allocate that much and fill it with zeroes, and the call
	 * allocsys() again with the correct base virtual address.
	 */

	v = vstart;
#define	valloc(name, type, num)	\
	    (name) = (type *)v; v = (vm_offset_t)((name)+(num))

#ifdef REAL_CLISTS
	valloc(cfree, struct cblock, nclist);
#endif
	valloc(callout, struct callout, ncallout);
	nswapmap = maxproc * 2;
	valloc(swapmap, struct map, nswapmap);
#ifdef SYSVSHM
	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
#endif
#ifdef SYSVSEM 
	valloc(sema, struct semid_ds, seminfo.semmni);
	valloc(sem, struct sem, seminfo.semmns); 
	/* This is pretty disgusting! */
	valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
#endif
#ifdef SYSVMSG
	valloc(msgpool, char, msginfo.msgmax);
	valloc(msgmaps, struct msgmap, msginfo.msgseg);
	valloc(msghdrs, struct msg, msginfo.msgtql);
	valloc(msqids, struct msqid_ds, msginfo.msgmni);
#endif

#ifndef BUFCACHEPERCENT
#define BUFCACHEPERCENT 10
#endif /* BUFCACHEPERCENT */

	if (bufpages == 0)
		bufpages = totalphysmem / BUFCACHEPERCENT / CLSIZE;
	if (nbuf == 0) {
		nbuf = bufpages;
		if (nbuf < 16)
			nbuf = 16;
	}

	/* Restrict to at most 70% filled kvm */
	if (nbuf * MAXBSIZE >
	    (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) * 7 / 10)
		nbuf = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
		    MAXBSIZE * 7 / 10;

	/* More buffer pages than fits into the buffers is senseless.  */
	if (bufpages > nbuf * MAXBSIZE / CLBYTES)
		bufpages = nbuf * MAXBSIZE / CLBYTES;

	if (nswbuf == 0) {
		nswbuf = (nbuf / 2) & ~1;	/* force even */
		if (nswbuf > 256)
			nswbuf = 256;		/* sanity */
	}

	valloc(swbuf, struct buf, nswbuf);
	valloc(buf, struct buf, nbuf);
#undef valloc
	bzero ((void *)vstart, (v - vstart));
	vstart = v;

	pmap_bootstrap(&vstart, &vend);
	physmem = totalphysmem - btoc(vstart);

	/* alloc msgbuf */
	if (!(msgbufp = (void *)pmap_steal_memory(sizeof(struct msgbuf),
						  NULL, NULL)))
		panic("cannot allocate msgbuf");
	msgbufmapped = 1;

#ifdef DEBUG
	printf("mem: %x+%x, %x\n", physmem, resvmem, totalphysmem);
#endif
	/* Turn on the HW TLB assist */
	if (usehpt) {
		if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_TLB,
				       PDC_TLB_CONFIG, &pdc_hwtlb, hpt_table,
				       sizeof(struct hpt_entry) * hpt_hashsize,
				       PDC_TLB_WORD3)) < 0) {
			printf("Warning: HW TLB init failed (%d), disabled\n",
			       pdcerr);
			usehpt = 0;
		} else
			printf("HW TLB(%d entries at 0x%x) initialized (%d)\n",
			       hpt_hashsize, hpt_table, pdcerr);
	}

        /*
         * Locate any coprocessors and enable them by setting up the CCR.
         * SFU's are ignored (since we dont have any).  Also, initialize
         * the floating point registers here.
         */
        if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT,
			       &pdc_coproc)) < 0)
                printf("WARNING: PDC_COPROC call Ret'd %d\n", pdcerr);
	else {
#ifdef DEBUG
		printf("pdc_coproc: %x, %x\n", pdc_coproc.ccr_enable,
		       pdc_coproc.ccr_present);
#endif
	}
        copr_sfu_config = pdc_coproc.ccr_enable;
        mtctl(copr_sfu_config & CCR_MASK, CR_CCR);
/*
        fprinit(&fpcopr_version);
	fpcopr_version = (fpcopr_version & 0x003ff800) >> 11;
        mtctl(CR_CCR, 0);
*/
        /*
         * Clear the FAULT light (so we know when we get a real one)
         * PDC_COPROC apparently turns it on (for whatever reason).
         */
        pdcerr = PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0;
        (void) (*pdc)(PDC_CHASSIS, PDC_CHASSIS_DISP, pdcerr);

#ifdef DDB
	ddb_init();
#endif
#ifdef DEBUG
	printf("hppa_init: leaving\n");
#endif
	kernelmapped++;
}
Ejemplo n.º 5
0
void
memattach(struct device *parent, struct device *self, void *aux)
{
	struct pdc_iodc_minit pdc_minit PDC_ALIGNMENT;
	struct confargs *ca = aux;
	struct mem_softc *sc = (struct mem_softc *)self;
	int s, err, pagezero_cookie;
	char bits[128];

	printf (":");

	pagezero_cookie = hp700_pagezero_map();

	/* XXX check if we are dealing w/ Viper */
	if (ca->ca_hpa == (hppa_hpa_t)VIPER_HPA) {

		sc->sc_vp = (struct vi_trs *)
		    &((struct iomod *)ca->ca_hpa)->priv_trs;

		/* XXX other values seem to blow it up */
		if (sc->sc_vp->vi_status.hw_rev == 0) {
			bitmask_snprintf(VI_CTRL, VIPER_BITS, bits, 
			    sizeof(bits));
			printf (" viper rev %x, ctrl %s",
			    sc->sc_vp->vi_status.hw_rev,
			    bits);

			s = splhigh();
			VI_CTRL |= VI_CTRL_ANYDEN;
			((struct vi_ctrl *)&VI_CTRL)->core_den = 0;
			((struct vi_ctrl *)&VI_CTRL)->sgc0_den = 0;
			((struct vi_ctrl *)&VI_CTRL)->sgc1_den = 0;
			((struct vi_ctrl *)&VI_CTRL)->core_prf = 1;
			sc->sc_vp->vi_control = VI_CTRL;
			splx(s);
#ifdef DEBUG
			bitmask_snprintf(VI_CTRL, VIPER_BITS, bits, 
			    sizeof(bits));
			printf (" >> %s", bits);
#endif
		} else
			sc->sc_vp = NULL;
	} else
		sc->sc_vp = NULL;

	if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_NINIT,
			    &pdc_minit, ca->ca_hpa, PAGE0->imm_spa_size)) < 0)
		pdc_minit.max_spa = PAGE0->imm_max_mem;

	hp700_pagezero_unmap(pagezero_cookie);

	printf (" size %d", pdc_minit.max_spa / (1024*1024));
	if (pdc_minit.max_spa % (1024*1024))
		printf (".%d", pdc_minit.max_spa % (1024*1024));
	printf ("MB");

	/* L2 cache controller is a part of the memory controller on PCXL2 */
	if (HPPA_PA_SPEC_MAJOR(hppa_cpu_info->hppa_cpu_info_pa_spec) == 1 &&
	    HPPA_PA_SPEC_MINOR(hppa_cpu_info->hppa_cpu_info_pa_spec) == 1 &&
	    HPPA_PA_SPEC_LETTER(hppa_cpu_info->hppa_cpu_info_pa_spec) == 'e') {
		sc->sc_l2 = (struct l2_mioc *)ca->ca_hpa;
#ifdef DEBUG
		bitmask_snprintf(sc->sc_l2->sltcv, SLTCV_BITS, bits,
				 sizeof(bits));
		printf(", sltcv %s", bits);
#endif
		/* sc->sc_l2->sltcv |= SLTCV_UP4COUT; */
		if (sc->sc_l2->sltcv & SLTCV_ENABLE) {
			uint32_t tagmask = sc->sc_l2->tagmask >> 20;
			printf(", %dMB L2 cache", tagmask + 1);
		}
Ejemplo n.º 6
0
void
pdc_scan(struct device *self, struct confargs *ca)
{
	struct device_path path;
	struct confargs nca;
	u_long	rv[16];
	int	i, err, mod = ca->ca_mod;

	if (pdc_call((iodcio_t)pdc, 0, PDC_PAT_CELL, PDC_PAT_CELL_GETID,
	    &pdc_pat_cell_id, 0))
		for (i = 0; !(err = pdc_call((iodcio_t)pdc, 0, PDC_SYSMAP,
		    PDC_SYSMAP_FIND, &pdc_find, &path, i)); i++) {
			if (autoconf_verbose)
				printf(">> hpa %x/%x dp %d/%d/%d/%d/%d/%d.%d\n",
				    pdc_find.hpa, pdc_find.size,
				    path.dp_bc[0], path.dp_bc[1], path.dp_bc[2],
				    path.dp_bc[3], path.dp_bc[4], path.dp_bc[5],
				    path.dp_mod);

			if (path.dp_bc[5] == mod) {
				nca = *ca;
				nca.ca_name = NULL;
				nca.ca_hpa = 0xffffffff00000000ULL |
				    (hppa_hpa_t)pdc_find.hpa;
				nca.ca_hpasz = pdc_find.size;
				nca.ca_mod = path.dp_mod;

				err = pdc_call((iodcio_t)pdc, 0, PDC_IODC,
				    PDC_IODC_READ, &pdc_iodc_read, nca.ca_hpa,
				    IODC_DATA, &nca.ca_type, sizeof(nca.ca_type));
				if (err < 0 || pdc_iodc_read.size < 8) {
					if (autoconf_verbose)
						printf(">> iodc_data error %d\n", err);
					bzero(&nca.ca_type, sizeof(nca.ca_type));
				}

				if (autoconf_verbose) {
					u_int *p = (u_int *)&nca.ca_type;
					printf(">> iodc_data 0x%08x 0x%08x\n",
					    p[0], p[1]);
				}

				config_found(self, &nca, mbprint);
			}
		}

	for (i = 0; !(err = pdc_call((iodcio_t)pdc, 0, PDC_PAT_CELL,
	    PDC_PAT_CELL_MODULE, rv, pdc_pat_cell_id.loc, i,
	    PDC_PAT_PAVIEW, &pdc_pat_cell_module, 0)); i++) {
		if (autoconf_verbose)
			printf(">> chpa %lx info %lx loc %lx "
			    "dp %d/%d/%d/%d/%d/%d.%d\n",
			    pdc_pat_cell_module.chpa, pdc_pat_cell_module.info,
			    pdc_pat_cell_module.loc,
			    pdc_pat_cell_module.dp.dp_bc[0],
			    pdc_pat_cell_module.dp.dp_bc[1],
			    pdc_pat_cell_module.dp.dp_bc[2],
			    pdc_pat_cell_module.dp.dp_bc[3],
			    pdc_pat_cell_module.dp.dp_bc[4],
			    pdc_pat_cell_module.dp.dp_bc[5],
			    pdc_pat_cell_module.dp.dp_mod);

		if (pdc_pat_cell_module.dp.dp_bc[5] == mod) {
			int t;

			t = PDC_PAT_CELL_MODTYPE(pdc_pat_cell_module.info);
			if (t >= sizeof(pat_names)/sizeof(pat_names[0]))
				continue;

			nca = *ca;
			nca.ca_name = pat_names[t];
			nca.ca_hpa = pdc_pat_cell_module.chpa &
			    ~(u_long)PAGE_MASK;
			nca.ca_hpasz =
			    PDC_PAT_CELL_MODSIZE(pdc_pat_cell_module.info);
			nca.ca_mod = pdc_pat_cell_module.dp.dp_mod;

			err = pdc_call((iodcio_t)pdc, 0, PDC_IODC,
			    PDC_IODC_READ, &pdc_iodc_read, nca.ca_hpa,
			    IODC_DATA, &nca.ca_type, sizeof(nca.ca_type));
			if (err < 0 || pdc_iodc_read.size < 8) {
				if (autoconf_verbose)
					printf(">> iodc_data error %d\n", err);
				bzero(&nca.ca_type, sizeof(nca.ca_type));
			}
			if (autoconf_verbose) {
				u_int *p = (u_int *)&nca.ca_type;
				printf(">> iodc_data 0x%08x 0x%08x\n",
				    p[0], p[1]);
			}

			config_found(self, &nca, mbprint);
		}
	}
}