|  | @@ -70,17 +70,8 @@ void __hot romcopy_bzero(void *dst, size_t len)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  | - * Read unique serial number programmed into ROM. Convert the serial
 | 
	
		
			
				|  |  | - * number to 12 characters in base32; we lose four bits but that is never
 | 
	
		
			
				|  |  | - * going to matter. It's more fun than plain hex... :)
 | 
	
		
			
				|  |  | + * Read unique serial number programmed into ROM
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | - * This is run before the 64-bit division routines are available in SDRAM,
 | 
	
		
			
				|  |  | - * so it needs to be an encoding that can be generated with only plain
 | 
	
		
			
				|  |  | - * 32-bit instructions.
 | 
	
		
			
				|  |  | - *
 | 
	
		
			
				|  |  | - * Doing this as early as possible means a much better chance to see
 | 
	
		
			
				|  |  | - * the proper serial number during USB enumeration, so doing it
 | 
	
		
			
				|  |  | - * immediately after SPI ROM conditioning is a great time.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  char __bss_hot rom_serial_str[16];
 | 
	
		
			
				|  |  |  qword_t __bss_hot rom_serial;
 | 
	
	
		
			
				|  | @@ -101,38 +92,46 @@ static __must_inline void rom_read_serial(void)
 | 
	
		
			
				|  |  |      rom_serial.l[0] = ROMCOPY_INPUT;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * Convert the ROM serial number to a hex string and poke it into the
 | 
	
		
			
				|  |  | + * USB descriptor "ROM". Used to use base36, but this has to be done
 | 
	
		
			
				|  |  | + * very early, and it has turned out that making it consistent with
 | 
	
		
			
				|  |  | + * what one can easily get out of a debugger is really useful.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Doing this as early as possible means a much better chance to see
 | 
	
		
			
				|  |  | + * the proper serial number during USB enumeration, so doing it
 | 
	
		
			
				|  |  | + * immediately after SPI ROM conditioning is a great time.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  |  static __must_inline void rom_mangle_serial(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    rom_serial_str[12] = '\0';
 | 
	
		
			
				|  |  | -    uint64_t v = rom_serial.q;
 | 
	
		
			
				|  |  | +    volatile uint32_t *udp = &usbdesc_rom[2];
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    for (int i = 7; i >= 0; i--) {
 | 
	
		
			
				|  |  | +	unsigned int v = rom_serial.b[i];
 | 
	
		
			
				|  |  | +	unsigned int c;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    for (int i = 11; i >= 0; i--) {
 | 
	
		
			
				|  |  | -	unsigned char c;
 | 
	
		
			
				|  |  | -	unsigned int d = v & 31;
 | 
	
		
			
				|  |  | -	v >>= 5;
 | 
	
		
			
				|  |  | +	c = (v >> 4)+'0';
 | 
	
		
			
				|  |  | +	if (c > '9')
 | 
	
		
			
				|  |  | +	    c += 'A'-'9'-1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	udp[0] = c;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	c = d + '0';
 | 
	
		
			
				|  |  | +	c = (v & 15)+'0';
 | 
	
		
			
				|  |  |  	if (c > '9')
 | 
	
		
			
				|  |  |  	    c += 'A'-'9'-1;
 | 
	
		
			
				|  |  | -	if (c >= 'I')
 | 
	
		
			
				|  |  | -	    c++;
 | 
	
		
			
				|  |  | -	if (c >= 'O')
 | 
	
		
			
				|  |  | -	    c++;
 | 
	
		
			
				|  |  | -	if (c >= 'S')
 | 
	
		
			
				|  |  | -	    c++;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/* IOSZ not used to avoid confusion with 1052 */
 | 
	
		
			
				|  |  | +	udp[2] = c;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	rom_serial_str[i] = c;
 | 
	
		
			
				|  |  | -	usbdesc_rom[2+2*i] = c;
 | 
	
		
			
				|  |  | +	udp += 4;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void rom_print_serial(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      /* Print the ROM serial when we actually can */
 | 
	
		
			
				|  |  | -    con_printf("ROM serial: %08x-%08x (%s)\n",
 | 
	
		
			
				|  |  | -	       rom_serial.l[1], rom_serial.l[0], rom_serial_str);
 | 
	
		
			
				|  |  | +    con_printf("ROM serial: %08X%08X (%08x-%08x)\n",
 | 
	
		
			
				|  |  | +	       rom_serial.l[1], rom_serial.l[0],
 | 
	
		
			
				|  |  | +	       rom_serial.l[1], rom_serial.l[0]);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static __must_inline void romcopy_config_flash(void)
 | 
	
	
		
			
				|  | @@ -146,8 +145,6 @@ static __must_inline void romcopy_config_flash(void)
 | 
	
		
			
				|  |  |      ROMCOPY_ROMCMD = ROM_WRITE_SR3 << 24;
 | 
	
		
			
				|  |  |      ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(2);
 | 
	
		
			
				|  |  |      waitfor(ROMCOPY_IRQ);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    asm volatile("nop; nop");	/* Make extra sure tSHSL2 is OK */
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  IRQHANDLER(romcopy,0)
 |