mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 07:06:52 +01:00
flashing works
This commit is contained in:
parent
5ad902aa10
commit
c4036a65cf
@ -19,7 +19,7 @@
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
# Date created = 00:50:07 October 26, 2021
|
||||
# Date created = 22:44:04 October 26, 2021
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
@ -303,7 +303,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
@ -7,6 +7,7 @@ module n64_bootloader (
|
||||
logic mem_request;
|
||||
logic csr_ack;
|
||||
logic data_ack;
|
||||
logic write_ack;
|
||||
logic data_busy;
|
||||
logic mem_write;
|
||||
logic [31:0] mem_address;
|
||||
@ -29,6 +30,7 @@ module n64_bootloader (
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
csr_ack <= 1'b0;
|
||||
write_ack <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
@ -61,7 +63,10 @@ module n64_bootloader (
|
||||
if ((!mem_address[27] || source_request == T_N64) && !data_busy) begin
|
||||
mem_request <= 1'b0;
|
||||
end
|
||||
if (csr_ack || data_ack) begin
|
||||
if (!mem_address[27] && mem_write && !data_busy && !write_ack) begin
|
||||
write_ack <= 1'b1;
|
||||
end
|
||||
if (csr_ack || data_ack || write_ack) begin
|
||||
state <= S_IDLE;
|
||||
end
|
||||
end
|
||||
@ -89,7 +94,7 @@ module n64_bootloader (
|
||||
else bus.rdata = {data_rdata[7:0], data_rdata[15:8]};
|
||||
end
|
||||
|
||||
flash.ack = source_request == T_CPU && (csr_ack || data_ack);
|
||||
flash.ack = source_request == T_CPU && (csr_ack || data_ack || write_ack);
|
||||
flash.rdata = 32'd0;
|
||||
if (flash.ack) begin
|
||||
flash.rdata = csr_or_data ? csr_rdata : data_rdata;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "cfg.h"
|
||||
#include "flash.h"
|
||||
#include "joybus.h"
|
||||
#include "usb.h"
|
||||
|
||||
@ -26,6 +27,7 @@ enum cfg_id {
|
||||
CFG_ID_SAVE_OFFEST,
|
||||
CFG_ID_DD_OFFEST,
|
||||
CFG_ID_SKIP_BOOTLOADER,
|
||||
CFG_ID_FLASH_OPERATION,
|
||||
};
|
||||
|
||||
enum save_type {
|
||||
@ -132,6 +134,9 @@ void cfg_update (uint32_t *args) {
|
||||
case CFG_ID_SKIP_BOOTLOADER:
|
||||
change_scr_bits(CFG_SCR_SKIP_BOOTLOADER, args[1]);
|
||||
break;
|
||||
case CFG_ID_FLASH_OPERATION:
|
||||
flash_program(args[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,6 +172,9 @@ void cfg_query (uint32_t *args) {
|
||||
case CFG_ID_SKIP_BOOTLOADER:
|
||||
args[1] = CFG->SCR & CFG_SCR_SKIP_BOOTLOADER;
|
||||
break;
|
||||
case CFG_ID_FLASH_OPERATION:
|
||||
args[1] = flash_read(args[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
60
sw/riscv/src/flash.c
Normal file
60
sw/riscv/src/flash.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "flash.h"
|
||||
|
||||
|
||||
uint32_t flash_read (uint32_t sdram_offset) {
|
||||
io32_t *flash = (io32_t *) (FLASH_BASE);
|
||||
io32_t *sdram = (io32_t *) (SDRAM_BASE + sdram_offset);
|
||||
|
||||
for (size_t i = 0; i < FLASH_SIZE; i += 4) {
|
||||
*sdram++ = *flash++;
|
||||
}
|
||||
|
||||
return FLASH_SIZE;
|
||||
}
|
||||
|
||||
void flash_program (uint32_t sdram_offset) {
|
||||
uint32_t cr;
|
||||
|
||||
io32_t *flash = (io32_t *) (FLASH_BASE);
|
||||
io32_t *sdram = (io32_t *) (SDRAM_BASE + sdram_offset);
|
||||
|
||||
cr = FLASH_CONFIG->CR;
|
||||
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
|
||||
cr &= ~(1 << (FLASH_CR_WRITE_PROTECT_BIT + sector));
|
||||
}
|
||||
FLASH_CONFIG->CR = cr;
|
||||
|
||||
while ((FLASH_CONFIG->SR & FLASH_SR_STATUS_MASK) != FLASH_SR_STATUS_IDLE);
|
||||
|
||||
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
|
||||
cr = FLASH_CONFIG->CR;
|
||||
cr &= ~(FLASH_CR_SECTOR_ERASE_MASK);
|
||||
cr |= ((sector + 1) << FLASH_CR_SECTOR_ERASE_BIT);
|
||||
FLASH_CONFIG->CR = cr;
|
||||
|
||||
while ((FLASH_CONFIG->SR & FLASH_SR_STATUS_MASK) == FLASH_SR_STATUS_BUSY_ERASE);
|
||||
|
||||
if (!(FLASH_CONFIG->SR & FLASH_SR_ERASE_SUCCESSFUL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FLASH_CONFIG->SR & FLASH_SR_ERASE_SUCCESSFUL) {
|
||||
for (size_t word = 0; word < FLASH_SIZE; word += 4) {
|
||||
*flash++ = *sdram++;
|
||||
|
||||
if (!(FLASH_CONFIG->SR & FLASH_SR_WRITE_SUCCESSFUL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cr = FLASH_CONFIG->CR;
|
||||
cr |= FLASH_CR_SECTOR_ERASE_MASK;
|
||||
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
|
||||
cr |= (1 << (FLASH_CR_WRITE_PROTECT_BIT + sector));
|
||||
}
|
||||
FLASH_CONFIG->CR = cr;
|
||||
|
||||
return;
|
||||
}
|
12
sw/riscv/src/flash.h
Normal file
12
sw/riscv/src/flash.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef FLASH_H__
|
||||
#define FLASH_H__
|
||||
|
||||
|
||||
#include "sys.h"
|
||||
|
||||
|
||||
uint32_t flash_read (uint32_t sdram_offset);
|
||||
void flash_program (uint32_t sdram_offset);
|
||||
|
||||
|
||||
#endif
|
@ -4,7 +4,7 @@
|
||||
|
||||
__attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
|
||||
io32_t *ram = (io32_t *) &RAM;
|
||||
io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_IMAGE_OFFSET);
|
||||
io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_CPU_IMAGE_OFFSET);
|
||||
|
||||
for (int i = 0; i < RAM_SIZE; i += 4) {
|
||||
*ram++ = *flash++;
|
||||
|
@ -157,16 +157,33 @@ typedef volatile struct joybus_regs {
|
||||
#define FLASH_BASE (0xB0000000UL)
|
||||
#define FLASH (*((io32_t *) FLASH_BASE))
|
||||
|
||||
#define FLASH_IMAGE_OFFSET (0x35800)
|
||||
#define FLASH_CPU_IMAGE_OFFSET (0x35800)
|
||||
#define FLASH_SIZE (0x39800)
|
||||
#define FLASH_NUM_SECTORS (4)
|
||||
|
||||
|
||||
typedef volatile struct flash_regs {
|
||||
typedef volatile struct flash_config_regs {
|
||||
io32_t SR;
|
||||
io32_t CR;
|
||||
} flash_regs_t;
|
||||
} flash_config_regs_t;
|
||||
|
||||
#define FLASH_SCR_BASE (0xB8000000UL)
|
||||
#define FLASH_SCR ((flash_regs_t *) FLASH_SCR_BASE)
|
||||
#define FLASH_CONFIG_BASE (0xB8000000UL)
|
||||
#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
|
||||
|
||||
#define FLASH_SR_STATUS_MASK (3 << 0)
|
||||
#define FLASH_SR_STATUS_IDLE (0)
|
||||
#define FLASH_SR_STATUS_BUSY_ERASE (1)
|
||||
#define FLASH_SR_STATUS_BUSY_WRITE (2)
|
||||
#define FLASH_SR_STATUS_BUSY_READ (3)
|
||||
#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
|
||||
#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
|
||||
#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
|
||||
#define FLASH_SR_WRITE_PROTECT_BIT (5)
|
||||
|
||||
#define FLASH_CR_PAGE_ERASE_BIT (0)
|
||||
#define FLASH_CR_SECTOR_ERASE_BIT (20)
|
||||
#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
|
||||
#define FLASH_CR_WRITE_PROTECT_BIT (23)
|
||||
|
||||
|
||||
void reset_handler (void);
|
||||
|
@ -77,6 +77,7 @@ struct process {
|
||||
uint32_t args[2];
|
||||
bool error;
|
||||
bool dma_in_progress;
|
||||
bool queried;
|
||||
|
||||
bool debug_rx_busy;
|
||||
uint32_t debug_rx_address;
|
||||
@ -173,6 +174,7 @@ void process_usb (void) {
|
||||
p.counter = 0;
|
||||
p.error = false;
|
||||
p.dma_in_progress = false;
|
||||
p.queried = false;
|
||||
p.state = STATE_ARGS;
|
||||
} else {
|
||||
p.cmd = '!';
|
||||
@ -199,7 +201,10 @@ void process_usb (void) {
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
cfg_query(p.args);
|
||||
if (!p.queried) {
|
||||
cfg_query(p.args);
|
||||
p.queried = true;
|
||||
}
|
||||
if (tx_word(p.args[1])) {
|
||||
p.state = STATE_RESPONSE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user