Subject: Support for WorkPad addin memory card
To: None <port-hpcmips@netbsd.org>
From: Mycroft <root@ihack.net>
List: port-hpcmips
Date: 02/18/2000 13:58:44
To support probing the 32MB addin memory card in my WorkPad, I've made
the following changes.  The TX39x2 code has *not* been tested.  Could
someone test this on other hardware and commit it?


Index: hpcmips/hpcmips/machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/hpcmips/machdep.c,v
retrieving revision 1.18
diff -c -2 -r1.18 machdep.c
*** machdep.c	2000/02/10 08:34:08	1.18
--- machdep.c	2000/02/18 18:51:40
***************
*** 132,136 ****
  
  int	systype;		/* mother board type */
- int	maxmem;			/* max memory per process */
  int	physmem;		/* max supported memory, changes to actual */
  int	mem_cluster_cnt;
--- 132,135 ----
***************
*** 172,176 ****
  void	unimpl_clockintr __P ((void *));
  void    unimpl_fb_init __P((caddr_t*));
! int     unimpl_mem_init __P((caddr_t));
  void	unimpl_reboot __P((int howto, char *bootstr));
  
--- 171,175 ----
  void	unimpl_clockintr __P ((void *));
  void    unimpl_fb_init __P((caddr_t*));
! void    unimpl_mem_init __P((paddr_t));
  void	unimpl_reboot __P((int howto, char *bootstr));
  
***************
*** 209,213 ****
  	struct bootinfo *bi;
  {
- 	u_long first, last;
  	int i;
  	caddr_t kernend, v;
--- 208,211 ----
***************
*** 389,415 ****
  #endif
  
! 	/*
! 	 * Find out how much memory is available and clear memory.
! 	 */
! 	physmem = btoc((paddr_t)kernend - MIPS_KSEG0_START) + 
! 		(*platform.mem_init)(kernend);
! 	maxmem = physmem;
  
! 	/*
! 	 * 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;
  
! 	/*
! 	 * 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).
--- 387,419 ----
  #endif
  
! 	/* Find physical memory regions. */
! 	(*platform.mem_init)((paddr_t)kernend - MIPS_KSEG0_START);
  
! 	printf("mem_cluster_cnt = %d\n", mem_cluster_cnt);
! 	physmem = 0;
! 	for (i = 0; i < mem_cluster_cnt; i++) {
! 		printf("mem_clusters[%d] = {0x%lx,0x%lx}\n", i,
! 		    (paddr_t)mem_clusters[i].start,
! 		    (paddr_t)mem_clusters[i].size);
! 		physmem += atop(mem_clusters[i].size);
! 	}
  
! 	/* Cluster 0 is always the kernel, which doesn't get loaded. */
! 	for (i = 1; i < mem_cluster_cnt; i++) {
! 		paddr_t start, size;
  
+ 		start = (paddr_t)mem_clusters[i].start;
+ 		size = (paddr_t)mem_clusters[i].size;
+ 
+ 		printf("loading 0x%lx,0x%lx\n", start, size);
+ 
+ 		memset((void *)MIPS_PHYS_TO_KSEG1(start), 0,
+ 		       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).
***************
*** 762,768 ****
  }
  
! int
  unimpl_mem_init(kernend)
! 	caddr_t kernend;
  {
  	panic("sysconf.init didnt set memory");
--- 766,772 ----
  }
  
! void
  unimpl_mem_init(kernend)
! 	paddr_t kernend;
  {
  	panic("sysconf.init didnt set memory");
Index: hpcmips/include/sysconf.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/include/sysconf.h,v
retrieving revision 1.5
diff -c -2 -r1.5 sysconf.h
*** sysconf.h	1999/12/04 10:55:18	1.5
--- sysconf.h	2000/02/18 18:51:41
***************
*** 87,91 ****
  	void	(*clockintr) __P((void *));
  	void	(*fb_init) __P((caddr_t*));
! 	int	(*mem_init) __P((caddr_t));
  #ifdef notyet
  	void	(*mcheck_handler) __P((unsigned long, struct trapframe *,
--- 87,91 ----
  	void	(*clockintr) __P((void *));
  	void	(*fb_init) __P((caddr_t*));
! 	void	(*mem_init) __P((paddr_t));
  #ifdef notyet
  	void	(*mcheck_handler) __P((unsigned long, struct trapframe *,
Index: hpcmips/include/vmparam.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/include/vmparam.h,v
retrieving revision 1.1.1.1
diff -c -2 -r1.1.1.1 vmparam.h
*** vmparam.h	1999/09/16 12:23:24	1.1.1.1
--- vmparam.h	2000/02/18 18:51:41
***************
*** 6,10 ****
   * hpcmips has one physical memory segment.
   */
! #define	VM_PHYSSEG_MAX		1
  
  #define	VM_NFREELIST		1
--- 6,10 ----
   * hpcmips has one physical memory segment.
   */
! #define	VM_PHYSSEG_MAX		5
  
  #define	VM_NFREELIST		1
Index: hpcmips/tx/tx39.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/tx/tx39.c,v
retrieving revision 1.13
diff -c -2 -r1.13 tx39.c
*** tx39.c	2000/02/10 02:15:02	1.13
--- tx39.c	2000/02/18 18:51:41
***************
*** 34,37 ****
--- 34,38 ----
  #include <sys/systm.h>
  #include <sys/device.h>
+ #include <sys/kcore.h>
  
  #include <machine/locore.h>   /* cpu_id */
***************
*** 80,84 ****
  void	tx_init __P((void));
  int	tx39icu_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t));
- int	tx39_find_dram __P((u_int32_t, u_int32_t));
  void	tx39clock_cpuspeed __P((int*, int*));
  
--- 81,84 ----
***************
*** 89,97 ****
  void	tx_device_register __P((struct device *, void *));
  void    tx_fb_init __P((caddr_t*));
! int     tx_mem_init __P((caddr_t));
  void	tx_reboot __P((int howto, char *bootstr));
  int	tx_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, 
  		     u_int32_t causeReg));
  
  void
  tx_init()
--- 89,101 ----
  void	tx_device_register __P((struct device *, void *));
  void    tx_fb_init __P((caddr_t*));
! void    tx_mem_init __P((paddr_t));
! void	tx_find_dram __P((paddr_t, paddr_t));
  void	tx_reboot __P((int howto, char *bootstr));
  int	tx_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, 
  		     u_int32_t causeReg));
  
+ extern phys_ram_seg_t mem_clusters[];
+ extern int mem_cluster_cnt;
+ 
  void
  tx_init()
***************
*** 189,232 ****
  }
  
! int
  tx_mem_init(kernend)
! 	caddr_t kernend; /* kseg0 */
  {
! 	u_int32_t startaddr, endaddr;
! 	int npage, xpage, kpage;
  
! 	startaddr = MIPS_PHYS_TO_KSEG1(
! 		(btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
! 	endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK0CS1 +
! 				     TX39_SYSADDR_DRAMBANK_LEN);
! 	kpage = btoc(MIPS_KSEG1_TO_PHYS(startaddr));
! 
! 	/* D-RAM bank0 */
! 	npage = tx39_find_dram(startaddr, endaddr);
! 
! 	printf("DRAM bank0: %d pages (%dMByte) reserved %d pages\n", 
! 	       npage + 1, ((npage  + 1) * NBPG) / 0x100000, kpage + 1);
! 	npage -= kpage; /* exclude kernel area */
  
! 	/* Clear DRAM area */
! 	memset((void*)startaddr, 0, npage * NBPG);
! 	
! 	/* D-RAM bank1 XXX find only. not usable yet */
! 	startaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1);
! 	endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1 +
! 				     TX39_SYSADDR_DRAMBANK_LEN);
! 	xpage = tx39_find_dram(startaddr, endaddr);
! 	printf("DRAM bank1: %d pages (%dMByte) ...but not usable yet\n", 
! 	       xpage + 1, ((xpage + 1) * NBPG) / 0x100000);
  
! 	/* 
! 	 *  Clear currently unused D-RAM area 
! 	 *  (For reboot Windows CE clearly)
! 	 */
! 	memset((void*)startaddr, 0, npage * NBPG);
! 	memset((void*)(KERNBASE + 0x400), 0, 
! 	       KERNTEXTOFF - KERNBASE - 0x800); 
! 	
! 	return npage; /* Return bank0's memory only */
  }
  
--- 193,244 ----
  }
  
! void
  tx_mem_init(kernend)
! 	paddr_t kernend;
  {
! 	mem_clusters[0].start = 0;
! 	mem_clusters[1].size = kernend;
! 	mem_cluster_cnt = 1;
! 	tx_find_dram(kernend, 0x02000000);
! 	tx_find_dram(0x02000000, 0x04000000);
! 	tx_find_dram(0x04000000, 0x06000000);
! 	tx_find_dram(0x06000000, 0x08000000);
  
! 	/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
! 	memset((void *)(KERNBASE + 0x400), 0, KERNTEXTOFF - (KERNBASE + 0x800));
! }
  
! void
! tx_find_dram(start, end)
! 	paddr_t start, end;
! {
! 	paddr_t addr;
! 	caddr_t page;
  
! #define DRAM_MAGIC0 0xac1dcafe
! #define DRAM_MAGIC1 0x19700220
! 
! 	page = (void *)MIPS_PHYS_TO_KSEG1(addr);
! 	if (badaddr(page, 4))
! 		return;
! 	*(volatile int *)(page+0) = DRAM_MAGIC0;
! 	*(volatile int *)(page+4) = DRAM_MAGIC1;
! 	wbflush();
! 	if (*(volatile int *)(page+0) != DRAM_MAGIC0 ||
! 	    *(volatile int *)(page+4) != DRAM_MAGIC1)
! 		return;
! 
! 	for (addr = start + NBPG; addr < end; addr += NBPG) {
! 		page = (void *)MIPS_PHYS_TO_KSEG1(addr);
! 		if (badaddr(page, 4))
! 			break;
! 		if (*(volatile int *)(page+0) == DRAM_MAGIC0 &&
! 		    *(volatile int *)(page+4) == DRAM_MAGIC1)
! 			break;
! 	}
! 
! 	mem_clusters[mem_cluster_cnt].start = start;
! 	mem_clusters[mem_cluster_cnt].size = addr - start;
! 	mem_cluster_cnt++;
  }
  
***************
*** 237,264 ****
  {
  	goto *(u_int32_t *)MIPS_RESET_EXC_VEC;
- }
- 
- int
- tx39_find_dram(startaddr, endaddr)
- 	u_int32_t startaddr; /* kseg1 */
- 	u_int32_t endaddr;    /* kseg1 */
- {
- #define DRAM_MAGIC0 0xac1dcafe
- #define DRAM_MAGIC1 0x19700220
- 	u_int32_t page;
- 	int npage;
- 
- 	page = startaddr;
- 	((volatile int *)page)[0] = DRAM_MAGIC0;
- 	((volatile int *)page)[4] = DRAM_MAGIC1;
- 	page += NBPG;
- 	for (npage = 0; page < endaddr; page += NBPG, npage++) {
- 		if ((((volatile int *)page)[0] == DRAM_MAGIC0 &&
- 		     ((volatile int *)page)[4] == DRAM_MAGIC1)) {
- 			return npage;
- 		}
- 	}
- 	/* no memory in this bank */
- 	return 0;
  }
  
--- 249,252 ----
Index: hpcmips/vr/vr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/hpcmips/vr/vr.c,v
retrieving revision 1.12
diff -c -2 -r1.12 vr.c
*** vr.c	2000/02/10 02:15:03	1.12
--- vr.c	2000/02/18 18:51:43
***************
*** 39,42 ****
--- 39,43 ----
  #include <sys/device.h>
  #include <sys/reboot.h>
+ #include <sys/kcore.h>
  
  #include <machine/cpu.h>
***************
*** 109,113 ****
  void	vr_device_register __P((struct device *, void *));
  void    vr_fb_init __P((caddr_t*));
! int     vr_mem_init __P((caddr_t));
  void	vr_reboot __P((int howto, char *bootstr));
  
--- 110,115 ----
  void	vr_device_register __P((struct device *, void *));
  void    vr_fb_init __P((caddr_t*));
! void    vr_mem_init __P((paddr_t));
! void	vr_find_dram __P((paddr_t, paddr_t));
  void	vr_reboot __P((int howto, char *bootstr));
  
***************
*** 128,131 ****
--- 130,136 ----
  static void *intr_arg[4];
  
+ extern phys_ram_seg_t mem_clusters[];
+ extern int mem_cluster_cnt;
+ 
  void
  vr_init()
***************
*** 158,188 ****
  }
  
! int
  vr_mem_init(kernend)
! 	caddr_t kernend; /* kseg0 */
  {
! 	u_int32_t startaddr, endaddr, page;
! 	int npage;
! #define VR41_SYSADDR_DRAMSTART 0x0
! #define VR41_SYSADDR_DRAM_LEN 0x04000000
! 	startaddr = MIPS_PHYS_TO_KSEG1(
! 		(btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
! 	endaddr = MIPS_PHYS_TO_KSEG1(VR41_SYSADDR_DRAMSTART +
! 				     VR41_SYSADDR_DRAM_LEN);
! 	for(page = startaddr, npage = 0; page < endaddr; 
! 	    page+= NBPG, npage++) {
! 		if (badaddr((char*)page, 4))
! 			break;
! 		((volatile int *)page)[0] = 0xa5a5a5a5;
! 		((volatile int *)page)[4] = 0x5a5a5a5a;
! 		wbflush();
! 		if (*(volatile int *)page != 0xa5a5a5a5)
! 			break;
! 	}
  	/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
! 	memset((void*)startaddr, 0, npage * NBPG);
! 	memset((void*)(KERNBASE + 0x400), 0, KERNTEXTOFF - KERNBASE - 0x800); 
  
! 	return npage;
  }
  
--- 163,242 ----
  }
  
! void
  vr_mem_init(kernend)
! 	paddr_t kernend;
  {
! 	mem_clusters[0].start = 0;
! 	mem_clusters[0].size = kernend;
! 	mem_cluster_cnt = 1;
! 	vr_find_dram(kernend, 0x02000000);
! 	vr_find_dram(0x02000000, 0x04000000);
! 	vr_find_dram(0x04000000, 0x06000000);
! 	vr_find_dram(0x06000000, 0x08000000);
! 
  	/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
! 	memset((void *)(KERNBASE + 0x400), 0, KERNTEXTOFF - (KERNBASE + 0x800));
! }
! 
! void
! vr_find_dram(addr, end)
! 	paddr_t addr, end;
! {
! 	int n;
! 	caddr_t page;
! #ifdef NARLY_MEMORY_PROBE
! 	int x, i;
! #endif
! 
! 	n = mem_cluster_cnt;
! 	for (; addr < end; addr += NBPG) {
  
! 		page = (void *)MIPS_PHYS_TO_KSEG1(addr);
! 		if (badaddr(page, 4))
! 			goto bad;
! 
! 		*(volatile int *)(page+0) = 0xa5a5a5a5;
! 		*(volatile int *)(page+4) = 0x5a5a5a5a;
! 		wbflush();
! 		if (*(volatile int *)(page+0) != 0xa5a5a5a5)
! 			goto bad;
! 
! 		*(volatile int *)(page+0) = 0x5a5a5a5a;
! 		*(volatile int *)(page+4) = 0xa5a5a5a5;
! 		wbflush();
! 		if (*(volatile int *)(page+0) != 0x5a5a5a5a)
! 			goto bad;
! 
! #ifdef NARLY_MEMORY_PROBE
! 		x = random();
! 		for (i = 0; i < NBPG; i += 4)
! 			*(volatile int *)(page+i) = (x ^ i);
! 		wbflush();
! 		for (i = 0; i < NBPG; i += 4)
! 			if (*(volatile int *)(page+i) != (x ^ i))
! 				goto bad;
! 
! 		x = random();
! 		for (i = 0; i < NBPG; i += 4)
! 			*(volatile int *)(page+i) = (x ^ i);
! 		wbflush();
! 		for (i = 0; i < NBPG; i += 4)
! 			if (*(volatile int *)(page+i) != (x ^ i))
! 				goto bad;
! #endif
! 
! 		if (!mem_clusters[n].size)
! 			mem_clusters[n].start = addr;
! 		mem_clusters[n].size += NBPG;
! 		continue;
! 
! 	bad:
! 		if (mem_clusters[n].size)
! 			++n;
! 		continue;
! 	}
! 	if (mem_clusters[n].size)
! 		++n;
! 	mem_cluster_cnt = n;
  }