freertos: release the generic version source code
freertos runs on the second core (small one) of the CPU
This commit is contained in:
101
freertos/cvitek/driver/sys/src/devmem.c
Normal file
101
freertos/cvitek/driver/sys/src/devmem.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
** read/write phy addr in userspace
|
||||
** open /dev/mem
|
||||
** taiqiang.cao@bitmain.com
|
||||
*/
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
//#include <sys/types.h>
|
||||
//#include <sys/mman.h>
|
||||
#include "xil_types.h"
|
||||
#include <linux/mman.h>
|
||||
//#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
//#include <termios.h>
|
||||
#include <linux/termios.h>
|
||||
//#include <signal.h>
|
||||
#include "FreeRTOS_POSIX/signal.h"
|
||||
//#include <fcntl.h>
|
||||
#include <linux/fcntl.h>
|
||||
//#include <ctype.h>
|
||||
//#include <inttypes.h>
|
||||
#include "linux/confname.h"
|
||||
|
||||
#include "devmem.h"
|
||||
|
||||
int devm_open(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||||
if (fd == -1) {
|
||||
printf("cannot open '/dev/mem'\n");
|
||||
goto open_err;
|
||||
}
|
||||
|
||||
return fd;
|
||||
open_err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int devm_open_cached(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/mem", O_RDWR);
|
||||
if (fd == -1) {
|
||||
printf("cannot open '/dev/mem'\n");
|
||||
goto open_err;
|
||||
}
|
||||
|
||||
return fd;
|
||||
open_err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void devm_close(int fd)
|
||||
{
|
||||
if (fd)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void *devm_map(int fd, uint64_t phy_addr, size_t len)
|
||||
{
|
||||
off_t offset;
|
||||
void *map_base;
|
||||
uint32_t padding;
|
||||
|
||||
offset = phy_addr & ~(sysconf(_SC_PAGE_SIZE) - 1);
|
||||
padding = phy_addr - offset;
|
||||
|
||||
map_base = mmap(NULL, len + padding, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, offset);
|
||||
|
||||
if (map_base == MAP_FAILED) {
|
||||
perror("mmap failed\n");
|
||||
//poshiun
|
||||
// printf("phy_addr = %#"PRIx64", length = %zu\t, mapped memory length = %zu\t, pa_offset = %#"PRIx64"\n"
|
||||
// , phy_addr, len, len + padding, offset);
|
||||
printf("phy_addr = %#lx, length = %zu\t, mapped memory length = %zu\t, pa_offset = %lx\n"
|
||||
, phy_addr, len, len + padding, offset);
|
||||
goto mmap_err;
|
||||
}
|
||||
|
||||
return map_base + padding;
|
||||
|
||||
mmap_err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void devm_unmap(void *virt_addr, size_t len)
|
||||
{
|
||||
uint64_t addr;
|
||||
|
||||
/* page align */
|
||||
addr = (((uint64_t)(uintptr_t)virt_addr) & ~(sysconf(_SC_PAGE_SIZE) - 1));
|
||||
|
||||
munmap((void *)(uintptr_t)addr, len + (unsigned long) virt_addr - addr);
|
||||
}
|
||||
368
freertos/cvitek/driver/sys/src/hashmap.c
Normal file
368
freertos/cvitek/driver/sys/src/hashmap.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* 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 "hashmap.h"
|
||||
//#include <assert.h>
|
||||
#include <xil_assert.h>
|
||||
#include "FreeRTOS_POSIX.h"
|
||||
//#include <errno.h>
|
||||
#include "FreeRTOS_POSIX/errno.h"
|
||||
#include "FreeRTOS_POSIX/pthread.h"
|
||||
#include "malloc.h"
|
||||
|
||||
//#include <pthread.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#include <stdbool.h>
|
||||
//#include <sys/types.h>
|
||||
|
||||
Hashmap *hashmapCreate(size_t initialCapacity, int (*hash)(void *key), bool (*equals)(void *keyA, void *keyB))
|
||||
{
|
||||
assert(hash != NULL);
|
||||
assert(equals != NULL);
|
||||
|
||||
Hashmap *map = malloc(sizeof(Hashmap));
|
||||
// 0.75 load factor.
|
||||
size_t minimumBucketCount = initialCapacity * 4 / 3;
|
||||
|
||||
if (map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map->bucketCount = 1;
|
||||
while (map->bucketCount <= minimumBucketCount) {
|
||||
// Bucket count must be power of 2.
|
||||
map->bucketCount <<= 1;
|
||||
}
|
||||
map->buckets = calloc(map->bucketCount, sizeof(Entry *));
|
||||
if (map->buckets == NULL) {
|
||||
free(map);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map->size = 0;
|
||||
map->hash = hash;
|
||||
map->equals = equals;
|
||||
|
||||
pthread_mutex_init(&map->lock, NULL);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the given key.
|
||||
*/
|
||||
#ifdef __clang__
|
||||
__attribute__((no_sanitize("integer")))
|
||||
#endif
|
||||
static inline int hashKey(Hashmap *map, void *key)
|
||||
{
|
||||
int h = map->hash(key);
|
||||
|
||||
// We apply this secondary hashing discovered by Doug Lea to defend
|
||||
// against bad hashes.
|
||||
h += ~(h << 9);
|
||||
h ^= (((unsigned int)h) >> 14);
|
||||
h += (h << 4);
|
||||
h ^= (((unsigned int)h) >> 10);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
size_t hashmapSize(Hashmap *map)
|
||||
{
|
||||
return map->size;
|
||||
}
|
||||
|
||||
static inline size_t calculateIndex(size_t bucketCount, int hash)
|
||||
{
|
||||
return ((size_t)hash) & (bucketCount - 1);
|
||||
}
|
||||
|
||||
static void expandIfNecessary(Hashmap *map)
|
||||
{
|
||||
// If the load factor exceeds 0.75...
|
||||
if (map->size > (map->bucketCount * 3 / 4)) {
|
||||
// Start off with a 0.33 load factor.
|
||||
size_t newBucketCount = map->bucketCount << 1;
|
||||
Entry **newBuckets = calloc(newBucketCount, sizeof(Entry *));
|
||||
|
||||
if (newBuckets == NULL) {
|
||||
// Abort expansion.
|
||||
return;
|
||||
}
|
||||
|
||||
// Move over existing entries.
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->bucketCount; i++) {
|
||||
Entry *entry = map->buckets[i];
|
||||
|
||||
while (entry != NULL) {
|
||||
Entry *next = entry->next;
|
||||
size_t index = calculateIndex(newBucketCount, entry->hash);
|
||||
|
||||
entry->next = newBuckets[index];
|
||||
newBuckets[index] = entry;
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
// Copy over internals.
|
||||
free(map->buckets);
|
||||
map->buckets = newBuckets;
|
||||
map->bucketCount = newBucketCount;
|
||||
}
|
||||
}
|
||||
|
||||
void hashmapLock(Hashmap *map)
|
||||
{
|
||||
pthread_mutex_lock(&map->lock);
|
||||
}
|
||||
|
||||
void hashmapUnlock(Hashmap *map)
|
||||
{
|
||||
pthread_mutex_unlock(&map->lock);
|
||||
}
|
||||
|
||||
void hashmapFree(Hashmap *map)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->bucketCount; i++) {
|
||||
Entry *entry = map->buckets[i];
|
||||
|
||||
while (entry != NULL) {
|
||||
Entry *next = entry->next;
|
||||
|
||||
free(entry);
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
free(map->buckets);
|
||||
pthread_mutex_destroy(&map->lock);
|
||||
free(map);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
__attribute__((no_sanitize("integer")))
|
||||
#endif
|
||||
/* FIXME: relies on signed integer overflow, which is undefined behavior */
|
||||
int hashmapHash(void *key, size_t keySize)
|
||||
{
|
||||
int h = keySize;
|
||||
char *data = (char *)key;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < keySize; i++) {
|
||||
h = h * 31 + *data;
|
||||
data++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static Entry *createEntry(void *key, int hash, void *value)
|
||||
{
|
||||
Entry *entry = malloc(sizeof(Entry));
|
||||
|
||||
if (entry == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
entry->key = key;
|
||||
entry->hash = hash;
|
||||
entry->value = value;
|
||||
entry->next = NULL;
|
||||
return entry;
|
||||
}
|
||||
|
||||
static inline bool equalKeys(void *keyA, int hashA, void *keyB, int hashB, bool (*equals)(void *, void *))
|
||||
{
|
||||
if (keyA == keyB)
|
||||
return true;
|
||||
if (hashA != hashB)
|
||||
return false;
|
||||
return equals(keyA, keyB);
|
||||
}
|
||||
|
||||
void *hashmapPut(Hashmap *map, void *key, void *value)
|
||||
{
|
||||
int hash = hashKey(map, key);
|
||||
size_t index = calculateIndex(map->bucketCount, hash);
|
||||
Entry **p = &(map->buckets[index]);
|
||||
|
||||
while (true) {
|
||||
Entry *current = *p;
|
||||
|
||||
// Add a new entry.
|
||||
if (current == NULL) {
|
||||
*p = createEntry(key, hash, value);
|
||||
if (*p == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
map->size++;
|
||||
expandIfNecessary(map);
|
||||
return NULL;
|
||||
}
|
||||
// Replace existing entry.
|
||||
if (equalKeys(current->key, current->hash, key, hash, map->equals)) {
|
||||
void *oldValue = current->value;
|
||||
|
||||
current->value = value;
|
||||
return oldValue;
|
||||
}
|
||||
// Move to next entry.
|
||||
p = ¤t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void *hashmapGet(Hashmap *map, void *key)
|
||||
{
|
||||
int hash = hashKey(map, key);
|
||||
size_t index = calculateIndex(map->bucketCount, hash);
|
||||
Entry *entry = map->buckets[index];
|
||||
|
||||
while (entry != NULL) {
|
||||
if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) {
|
||||
return entry->value;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool hashmapContainsKey(Hashmap *map, void *key)
|
||||
{
|
||||
int hash = hashKey(map, key);
|
||||
size_t index = calculateIndex(map->bucketCount, hash);
|
||||
Entry *entry = map->buckets[index];
|
||||
|
||||
while (entry != NULL) {
|
||||
if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) {
|
||||
return true;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void *hashmapMemoize(Hashmap *map, void *key, void *(*initialValue)(void *key, void *context), void *context)
|
||||
{
|
||||
int hash = hashKey(map, key);
|
||||
size_t index = calculateIndex(map->bucketCount, hash);
|
||||
Entry **p = &(map->buckets[index]);
|
||||
|
||||
while (true) {
|
||||
Entry *current = *p;
|
||||
// Add a new entry.
|
||||
if (current == NULL) {
|
||||
*p = createEntry(key, hash, NULL);
|
||||
if (*p == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
void *value = initialValue(key, context);
|
||||
(*p)->value = value;
|
||||
map->size++;
|
||||
expandIfNecessary(map);
|
||||
return value;
|
||||
}
|
||||
// Return existing value.
|
||||
if (equalKeys(current->key, current->hash, key, hash, map->equals)) {
|
||||
return current->value;
|
||||
}
|
||||
// Move to next entry.
|
||||
p = ¤t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void *hashmapRemove(Hashmap *map, void *key)
|
||||
{
|
||||
int hash = hashKey(map, key);
|
||||
size_t index = calculateIndex(map->bucketCount, hash);
|
||||
// Pointer to the current entry.
|
||||
Entry **p = &(map->buckets[index]);
|
||||
Entry *current;
|
||||
|
||||
while ((current = *p) != NULL) {
|
||||
if (equalKeys(current->key, current->hash, key, hash, map->equals)) {
|
||||
void *value = current->value;
|
||||
*p = current->next;
|
||||
free(current);
|
||||
map->size--;
|
||||
return value;
|
||||
}
|
||||
p = ¤t->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hashmapForEach(Hashmap *map, bool (*callback)(void *key, void *value, void *context), void *context)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->bucketCount; i++) {
|
||||
Entry *entry = map->buckets[i];
|
||||
|
||||
while (entry != NULL) {
|
||||
Entry *next = entry->next;
|
||||
|
||||
if (!callback(entry->key, entry->value, context)) {
|
||||
return;
|
||||
}
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t hashmapCurrentCapacity(Hashmap *map)
|
||||
{
|
||||
size_t bucketCount = map->bucketCount;
|
||||
|
||||
return bucketCount * 3 / 4;
|
||||
}
|
||||
|
||||
size_t hashmapCountCollisions(Hashmap *map)
|
||||
{
|
||||
size_t collisions = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->bucketCount; i++) {
|
||||
Entry *entry = map->buckets[i];
|
||||
|
||||
while (entry != NULL) {
|
||||
if (entry->next != NULL) {
|
||||
collisions++;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
return collisions;
|
||||
}
|
||||
|
||||
int hashmapIntHash(void *key)
|
||||
{
|
||||
// Return the key value itself.
|
||||
return *((int *)key);
|
||||
}
|
||||
|
||||
bool hashmapIntEquals(void *keyA, void *keyB)
|
||||
{
|
||||
int a = *((int *)keyA);
|
||||
int b = *((int *)keyB);
|
||||
|
||||
return a == b;
|
||||
}
|
||||
Reference in New Issue
Block a user