another cleanup

This commit is contained in:
Mateusz Faderewski 2024-05-27 20:04:07 +02:00
parent 5cba981f82
commit 392ad5bece
13 changed files with 187 additions and 150 deletions

View File

@ -31,7 +31,8 @@ SRC_FILES = \
exception.S \ exception.S \
font.c \ font.c \
init.c \ init.c \
interrupt.c \ interrupts.c \
interrupts.S \
io.c \ io.c \
main.c \ main.c \
menu.c \ menu.c \

View File

@ -1,8 +1,6 @@
#include "vr4300.h" #include "vr4300.h"
#define WATCHDOG_TIMEOUT (5 * (93750000UL / 2))
#define ZR_OFFSET (0) #define ZR_OFFSET (0)
#define AT_OFFSET (8) #define AT_OFFSET (8)
#define V0_OFFSET (16) #define V0_OFFSET (16)
@ -51,14 +49,18 @@ exception_xtlb_miss:
.org 0x0080 .org 0x0080
j exception_handler j exception_handler
exception_ecc:
.org 0x0100
j exception_handler
exception_other: exception_other:
.org 0x0180 .org 0x0180
j exception_handler j exception_handler
.section .text.exception_handler .section .text.exception_handler
.type exception_handler, %function
exception_handler: exception_handler:
.type exception_handler, %function
.set noat .set noat
la $k0, (_esp - SAVE_REGISTERS_SIZE) la $k0, (_esp - SAVE_REGISTERS_SIZE)
sd $zero, ZR_OFFSET($k0) sd $zero, ZR_OFFSET($k0)
@ -124,7 +126,7 @@ exception_interrupt:
andi $t0, C0_SR_IM_MASK andi $t0, C0_SR_IM_MASK
srl $t0, C0_SR_IM_BIT srl $t0, C0_SR_IM_BIT
and $a0, $t0 and $a0, $t0
jal exception_interrupt_handler jal interrupts_handler
exception_restore: exception_restore:
.set noat .set noat
@ -160,51 +162,3 @@ exception_restore:
.set at .set at
eret eret
.section .text.exception_enable_interrupts
exception_enable_interrupts:
.type exception_enable_interrupts, %function
.global exception_enable_interrupts
mfc0 $t0, C0_STATUS
li $t1, (C0_SR_IM4 | C0_SR_IM3 | C0_SR_IE)
or $t0, $t1
mtc0 $t0, C0_STATUS
jr $ra
.section .text.exception_disable_interrupts
exception_disable_interrupts:
.type exception_disable_interrupts, %function
.global exception_disable_interrupts
mfc0 $t0, C0_STATUS
li $t1, ~(C0_SR_IM4 | C0_SR_IM3 | C0_SR_IE)
and $t0, $t1
mtc0 $t0, C0_STATUS
jr $ra
.section .text.exception_enable_watchdog
exception_enable_watchdog:
.type exception_enable_watchdog, %function
.global exception_enable_watchdog
mtc0 $zero, C0_COUNT
li $t1, WATCHDOG_TIMEOUT
mtc0 $t1, C0_COMPARE
mfc0 $t0, C0_STATUS
li $t1, C0_SR_IM7
or $t0, $t1
mtc0 $t0, C0_STATUS
jr $ra
.section .text.exception_disable_watchdog
exception_disable_watchdog:
.type exception_disable_watchdog, %function
.global exception_disable_watchdog
mfc0 $t0, C0_STATUS
li $t1, ~(C0_SR_IM7)
and $t0, $t1
mtc0 $t0, C0_STATUS
mtc0 $zero, C0_COMPARE
jr $ra

View File

@ -1,6 +1,5 @@
#include <stdarg.h> #include <stdarg.h>
#include "display.h" #include "display.h"
#include "exception_regs.h"
#include "exception.h" #include "exception.h"
#include "io.h" #include "io.h"
#include "version.h" #include "version.h"

View File

@ -2,10 +2,55 @@
#define EXCEPTION_H__ #define EXCEPTION_H__
void exception_enable_interrupts (void); #include <stdint.h>
void exception_disable_interrupts (void);
void exception_enable_watchdog (void);
void exception_disable_watchdog (void); typedef union {
uint64_t u64;
struct {
uint32_t u32_h;
uint32_t u32;
};
} uint64_32_t;
typedef struct {
uint64_32_t zr;
uint64_32_t at;
uint64_32_t v0;
uint64_32_t v1;
uint64_32_t a0;
uint64_32_t a1;
uint64_32_t a2;
uint64_32_t a3;
uint64_32_t t0;
uint64_32_t t1;
uint64_32_t t2;
uint64_32_t t3;
uint64_32_t t4;
uint64_32_t t5;
uint64_32_t t6;
uint64_32_t t7;
uint64_32_t s0;
uint64_32_t s1;
uint64_32_t s2;
uint64_32_t s3;
uint64_32_t s4;
uint64_32_t s5;
uint64_32_t s6;
uint64_32_t s7;
uint64_32_t t8;
uint64_32_t t9;
uint64_32_t k0;
uint64_32_t k1;
uint64_32_t gp;
uint64_32_t sp;
uint64_32_t s8;
uint64_32_t ra;
uint32_t sr;
uint32_t cr;
uint64_32_t epc;
uint64_32_t badvaddr;
} exception_t;
#endif #endif

View File

@ -1,56 +0,0 @@
#ifndef EXCEPTION_REGS_H__
#define EXCEPTION_REGS_H__
#include <stdint.h>
typedef union {
uint64_t u64;
struct {
uint32_t u32_h;
uint32_t u32;
};
} uint64_32_t;
typedef struct {
uint64_32_t zr;
uint64_32_t at;
uint64_32_t v0;
uint64_32_t v1;
uint64_32_t a0;
uint64_32_t a1;
uint64_32_t a2;
uint64_32_t a3;
uint64_32_t t0;
uint64_32_t t1;
uint64_32_t t2;
uint64_32_t t3;
uint64_32_t t4;
uint64_32_t t5;
uint64_32_t t6;
uint64_32_t t7;
uint64_32_t s0;
uint64_32_t s1;
uint64_32_t s2;
uint64_32_t s3;
uint64_32_t s4;
uint64_32_t s5;
uint64_32_t s6;
uint64_32_t s7;
uint64_32_t t8;
uint64_32_t t9;
uint64_32_t k0;
uint64_32_t k1;
uint64_32_t gp;
uint64_32_t sp;
uint64_32_t s8;
uint64_32_t ra;
uint32_t sr;
uint32_t cr;
uint64_32_t epc;
uint64_32_t badvaddr;
} exception_t;
#endif

View File

@ -1,6 +1,6 @@
#include "error.h" #include "error.h"
#include "exception.h"
#include "init.h" #include "init.h"
#include "interrupts.h"
#include "io.h" #include "io.h"
#include "sc64.h" #include "sc64.h"
#include "test.h" #include "test.h"
@ -24,22 +24,22 @@ void init (init_tv_type_t tv_type, init_reset_type_t reset_type, uint32_t entrop
error_display("SC64 hardware not detected"); error_display("SC64 hardware not detected");
} }
exception_enable_watchdog(); interrupts_init();
exception_enable_interrupts(); interrupts_start_watchdog();
if ((error = sc64_set_config(CFG_ID_BOOTLOADER_SWITCH, false)) != SC64_OK) { if ((error = sc64_set_config(CFG_ID_BOOTLOADER_SWITCH, false)) != SC64_OK) {
error_display("Command CONFIG_SET [BOOTLOADER_SWITCH] failed\n (%08X) - %s", error, sc64_error_description(error)); error_display("Command CONFIG_SET [BOOTLOADER_SWITCH] failed\n (%08X) - %s", error, sc64_error_description(error));
} }
if (test_check()) { if (test_check()) {
exception_disable_watchdog(); interrupts_stop_watchdog();
test_execute(); test_execute();
} }
} }
void deinit (void) { void deinit (void) {
exception_disable_interrupts(); interrupts_stop_watchdog();
exception_disable_watchdog(); interrupts_disable();
sc64_lock(); sc64_lock();
} }

View File

@ -0,0 +1,58 @@
#include "vr4300.h"
#define WATCHDOG_TIMEOUT (5 * (93750000UL / 2))
.section .text.interrupts
.type interrupts_init, %function
.global interrupts_init
interrupts_init:
li $t1, (C0_SR_IM4 | C0_SR_IM3 | C0_SR_IE)
mfc0 $t0, C0_STATUS
or $t0, $t1
mtc0 $t0, C0_STATUS
jr $ra
.type interrupts_disable, %function
.global interrupts_disable
interrupts_disable:
li $t0, ~(C0_SR_IE)
mfc0 $v0, C0_STATUS
and $t0, $v0
mtc0 $t0, C0_STATUS
jr $ra
.type interrupts_restore, %function
.global interrupts_restore
interrupts_restore:
mtc0 $a0, C0_STATUS
jr $ra
.type interrupts_start_watchdog, %function
.global interrupts_start_watchdog
interrupts_start_watchdog:
mtc0 $zero, C0_COUNT
li $t1, WATCHDOG_TIMEOUT
mtc0 $t1, C0_COMPARE
li $t1, C0_SR_IM7
mfc0 $t0, C0_STATUS
or $t0, $t1
mtc0 $t0, C0_STATUS
jr $ra
.type interrupts_stop_watchdog, %function
.global interrupts_stop_watchdog
interrupts_stop_watchdog:
li $t1, ~(C0_SR_IM7)
mfc0 $t0, C0_STATUS
and $t0, $t1
mtc0 $t0, C0_STATUS
mtc0 $zero, C0_COMPARE
jr $ra

View File

@ -17,8 +17,8 @@ typedef enum {
} interrupt_t; } interrupt_t;
void exception_interrupt_handler (uint8_t interrupt) { void interrupts_handler (uint8_t interrupts) {
if (interrupt == INTERRUPT_NONE) { if (interrupts == INTERRUPT_NONE) {
display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed)); display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed));
version_print(); version_print();
@ -28,8 +28,8 @@ void exception_interrupt_handler (uint8_t interrupt) {
while (true); while (true);
} }
if (interrupt & INTERRUPT_CART) { if (interrupts & INTERRUPT_CART) {
interrupt &= ~(INTERRUPT_CART); interrupts &= ~(INTERRUPT_CART);
sc64_irq_t irq = sc64_irq_pending(); sc64_irq_t irq = sc64_irq_pending();
@ -38,8 +38,8 @@ void exception_interrupt_handler (uint8_t interrupt) {
} }
} }
if (interrupt & INTERRUPT_PRENMI) { if (interrupts & INTERRUPT_PRENMI) {
interrupt &= ~(INTERRUPT_PRENMI); interrupts &= ~(INTERRUPT_PRENMI);
if (display_ready()) { if (display_ready()) {
display_init(NULL); display_init(NULL);
@ -50,8 +50,8 @@ void exception_interrupt_handler (uint8_t interrupt) {
while (true); while (true);
} }
if (interrupt & INTERRUPT_TIMER) { if (interrupts & INTERRUPT_TIMER) {
interrupt &= ~(INTERRUPT_TIMER); interrupts &= ~(INTERRUPT_TIMER);
display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed)); display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed));
@ -62,14 +62,14 @@ void exception_interrupt_handler (uint8_t interrupt) {
while (true); while (true);
} }
if (interrupt != INTERRUPT_NONE) { if (interrupts != INTERRUPT_NONE) {
display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed)); display_init((uint32_t *) (&assets_sc64_logo_640_240_dimmed));
version_print(); version_print();
display_printf("[ Unhandled interrupt ]\n"); display_printf("[ Unhandled interrupt(s) ]\n");
display_printf("Pending (0x%02X):\n", interrupt); display_printf("Pending (0x%02X):\n", interrupts);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
switch (interrupt & (1 << i)) { switch (interrupts & (1 << i)) {
case INTERRUPT_SW_0: display_printf(" (0) Software interrupt\n"); break; case INTERRUPT_SW_0: display_printf(" (0) Software interrupt\n"); break;
case INTERRUPT_SW_1: display_printf(" (1) Software interrupt\n"); break; case INTERRUPT_SW_1: display_printf(" (1) Software interrupt\n"); break;
case INTERRUPT_RCP: display_printf(" (2) RCP interrupt\n"); break; case INTERRUPT_RCP: display_printf(" (2) RCP interrupt\n"); break;

View File

@ -0,0 +1,15 @@
#ifndef INTERRUPTS_H__
#define INTERRUPTS_H__
#include <stdint.h>
void interrupts_init (void);
uint32_t interrupts_disable (void);
void interrupts_restore (uint32_t sr);
void interrupts_start_watchdog (void);
void interrupts_stop_watchdog (void);
#endif

View File

@ -1,3 +1,4 @@
#include "interrupts.h"
#include "io.h" #include "io.h"
#include "vr4300.h" #include "vr4300.h"
@ -72,26 +73,38 @@ uint32_t pi_busy (void) {
} }
uint32_t pi_io_read (io32_t *address) { uint32_t pi_io_read (io32_t *address) {
return cpu_io_read(address); uint32_t sr = interrupts_disable();
while (pi_busy());
uint32_t value = cpu_io_read(address);
interrupts_restore(sr);
return value;
} }
void pi_io_write (io32_t *address, uint32_t value) { void pi_io_write (io32_t *address, uint32_t value) {
cpu_io_write(address, value); uint32_t sr = interrupts_disable();
while (pi_busy()); while (pi_busy());
cpu_io_write(address, value);
interrupts_restore(sr);
} }
void pi_dma_read (io32_t *address, void *buffer, size_t length) { void pi_dma_read (io32_t *address, void *buffer, size_t length) {
cache_data_hit_writeback_invalidate(buffer, length); cache_data_hit_writeback_invalidate(buffer, length);
uint32_t sr = interrupts_disable();
while (pi_busy());
cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address))); cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer))); cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
cpu_io_write(&PI->WDMA, length - 1); cpu_io_write(&PI->WDMA, length - 1);
interrupts_restore(sr);
while (pi_busy()); while (pi_busy());
} }
void pi_dma_write (io32_t *address, void *buffer, size_t length) { void pi_dma_write (io32_t *address, void *buffer, size_t length) {
cache_data_hit_writeback(buffer, length); cache_data_hit_writeback(buffer, length);
uint32_t sr = interrupts_disable();
while (pi_busy());
cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address))); cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer))); cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
cpu_io_write(&PI->RDMA, length - 1); cpu_io_write(&PI->RDMA, length - 1);
interrupts_restore(sr);
while (pi_busy()); while (pi_busy());
} }

View File

@ -214,14 +214,21 @@ sc64_irq_t sc64_irq_pending (void) {
} }
void sc64_irq_callback (sc64_irq_t irq) { void sc64_irq_callback (sc64_irq_t irq) {
uint32_t clear = 0;
if (irq & SC64_IRQ_MCU) {
clear |= SC64_IRQ_MCU_CLEAR;
}
if (irq & SC64_IRQ_CMD) {
clear |= SC64_IRQ_CMD_CLEAR;
}
pi_io_write(&SC64_REGS->IRQ, clear);
if (irq & SC64_IRQ_MCU) { if (irq & SC64_IRQ_MCU) {
sc64_mcu_irq_callback(); sc64_mcu_irq_callback();
pi_io_write(&SC64_REGS->IRQ, SC64_IRQ_MCU_CLEAR);
} }
if (irq & SC64_IRQ_CMD) { if (irq & SC64_IRQ_CMD) {
sc64_cmd_irq_callback(); sc64_cmd_irq_callback();
pi_io_write(&SC64_REGS->IRQ, SC64_IRQ_CMD_CLEAR);
} }
while (pi_busy());
} }

View File

@ -1,27 +1,27 @@
#include "vr4300.h" #include "vr4300.h"
#define RSP_DMEM_ADDRESS 0xA4000000
.section .text.entry_handler, "ax", %progbits .section .text.entry_handler, "ax", %progbits
.type entry_handler, %function
.global entry_handler
entry_handler: entry_handler:
.type entry_handler, %function li $t0, (C0_SR_CU1 | C0_SR_CU0 | C0_SR_FR)
.global entry_handler mtc0 $t0, C0_STATUS
la $gp, _gp la $gp, _gp
la $sp, _sp la $sp, _sp
li $v0, (C0_SR_CU0) li $t0, RSP_DMEM_ADDRESS # IPL3 Boot flags location
mtc0 $v0, C0_STATUS
lui $t0, 0xA400
lbu $a0, 9($t0) # TV type lbu $a0, 9($t0) # TV type
lbu $a1, 10($t0) # Reset type lbu $a1, 10($t0) # Reset type
lw $a2, 4($t0) # Entropy lw $a2, 4($t0) # Entropy
la $t0, init jal init
jalr $t0
la $t0, main jal main
jalr $t0
loop: loop:
j loop j loop

View File

@ -9,6 +9,7 @@
#define CACHE_LINE_SIZE_I (32) #define CACHE_LINE_SIZE_I (32)
#define CACHE_LINE_SIZE_D (16) #define CACHE_LINE_SIZE_D (16)
#define C0_BADVADDR $8 #define C0_BADVADDR $8
#define C0_COUNT $9 #define C0_COUNT $9
#define C0_COMPARE $11 #define C0_COMPARE $11