|  | @@ -15,9 +15,11 @@ extern "C" {
 | 
	
		
			
				|  |  |  // As of 2022-09-13, the platformio RP2040 core is missing cplusplus guard on flash.h
 | 
	
		
			
				|  |  |  // For that reason this has to be inside the extern "C" here.
 | 
	
		
			
				|  |  |  #include <hardware/flash.h>
 | 
	
		
			
				|  |  | +#include "rp2040_flash_do_cmd.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const char *g_azplatform_name = PLATFORM_NAME;
 | 
	
		
			
				|  |  |  static bool g_scsi_initiator = false;
 | 
	
		
			
				|  |  | +static uint32_t g_flash_chip_size = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void mbed_error_hook(const mbed_error_ctx * error_context);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -78,6 +80,13 @@ void azplatform_init()
 | 
	
		
			
				|  |  |          azlog("NOTE: SCSI termination is disabled");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // Get flash chip size
 | 
	
		
			
				|  |  | +    uint8_t cmd_read_jedec_id[4] = {0x9f, 0, 0, 0};
 | 
	
		
			
				|  |  | +    uint8_t response_jedec[4] = {0};
 | 
	
		
			
				|  |  | +    flash_do_cmd(cmd_read_jedec_id, response_jedec, 4);
 | 
	
		
			
				|  |  | +    g_flash_chip_size = (1 << response_jedec[3]);
 | 
	
		
			
				|  |  | +    azlog("Flash chip size: ", (int)(g_flash_chip_size / 1024), " kB");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      // SD card pins
 | 
	
		
			
				|  |  |      // Card is used in SDIO mode for main program, and in SPI mode for crash handler & bootloader.
 | 
	
		
			
				|  |  |      //        pin             function       pup   pdown  out    state fast
 | 
	
	
		
			
				|  | @@ -463,15 +472,20 @@ const void * btldr_vectors[2] = {&__StackTop, (void*)&btldr_reset_handler};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef PLATFORM_HAS_ROM_DRIVE
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// Reserve up to 512 kB for firmware.
 | 
	
		
			
				|  |  | -#define ROMDRIVE_OFFSET (512 * 1024)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -// TODO: Actually read the flash chip size instead of assuming 2 MB.
 | 
	
		
			
				|  |  | -static uint32_t g_romdrive_max_size = 2048 * 1024 - ROMDRIVE_OFFSET;
 | 
	
		
			
				|  |  | +// Reserve up to 384 kB for firmware.
 | 
	
		
			
				|  |  | +#define ROMDRIVE_OFFSET (384 * 1024)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  uint32_t azplatform_get_romdrive_maxsize()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    return g_romdrive_max_size;
 | 
	
		
			
				|  |  | +    if (g_flash_chip_size >= ROMDRIVE_OFFSET)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        return g_flash_chip_size - ROMDRIVE_OFFSET;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        // Failed to read flash chip size, default to 2 MB
 | 
	
		
			
				|  |  | +        return 2048 * 1024 - ROMDRIVE_OFFSET;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  bool azplatform_read_romdrive(uint8_t *dest, uint32_t start, uint32_t count)
 | 
	
	
		
			
				|  | @@ -487,7 +501,7 @@ bool azplatform_read_romdrive(uint8_t *dest, uint32_t start, uint32_t count)
 | 
	
		
			
				|  |  |      xip_ctrl_hw->stream_ctr = count / 4;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Transfer happens in multiples of 4 bytes
 | 
	
		
			
				|  |  | -    assert(start < g_romdrive_max_size);
 | 
	
		
			
				|  |  | +    assert(start < azplatform_get_romdrive_maxsize());
 | 
	
		
			
				|  |  |      assert((count & 3) == 0);
 | 
	
		
			
				|  |  |      assert((((uint32_t)dest) & 3) == 0);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -507,8 +521,9 @@ bool azplatform_read_romdrive(uint8_t *dest, uint32_t start, uint32_t count)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  bool azplatform_write_romdrive(const uint8_t *data, uint32_t start, uint32_t count)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    assert(start < g_romdrive_max_size);
 | 
	
		
			
				|  |  | +    assert(start < azplatform_get_romdrive_maxsize());
 | 
	
		
			
				|  |  |      assert((count % AZPLATFORM_ROMDRIVE_PAGE_SIZE) == 0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      __disable_irq();
 | 
	
		
			
				|  |  |      flash_range_erase(start + ROMDRIVE_OFFSET, count);
 | 
	
		
			
				|  |  |      flash_range_program(start + ROMDRIVE_OFFSET, data, count);
 |