ARM: Add support for Versatile Express extended memory map

Also clean up how we create boot loader memory a bit.
This commit is contained in:
Ali Saidi 2012-03-01 17:26:31 -06:00
parent 3876105bdb
commit 91b737ed48
9 changed files with 130 additions and 29 deletions

View file

@ -252,6 +252,9 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
self.realview = RealViewEB() self.realview = RealViewEB()
elif machine_type == "VExpress_ELT": elif machine_type == "VExpress_ELT":
self.realview = VExpress_ELT() self.realview = VExpress_ELT()
elif machine_type == "VExpress_EMM":
self.realview = VExpress_EMM()
self.load_addr_mask = 0xffffffff
else: else:
print "Unknown Machine Type" print "Unknown Machine Type"
sys.exit(1) sys.exit(1)
@ -273,21 +276,17 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
else: else:
self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8') self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8')
self.machine_type = machine_type self.machine_type = machine_type
if convert.toMemorySize(mdesc.mem()) > convert.toMemorySize('256MB'): if convert.toMemorySize(mdesc.mem()) > self.realview.max_mem_size:
print "The currently implemented ARM platforms only easily support 256MB of DRAM" print "The currently selected ARM platforms doesn't support"
print "It might be possible to get some more by using 256MB@0x30000000, but this" print " the amount of DRAM you've selected. Please try"
print "is untested and may require some heroics" print " another platform"
boot_flags = 'earlyprintk console=ttyAMA0 lpj=19988480 norandmaps ' + \ boot_flags = 'earlyprintk console=ttyAMA0 lpj=19988480 norandmaps ' + \
'rw loglevel=8 mem=%s root=/dev/sda1' % mdesc.mem() 'rw loglevel=8 mem=%s root=/dev/sda1' % mdesc.mem()
self.physmem = PhysicalMemory(range = AddrRange(Addr(mdesc.mem())), self.physmem = PhysicalMemory(range = AddrRange(self.realview.mem_start_addr,
zero = True) size = mdesc.mem()))
self.nvmem = PhysicalMemory(range = AddrRange(Addr('2GB'), self.realview.setupBootLoader(self.membus, self, binary)
size = '64MB'), zero = True)
self.nvmem.port = self.membus.master
self.boot_loader = binary('boot.arm')
self.boot_loader_mem = self.nvmem
self.gic_cpu_addr = self.realview.gic.cpu_addr self.gic_cpu_addr = self.realview.gic.cpu_addr
self.flags_addr = self.realview.realview_io.pio_addr + 0x30 self.flags_addr = self.realview.realview_io.pio_addr + 0x30

View file

@ -159,12 +159,12 @@ if bm[0]:
else: else:
mem_size = SysConfig().mem() mem_size = SysConfig().mem()
if options.caches or options.l2cache: if options.caches or options.l2cache:
test_sys.iocache = IOCache(addr_range=mem_size) test_sys.iocache = IOCache(addr_range=test_sys.physmem.range)
test_sys.iocache.cpu_side = test_sys.iobus.master test_sys.iocache.cpu_side = test_sys.iobus.master
test_sys.iocache.mem_side = test_sys.membus.slave test_sys.iocache.mem_side = test_sys.membus.slave
else: else:
test_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns', test_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns',
ranges = [AddrRange(mem_size)]) ranges = [test_sys.physmem.range])
test_sys.iobridge.slave = test_sys.iobus.master test_sys.iobridge.slave = test_sys.iobus.master
test_sys.iobridge.master = test_sys.membus.slave test_sys.iobridge.master = test_sys.membus.slave
@ -195,7 +195,7 @@ if len(bm) == 2:
if options.kernel is not None: if options.kernel is not None:
drive_sys.kernel = binary(options.kernel) drive_sys.kernel = binary(options.kernel)
drive_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns', drive_sys.iobridge = Bridge(delay='50ns', nack_delay='4ns',
ranges = [AddrRange(bm[1].mem())]) ranges = [drive_sys.physmem.range])
drive_sys.iobridge.slave = drive_sys.iobus.master drive_sys.iobridge.slave = drive_sys.iobus.master
drive_sys.iobridge.master = drive_sys.membus.slave drive_sys.iobridge.master = drive_sys.membus.slave

View file

@ -43,7 +43,8 @@ class ArmMachineType(Enum):
map = {'RealView_EB' : 827, map = {'RealView_EB' : 827,
'RealView_PBX' : 1901, 'RealView_PBX' : 1901,
'VExpress_ELT' : 2272, 'VExpress_ELT' : 2272,
'VExpress_CA9' : 2272} 'VExpress_CA9' : 2272,
'VExpress_EMM' : 2272}
class ArmSystem(System): class ArmSystem(System):
type = 'ArmSystem' type = 'ArmSystem'
@ -65,5 +66,6 @@ class LinuxArmSystem(ArmSystem):
load_addr_mask = 0x0fffffff load_addr_mask = 0x0fffffff
machine_type = Param.ArmMachineType('RealView_PBX', machine_type = Param.ArmMachineType('RealView_PBX',
"Machine id from http://www.arm.linux.org.uk/developer/machines/") "Machine id from http://www.arm.linux.org.uk/developer/machines/")
atags_addr = Param.Addr(0x100, "Address where default atags structure should be written")

View file

@ -213,8 +213,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
"config registers and jumping to ThumbEE vectors\n"); "config registers and jumping to ThumbEE vectors\n");
return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
case MISCREG_ID_PFR1: case MISCREG_ID_PFR1:
warn("reading unimplmented register ID_PFR1"); return 0x00001; // !Timer | !Virti | !M Profile | !TrustZone | ARMv4
return 0;
case MISCREG_CTR: case MISCREG_CTR:
return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
case MISCREG_ACTLR: case MISCREG_ACTLR:

View file

@ -114,7 +114,7 @@ LinuxArmSystem::initState()
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2); DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
DDUMP(Loader, boot_data, size << 2); DDUMP(Loader, boot_data, size << 2);
physProxy.writeBlob(ParamsList, boot_data, size << 2); physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
#ifndef NDEBUG #ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
@ -154,7 +154,7 @@ LinuxArmSystem::initState()
for (int i = 0; i < threadContexts.size(); i++) { for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(0, 0); threadContexts[i]->setIntReg(0, 0);
threadContexts[i]->setIntReg(1, params()->machine_type); threadContexts[i]->setIntReg(1, params()->machine_type);
threadContexts[i]->setIntReg(2, ParamsList); threadContexts[i]->setIntReg(2, params()->atags_addr);
} }
} }

View file

@ -52,9 +52,6 @@
class LinuxArmSystem : public ArmSystem class LinuxArmSystem : public ArmSystem
{ {
protected:
static const int ParamsList = 0x100;
public: public:
/** Boilerplate params code */ /** Boilerplate params code */
typedef LinuxArmSystemParams Params; typedef LinuxArmSystemParams Params;

View file

@ -1,4 +1,4 @@
# Copyright (c) 2009-2011 ARM Limited # Copyright (c) 2009-2012 ARM Limited
# All rights reserved. # All rights reserved.
# #
# The license below extends only to copyright in the software and shall # The license below extends only to copyright in the software and shall
@ -49,6 +49,7 @@ from Ide import *
from Platform import Platform from Platform import Platform
from Terminal import Terminal from Terminal import Terminal
from Uart import Uart from Uart import Uart
from PhysicalMemory import *
class AmbaDevice(BasicPioDevice): class AmbaDevice(BasicPioDevice):
type = 'AmbaDevice' type = 'AmbaDevice'
@ -119,6 +120,11 @@ class CpuLocalTimer(BasicPioDevice):
int_num_watchdog = Param.UInt32("Interrupt number for per-cpu watchdog to GIC") int_num_watchdog = Param.UInt32("Interrupt number for per-cpu watchdog to GIC")
clock = Param.Clock('1GHz', "Clock speed at which the timer counts") clock = Param.Clock('1GHz', "Clock speed at which the timer counts")
class PL031(AmbaIntDevice):
type = 'PL031'
time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
amba_id = 0x00341031
class Pl050(AmbaIntDevice): class Pl050(AmbaIntDevice):
type = 'Pl050' type = 'Pl050'
vnc = Param.VncServer(Parent.any, "Vnc server for remote frame buffer display") vnc = Param.VncServer(Parent.any, "Vnc server for remote frame buffer display")
@ -136,6 +142,15 @@ class RealView(Platform):
type = 'RealView' type = 'RealView'
system = Param.System(Parent.any, "system") system = Param.System(Parent.any, "system")
pci_cfg_base = Param.Addr(0, "Base address of PCI Configuraiton Space") pci_cfg_base = Param.Addr(0, "Base address of PCI Configuraiton Space")
mem_start_addr = Param.Addr(0, "Start address of main memory")
max_mem_size = Param.Addr('256MB', "Maximum amount of RAM supported by platform")
def setupBootLoader(self, mem_bus, cur_sys, loc):
self.nvmem = PhysicalMemory(range = AddrRange(Addr('2GB'), size = '64MB'), zero = True)
self.nvmem.port = mem_bus.master
cur_sys.boot_loader = loc('boot.arm')
cur_sys.boot_loader_mem = self.nvmem
# Reference for memory map and interrupt number # Reference for memory map and interrupt number
# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A) # RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
@ -189,7 +204,9 @@ class RealViewPBX(RealView):
# (gic, l2x0, a9scu, local_cpu_timer) # (gic, l2x0, a9scu, local_cpu_timer)
bridge.ranges = [AddrRange(self.realview_io.pio_addr, bridge.ranges = [AddrRange(self.realview_io.pio_addr,
self.a9scu.pio_addr - 1), self.a9scu.pio_addr - 1),
AddrRange(self.flash_fake.pio_addr, Addr.max)] AddrRange(self.flash_fake.pio_addr,
self.flash_fake.pio_addr + \
self.flash_fake.pio_size - 1)]
# Attach I/O devices to specified bus object. Can't do this # Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the # earlier, since the bus object itself is typically defined at the
@ -300,6 +317,7 @@ class RealViewEB(RealView):
self.smcreg_fake.pio = bus.master self.smcreg_fake.pio = bus.master
class VExpress_ELT(RealView): class VExpress_ELT(RealView):
max_mem_size = '2GB'
pci_cfg_base = 0xD0000000 pci_cfg_base = 0xD0000000
elba_uart = Pl011(pio_addr=0xE0009000, int_num=42) elba_uart = Pl011(pio_addr=0xE0009000, int_num=42)
uart = Pl011(pio_addr=0xFF009000, int_num=121) uart = Pl011(pio_addr=0xFF009000, int_num=121)
@ -402,3 +420,84 @@ class VExpress_ELT(RealView):
self.lan_fake.pio = bus.master self.lan_fake.pio = bus.master
self.usb_fake.pio = bus.master self.usb_fake.pio = bus.master
class VExpress_EMM(RealView):
mem_start_addr = '2GB'
max_mem_size = '2GB'
uart = Pl011(pio_addr=0x1c090000, int_num=37)
realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000, pio_addr=0x1C010000)
gic = Gic(dist_addr=0x2C001000, cpu_addr=0x2C002000)
local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, pio_addr=0x2C080000)
timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='50MHz', clock1='50MHz')
timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='50MHz', clock1='50MHz')
clcd = Pl111(pio_addr=0x1c1f0000, int_num=46)
kmi0 = Pl050(pio_addr=0x1c060000, int_num=44)
kmi1 = Pl050(pio_addr=0x1c070000, int_num=45)
cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
io_shift = 2, ctrl_offset = 2, Command = 0x1,
BAR0 = 0x1C1A0000, BAR0Size = '256B',
BAR1 = 0x1C1A0100, BAR1Size = '4096B',
BAR0LegacyIO = True, BAR1LegacyIO = True)
vram = PhysicalMemory(range = AddrRange(0x18000000, size='32MB'), zero = True)
rtc = PL031(pio_addr=0x1C170000, int_num=36)
l2x0_fake = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
uart1_fake = AmbaFake(pio_addr=0x1C0A0000)
uart2_fake = AmbaFake(pio_addr=0x1C0B0000)
uart3_fake = AmbaFake(pio_addr=0x1C0C0000)
sp810_fake = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
watchdog_fake = AmbaFake(pio_addr=0x1C0F0000)
aaci_fake = AmbaFake(pio_addr=0x1C040000)
lan_fake = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
usb_fake = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
mmc_fake = AmbaFake(pio_addr=0x1c050000)
def setupBootLoader(self, mem_bus, cur_sys, loc):
self.nvmem = PhysicalMemory(range = AddrRange(0, size = '64MB'), zero = True)
self.nvmem.port = mem_bus.master
cur_sys.boot_loader = loc('boot_emm.arm')
cur_sys.boot_loader_mem = self.nvmem
cur_sys.atags_addr = 0x80000100
# Attach I/O devices that are on chip and also set the appropriate
# ranges for the bridge
def attachOnChipIO(self, bus, bridge):
self.gic.pio = bus.master
self.local_cpu_timer.pio = bus.master
# Bridge ranges based on excluding what is part of on-chip I/O
# (gic, a9scu)
bridge.ranges = [AddrRange(0x2F000000, size='16MB'),
AddrRange(0x30000000, size='256MB'),
AddrRange(0x40000000, size='512MB'),
AddrRange(0x18000000, size='64MB'),
AddrRange(0x1C000000, size='64MB')]
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
# System level.
def attachIO(self, bus):
self.uart.pio = bus.master
self.realview_io.pio = bus.master
self.timer0.pio = bus.master
self.timer1.pio = bus.master
self.clcd.pio = bus.master
self.clcd.dma = bus.slave
self.kmi0.pio = bus.master
self.kmi1.pio = bus.master
self.cf_ctrl.pio = bus.master
self.cf_ctrl.config = bus.master
self.rtc.pio = bus.master
bus.use_default_range = True
self.vram.port = bus.master
self.l2x0_fake.pio = bus.master
self.uart1_fake.pio = bus.master
self.uart2_fake.pio = bus.master
self.uart3_fake.pio = bus.master
self.sp810_fake.pio = bus.master
self.watchdog_fake.pio = bus.master
self.aaci_fake.pio = bus.master
self.lan_fake.pio = bus.master
self.usb_fake.pio = bus.master
self.mmc_fake.pio = bus.master

View file

@ -103,6 +103,8 @@ RealViewCtrl::read(PacketPtr pkt)
case IdReg: case IdReg:
pkt->set<uint32_t>(params()->idreg); pkt->set<uint32_t>(params()->idreg);
break; break;
case CfgStat:
pkt->set<uint32_t>(1);
default: default:
warn("Tried to read RealView I/O at offset %#x that doesn't exist\n", warn("Tried to read RealView I/O at offset %#x that doesn't exist\n",
daddr); daddr);

View file

@ -40,21 +40,24 @@
# Need to have CROSS_COMPILE set to /path/to/bin/arm-unknown-linux-gnu- # Need to have CROSS_COMPILE set to /path/to/bin/arm-unknown-linux-gnu-
# or have arm-unknown-linux-gnu in your path # or have arm-unknown-linux-gnu in your path
CROSS_COMPILE?=arm-none-linux-gnueabi- CROSS_COMPILE?=arm-linux-gnueabi-
CC=$(CROSS_COMPILE)gcc CC=$(CROSS_COMPILE)gcc
CPP=$(CROSS_COMPILE)g++ CPP=$(CROSS_COMPILE)g++
LD=$(CROSS_COMPILE)ld LD=$(CROSS_COMPILE)ld
all: boot.arm all: boot.arm boot_emm.arm
boot.o: simple.S boot.o: simple.S
$(CC) -mfloat-abi=softfp -march=armv7-a -fno-builtin -nostdinc -o boot.o -c simple.S $(CC) -mfloat-abi=softfp -march=armv7-a -fno-builtin -nostdinc -o $@ -c $<
boot.arm: boot.o boot.arm: boot.o
$(LD) -o boot.arm -N -Ttext 0x80000000 boot.o -non_shared -static $(LD) -o $@ -N -Ttext 0x80000000 $< -non_shared -static
boot_emm.arm: boot.o
$(LD) -o $@ -N -Ttext 0x00000010 $< -non_shared -static
clean: clean:
rm *.o boot.arm $(RM) -f *.o boot.arm boot_emm.arm
.PHONY: all clean