NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-newsmips/53626 (NetBSD/newsmips 8.0 GENERIC boot fails on NWS-5000X)



The following reply was made to PR port-newsmips/53626; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-newsmips/53626 (NetBSD/newsmips 8.0 GENERIC boot fails on
	 NWS-5000X)
Date: Sun, 30 Sep 2018 14:03:03 +0900

 I discussed with ryo@ (the original author of initial news5000 support):
 
 - mapping against 0xfff00000 region was handled in (MI) TLB miss handler
   as a temporary hack
 - instead of using wired map (or dinamic allocation in the TLB miss handler)
   there was a (unused) aptokseg0() function that convert PROM work address
   to KSEG0 (the PROM work was allocated at end of RAM so it can be
   calculated from physmem)
 - to use APbus ROM calls maybe the VA region should be at original
   0xfff00000-0xffffffff area (but currently no users)
 - on the other hand 0xfff00000 region is not managed by the kernel
   so it can't be accessed from userand programs (vmstat(8) etc) via kvm(3) 
 
 Actually the following patch using aptokseg0() function works:
 ---
 Index: apbus/apbus.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbus.c,v
 retrieving revision 1.22
 diff -u -p -d -r1.22 apbus.c
 --- apbus/apbus.c	20 Feb 2011 07:56:31 -0000	1.22
 +++ apbus/apbus.c	30 Sep 2018 04:37:02 -0000
 @@ -49,9 +49,6 @@ __KERNEL_RCSID(0, "$NetBSD: apbus.c,v 1.
  static int  apbusmatch(device_t, cfdata_t, void *);
  static void apbusattach(device_t, device_t, void *);
  static int apbusprint(void *, const char *);
 -#if 0
 -static void *aptokseg0 (void *);
 -#endif
  static void apbus_dma_unmapped(bus_dma_tag_t, bus_dmamap_t);
  static int apbus_dma_mapalloc(bus_dma_tag_t, bus_dmamap_t, int);
  static void apbus_dma_mapfree(bus_dma_tag_t, bus_dmamap_t);
 @@ -116,13 +113,13 @@ apbusattach(device_t parent, device_t se
  	/*
  	 * get first ap-device
  	 */
 -	apdev = apbus_lookupdev(NULL);
 +	apdev = aptokseg0(apbus_lookupdev(NULL));
  
  	/*
  	 * trace device chain
  	 */
  	while (apdev) {
 -		apctl = apdev->apbd_ctl;
 +		apctl = aptokseg0(apdev->apbd_ctl);
  
  		/*
  		 * probe physical device only
 @@ -134,18 +131,18 @@ apbusattach(device_t parent, device_t se
  			 */
  			while (apctl) {
  				/* make apbus_attach_args for devices */
 -				child.apa_name = apdev->apbd_name;
 +				child.apa_name = aptokseg0(apdev->apbd_name);
  				child.apa_ctlnum = apctl->apbc_ctlno;
  				child.apa_slotno = apctl->apbc_sl;
  				child.apa_hwbase = apctl->apbc_hwbase;
  
  				config_found(self, &child, apbusprint);
  
 -				apctl = apctl->apbc_link;
 +				apctl = aptokseg0(apctl->apbc_link);
  			}
  		}
  
 -		apdev = apdev->apbd_link;
 +		apdev = aptokseg0(apdev->apbd_link);
  	}
  }
  
 @@ -161,22 +158,6 @@ apbusprint(void *aux, const char *pnp)
  	return UNCONF;
  }
  
 -#if 0
 -void *
 -aptokseg0(void *va)
 -{
 -	vaddr_t addr = (vaddr_t)va;
 -
 -	if (addr >= 0xfff00000) {
 -		addr -= 0xfff00000;
 -		addr += physmem << PGSHIFT;
 -		addr += 0x80000000;
 -		va = (void *)addr;
 -	}
 -	return va;
 -}
 -#endif
 -
  void
  apbus_wbflush(void)
  {
 Index: apbus/apbus_subr.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbus_subr.c,v
 retrieving revision 1.9
 diff -u -p -d -r1.9 apbus_subr.c
 --- apbus/apbus_subr.c	24 Mar 2014 20:05:20 -0000	1.9
 +++ apbus/apbus_subr.c	30 Sep 2018 04:37:02 -0000
 @@ -32,11 +32,26 @@ __KERNEL_RCSID(0, "$NetBSD: apbus_subr.c
  #include <sys/param.h>
  #include <sys/systm.h>
  
 +#include <mips/cpuregs.h>
 +
  #include <newsmips/apbus/apbusvar.h>
  
  static void apctl_dump(struct apbus_ctl *);
  
  void *
 +aptokseg0(void *va)
 +{
 +	vaddr_t addr = (vaddr_t)va;
 +
 +	if (addr >= 0xfff00000) {
 +		addr &= ~0xfff00000;
 +		addr += ctob(physmem);
 +		addr = MIPS_PHYS_TO_KSEG0(addr);
 +	}
 +	return (void *)addr;
 +}
 +
 +void *
  apbus_device_to_hwaddr(struct apbus_dev *apbus_dev)
  {
  	struct apbus_ctl *ctl;
 @@ -44,7 +59,7 @@ apbus_device_to_hwaddr(struct apbus_dev 
  	if (apbus_dev == NULL)
  		return NULL;
  
 -	ctl = apbus_dev->apbd_ctl;
 +	ctl = aptokseg0(apbus_dev->apbd_ctl);
  	if (ctl == NULL)
  		return NULL;
  
 @@ -54,7 +69,7 @@ apbus_device_to_hwaddr(struct apbus_dev 
  struct apbus_dev *
  apbus_lookupdev(char *devname)
  {
 -	struct apbus_dev *dp;
 +	struct apbus_dev *dp, *dp0;
  
  	dp = _sip->apbsi_dev;
  	if (devname == NULL || *devname == '\0')
 @@ -62,10 +77,11 @@ apbus_lookupdev(char *devname)
  
  	/* search apbus_dev named 'devname' */
  	while (dp) {
 -		if (strcmp(devname, dp->apbd_name) == 0)
 +		dp0 = aptokseg0(dp);
 +		if (strcmp(devname, dp0->apbd_name) == 0)
  			return dp;
  
 -		dp = dp->apbd_link;
 +		dp = dp0->apbd_link;
  	}
  
  	return NULL;
 @@ -74,42 +90,49 @@ apbus_lookupdev(char *devname)
  static void
  apctl_dump(struct apbus_ctl *apctl)
  {
 +	struct apbus_ctl *apctl0;
 +	
  	if (!apctl)
  		return;
 +	apctl0 = aptokseg0(apctl);
  
  	printf("	apbus_ctl dump (%p)\n", apctl);
  
 -	printf("	Num:		%d\n", apctl->apbc_ctlno);
 -	printf("	HWaddr:		0x%08x\n", apctl->apbc_hwbase);
 -	printf("	softc:		%p\n", apctl->apbc_softc);
 -	printf("	Slot:		%d\n", apctl->apbc_sl);
 +	printf("	Num:		%d\n", apctl0->apbc_ctlno);
 +	printf("	HWaddr:		0x%08x\n", apctl0->apbc_hwbase);
 +	printf("	softc:		%p\n", apctl0->apbc_softc);
 +	printf("	Slot:		%d\n", apctl0->apbc_sl);
  	printf("\n");
  
 -	if (apctl->apbc_link)
 -		apctl_dump(apctl->apbc_link);
 +	if (apctl0->apbc_link) {
 +		apctl_dump(apctl0->apbc_link);
 +	}
  }
  
  void
  apdevice_dump(struct apbus_dev *apdev)
  {
 -	struct apbus_ctl *apctl;
 +	struct apbus_dev *apdev0;
 +	struct apbus_ctl *apctl, *apctl0;
  
  	if (apdev == NULL)
  		return;
  
  	/* only no pseudo device */
 -	apctl = apdev->apbd_ctl;
 -	if (apctl == NULL || apctl->apbc_hwbase == 0)
 +	apdev0 = aptokseg0(apdev);
 +	apctl = apdev0->apbd_ctl;
 +	apctl0 = aptokseg0(apctl);
 +	if (apctl == NULL || apctl0->apbc_hwbase == 0)
  		return;
  
  	printf("apbus_dev dump (%p)\n", apdev);
 -	printf("name:		%s\n", apdev->apbd_name);
 -	printf("vendor:		%s\n", apdev->apbd_vendor);
 -	printf("atr:		%08x\n", apdev->apbd_atr);
 -	printf("rev:		%d\n", apdev->apbd_rev);
 -	printf("driver:		0x%08x\n", (unsigned int)apdev->apbd_driver);
 -	printf("ctl:		0x%08x\n", (unsigned int)apdev->apbd_ctl);
 -	printf("link:		0x%08x\n", (unsigned int)apdev->apbd_link);
 +	printf("name:		%s\n", apdev0->apbd_name);
 +	printf("vendor:		%s\n", apdev0->apbd_vendor);
 +	printf("atr:		%08x\n", apdev0->apbd_atr);
 +	printf("rev:		%d\n", apdev0->apbd_rev);
 +	printf("driver:		0x%08x\n", (unsigned int)apdev0->apbd_driver);
 +	printf("ctl:		0x%08x\n", (unsigned int)apdev0->apbd_ctl);
 +	printf("link:		0x%08x\n", (unsigned int)apdev0->apbd_link);
  	printf("\n");
  
  	apctl_dump(apctl);
 Index: apbus/apbusvar.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbusvar.h,v
 retrieving revision 1.9
 diff -u -p -d -r1.9 apbusvar.h
 --- apbus/apbusvar.h	17 Oct 2007 19:55:54 -0000	1.9
 +++ apbus/apbusvar.h	30 Sep 2018 04:37:02 -0000
 @@ -39,6 +39,7 @@ struct apbus_attach_args {
  	u_long	apa_hwbase;	/* hardware I/O address */
  };
  
 +void *aptokseg0(void *);
  void *apbus_device_to_hwaddr(struct apbus_dev *);
  struct apbus_dev *apbus_lookupdev(char *);
  void apdevice_dump(struct apbus_dev *);
  
 ---
 
 However it's a bit difficult to check there is no other invalid accesses.
 
 I would like to choose wired map version to avoid address translation
 confusion for now, and there is no objection from ryo@.
 
 I also modified wired map patch to call it from apbusattach()
 because (old, uncommitted, but forthcomming) news4000 also
 requires the similar hack for APbus devices.
 
 ---
 
 Index: apbus/apbus.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbus.c,v
 retrieving revision 1.22
 diff -u -p -d -r1.22 apbus.c
 --- apbus/apbus.c	20 Feb 2011 07:56:31 -0000	1.22
 +++ apbus/apbus.c	29 Sep 2018 19:05:05 -0000
 @@ -99,6 +99,7 @@ apbusattach(device_t parent, device_t se
  	struct newsmips_intr *ip;
  	int i;
  
 +	apbus_map_romwork();
  	mips_set_wbflush(apbus_wbflush);
  
  	*(volatile uint32_t *)(NEWS5000_APBUS_INTST) = 0xffffffff;
 Index: apbus/apbus_subr.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbus_subr.c,v
 retrieving revision 1.9
 diff -u -p -d -r1.9 apbus_subr.c
 --- apbus/apbus_subr.c	24 Mar 2014 20:05:20 -0000	1.9
 +++ apbus/apbus_subr.c	29 Sep 2018 19:05:06 -0000
 @@ -32,10 +32,42 @@ __KERNEL_RCSID(0, "$NetBSD: apbus_subr.c
  #include <sys/param.h>
  #include <sys/systm.h>
  
 +#include <uvm/uvm_extern.h>
 +
 +#include <mips/locore.h>
 +#include <mips/pte.h>
 +
 +#include <machine/wired_map.h>
 +
  #include <newsmips/apbus/apbusvar.h>
  
  static void apctl_dump(struct apbus_ctl *);
  
 +#define	APBUS_ROMWORK_VA	0xfff00000
 +
 +void
 +apbus_map_romwork(void)
 +{
 +	static bool mapped = false;
 +	vaddr_t apbd_work_va;
 +	vsize_t apbd_work_sz;
 +	paddr_t apbd_work_pa;
 +
 +	if (!mapped) {
 +		/* map PROM work RAM into VA 0xFFF00000 - 0xFFFFFFFF */
 +		apbd_work_va = APBUS_ROMWORK_VA;
 +		apbd_work_sz = MIPS3_PG_SIZE_MASK_TO_SIZE(MIPS3_PG_SIZE_1M);
 +		apbd_work_pa = ctob(physmem);
 +
 +		mapped = mips3_wired_enter_page(apbd_work_va, apbd_work_pa,
 +		    apbd_work_sz);
 +		if (!mapped) {
 +			printf("%s: cannot allocate APbus PROM work\n",
 +			    __func__);
 +		}
 +	}
 +}
 +
  void *
  apbus_device_to_hwaddr(struct apbus_dev *apbus_dev)
  {
 Index: apbus/apbusvar.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbusvar.h,v
 retrieving revision 1.9
 diff -u -p -d -r1.9 apbusvar.h
 --- apbus/apbusvar.h	17 Oct 2007 19:55:54 -0000	1.9
 +++ apbus/apbusvar.h	29 Sep 2018 19:05:06 -0000
 @@ -39,6 +39,7 @@ struct apbus_attach_args {
  	u_long	apa_hwbase;	/* hardware I/O address */
  };
  
 +void apbus_map_romwork(void);
  void *apbus_device_to_hwaddr(struct apbus_dev *);
  struct apbus_dev *apbus_lookupdev(char *);
  void apdevice_dump(struct apbus_dev *);
 Index: conf/std.newsmips
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/newsmips/conf/std.newsmips,v
 retrieving revision 1.17
 diff -u -p -d -r1.17 std.newsmips
 --- conf/std.newsmips	11 Dec 2005 12:18:24 -0000	1.17
 +++ conf/std.newsmips	29 Sep 2018 19:05:06 -0000
 @@ -7,5 +7,7 @@ makeoptions	MACHINE_ARCH="mipseb"
  options 	EXEC_ELF32	# exec ELF32 binaries
  options 	EXEC_SCRIPT	# exec #! scripts
  
 +options 	ENABLE_MIPS3_WIRED_MAP
 +
  makeoptions	DEFTEXTADDR="0x80001000"
  makeoptions	LINKFORMAT="-N"
 
 ---
 Izumi Tsutsui
 


Home | Main Index | Thread Index | Old Index