Ver Fonte

iodev: move one-register "devices" into a common "sys"; add "abc" device

Devices that by their nature won't be more than one register, and
which don't require interrupts, can be coalesced into a single device
space.

Add a device "abc" which currently contains only the status register,
but will add additional ones later. Add interrupt on status change.
H. Peter Anvin há 3 anos atrás
pai
commit
55b0aeee3f
11 ficheiros alterados com 3529 adições e 3503 exclusões
  1. 23 27
      fpga/iodevs.vh
  2. 23 6
      fpga/max80.sv
  3. BIN
      fpga/output_files/max80.jbc
  4. BIN
      fpga/output_files/max80.jic
  5. BIN
      fpga/output_files/max80.pof
  6. BIN
      fpga/output_files/max80.sof
  7. 3456 3456
      fw/boot.mif
  8. 6 4
      fw/hello.c
  9. 8 2
      fw/io.h
  10. 11 5
      fw/ioregs.h
  11. 2 3
      iodevs.conf

+ 23 - 27
fpga/iodevs.vh

@@ -3,38 +3,35 @@
 	wire [3:0]  xdev_valid  = iodev_mem_valid << cpu_mem_addr[29:28];
 	wire [15:0]  iodev_valid = xdev_valid[3] << cpu_mem_addr[10:7];
 
-	wire [31:0] iodev_rdata_led;
-	wire [ 0:0] iodev_valid_led = iodev_valid[0:0];
-	tri1 [ 0:0] iodev_wait_n_led;
-
-	wire [31:0] iodev_rdata_reset;
-	wire [ 0:0] iodev_valid_reset = iodev_valid[1:1];
-	tri1 [ 0:0] iodev_wait_n_reset;
-
-	wire [31:0] iodev_rdata_romcopy;
-	wire [ 0:0] iodev_valid_romcopy = iodev_valid[2:2];
-	tri1 [ 0:0] iodev_wait_n_romcopy;
+	wire [31:0] iodev_rdata_sys;
+	wire [ 0:0] iodev_valid_sys = iodev_valid[0:0];
+	tri1 [ 0:0] iodev_wait_n_sys;
 
 	wire [31:0] iodev_rdata_sysclock;
 	wire [ 0:0] iodev_irq_sysclock;
-	wire [ 0:0] iodev_valid_sysclock = iodev_valid[3:3];
+	wire [ 0:0] iodev_valid_sysclock = iodev_valid[1:1];
 	tri1 [ 0:0] iodev_wait_n_sysclock;
 
 	wire [31:0] iodev_rdata_console;
 	wire [ 0:0] iodev_irq_console;
-	wire [ 0:0] iodev_valid_console = iodev_valid[4:4];
+	wire [ 0:0] iodev_valid_console = iodev_valid[2:2];
 	tri1 [ 0:0] iodev_wait_n_console;
 
 	wire [31:0] iodev_rdata_sdcard;
 	wire [ 0:0] iodev_irq_sdcard;
-	wire [ 0:0] iodev_valid_sdcard = iodev_valid[5:5];
+	wire [ 0:0] iodev_valid_sdcard = iodev_valid[3:3];
 	tri1 [ 0:0] iodev_wait_n_sdcard;
 
 	wire [31:0] iodev_rdata_esp;
 	wire [ 0:0] iodev_irq_esp;
-	wire [ 0:0] iodev_valid_esp = iodev_valid[6:6];
+	wire [ 0:0] iodev_valid_esp = iodev_valid[4:4];
 	tri1 [ 0:0] iodev_wait_n_esp;
 
+	wire [31:0] iodev_rdata_abc;
+	wire [ 0:0] iodev_irq_abc;
+	wire [ 0:0] iodev_valid_abc = iodev_valid[5:5];
+	tri1 [ 0:0] iodev_wait_n_abc;
+
 	wire [31:0] iodev_rdata_abcmemmap;
 	wire [ 0:0] iodev_valid_abcmemmap = xdev_valid[0:0];
 	tri1 [ 0:0] iodev_wait_n_abcmemmap;
@@ -45,13 +42,12 @@
 			2'd0:	 iodev_rdata = iodev_rdata_abcmemmap;
 			2'd3:
 			case (cpu_mem_addr[10:7])
-				4'd0:	 iodev_rdata = iodev_rdata_led;
-				4'd1:	 iodev_rdata = iodev_rdata_reset;
-				4'd2:	 iodev_rdata = iodev_rdata_romcopy;
-				4'd3:	 iodev_rdata = iodev_rdata_sysclock;
-				4'd4:	 iodev_rdata = iodev_rdata_console;
-				4'd5:	 iodev_rdata = iodev_rdata_sdcard;
-				4'd6:	 iodev_rdata = iodev_rdata_esp;
+				4'd0:	 iodev_rdata = iodev_rdata_sys;
+				4'd1:	 iodev_rdata = iodev_rdata_sysclock;
+				4'd2:	 iodev_rdata = iodev_rdata_console;
+				4'd3:	 iodev_rdata = iodev_rdata_sdcard;
+				4'd4:	 iodev_rdata = iodev_rdata_esp;
+				4'd5:	 iodev_rdata = iodev_rdata_abc;
 				default: iodev_rdata = 32'hffffffff;
 			endcase
 			default: iodev_rdata = 32'hffffffff;
@@ -62,15 +58,15 @@
 	assign sys_irq[ 4] = iodev_irq_console[0];
 	assign sys_irq[ 5] = iodev_irq_sdcard[0];
 	assign sys_irq[ 6] = iodev_irq_esp[0];
+	assign sys_irq[ 7] = iodev_irq_abc[0];
 
-	localparam [31:0] irq_edge_mask =  32'h00000008;
-	localparam [31:0] irq_masked    = ~32'h0000007f;
+	localparam [31:0] irq_edge_mask =  32'h00000088;
+	localparam [31:0] irq_masked    = ~32'h000000ff;
 
-	wire iodev_wait_n = (&iodev_wait_n_led) & 
-		(&iodev_wait_n_reset) & 
-		(&iodev_wait_n_romcopy) & 
+	wire iodev_wait_n = (&iodev_wait_n_sys) & 
 		(&iodev_wait_n_sysclock) & 
 		(&iodev_wait_n_console) & 
 		(&iodev_wait_n_sdcard) & 
 		(&iodev_wait_n_esp) & 
+		(&iodev_wait_n_abc) & 
 		(&iodev_wait_n_abcmemmap);

+ 23 - 6
fpga/max80.sv

@@ -686,11 +686,28 @@ module max80
        default: cpu_mem_rdata = 32'hxxxx_xxxx;
      endcase
 
+   // Miscellaneous system control/status registers
+   wire [ 4:0] sysreg_subreg = cpu_mem_addr[6:2];
+   wire [31:0] sysreg = iodev_valid_sys << sysreg_subreg;
+   tri1 [31:0] sysreg_rdata[0:31];
+   assign iodev_sys_rdata = sysreg_rdata[sysreg_subreg];
+
+   assign sysreg_rdata[0] = 32'h5058414d;
+   assign sysreg_rdata[1] = { 31'b0, rtc_32khz_rework };
+
    // Hard system reset under program control
-   assign reset_cmd = iodev_valid_reset & cpu_mem_wstrb[0] & cpu_mem_wdata[0];
+   assign reset_cmd = sysreg[3] & cpu_mem_wstrb[0] & cpu_mem_wdata[0];
+
+   // ABC80/800 status
+   assign iodev_rdata_abcbus = { 30'b0, abc800, abc_clk_active };
+   reg [1:0] abc_status[0:1];
+   always @(posedge sys_clk)
+     begin
+	abc_status[0] <= iodev_rdata_abcbus;
+	abc_status[1] <= abc_status[0];
+     end
 
-   // ABC80/800 status (change the name of the reset device...)
-   assign iodev_rdev_reset = { 30'b0, abc800, abc_clk_active };
+   wire iodev_irq_abcbus = (abc_status[1] != abc_status[0]);
 
    // LED indication from the CPU
    reg [2:0]   led_q;
@@ -698,11 +715,11 @@ module max80
      if (~rst_n)
        led_q <= 3'b000;
      else
-       if ( iodev_valid_led & cpu_mem_wstrb[0] )
+       if ( sysreg[2] & cpu_mem_wstrb[0] )
 	 led_q <= cpu_mem_wdata[2:0];
 
    assign led = led_q;
-   assign iodev_rdata_led = { 29'b0, led_q };
+   assign sysreg_rdata[2] = { 29'b0, led_q };
 
    //
    // Serial ROM (also configuration ROM.) Fast hardwired data download
@@ -730,7 +747,7 @@ module max80
    always @(posedge sys_clk)
      rom_done_q <= rom_done;
 
-   assign iodev_rdata_romcopy = { 31'b0, rom_done_q };
+   assign sysreg_rdata[4] = { 31'b0, rom_done_q };
 
    //
    // Serial port. Direct to the CP2102N for reworked

BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


Diff do ficheiro suprimidas por serem muito extensas
+ 3456 - 3456
fw/boot.mif


+ 6 - 4
fw/hello.c

@@ -186,8 +186,9 @@ void main(void)
 
     uint32_t done;
     uint32_t irq_count;
+    uint32_t abc_status;
 
-    while (!ROMCOPY_DONE)
+    while (!(SYS_ROMCOPY & SYS_ROMCOPY_DONE))
 	pause();
 
     done = rdtime() - time_zero;
@@ -197,9 +198,10 @@ void main(void)
     con_printf("This is loop: %u\n", loops++);
     con_printf("SDRAM download took %u us\n", done/(CPU_HZ/1000000));
 
-    if (RESET_CMD & 1) {
+    abc_status = ABC_STATUS;
+    if (abc_status & ABC_STATUS_LIVE) {
 	con_printf("I seem to be connected to ABC%d\n",
-		   (RESET_CMD & 2) ? 800 : 80);
+		   (ABC_STATUS & ABC_STATUS_800) ? 800 : 80);
     } else {
 	con_puts("No ABC-bus host detected\n");
     }
@@ -220,5 +222,5 @@ void main(void)
     con_puts("*** Doing reset ***\n");
     con_flush();
     while ( 1 )
-      RESET_CMD = 1;
+	reset();
 }

+ 8 - 2
fw/io.h

@@ -13,7 +13,13 @@ static inline void pause(void)
 
 static inline void set_led(uint8_t leds)
 {
-    LED = leds;
+    SYS_LED = leds;
+}
+
+static inline __attribute__((noreturn)) void reset(void)
+{
+    while (1)
+	SYS_RESET = 1;
 }
 
 extern const uint32_t time_zero;
@@ -33,7 +39,7 @@ static inline uint64_t rdtimeq(void)
     asm volatile("rdtimeh %0; rdtime %1; %rdtimeh %2"
 		 : "=r" (h1), "=r" (l), "=r" (h0));
 
-    return ((int32_t)l < 0) ? h1 : h0;
+    return ((uint64_t)(((int32_t)l < 0) ? h1 : h0) << 32) + l;
 }
 
 static inline void udelay(uint32_t us)

+ 11 - 5
fw/ioregs.h

@@ -50,11 +50,13 @@
 
 #define CPU_HZ			84000000
 
-#define LED			IODEVB(LED,0)
-
-#define RESET_CMD		IODEVL(RESET,0)
-
-#define ROMCOPY_DONE		IODEVRL(ROMCOPY,0)
+/* Basic system registers */
+#define SYS_MAGIC		IODEVL(SYS,0)
+#define SYS_BOARDCFG		IODEVL(SYS,1)
+#define SYS_LED			IODEVL(SYS,2)
+#define SYS_RESET		IODEVL(SYS,3)
+#define SYS_ROMCOPY		IODEVL(SYS,4)
+#define SYS_ROMCOPY_DONE	1
 
 #define CON_DATA		IODEVB(CONSOLE,0)
 #define CON_BAUDDIV		IODEVL(CONSOLE,1)
@@ -82,6 +84,10 @@
 #define SYSCLOCK_TICK_HOLD	IODEVH0(SYSCLOCK,1)
 #define SYSCLOCK_TICK_NOW	IODEVH1(SYSCLOCK,1)
 
+#define ABC_STATUS		IODEVL(ABC,0)
+#define ABC_STATUS_LIVE		1
+#define ABC_STATUS_800		2
+
 #define ABCMEMMAP_PAGE(n)	IODEVL(ABCMEMMAP,n)
 #define ABCMEMMAP_WR		0x10000
 #define ABCMEMMAP_RD		0x20000

+ 2 - 3
iodevs.conf

@@ -14,12 +14,11 @@ our @sysirqs = ('timer', 'ebreak', 'buserr');
 # Define -irq to a string of 'e' (edge) or 'l' (level)
 # for a corresponding number of IRQs.
 our @iodevs = (
-    { -name => 'led' },
-    { -name => 'reset' },
-    { -name => 'romcopy' },
+    { -name => 'sys' },
     { -name => 'sysclock',  -irq => 'e' },
     { -name => 'console',   -irq => 'l' },
     { -name => 'sdcard',    -irq => 'l' },
     { -name => 'esp',       -irq => 'l' },
+    { -name => 'abc',       -irq => 'e' },
     { -name => 'abcmemmap', -xdev => 1 },
 );

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff