;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; This file is part of 'M', a MIPS system emulator. ;; ;; ;; ;; (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) ;; ;; http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html ;; ;; ;; ;; You do not have, nor can you ever acquire the right to use, copy or ;; ;; distribute this software ; Should you use this software for any purpose, ;; ;; or copy and distribute it to anyone or in any manner, you are breaking ;; ;; the laws of whatever soi-disant jurisdiction, and you promise to ;; ;; continue doing so for the indefinite future. In any case, please ;; ;; always : read and understand any software ; verify any PGP signatures ;; ;; that you use - for any purpose. ;; ;; ;; ;; See also http://trilema.com/2015/a-new-software-licensing-paradigm . ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Universal MMIO Bus Dispatcher. Addition of new simulated devices will NOT ;; require any changes to this mechanism. Be sure to add any device component ;; to 'devices.asm'. ;; NOTE 1: The DECLARE_BUS_DEVICE macro is valid ONLY inside text included by ;; 'devices.asm' ! ;; NOTE 2: Currently there is NO support for devices which demand a ;; non-contiguous MMIO segment ! ;; NOTE 3: Make ABSOLUTELY certain that the MMIO Device ranges do not overlap! section .text ;----------------------------------------------------------------------------- ; MMIO_ADDR ;----------------------------------------------------------------------------- %define MMIO_ADDR(A) (MMIO_BASE + A) ; Address to be offset from MMIO_BASE ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Proclaim Device and connect it to Bus; %1: Name, %2: Base Addr, %3: Top Addr ;----------------------------------------------------------------------------- %macro DECLARE_BUS_DEVICE 3 %define %1_BASE MMIO_ADDR(%2) ;; Declare DEVICE_BASE MMIO Address (first) %define %1_TOP MMIO_ADDR(%3) ;; Declare DEVICE_TOP MMIO Address (last) ;; Put this device's MMIO range in _Phys_Device_Read_Word's set of cases SECTION .PD_Rd_Word JMP_If_In eax, %1_BASE, %1_TOP, _PD_Read_Word_%1 ;; Put this device's MMIO range in _Phys_Device_Write_Word's set of cases SECTION .PD_Wr_Word JMP_If_In eax, %1_BASE, %1_TOP, _PD_Write_Word_%1 ;; Put this device's MMIO range in _Phys_Device_Read_Byte's set of cases SECTION .PD_Rd_Byte JMP_If_In eax, %1_BASE, %1_TOP, _PD_Read_Byte_%1 ;; Put this device's MMIO range in _Phys_Device_Write_Byte's set of cases SECTION .PD_Wr_Byte JMP_If_In eax, %1_BASE, %1_TOP, _PD_Write_Byte_%1 ;; Put this device's initialization routine in the list of ;; called by _Phys_Devices_Initialize: SECTION .PD_Initialize call _Device_Init_%1 ;; Put this device's termination routine in the list of ;; called by _Phys_Devices_Shutdown: SECTION .PD_Shutdown call _Device_Shutdown_%1 section .text ;; Resume the .text section. %endmacro ;----------------------------------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Prologues of Physical Device Bus Wires ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- ; Device Read Word -- we jump here from _Virt_Read_Word if pAddr in range ;----------------------------------------------------------------------------- section .PD_Rd_Word progbits exec alloc nowrite _Phys_Device_Read_Word: ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Device Write Word -- we jump here from _Virt_Write_Word if pAddr in range ;----------------------------------------------------------------------------- section .PD_Wr_Word progbits exec alloc nowrite _Phys_Device_Write_Word: ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Device Read Byte -- we jump here from _Virt_Read_Byte if pAddr in range ;----------------------------------------------------------------------------- section .PD_Rd_Byte progbits exec alloc nowrite _Phys_Device_Read_Byte: ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Device Write Byte -- we jump here from _Virt_Write_Byte if pAddr in range ;----------------------------------------------------------------------------- section .PD_Wr_Byte progbits exec alloc nowrite _Phys_Device_Write_Byte: ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Device Initialization ;----------------------------------------------------------------------------- section .PD_Initialize progbits exec alloc nowrite _Phys_Devices_Initialize: ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Device Shutdown ;----------------------------------------------------------------------------- section .PD_Shutdown progbits exec alloc nowrite _Phys_Devices_Shutdown: ;----------------------------------------------------------------------------- ;; ALL Device implementations MUST be included from: %include "devices/devices.asm" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Epilogues of Physical Device Bus Wires ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- SECTION .PD_Rd_Word ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Unknown Device ? xor eax, eax ; Always return 0 ACHTUNG "Read Word from Unknown Device?" ; TODO: print detail ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- SECTION .PD_Wr_Word ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Unknown Device ? ACHTUNG "Write Word to Unknown Device?" ; TODO: print detail ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- SECTION .PD_Rd_Byte ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Unknown Device ? xor eax, eax ; Always return 0 ACHTUNG "Read Byte from Unknown Device?" ; TODO: print detail ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- SECTION .PD_Wr_Byte ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Unknown Device ? ACHTUNG "Write Byte to Unknown Device?" ; TODO: print detail ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- SECTION .PD_Initialize ret ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- SECTION .PD_Shutdown ret ;----------------------------------------------------------------------------- ;; Back to code section: section .text