Skip to content
Snippets Groups Projects
Commit e9fc74b5 authored by Simon Shields's avatar Simon Shields
Browse files

hardware_gen: support specifying size of kernel device

This allows for mapping of consecutive pages for a single device in the
kernel.
parent a5da502b
No related branches found
No related tags found
No related merge requests found
......@@ -139,7 +139,7 @@ class Offset:
return (self.base + self.offset) > (other.base + other.offset)
class Region:
def __init__(self, start, size, name, index=0):
def __init__(self, start, size, name, index=0, kaddr=0):
self.start = start
self.size = size
......@@ -149,13 +149,15 @@ class Region:
self.names = set(other.names)
self.index = other.index
self.kaddr = other.kaddr
self.kernel_size = other.kernel_size
self.kernel_var = other.kernel_var[:]
self.var_names = other.var_names[:]
else:
self.names = set()
self.names.add(name)
self.index = index
self.kaddr = 0
self.kaddr = kaddr
self.kernel_size = 0
self.kernel_var = []
self.var_names = []
self.user_macro = False
......@@ -461,6 +463,7 @@ class Config:
if 'kernel' in rule and rule['kernel'] != False:
region.kernel_var.append(Offset(rule['kernel'], 0, rule.get('macro', None)))
region.executeNever = rule['executeNever']
region.kernel_size = rule.get('kernel_size', 0)
region.user_macro = (not rule.get('user', False)) and 'macro' in rule
return region
......@@ -793,17 +796,24 @@ def output_regions(args, devices, memory, kernel, irqs, fp):
""" generate the device list for the C header file """
memory = sorted(memory, key=lambda a: a.start)
kernel = sorted(kernel, key=lambda a: a.start)
extra_kernel = []
addr = 0
macros = {}
# TODO: this will only map the first page of each device. That seems to be adequate for now,
# but in the future we may need more.
for reg in kernel:
reg.kaddr = addr
addr += 1 << args.page_bits
if reg.size > (1 << args.page_bits):
# print out a warning for now
logging.warning('Only mapping 0x%x bytes of 0x%x for kernel region at 0x%x (%s)'%
if reg.size > (1 << args.page_bits) and reg.kernel_size == 0x0:
# print out a warning if the region has more than one page and max size is not set
logging.warning('Only mapping 0x%x bytes of 0x%x for kernel region at 0x%x (%s), set "kernel_size" in YAML to silence'%
(1 << args.page_bits, reg.size, reg.start, ' '.join(sorted(reg.names))))
size = 1 << args.page_bits
while size < reg.kernel_size and size < reg.size:
extra_kernel.append(Region(reg.start + size, 1 << args.page_bits,
'above region continued...', kaddr=addr))
addr += 1 << args.page_bits
size += 1 << args.page_bits
for var in reg.kernel_var:
var.base = reg.kaddr
if var.base + var.offset in macros:
......@@ -812,6 +822,9 @@ def output_regions(args, devices, memory, kernel, irqs, fp):
continue
macros[var.base + var.offset] = var
reg.var_names = sorted(i.name for i in reg.kernel_var)
kernel += extra_kernel
kernel.sort(key=lambda a: a.start)
# make sure physBase is at least 16MB (supersection) aligned for the ELF loader's sake.
# TODO: this may need to be larger for aarch64. It seems to work OK on currently supported platforms though.
paddr = align_up(memory[0].start, 1 << args.phys_align)
......
......@@ -88,6 +88,13 @@ definitions:
kernel:
description: kernel macro used to access this region. If not present, region will not be mapped.
$ref: '#/definitions/macro'
kernel_size:
description: >
Maximum size of the region in the kernel.
This will map PAGE_ALIGN_UP(max(kernel_size, region_size)) bytes starting at the
device's base address into the kernel.
type: integer
default: 1 << PAGE_BITS
macro:
description: only map the region to the kernel if this macro is defined
$ref: '#/definitions/macro'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment