Examples
The first example shows how to create and connect the AHB and APB bus controllers.
import AhbCtrl
import ApbCtrl
# Create two bus objects
object-create class=AhbCtrl name=ahbctrl0
object-create class=ApbCtrl name=apbctrl0
# Map to the normal addresses
memory-map memspace=mem0 addr=0x800ff000 length=0x1000 object=apbctrl0
memory-map memspace=mem0 addr=0xfffff000 length=0x1000 object=ahbctrl0
# Connect various APB devices to the APB controller
connect a=apbctrl0.slaves b=ftmctrl0:ApbIface
connect a=apbctrl0.slaves b=apbuart0:ApbIface
connect a=apbctrl0.slaves b=irqMp0:ApbIface
connect a=apbctrl0.slaves b=gpTimer0:ApbIface
connect a=apbctrl0.slaves b=ahbstat0:ApbIface
# Connect various AHB devices to the AHB controller
connect a=ahbctrl0.masters b=cpu0:AhbIface
connect a=ahbctrl0.slaves b=ftmctrl0:AhbIface
connect a=ahbctrl0.slaves b=apbctrl0:AhbIface
The next example shows how to implement a simple APB device.
#include "temu-c/Bus/Amba.h"
// This is the model type, we need to add the Pnp info.
typedef struct MyDevice {
temu_ApbPnpInfo Pnp;
// ...
} MyDevice;
// Implement the APB PNP interface
temu_ApbPnpInfo*
getApbPnp(void *Obj)
{
MyDevice *Dev = (MyDevice*)Obj;
return &Dev->Pnp;
}
temu_ApbIface ApbIface = {
.getApbPnp = getApbPnp
};
// Define functions to allocate and destroy the object
void*
create(int Argc, const temu_CreateArg *Argv)
{
MyDevice *Dev = malloc(sizeof(MyDevice));
memset(Dev, 0, sizeof(MyDevice));
// PNP init
temu_apbSetVendorId(&MyDevice->Pnp, 0x99);
temu_apbSetDeviceId(&MyDevice->Pnp, 0x001);
temu_apbSetVersion(&MyDevice->Pnp, 1);
temu_apbSetAddr(&MyDevice->Pnp, 0);
temu_apbSetCP(&MyDevice->Pnp, 0);
temu_apbSetMask(&MyDevice->Pnp, 0xfff);
temu_apbSetType(&MyDevice->Pnp, 1); // APB I/O space
return MyDevice;
}
void
dispose(void *Obj)
{
MyDevice *Dev = (MyDevice*)Obj;
free(Irq);
}
// Define the device interface
void
reset(void *Obj, int ResetKind)
{
}
void
mapDevice(void *Obj, uint64_t Addr, uint64_t Len)
{
MyDevice *Dev = (MyDevice*)Obj;
temu_apbSetAddr(&Dev->Pnp, Addr);
}
temu_DeviceIface DeviceIface = {
reset, // Called on resets
mapDevice, // Called when a device is mapped to a memory location.
};
TEMU_PLUGIN_INIT
{
temu_Class *cls = temu_registerClass("MyClass", create, dispose);
temu_addInterface(cls, "ApbIface", "ApbIface", &ApbIface);
temu_addInterface(cls, "DeviceIface", "DeviceIface", &DeviceIface);
}