Magic‐1 Hardware Initialization Procedure - retrotruestory/M1DEV GitHub Wiki
Magic-1 Hardware Initialization Procedure
Based on the provided Magic-1 source files, here's the hardware initialization procedure sequence:
Magic-1 Hardware Initialization Procedure
1. Initial Reset and Mode Setup
// 1. Initial CPU state after reset:
- Interrupts disabled
- System mode active
- Paging disabled
- MSW (Machine Status Word) = 0x0000
2. Core System Setup
// From bcrt0.s startup sequence:
_start:
// Ensure system state
ld.16 a,0x0000
copy msw,a // Interrupts off, system mode
// Setup kernel stack
ld.16 a,stack_start // stack_start = 0x8000
copy sp,a
// Initialize data pointer
ld.16 a,dp_start // dp_start = 0x0000
copy dp,a
3. Device Initialization Sequence
3.1 UART Initialization
void init_uart(t_rs232 *p, unsigned int baud_rate) {
// Set baud rate
*p->p_uart_lcr = UART_DLAB_1;
*p->p_uart_div_lsb = baud_rate & 0xff;
*p->p_uart_div_msb = (baud_rate >> 8) & 0xff;
// Configure 8N1 mode
*p->p_uart_lcr = UART_8N1;
// Enable FIFO
*p->p_uart_fcr = (UART_FIFO_ON | UART_FIFO_RESET | UART_FIFO_SIG1);
// Set modem control
*p->p_uart_mcr = (UART_DTR | UART_RTS);
// Clear data
*p->p_uart_msr;
*p->p_uart_lsr;
*p->p_uart_data;
// Disable interrupts
*p->p_uart_ier = 0;
}
3.2 RTC Initialization
void init_rtc() {
unsigned char *p = (unsigned char*) RTC_BASE;
// Disable interrupts
p[RTC_CE] = RTC_INTERRUPTS_OFF;
// Clear pending interrupts
p[RTC_CD] = 0;
// Configure clock:
// - 64ths timing mode
// - Pulse mode
// - Enable interrupts (though they're ignored)
p[RTC_CE] = (RTC_64ths | RTC_PULSE_MODE | RTC_INTERRUPTS_ON);
}
3.3 IDE/Storage Initialization
void ide_reset() {
// Reset IDE interface
p = (unsigned char *) CFG_8255;
*p = WR_IDE_8255;
// Reset control lines
p = (unsigned char *) IDE_8255_CTL;
*p = 0;
// Assert reset
*p = IDE_RESET_LINE;
// Delay >25us
// Deassert reset
*p = 0;
}
void init_ide_info() {
// Initialize IDE interfaces
ide_reset();
// Configure master drive
ide_init(IDE_MASTER, IDE_LBA);
// Configure slave drive
ide_init(IDE_SLAVE, IDE_LBA);
// Configure CF if present
cf_init(CF_MASTER, CF_MODE);
}
4. Memory Management Setup
void setup_address_space() {
// Set up initial page tables
create_boot_image_address_space(0, FALSE);
// Enable paging
paging_on();
}
5. Interrupt Vector Setup
_interrupt_vector:
// Set up interrupt vectors at fixed locations
defw unhandled_exception ; IRQ5 (RTC)
defw unhandled_exception ; IRQ4
defw unhandled_exception ; IRQ3 (UART0)
defw unhandled_exception ; IRQ2 (UART1)
defw unhandled_exception ; IRQ1 (IDE)
defw unhandled_exception ; IRQ0
defw unhandled_exception ; DMA
defw unhandled_exception ; SYSCALL
The initialization sequence ensures:
- Safe initial CPU state
- Working stack and data pointers
- Configured I/O devices
- Memory management ready
- System prepared for OS loading
Based on the Magic-1 specifications, let's implement the hardware initialization sequence in Verilog. This procedure ensures proper reset and initialization of all CPU components.
module magic1_init (
input wire clk,
input wire ext_reset_n,
output reg sys_ready,
output reg [7:0] init_state
);
// Initialization states
localparam [7:0]
INIT_RESET = 8'h00,
INIT_CLOCK = 8'h01,
INIT_REGISTERS = 8'h02,
INIT_MEMORY = 8'h03,
INIT_MMU = 8'h04,
INIT_CACHE = 8'h05,
INIT_IO = 8'h06,
INIT_COMPLETE = 8'h07;
// Reset sequence counter
reg [7:0] reset_counter;
// Initialization sequence
always @(posedge clk or negedge ext_reset_n) begin
if (!ext_reset_n) begin
init_state <= INIT_RESET;
sys_ready <= 1'b0;
reset_counter <= 8'h00;
end else begin
case (init_state)
INIT_RESET: begin
// Hold reset for 16 cycles
if (reset_counter == 8'h0F) begin
init_state <= INIT_CLOCK;
reset_counter <= 8'h00;
end else begin
reset_counter <= reset_counter + 1;
end
end
INIT_CLOCK: begin
// Initialize clock generation
if (reset_counter == 8'h03) begin
init_state <= INIT_REGISTERS;
reset_counter <= 8'h00;
end else begin
reset_counter <= reset_counter + 1;
end
end
INIT_REGISTERS: begin
// Clear all registers
init_state <= INIT_MEMORY;
end
INIT_MEMORY: begin
// Initialize memory subsystem
init_state <= INIT_MMU;
end
INIT_MMU: begin
// Setup MMU with default page tables
init_state <= INIT_CACHE;
end
INIT_CACHE: begin
// Invalidate cache
init_state <= INIT_IO;
end
INIT_IO: begin
// Initialize I/O subsystems
init_state <= INIT_COMPLETE;
end
INIT_COMPLETE: begin
sys_ready <= 1'b1;
end
endcase
end
end
endmodule
To integrate this initialization module with the main system:
module magic1_top (
input wire ext_clk,
input wire ext_reset_n,
// ...other ports...
);
// System signals
wire sys_clk;
wire sys_reset_n;
wire sys_ready;
wire [7:0] init_state;
// Instantiate initialization controller
magic1_init init_controller (
.clk(ext_clk),
.ext_reset_n(ext_reset_n),
.sys_ready(sys_ready),
.init_state(init_state)
);
// Hold system in reset until initialization complete
assign sys_reset_n = ext_reset_n & sys_ready;
// ...rest of system implementation...
endmodule
To test the initialization sequence:
# Compile and run initialization test
cd /testbench
iverilog -g2012 magic1_init_test.v ../rtl/magic1_init.v -o init_test
./init_test
The initialization sequence follows these key steps:
- Assert reset for 16 clock cycles
- Initialize clock generation
- Clear all registers to known state
- Initialize memory subsystem
- Setup MMU and page tables
- Invalidate cache
- Initialize I/O subsystems
- Signal system ready