Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example code to implement vSOC #6

Open
AlanOommen opened this issue Jul 18, 2024 · 5 comments
Open

Example code to implement vSOC #6

AlanOommen opened this issue Jul 18, 2024 · 5 comments

Comments

@AlanOommen
Copy link

How can we implement vSOC communication in Qbox? How should we configure the .lua file or any other files for the same? Can you provide an example code for the same taking two CPUs like cortex A53 and cortex A76?

@markfoodyburton
Copy link
Contributor

Depends how you want to connect externally, but if you use a UART, and want a serial channel, I suggest you look at the bidirectional flow socket, which might be an easy way to provide the sort of integration your looking for.

@AlanOommen
Copy link
Author

Can we implement it like this

-- Virtual platform configuration

function top()
local str = debug.getinfo(2, "S").source:sub(2)
if str:match("(./)")
then
return str:match("(.
/)")
else
return "./"
end
end

dofile(top().."../fw/utils.lua")
print("Lua config running...")

INITIAL_DDR_SPACE = 0x80000000

_KERNEL64_LOAD_ADDR = INITIAL_DDR_SPACE + 0x01200000
_DTB_LOAD_ADDR = INITIAL_DDR_SPACE + 0x07600000
_INITRD_LOAD_ADDR = INITIAL_DDR_SPACE + 0x0A800000

dofile(top().."fw/arm64_bootloader.lua")

local HEX_DIGITS = '0123456789ABCDEF'

local IPC_ROUTER_TOP = 0x00400000

local APSS_GIC600_GICD_APSS = 0x17A00000
local OFFSET_APSS_ALIAS0_GICR_CTLR = 0x60000

local UART0 = 0x10000000

local ARM_NUM_CPUS = 2
local NUM_GPUS = 0

local IS_SHARED_MEM = false

if ACCEL == nil then
ACCEL = "tcg"
end
print("Virtual acceleration: " .. ACCEL)

local ARCH_TIMER_VIRT_IRQ = 16 + 11
local ARCH_TIMER_S_EL1_IRQ = 16 + 13
local ARCH_TIMER_NS_EL1_IRQ = 16 + 14
local ARCH_TIMER_NS_EL2_IRQ = 16 + 10

local NUM_REDISTS = 1

platform = {

moduletype = "Container",

quantum_ns = 10000000,

router = {
    moduletype = "router",
    log_level = 0
},

ram_0 = {
    moduletype = "gs_memory",
    target_socket = {address = INITIAL_DDR_SPACE, size = 0x100000000, bind = "&router.initiator_socket"},
    log_level = 0,
    shared_memory = IS_SHARED_MEM
},

qemu_inst_mgr = {
    moduletype = "QemuInstanceManager"
},

qemu_inst = {
    moduletype = "QemuInstance",
    args = {"&platform.qemu_inst_mgr", "AARCH64"},
    accel = ACCEL,
    tcg_mode = "MULTI",
    sync_policy = "multithread-unconstrained"
},

gpex_0 = {
    moduletype = "qemu_gpex",
    args = {"&platform.qemu_inst"},
    bus_master = {bind = "&router.target_socket"},
    pio_iface = {address = 0x60200000, size = 0x0000100000, bind = "&router.initiator_socket"},
    mmio_iface = {address = 0x60300000, size = 0x001fd00000, bind = "&router.initiator_socket"},
    ecam_iface = {address = 0x43B50000, size = 0x0010000000, bind = "&router.initiator_socket"},
    mmio_iface_high = {address = 0x400000000, size = 0x200000000, bind = "&router.initiator_socket"},
    irq_out_0 = {bind = "&gic_0.spi_in_541"},
    irq_out_1 = {bind = "&gic_0.spi_in_542"},
    irq_out_2 = {bind = "&gic_0.spi_in_543"},
    irq_out_3 = {bind = "&gic_0.spi_in_544"}
},

gic_0 = {
    moduletype = "arm_gicv3",
    args = {"&platform.qemu_inst"},
    dist_iface = {address = APSS_GIC600_GICD_APSS, size = OFFSET_APSS_ALIAS0_GICR_CTLR, bind = "&router.initiator_socket"},
    redist_iface_0 = {address = APSS_GIC600_GICD_APSS + OFFSET_APSS_ALIAS0_GICR_CTLR, size = 0x1C0000, bind = "&router.initiator_socket"},
    num_cpus = ARM_NUM_CPUS,
    redist_region = {ARM_NUM_CPUS / NUM_REDISTS},
    num_spi = 960
},

virtionet0_0 = {
    moduletype = "virtio_mmio_net",
    args = {"&platform.qemu_inst"},
    mem = {address = 0x1c120000, size = 0x10000, bind = "&router.initiator_socket"},
    irq_out = {bind = "&gic_0.spi_in_18"},
    netdev_str = "type=user,hostfwd=tcp::2222-:22,hostfwd=tcp::2221-:21,hostfwd=tcp::56283-:56283,hostfwd=tcp::55534-:65534,hostfwd=tcp::55535-:65535"
},

virtioblk_0 = {
    moduletype = "virtio_mmio_blk",
    args = {"&platform.qemu_inst"},
    mem = {address = 0x1c0d0000, size = 0x2000, bind = "&router.initiator_socket"},
    irq_out = {bind = "&gic_0.spi_in_46"},
    blkdev_str = "file=" .. top() .. "fw/Artifacts/image_ext4.img" .. ",format=raw,if=none,readonly=off"
},

charbackend_stdio_0 = {
    moduletype = "char_backend_stdio",
    read_write = true
},

pl011_uart_0 = {
    moduletype = "Pl011",
    dylib_path = "uart-pl011",
    target_socket = {address = UART0, size = 0x1000, bind = "&router.initiator_socket"},
    irq = {bind = "&gic_0.spi_in_379"},
    backend_socket = {bind = "&charbackend_stdio_0.biflow_socket"}
},

global_peripheral_initiator_arm_0 = {
    moduletype = "global_peripheral_initiator",
    args = {"&platform.qemu_inst", "&platform.cpu_0"},
    global_initiator = {bind = "&router.target_socket"}
},

global_peripheral_initiator_arm_1 = {
    moduletype = "global_peripheral_initiator",
    args = {"&platform.qemu_inst", "&platform.cpu_1"},
    global_initiator = {bind = "&router.target_socket"}
},

fallback_0 = {
    moduletype = "gs_memory",
    target_socket = {address = 0x0, size = 0x800000000, bind = "&router.initiator_socket", priority = 1},
    dmi_allow = false,
    log_level = 0,
    shared_memory = IS_SHARED_MEM
},

load = {
    moduletype = "loader",
    initiator_socket = {bind = "&router.target_socket"},
    {bin_file = top() .. "fw/Artifacts/Image.bin", address = _KERNEL64_LOAD_ADDR},
    {bin_file = top() .. "fw/Artifacts/ubuntu.dtb", address = _DTB_LOAD_ADDR},
    {bin_file = top() .. "fw/Artifacts/image_ext4_initrd.img", address = _INITRD_LOAD_ADDR},
    {data = _bootloader_aarch64, address = INITIAL_DDR_SPACE}
}

}

print("kernel is loaded at: 0x" .. string.format("%x", _KERNEL64_LOAD_ADDR))
print("dtb is loaded at: 0x" .. string.format("%x", _DTB_LOAD_ADDR))
print("initrd is loaded at: 0x" .. string.format("%x", _INITRD_LOAD_ADDR))

if (ARM_NUM_CPUS > 0) then
local psci_conduit = "smc"
if ACCEL == "kvm" then
psci_conduit = "hvc"
end
print("PSCI conduit: " .. psci_conduit)
i = 1;
-- CPU 0: Cortex A53
local cpu_0 = {
moduletype = "cpu_arm_cortexA53",
args = {"&platform.qemu_inst"},
mem = {bind = "&router.target_socket"},
has_el3 = false,
has_el2 = false,
irq_timer_phys_out = {bind = "&gic_0.ppi_in_cpu_"..i..""..ARCH_TIMER_NS_EL1_IRQ},
irq_timer_virt_out = {bind = "&gic_0.ppi_in_cpu
"..i..""..ARCH_TIMER_VIRT_IRQ},
irq_timer_hyp_out = {bind = "&gic_0.ppi_in_cpu
"..i..""..ARCH_TIMER_NS_EL2_IRQ},
irq_timer_sec_out = {bind = "&gic_0.ppi_in_cpu
"..i.."_"..ARCH_TIMER_S_EL1_IRQ},
psci_conduit = psci_conduit,
mp_affinity = (math.floor(i / 8) << 8) | (i % 8),
start_powered_off = false,
rvbar = INITIAL_DDR_SPACE
}

i = 0;
-- CPU 1: Cortex A76
local cpu_1 = {
    moduletype = "cpu_arm_cortexA76",
    args = {"&platform.qemu_inst"},
    mem = {bind = "&router.target_socket"},
    has_el3 = false,
    has_el2 = false,
    irq_timer_phys_out = {bind = "&gic_0.ppi_in_cpu_"..i.."_"..ARCH_TIMER_NS_EL1_IRQ},
    irq_timer_virt_out = {bind = "&gic_0.ppi_in_cpu_"..i.."_"..ARCH_TIMER_VIRT_IRQ},
    irq_timer_hyp_out = {bind = "&gic_0.ppi_in_cpu_"..i.."_"..ARCH_TIMER_NS_EL2_IRQ},
    irq_timer_sec_out = {bind = "&gic_0.ppi_in_cpu_"..i.."_"..ARCH_TIMER_S_EL1_IRQ},
    gicv3_maintenance_interrupt = {bind = "&gic_0.ppi_in_cpu_"..i.."_25"},
    pmu_interrupt = {bind = "&gic_0.ppi_in_cpu_"..i.."_23"},
    psci_conduit = psci_conduit,
    mp_affinity = (math.floor(i / 4) << 16) | ((i % 4)<<8);
    start_powered_off = false,
    rvbar = INITIAL_DDR_SPACE
}
platform["cpu_1"] = cpu_0
platform["cpu_0"] = cpu_1 

i = 0;
platform["gic_0"]["irq_out_" .. i] = {bind="&cpu_"..i..".irq_in"}
platform["gic_0"]["fiq_out_" .. i] = {bind="&cpu_"..i..".fiq_in"}
platform["gic_0"]["virq_out_" .. i] = {bind="&cpu_"..i..".virq_in"}
platform["gic_0"]["vfiq_out_" .. i] = {bind="&cpu_"..i..".vfiq_in"}

i = 1;
platform["gic_0"]["irq_out_" .. i] = {bind="&cpu_"..i..".irq_in"}
platform["gic_0"]["fiq_out_" .. i] = {bind="&cpu_"..i..".fiq_in"}
platform["gic_0"]["virq_out_" .. i] = {bind="&cpu_"..i..".virq_in"}
platform["gic_0"]["vfiq_out_" .. i] = {bind="&cpu_"..i..".vfiq_in"}

end

print("Lua config done.")
?
Should we change the addresses of UART ports, gic etc? If there is any error can you give example code to correct it?

@markfoodyburton
Copy link
Contributor

I think the a76 is available, so that should work.

@AlanOommen
Copy link
Author

Screenshot 2024-07-18 141414
When I wrote the lua file and successfully after booting it. I tried lscpu to get the details of the cpu I am only getting Cortex A76

@markfoodyburton
Copy link
Contributor

in no particular order, you'll need a O/S ready to use an A76/a53, some device tree(s?), some boot code, which may or may not require EL3, so you will have to adjust your lua file accordingly, you'll probably have to fiddle with the affinity, I've probably forgotten many other things...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants