1 Star 0 Fork 5

王国琨/plat-raspi

forked from TenonOS/plat-raspi 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
mbox.c 2.92 KB
一键复制 编辑 原始数据 按行查看 历史
李浩德 提交于 2024-06-12 18:46 . add mailbox
/*
* Copyright 2024 Hangzhou Yingyi Technology Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <raspi/mbox.h>
#include <uk/assert.h>
#include <uk/ofw/fdt.h>
#include <libfdt.h>
#include <stdarg.h>
/* mailbox message buffer */
static unsigned int __align(16) mbox[MBOX_BUFFER_LENGTH];
static uint64_t mbox_mem_addr;
static uint8_t mbox_initialized;
/* Macros to access Mailbox Registers with base address 'mbox_mem_addr'*/
#define MBOX_REG(r) ((uint32_t *)(mbox_mem_addr + (r)))
#define MBOX_REG_READ(r) ioreg_read32(MBOX_REG(r))
#define MBOX_REG_WRITE(r, v) ioreg_write32(MBOX_REG(r), v)
/*mbox full return true, else return false */
static inline bool mbox_full(void)
{
return (MBOX_REG_READ(MBOX_STATUS) & MBOX_FULL);
}
// /*mbox empty return true, else return false */
static inline bool mbox_empty(void)
{
return (MBOX_REG_READ(MBOX_STATUS) & MBOX_EMPTY);
}
/**
* Make a mailbox call. Returns 0 on failure, non-zero on success
*/
int mbox_call(unsigned char ch)
{
if (!mbox_initialized) {
UK_CRASH("MBOX not initialized!\n");
return -1;
}
/**
* The buffer mbox is 16-byte aligned
* only the upper 28 bits of the address
* can be passed via the mailbox. The last 4 bits
* take the lower 4 digits of the channel, also 16-byte aligned.
*/
unsigned int r = (((uint32_t)((uint64_t)&mbox)&~0xF) | (ch&0xF));
/* wait until we can write to the mailbox */
do {
asm volatile("nop");
} while (mbox_full());
MBOX_REG_WRITE(MBOX_WRITE, r);
barrier();
clean_and_invalidate_dcache_range(
(unsigned long)&mbox, MBOX_BUFFER_LENGTH*sizeof(mbox[0]));
/* now wait for the response */
do {
asm volatile("nop");
} while (mbox_empty() ||
r != MBOX_REG_READ(MBOX_READ) || mbox[1] == MBOX_REQUEST);
return mbox[1] == MBOX_RESPONSE_NORMAL;
}
void _libraspiplat_init_mbox(void *fdtp)
{
int mbox_offset, rc;
uint64_t addr, size;
mbox_offset = fdt_node_offset_by_compatible(fdtp, -1,
"brcm,bcm2835-mbox");
if (mbox_offset < 0)
UK_CRASH("No mailbox device found!\n");
rc = fdt_get_address(fdtp, mbox_offset, 0, &addr, &size);
if (rc < 0)
UK_CRASH("Could not find Mailbox address!\n");
mbox_mem_addr = addr;
mbox_initialized = 1;
}
void mbox_msg_create(int paras_num, ...)
{
va_list args;
va_start(args, paras_num);
for (int i = 0; i < paras_num && i < MBOX_BUFFER_LENGTH; ++i)
mbox[i] = va_arg(args, uint32_t);
va_end(args);
for (int i = paras_num; i < MBOX_BUFFER_LENGTH; ++i)
mbox[i] = 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wang-guo-kun/plat-raspi.git
git@gitee.com:wang-guo-kun/plat-raspi.git
wang-guo-kun
plat-raspi
plat-raspi
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385