Merge pull request #1388 from p-woj/json2renode-fb-plic

tools/litex_json2renode: Add video_framebuffer support, vexriscv interrupt fixes
This commit is contained in:
Mateusz Hołenko 2022-08-02 15:35:06 +02:00 committed by GitHub
commit 6932fc51e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 11 deletions

View File

@ -166,7 +166,7 @@ was {} bytes.
{}: Memory.MappedMemory @ {} {}: Memory.MappedMemory @ {}
size: {} size: {}
""".format(region_descriptor['name'], """.format(region_descriptor['name'],
generate_sysbus_registration(region_descriptor, skip_size=True), generate_sysbus_registration(region_descriptor, skip_size=True, skip_braces=True),
hex(region_descriptor['size'])) hex(region_descriptor['size']))
return result return result
@ -186,7 +186,7 @@ def generate_silencer(csr, name, **kwargs):
return """ return """
sysbus: sysbus:
init add: init add:
SilenceRange <{} 0x200> # {} SilenceRange <0x{:08x} 0x200> # {}
""".format(csr['csr_bases'][name], name) """.format(csr['csr_bases'][name], name)
@ -235,11 +235,6 @@ cpu: CPU.VexRiscv @ sysbus
timeProvider: {} timeProvider: {}
""".format(time_provider) """.format(time_provider)
if kind == 'vexriscv_smp':
result += """
builtInIrqController: false
"""
return result return result
elif kind == 'picorv32': elif kind == 'picorv32':
return """ return """
@ -433,12 +428,12 @@ clint: IRQControllers.CoreLevelInterruptor @ {}
def generate_plic(plic): def generate_plic(plic):
# TODO: this is configuration for VexRiscv - add support for other CPU types # TODO: this is configuration for linux-on-litex-vexriscv - add support for other CPU types
result = """ result = """
plic: IRQControllers.PlatformLevelInterruptController @ {} plic: IRQControllers.PlatformLevelInterruptController @ {}
[0-3] -> cpu@[8-11] [0, 1] -> cpu@[11, 9]
numberOfSources: 31 numberOfSources: 31
numberOfTargets: 2 numberOfContexts: 2
prioritiesEnabled: false prioritiesEnabled: false
""".format(generate_sysbus_registration(plic, """.format(generate_sysbus_registration(plic,
skip_braces=True, skip_braces=True,
@ -447,6 +442,41 @@ plic: IRQControllers.PlatformLevelInterruptController @ {}
return result return result
def generate_video_framebuffer(csr, name, **kwargs):
peripheral = get_descriptor(csr, name, 0xc) # This is simultaneously the "dma" region
vtg = get_descriptor(csr, name + "_vtg", 0x24)
constants = peripheral['constants']
hres = int(constants['hres'])
vres = int(constants['vres'])
base = int(constants['base'])
memory = find_memory_region(csr['filtered_memories'], base)
if memory is None:
raise Exception("Framebuffer base does not belong to a memory region")
offset = base - memory['base']
result = """
litex_video: Video.LiteX_Framebuffer_CSR32 @ {{
{};
{}
}}
format: PixelFormat.XBGR8888
memory: {}
offset: 0x{:08x}
hres: {}
vres: {}
""".format(generate_sysbus_registration(peripheral,
skip_braces=True, region='dma'),
generate_sysbus_registration(vtg,
skip_braces=True, region='vtg'),
memory['name'], offset, hres, vres)
return result
def get_clock_frequency(csr): def get_clock_frequency(csr):
""" """
Args: Args:
@ -525,6 +555,12 @@ peripherals_handlers = {
'model': 'SPI.LiteX_SPI', 'model': 'SPI.LiteX_SPI',
'ignored_constants': ['interrupt'] # model in Renode currently doesn't support interrupts 'ignored_constants': ['interrupt'] # model in Renode currently doesn't support interrupts
}, },
'video_framebuffer': {
'handler': generate_video_framebuffer,
},
'video_framebuffer_vtg': {
'handler': lambda *args, **kwargs: "", # This is handled by generate_video_framebuffer
}
} }
@ -567,7 +603,10 @@ def generate_repl(csr, etherbone_peripherals, autoalign):
x['name'] = m x['name'] = m
memories.append(x) memories.append(x)
for mem_region in filter_memory_regions(memories, alignment=0x1000, autoalign=autoalign): filtered_memories = list(filter_memory_regions(memories, alignment=0x1000, autoalign=autoalign))
csr['filtered_memories'] = filtered_memories # Save for use by peripheral generators
for mem_region in filtered_memories:
result += generate_memory_region(mem_region) result += generate_memory_region(mem_region)
time_provider = None time_provider = None
@ -669,6 +708,28 @@ def filter_memory_regions(raw_regions, alignment=None, autoalign=[]):
yield r yield r
def find_memory_region(memory_regions, address):
""" Finds the memory region containing the specified address.
Args:
memory_regions (list): list of memory regions filtered
with filter_memory_regions
address (int): the address to find
Returns:
dict or None: the region from `memory_regions` that contains
`address` or None if none of them do
"""
for r in memory_regions:
base, size = r['base'], r['size']
end = base + size
if base <= address < end:
return r
return None
def generate_resc(csr, args, flash_binaries={}, tftp_binaries={}): def generate_resc(csr, args, flash_binaries={}, tftp_binaries={}):
""" Generates platform definition. """ Generates platform definition.