mirror of
https://github.com/gwenhael-le-moine/x49gp.git
synced 2024-12-25 21:58:49 +01:00
make code pretty (and consistent)
This commit is contained in:
parent
8e05de8737
commit
25a78e1ccc
49 changed files with 11790 additions and 13236 deletions
|
@ -5,32 +5,29 @@
|
||||||
#define _X49GP_BITMAP_FONT_H 1
|
#define _X49GP_BITMAP_FONT_H 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char* name;
|
||||||
int width;
|
int width;
|
||||||
int kern;
|
int kern;
|
||||||
int ascent;
|
int ascent;
|
||||||
int descent;
|
int descent;
|
||||||
const unsigned char *bits;
|
const unsigned char* bits;
|
||||||
} bitmap_glyph_t;
|
} bitmap_glyph_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ascent;
|
int ascent;
|
||||||
int descent;
|
int descent;
|
||||||
bitmap_glyph_t glyphs[];
|
bitmap_glyph_t glyphs[];
|
||||||
} bitmap_font_t;
|
} bitmap_font_t;
|
||||||
|
|
||||||
#define GLYPH(font, name) \
|
#define GLYPH( font, name ) \
|
||||||
{ \
|
{ #name, \
|
||||||
#name, \
|
font##_##name##_width - font##_##name##_x_hot, \
|
||||||
font##_##name##_width - font##_##name##_x_hot, \
|
-font##_##name##_x_hot, \
|
||||||
-font##_##name##_x_hot, \
|
font##_##name##_y_hot + 1, \
|
||||||
font##_##name##_y_hot + 1, \
|
font##_##name##_y_hot + 1 - font##_##name##_height, \
|
||||||
font##_##name##_y_hot + 1 - font##_##name##_height, \
|
font##_##name##_bits }
|
||||||
font##_##name##_bits \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SPACE(name, width, kern) \
|
#define SPACE( name, width, kern ) { name, width, kern, 0, 0, NULL }
|
||||||
{ name, width, kern, 0, 0, NULL }
|
|
||||||
|
|
||||||
extern const bitmap_font_t tiny_font;
|
extern const bitmap_font_t tiny_font;
|
||||||
|
|
||||||
|
|
506
src/block-qcow.c
506
src/block-qcow.c
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Block driver for the QCOW format
|
* Block driver for the QCOW format
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2006 Fabrice Bellard
|
* Copyright (c) 2004-2006 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
@ -26,19 +26,19 @@
|
||||||
#include "block_int.h"
|
#include "block_int.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#if 0
|
#if 0
|
||||||
#include "aes.h"
|
# include "aes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* QEMU COW block driver with compression and encryption support */
|
/* QEMU COW block driver with compression and encryption support */
|
||||||
|
|
||||||
#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
|
#define QCOW_MAGIC ( ( 'Q' << 24 ) | ( 'F' << 16 ) | ( 'I' << 8 ) | 0xfb )
|
||||||
#define QCOW_VERSION 1
|
#define QCOW_VERSION 1
|
||||||
|
|
||||||
#define QCOW_CRYPT_NONE 0
|
#define QCOW_CRYPT_NONE 0
|
||||||
#define QCOW_CRYPT_AES 1
|
#define QCOW_CRYPT_AES 1
|
||||||
|
|
||||||
#define QCOW_OFLAG_COMPRESSED (1LL << 63)
|
#define QCOW_OFLAG_COMPRESSED ( 1LL << 63 )
|
||||||
|
|
||||||
typedef struct QCowHeader {
|
typedef struct QCowHeader {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
@ -56,7 +56,7 @@ typedef struct QCowHeader {
|
||||||
#define L2_CACHE_SIZE 16
|
#define L2_CACHE_SIZE 16
|
||||||
|
|
||||||
typedef struct BDRVQcowState {
|
typedef struct BDRVQcowState {
|
||||||
BlockDriverState *hd;
|
BlockDriverState* hd;
|
||||||
int cluster_bits;
|
int cluster_bits;
|
||||||
int cluster_size;
|
int cluster_size;
|
||||||
int cluster_sectors;
|
int cluster_sectors;
|
||||||
|
@ -65,106 +65,104 @@ typedef struct BDRVQcowState {
|
||||||
int l1_size;
|
int l1_size;
|
||||||
uint64_t cluster_offset_mask;
|
uint64_t cluster_offset_mask;
|
||||||
uint64_t l1_table_offset;
|
uint64_t l1_table_offset;
|
||||||
uint64_t *l1_table;
|
uint64_t* l1_table;
|
||||||
uint64_t *l2_cache;
|
uint64_t* l2_cache;
|
||||||
uint64_t l2_cache_offsets[L2_CACHE_SIZE];
|
uint64_t l2_cache_offsets[ L2_CACHE_SIZE ];
|
||||||
uint32_t l2_cache_counts[L2_CACHE_SIZE];
|
uint32_t l2_cache_counts[ L2_CACHE_SIZE ];
|
||||||
uint8_t *cluster_cache;
|
uint8_t* cluster_cache;
|
||||||
uint8_t *cluster_data;
|
uint8_t* cluster_data;
|
||||||
uint64_t cluster_cache_offset;
|
uint64_t cluster_cache_offset;
|
||||||
} BDRVQcowState;
|
} BDRVQcowState;
|
||||||
|
|
||||||
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
|
static int decompress_cluster( BDRVQcowState* s, uint64_t cluster_offset );
|
||||||
|
|
||||||
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
|
static int qcow_probe( const uint8_t* buf, int buf_size, const char* filename )
|
||||||
{
|
{
|
||||||
const QCowHeader *cow_header = (const void *)buf;
|
const QCowHeader* cow_header = ( const void* )buf;
|
||||||
|
|
||||||
if (buf_size >= sizeof(QCowHeader) &&
|
if ( buf_size >= sizeof( QCowHeader ) && be32_to_cpu( cow_header->magic ) == QCOW_MAGIC &&
|
||||||
be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
|
be32_to_cpu( cow_header->version ) == QCOW_VERSION )
|
||||||
be32_to_cpu(cow_header->version) == QCOW_VERSION)
|
|
||||||
return 100;
|
return 100;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
|
static int qcow_open( BlockDriverState* bs, const char* filename, int flags )
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
int len, i, shift, ret;
|
int len, i, shift, ret;
|
||||||
QCowHeader header;
|
QCowHeader header;
|
||||||
|
|
||||||
ret = bdrv_file_open(&s->hd, filename, flags);
|
ret = bdrv_file_open( &s->hd, filename, flags );
|
||||||
if (ret < 0)
|
if ( ret < 0 )
|
||||||
return ret;
|
return ret;
|
||||||
if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
|
if ( bdrv_pread( s->hd, 0, &header, sizeof( header ) ) != sizeof( header ) )
|
||||||
goto fail;
|
goto fail;
|
||||||
be32_to_cpus(&header.magic);
|
be32_to_cpus( &header.magic );
|
||||||
be32_to_cpus(&header.version);
|
be32_to_cpus( &header.version );
|
||||||
be64_to_cpus(&header.backing_file_offset);
|
be64_to_cpus( &header.backing_file_offset );
|
||||||
be32_to_cpus(&header.backing_file_size);
|
be32_to_cpus( &header.backing_file_size );
|
||||||
be32_to_cpus(&header.mtime);
|
be32_to_cpus( &header.mtime );
|
||||||
be64_to_cpus(&header.size);
|
be64_to_cpus( &header.size );
|
||||||
be32_to_cpus(&header.crypt_method);
|
be32_to_cpus( &header.crypt_method );
|
||||||
be64_to_cpus(&header.l1_table_offset);
|
be64_to_cpus( &header.l1_table_offset );
|
||||||
|
|
||||||
if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
|
if ( header.magic != QCOW_MAGIC || header.version != QCOW_VERSION )
|
||||||
goto fail;
|
goto fail;
|
||||||
if (header.size <= 1 || header.cluster_bits < 9)
|
if ( header.size <= 1 || header.cluster_bits < 9 )
|
||||||
goto fail;
|
goto fail;
|
||||||
if (header.crypt_method > QCOW_CRYPT_AES)
|
if ( header.crypt_method > QCOW_CRYPT_AES )
|
||||||
goto fail;
|
goto fail;
|
||||||
s->cluster_bits = header.cluster_bits;
|
s->cluster_bits = header.cluster_bits;
|
||||||
s->cluster_size = 1 << s->cluster_bits;
|
s->cluster_size = 1 << s->cluster_bits;
|
||||||
s->cluster_sectors = 1 << (s->cluster_bits - 9);
|
s->cluster_sectors = 1 << ( s->cluster_bits - 9 );
|
||||||
s->l2_bits = header.l2_bits;
|
s->l2_bits = header.l2_bits;
|
||||||
s->l2_size = 1 << s->l2_bits;
|
s->l2_size = 1 << s->l2_bits;
|
||||||
bs->total_sectors = header.size / 512;
|
bs->total_sectors = header.size / 512;
|
||||||
s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
|
s->cluster_offset_mask = ( 1LL << ( 63 - s->cluster_bits ) ) - 1;
|
||||||
|
|
||||||
/* read the level 1 table */
|
/* read the level 1 table */
|
||||||
shift = s->cluster_bits + s->l2_bits;
|
shift = s->cluster_bits + s->l2_bits;
|
||||||
s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
|
s->l1_size = ( header.size + ( 1LL << shift ) - 1 ) >> shift;
|
||||||
|
|
||||||
s->l1_table_offset = header.l1_table_offset;
|
s->l1_table_offset = header.l1_table_offset;
|
||||||
s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
|
s->l1_table = qemu_malloc( s->l1_size * sizeof( uint64_t ) );
|
||||||
if (!s->l1_table)
|
if ( !s->l1_table )
|
||||||
goto fail;
|
goto fail;
|
||||||
if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
|
if ( bdrv_pread( s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof( uint64_t ) ) != s->l1_size * sizeof( uint64_t ) )
|
||||||
s->l1_size * sizeof(uint64_t))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
for(i = 0;i < s->l1_size; i++) {
|
for ( i = 0; i < s->l1_size; i++ ) {
|
||||||
be64_to_cpus(&s->l1_table[i]);
|
be64_to_cpus( &s->l1_table[ i ] );
|
||||||
}
|
}
|
||||||
/* alloc L2 cache */
|
/* alloc L2 cache */
|
||||||
s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
|
s->l2_cache = qemu_malloc( s->l2_size * L2_CACHE_SIZE * sizeof( uint64_t ) );
|
||||||
if (!s->l2_cache)
|
if ( !s->l2_cache )
|
||||||
goto fail;
|
goto fail;
|
||||||
s->cluster_cache = qemu_malloc(s->cluster_size);
|
s->cluster_cache = qemu_malloc( s->cluster_size );
|
||||||
if (!s->cluster_cache)
|
if ( !s->cluster_cache )
|
||||||
goto fail;
|
goto fail;
|
||||||
s->cluster_data = qemu_malloc(s->cluster_size);
|
s->cluster_data = qemu_malloc( s->cluster_size );
|
||||||
if (!s->cluster_data)
|
if ( !s->cluster_data )
|
||||||
goto fail;
|
goto fail;
|
||||||
s->cluster_cache_offset = -1;
|
s->cluster_cache_offset = -1;
|
||||||
|
|
||||||
/* read the backing file name */
|
/* read the backing file name */
|
||||||
if (header.backing_file_offset != 0) {
|
if ( header.backing_file_offset != 0 ) {
|
||||||
len = header.backing_file_size;
|
len = header.backing_file_size;
|
||||||
if (len > 1023)
|
if ( len > 1023 )
|
||||||
len = 1023;
|
len = 1023;
|
||||||
if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len)
|
if ( bdrv_pread( s->hd, header.backing_file_offset, bs->backing_file, len ) != len )
|
||||||
goto fail;
|
goto fail;
|
||||||
bs->backing_file[len] = '\0';
|
bs->backing_file[ len ] = '\0';
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
qemu_free(s->l1_table);
|
qemu_free( s->l1_table );
|
||||||
qemu_free(s->l2_cache);
|
qemu_free( s->l2_cache );
|
||||||
qemu_free(s->cluster_cache);
|
qemu_free( s->cluster_cache );
|
||||||
qemu_free(s->cluster_data);
|
qemu_free( s->cluster_data );
|
||||||
bdrv_delete(s->hd);
|
bdrv_delete( s->hd );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,174 +175,157 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
|
||||||
*
|
*
|
||||||
* 2 to allocate a compressed cluster of size
|
* 2 to allocate a compressed cluster of size
|
||||||
* 'compressed_size'. 'compressed_size' must be > 0 and <
|
* 'compressed_size'. 'compressed_size' must be > 0 and <
|
||||||
* cluster_size
|
* cluster_size
|
||||||
*
|
*
|
||||||
* return 0 if not allocated.
|
* return 0 if not allocated.
|
||||||
*/
|
*/
|
||||||
static uint64_t get_cluster_offset(BlockDriverState *bs,
|
static uint64_t get_cluster_offset( BlockDriverState* bs, uint64_t offset, int allocate, int compressed_size, int n_start, int n_end )
|
||||||
uint64_t offset, int allocate,
|
|
||||||
int compressed_size,
|
|
||||||
int n_start, int n_end)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
int min_index, i, j, l1_index, l2_index;
|
int min_index, i, j, l1_index, l2_index;
|
||||||
uint64_t l2_offset, *l2_table, cluster_offset, tmp;
|
uint64_t l2_offset, *l2_table, cluster_offset, tmp;
|
||||||
uint32_t min_count;
|
uint32_t min_count;
|
||||||
int new_l2_table;
|
int new_l2_table;
|
||||||
|
|
||||||
l1_index = offset >> (s->l2_bits + s->cluster_bits);
|
l1_index = offset >> ( s->l2_bits + s->cluster_bits );
|
||||||
l2_offset = s->l1_table[l1_index];
|
l2_offset = s->l1_table[ l1_index ];
|
||||||
new_l2_table = 0;
|
new_l2_table = 0;
|
||||||
if (!l2_offset) {
|
if ( !l2_offset ) {
|
||||||
if (!allocate)
|
if ( !allocate )
|
||||||
return 0;
|
return 0;
|
||||||
/* allocate a new l2 entry */
|
/* allocate a new l2 entry */
|
||||||
l2_offset = bdrv_getlength(s->hd);
|
l2_offset = bdrv_getlength( s->hd );
|
||||||
/* round to cluster size */
|
/* round to cluster size */
|
||||||
l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
|
l2_offset = ( l2_offset + s->cluster_size - 1 ) & ~( s->cluster_size - 1 );
|
||||||
/* update the L1 entry */
|
/* update the L1 entry */
|
||||||
s->l1_table[l1_index] = l2_offset;
|
s->l1_table[ l1_index ] = l2_offset;
|
||||||
tmp = cpu_to_be64(l2_offset);
|
tmp = cpu_to_be64( l2_offset );
|
||||||
if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
|
if ( bdrv_pwrite( s->hd, s->l1_table_offset + l1_index * sizeof( tmp ), &tmp, sizeof( tmp ) ) != sizeof( tmp ) )
|
||||||
&tmp, sizeof(tmp)) != sizeof(tmp))
|
|
||||||
return 0;
|
return 0;
|
||||||
new_l2_table = 1;
|
new_l2_table = 1;
|
||||||
}
|
}
|
||||||
for(i = 0; i < L2_CACHE_SIZE; i++) {
|
for ( i = 0; i < L2_CACHE_SIZE; i++ ) {
|
||||||
if (l2_offset == s->l2_cache_offsets[i]) {
|
if ( l2_offset == s->l2_cache_offsets[ i ] ) {
|
||||||
/* increment the hit count */
|
/* increment the hit count */
|
||||||
if (++s->l2_cache_counts[i] == 0xffffffff) {
|
if ( ++s->l2_cache_counts[ i ] == 0xffffffff ) {
|
||||||
for(j = 0; j < L2_CACHE_SIZE; j++) {
|
for ( j = 0; j < L2_CACHE_SIZE; j++ ) {
|
||||||
s->l2_cache_counts[j] >>= 1;
|
s->l2_cache_counts[ j ] >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l2_table = s->l2_cache + (i << s->l2_bits);
|
l2_table = s->l2_cache + ( i << s->l2_bits );
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* not found: load a new entry in the least used one */
|
/* not found: load a new entry in the least used one */
|
||||||
min_index = 0;
|
min_index = 0;
|
||||||
min_count = 0xffffffff;
|
min_count = 0xffffffff;
|
||||||
for(i = 0; i < L2_CACHE_SIZE; i++) {
|
for ( i = 0; i < L2_CACHE_SIZE; i++ ) {
|
||||||
if (s->l2_cache_counts[i] < min_count) {
|
if ( s->l2_cache_counts[ i ] < min_count ) {
|
||||||
min_count = s->l2_cache_counts[i];
|
min_count = s->l2_cache_counts[ i ];
|
||||||
min_index = i;
|
min_index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l2_table = s->l2_cache + (min_index << s->l2_bits);
|
l2_table = s->l2_cache + ( min_index << s->l2_bits );
|
||||||
if (new_l2_table) {
|
if ( new_l2_table ) {
|
||||||
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
|
memset( l2_table, 0, s->l2_size * sizeof( uint64_t ) );
|
||||||
if (bdrv_pwrite(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
|
if ( bdrv_pwrite( s->hd, l2_offset, l2_table, s->l2_size * sizeof( uint64_t ) ) != s->l2_size * sizeof( uint64_t ) )
|
||||||
s->l2_size * sizeof(uint64_t))
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
|
if ( bdrv_pread( s->hd, l2_offset, l2_table, s->l2_size * sizeof( uint64_t ) ) != s->l2_size * sizeof( uint64_t ) )
|
||||||
s->l2_size * sizeof(uint64_t))
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s->l2_cache_offsets[min_index] = l2_offset;
|
s->l2_cache_offsets[ min_index ] = l2_offset;
|
||||||
s->l2_cache_counts[min_index] = 1;
|
s->l2_cache_counts[ min_index ] = 1;
|
||||||
found:
|
found:
|
||||||
l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
|
l2_index = ( offset >> s->cluster_bits ) & ( s->l2_size - 1 );
|
||||||
cluster_offset = be64_to_cpu(l2_table[l2_index]);
|
cluster_offset = be64_to_cpu( l2_table[ l2_index ] );
|
||||||
if (!cluster_offset ||
|
if ( !cluster_offset || ( ( cluster_offset & QCOW_OFLAG_COMPRESSED ) && allocate == 1 ) ) {
|
||||||
((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
|
if ( !allocate )
|
||||||
if (!allocate)
|
|
||||||
return 0;
|
return 0;
|
||||||
/* allocate a new cluster */
|
/* allocate a new cluster */
|
||||||
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
|
if ( ( cluster_offset & QCOW_OFLAG_COMPRESSED ) && ( n_end - n_start ) < s->cluster_sectors ) {
|
||||||
(n_end - n_start) < s->cluster_sectors) {
|
|
||||||
/* if the cluster is already compressed, we must
|
/* if the cluster is already compressed, we must
|
||||||
decompress it in the case it is not completely
|
decompress it in the case it is not completely
|
||||||
overwritten */
|
overwritten */
|
||||||
if (decompress_cluster(s, cluster_offset) < 0)
|
if ( decompress_cluster( s, cluster_offset ) < 0 )
|
||||||
return 0;
|
return 0;
|
||||||
cluster_offset = bdrv_getlength(s->hd);
|
cluster_offset = bdrv_getlength( s->hd );
|
||||||
cluster_offset = (cluster_offset + s->cluster_size - 1) &
|
cluster_offset = ( cluster_offset + s->cluster_size - 1 ) & ~( s->cluster_size - 1 );
|
||||||
~(s->cluster_size - 1);
|
|
||||||
/* write the cluster content */
|
/* write the cluster content */
|
||||||
if (bdrv_pwrite(s->hd, cluster_offset, s->cluster_cache, s->cluster_size) !=
|
if ( bdrv_pwrite( s->hd, cluster_offset, s->cluster_cache, s->cluster_size ) != s->cluster_size )
|
||||||
s->cluster_size)
|
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
cluster_offset = bdrv_getlength(s->hd);
|
cluster_offset = bdrv_getlength( s->hd );
|
||||||
if (allocate == 1) {
|
if ( allocate == 1 ) {
|
||||||
/* round to cluster size */
|
/* round to cluster size */
|
||||||
cluster_offset = (cluster_offset + s->cluster_size - 1) &
|
cluster_offset = ( cluster_offset + s->cluster_size - 1 ) & ~( s->cluster_size - 1 );
|
||||||
~(s->cluster_size - 1);
|
bdrv_truncate( s->hd, cluster_offset + s->cluster_size );
|
||||||
bdrv_truncate(s->hd, cluster_offset + s->cluster_size);
|
|
||||||
} else {
|
} else {
|
||||||
cluster_offset |= QCOW_OFLAG_COMPRESSED |
|
cluster_offset |= QCOW_OFLAG_COMPRESSED | ( uint64_t )compressed_size << ( 63 - s->cluster_bits );
|
||||||
(uint64_t)compressed_size << (63 - s->cluster_bits);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* update L2 table */
|
/* update L2 table */
|
||||||
tmp = cpu_to_be64(cluster_offset);
|
tmp = cpu_to_be64( cluster_offset );
|
||||||
l2_table[l2_index] = tmp;
|
l2_table[ l2_index ] = tmp;
|
||||||
if (bdrv_pwrite(s->hd,
|
if ( bdrv_pwrite( s->hd, l2_offset + l2_index * sizeof( tmp ), &tmp, sizeof( tmp ) ) != sizeof( tmp ) )
|
||||||
l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cluster_offset;
|
return cluster_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
|
static int qcow_is_allocated( BlockDriverState* bs, int64_t sector_num, int nb_sectors, int* pnum )
|
||||||
int nb_sectors, int *pnum)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
int index_in_cluster, n;
|
int index_in_cluster, n;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
|
|
||||||
cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
|
cluster_offset = get_cluster_offset( bs, sector_num << 9, 0, 0, 0, 0 );
|
||||||
index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
index_in_cluster = sector_num & ( s->cluster_sectors - 1 );
|
||||||
n = s->cluster_sectors - index_in_cluster;
|
n = s->cluster_sectors - index_in_cluster;
|
||||||
if (n > nb_sectors)
|
if ( n > nb_sectors )
|
||||||
n = nb_sectors;
|
n = nb_sectors;
|
||||||
*pnum = n;
|
*pnum = n;
|
||||||
return (cluster_offset != 0);
|
return ( cluster_offset != 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
|
static int decompress_buffer( uint8_t* out_buf, int out_buf_size, const uint8_t* buf, int buf_size )
|
||||||
const uint8_t *buf, int buf_size)
|
|
||||||
{
|
{
|
||||||
z_stream strm1, *strm = &strm1;
|
z_stream strm1, *strm = &strm1;
|
||||||
int ret, out_len;
|
int ret, out_len;
|
||||||
|
|
||||||
memset(strm, 0, sizeof(*strm));
|
memset( strm, 0, sizeof( *strm ) );
|
||||||
|
|
||||||
strm->next_in = (uint8_t *)buf;
|
strm->next_in = ( uint8_t* )buf;
|
||||||
strm->avail_in = buf_size;
|
strm->avail_in = buf_size;
|
||||||
strm->next_out = out_buf;
|
strm->next_out = out_buf;
|
||||||
strm->avail_out = out_buf_size;
|
strm->avail_out = out_buf_size;
|
||||||
|
|
||||||
ret = inflateInit2(strm, -12);
|
ret = inflateInit2( strm, -12 );
|
||||||
if (ret != Z_OK)
|
if ( ret != Z_OK )
|
||||||
return -1;
|
return -1;
|
||||||
ret = inflate(strm, Z_FINISH);
|
ret = inflate( strm, Z_FINISH );
|
||||||
out_len = strm->next_out - out_buf;
|
out_len = strm->next_out - out_buf;
|
||||||
if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
|
if ( ( ret != Z_STREAM_END && ret != Z_BUF_ERROR ) || out_len != out_buf_size ) {
|
||||||
out_len != out_buf_size) {
|
inflateEnd( strm );
|
||||||
inflateEnd(strm);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
inflateEnd(strm);
|
inflateEnd( strm );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
|
static int decompress_cluster( BDRVQcowState* s, uint64_t cluster_offset )
|
||||||
{
|
{
|
||||||
int ret, csize;
|
int ret, csize;
|
||||||
uint64_t coffset;
|
uint64_t coffset;
|
||||||
|
|
||||||
coffset = cluster_offset & s->cluster_offset_mask;
|
coffset = cluster_offset & s->cluster_offset_mask;
|
||||||
if (s->cluster_cache_offset != coffset) {
|
if ( s->cluster_cache_offset != coffset ) {
|
||||||
csize = cluster_offset >> (63 - s->cluster_bits);
|
csize = cluster_offset >> ( 63 - s->cluster_bits );
|
||||||
csize &= (s->cluster_size - 1);
|
csize &= ( s->cluster_size - 1 );
|
||||||
ret = bdrv_pread(s->hd, coffset, s->cluster_data, csize);
|
ret = bdrv_pread( s->hd, coffset, s->cluster_data, csize );
|
||||||
if (ret != csize)
|
if ( ret != csize )
|
||||||
return -1;
|
return -1;
|
||||||
if (decompress_buffer(s->cluster_cache, s->cluster_size,
|
if ( decompress_buffer( s->cluster_cache, s->cluster_size, s->cluster_data, csize ) < 0 ) {
|
||||||
s->cluster_data, csize) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
s->cluster_cache_offset = coffset;
|
s->cluster_cache_offset = coffset;
|
||||||
|
@ -352,35 +333,34 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_read(BlockDriverState *bs, int64_t sector_num,
|
static int qcow_read( BlockDriverState* bs, int64_t sector_num, uint8_t* buf, int nb_sectors )
|
||||||
uint8_t *buf, int nb_sectors)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
int ret, index_in_cluster, n;
|
int ret, index_in_cluster, n;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
|
|
||||||
while (nb_sectors > 0) {
|
while ( nb_sectors > 0 ) {
|
||||||
cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
|
cluster_offset = get_cluster_offset( bs, sector_num << 9, 0, 0, 0, 0 );
|
||||||
index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
index_in_cluster = sector_num & ( s->cluster_sectors - 1 );
|
||||||
n = s->cluster_sectors - index_in_cluster;
|
n = s->cluster_sectors - index_in_cluster;
|
||||||
if (n > nb_sectors)
|
if ( n > nb_sectors )
|
||||||
n = nb_sectors;
|
n = nb_sectors;
|
||||||
if (!cluster_offset) {
|
if ( !cluster_offset ) {
|
||||||
if (bs->backing_hd) {
|
if ( bs->backing_hd ) {
|
||||||
/* read from the base image */
|
/* read from the base image */
|
||||||
ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
|
ret = bdrv_read( bs->backing_hd, sector_num, buf, n );
|
||||||
if (ret < 0)
|
if ( ret < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
memset(buf, 0, 512 * n);
|
memset( buf, 0, 512 * n );
|
||||||
}
|
}
|
||||||
} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
|
} else if ( cluster_offset & QCOW_OFLAG_COMPRESSED ) {
|
||||||
if (decompress_cluster(s, cluster_offset) < 0)
|
if ( decompress_cluster( s, cluster_offset ) < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
|
memcpy( buf, s->cluster_cache + index_in_cluster * 512, 512 * n );
|
||||||
} else {
|
} else {
|
||||||
ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
|
ret = bdrv_pread( s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512 );
|
||||||
if (ret != n * 512)
|
if ( ret != n * 512 )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nb_sectors -= n;
|
nb_sectors -= n;
|
||||||
|
@ -390,27 +370,24 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_write(BlockDriverState *bs, int64_t sector_num,
|
static int qcow_write( BlockDriverState* bs, int64_t sector_num, const uint8_t* buf, int nb_sectors )
|
||||||
const uint8_t *buf, int nb_sectors)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
int ret, index_in_cluster, n;
|
int ret, index_in_cluster, n;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
|
|
||||||
while (nb_sectors > 0) {
|
while ( nb_sectors > 0 ) {
|
||||||
index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
index_in_cluster = sector_num & ( s->cluster_sectors - 1 );
|
||||||
n = s->cluster_sectors - index_in_cluster;
|
n = s->cluster_sectors - index_in_cluster;
|
||||||
if (n > nb_sectors)
|
if ( n > nb_sectors )
|
||||||
n = nb_sectors;
|
n = nb_sectors;
|
||||||
cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
|
cluster_offset = get_cluster_offset( bs, sector_num << 9, 1, 0, index_in_cluster, index_in_cluster + n );
|
||||||
index_in_cluster,
|
if ( !cluster_offset )
|
||||||
index_in_cluster + n);
|
|
||||||
if (!cluster_offset)
|
|
||||||
return -1;
|
return -1;
|
||||||
{
|
{
|
||||||
ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
|
ret = bdrv_pwrite( s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512 );
|
||||||
}
|
}
|
||||||
if (ret != n * 512)
|
if ( ret != n * 512 )
|
||||||
return -1;
|
return -1;
|
||||||
nb_sectors -= n;
|
nb_sectors -= n;
|
||||||
sector_num += n;
|
sector_num += n;
|
||||||
|
@ -420,76 +397,75 @@ static int qcow_write(BlockDriverState *bs, int64_t sector_num,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qcow_close(BlockDriverState *bs)
|
static void qcow_close( BlockDriverState* bs )
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
qemu_free(s->l1_table);
|
qemu_free( s->l1_table );
|
||||||
qemu_free(s->l2_cache);
|
qemu_free( s->l2_cache );
|
||||||
qemu_free(s->cluster_cache);
|
qemu_free( s->cluster_cache );
|
||||||
qemu_free(s->cluster_data);
|
qemu_free( s->cluster_data );
|
||||||
bdrv_delete(s->hd);
|
bdrv_delete( s->hd );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_create(const char *filename, int64_t total_size,
|
static int qcow_create( const char* filename, int64_t total_size, const char* backing_file, int flags )
|
||||||
const char *backing_file, int flags)
|
|
||||||
{
|
{
|
||||||
int fd, header_size, backing_filename_len, l1_size, i, shift;
|
int fd, header_size, backing_filename_len, l1_size, i, shift;
|
||||||
QCowHeader header;
|
QCowHeader header;
|
||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
fd = open( filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644 );
|
||||||
if (fd < 0)
|
if ( fd < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
memset(&header, 0, sizeof(header));
|
memset( &header, 0, sizeof( header ) );
|
||||||
header.magic = cpu_to_be32(QCOW_MAGIC);
|
header.magic = cpu_to_be32( QCOW_MAGIC );
|
||||||
header.version = cpu_to_be32(QCOW_VERSION);
|
header.version = cpu_to_be32( QCOW_VERSION );
|
||||||
header.size = cpu_to_be64(total_size * 512);
|
header.size = cpu_to_be64( total_size * 512 );
|
||||||
header_size = sizeof(header);
|
header_size = sizeof( header );
|
||||||
backing_filename_len = 0;
|
backing_filename_len = 0;
|
||||||
if (backing_file) {
|
if ( backing_file ) {
|
||||||
header.backing_file_offset = cpu_to_be64(header_size);
|
header.backing_file_offset = cpu_to_be64( header_size );
|
||||||
backing_filename_len = strlen(backing_file);
|
backing_filename_len = strlen( backing_file );
|
||||||
header.backing_file_size = cpu_to_be32(backing_filename_len);
|
header.backing_file_size = cpu_to_be32( backing_filename_len );
|
||||||
header_size += backing_filename_len;
|
header_size += backing_filename_len;
|
||||||
header.mtime = cpu_to_be32(0);
|
header.mtime = cpu_to_be32( 0 );
|
||||||
header.cluster_bits = 9; /* 512 byte cluster to avoid copying
|
header.cluster_bits = 9; /* 512 byte cluster to avoid copying
|
||||||
unmodifyed sectors */
|
unmodifyed sectors */
|
||||||
header.l2_bits = 12; /* 32 KB L2 tables */
|
header.l2_bits = 12; /* 32 KB L2 tables */
|
||||||
} else {
|
} else {
|
||||||
header.cluster_bits = 12; /* 4 KB clusters */
|
header.cluster_bits = 12; /* 4 KB clusters */
|
||||||
header.l2_bits = 9; /* 4 KB L2 tables */
|
header.l2_bits = 9; /* 4 KB L2 tables */
|
||||||
}
|
}
|
||||||
header_size = (header_size + 7) & ~7;
|
header_size = ( header_size + 7 ) & ~7;
|
||||||
shift = header.cluster_bits + header.l2_bits;
|
shift = header.cluster_bits + header.l2_bits;
|
||||||
l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
|
l1_size = ( ( total_size * 512 ) + ( 1LL << shift ) - 1 ) >> shift;
|
||||||
|
|
||||||
header.l1_table_offset = cpu_to_be64(header_size);
|
header.l1_table_offset = cpu_to_be64( header_size );
|
||||||
if (flags) {
|
if ( flags ) {
|
||||||
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
|
header.crypt_method = cpu_to_be32( QCOW_CRYPT_AES );
|
||||||
} else {
|
} else {
|
||||||
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
|
header.crypt_method = cpu_to_be32( QCOW_CRYPT_NONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write all the data */
|
/* write all the data */
|
||||||
ret = write(fd, &header, sizeof(header));
|
ret = write( fd, &header, sizeof( header ) );
|
||||||
if (ret != sizeof(header)) {
|
if ( ret != sizeof( header ) ) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backing_file) {
|
if ( backing_file ) {
|
||||||
ret = write(fd, backing_file, backing_filename_len);
|
ret = write( fd, backing_file, backing_filename_len );
|
||||||
if (ret != backing_filename_len) {
|
if ( ret != backing_filename_len ) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lseek(fd, header_size, SEEK_SET);
|
lseek( fd, header_size, SEEK_SET );
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
for(i = 0;i < l1_size; i++) {
|
for ( i = 0; i < l1_size; i++ ) {
|
||||||
ret = write(fd, &tmp, sizeof(tmp));
|
ret = write( fd, &tmp, sizeof( tmp ) );
|
||||||
if (ret != sizeof(tmp)) {
|
if ( ret != sizeof( tmp ) ) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -497,106 +473,102 @@ static int qcow_create(const char *filename, int64_t total_size,
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
exit:
|
exit:
|
||||||
close(fd);
|
close( fd );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_make_empty(BlockDriverState *bs)
|
static int qcow_make_empty( BlockDriverState* bs )
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
uint32_t l1_length = s->l1_size * sizeof(uint64_t);
|
uint32_t l1_length = s->l1_size * sizeof( uint64_t );
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(s->l1_table, 0, l1_length);
|
memset( s->l1_table, 0, l1_length );
|
||||||
if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table, l1_length) < 0)
|
if ( bdrv_pwrite( s->hd, s->l1_table_offset, s->l1_table, l1_length ) < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
|
ret = bdrv_truncate( s->hd, s->l1_table_offset + l1_length );
|
||||||
if (ret < 0)
|
if ( ret < 0 )
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
|
memset( s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof( uint64_t ) );
|
||||||
memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
|
memset( s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof( uint64_t ) );
|
||||||
memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
|
memset( s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof( uint32_t ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: put compressed sectors first, then all the cluster aligned
|
/* XXX: put compressed sectors first, then all the cluster aligned
|
||||||
tables to avoid losing bytes in alignment */
|
tables to avoid losing bytes in alignment */
|
||||||
static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
static int qcow_write_compressed( BlockDriverState* bs, int64_t sector_num, const uint8_t* buf, int nb_sectors )
|
||||||
const uint8_t *buf, int nb_sectors)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
z_stream strm;
|
z_stream strm;
|
||||||
int ret, out_len;
|
int ret, out_len;
|
||||||
uint8_t *out_buf;
|
uint8_t* out_buf;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
|
|
||||||
if (nb_sectors != s->cluster_sectors)
|
if ( nb_sectors != s->cluster_sectors )
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
|
out_buf = qemu_malloc( s->cluster_size + ( s->cluster_size / 1000 ) + 128 );
|
||||||
if (!out_buf)
|
if ( !out_buf )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* best compression, small window, no zlib header */
|
/* best compression, small window, no zlib header */
|
||||||
memset(&strm, 0, sizeof(strm));
|
memset( &strm, 0, sizeof( strm ) );
|
||||||
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
|
ret = deflateInit2( &strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY );
|
||||||
Z_DEFLATED, -12,
|
if ( ret != 0 ) {
|
||||||
9, Z_DEFAULT_STRATEGY);
|
qemu_free( out_buf );
|
||||||
if (ret != 0) {
|
|
||||||
qemu_free(out_buf);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strm.avail_in = s->cluster_size;
|
strm.avail_in = s->cluster_size;
|
||||||
strm.next_in = (uint8_t *)buf;
|
strm.next_in = ( uint8_t* )buf;
|
||||||
strm.avail_out = s->cluster_size;
|
strm.avail_out = s->cluster_size;
|
||||||
strm.next_out = out_buf;
|
strm.next_out = out_buf;
|
||||||
|
|
||||||
ret = deflate(&strm, Z_FINISH);
|
ret = deflate( &strm, Z_FINISH );
|
||||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
if ( ret != Z_STREAM_END && ret != Z_OK ) {
|
||||||
qemu_free(out_buf);
|
qemu_free( out_buf );
|
||||||
deflateEnd(&strm);
|
deflateEnd( &strm );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out_len = strm.next_out - out_buf;
|
out_len = strm.next_out - out_buf;
|
||||||
|
|
||||||
deflateEnd(&strm);
|
deflateEnd( &strm );
|
||||||
|
|
||||||
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
|
if ( ret != Z_STREAM_END || out_len >= s->cluster_size ) {
|
||||||
/* could not compress: write normal cluster */
|
/* could not compress: write normal cluster */
|
||||||
qcow_write(bs, sector_num, buf, s->cluster_sectors);
|
qcow_write( bs, sector_num, buf, s->cluster_sectors );
|
||||||
} else {
|
} else {
|
||||||
cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
|
cluster_offset = get_cluster_offset( bs, sector_num << 9, 2, out_len, 0, 0 );
|
||||||
out_len, 0, 0);
|
|
||||||
cluster_offset &= s->cluster_offset_mask;
|
cluster_offset &= s->cluster_offset_mask;
|
||||||
if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
|
if ( bdrv_pwrite( s->hd, cluster_offset, out_buf, out_len ) != out_len ) {
|
||||||
qemu_free(out_buf);
|
qemu_free( out_buf );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_free(out_buf);
|
qemu_free( out_buf );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qcow_flush(BlockDriverState *bs)
|
static void qcow_flush( BlockDriverState* bs )
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
bdrv_flush(s->hd);
|
bdrv_flush( s->hd );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
static int qcow_get_info( BlockDriverState* bs, BlockDriverInfo* bdi )
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState* s = bs->opaque;
|
||||||
bdi->cluster_size = s->cluster_size;
|
bdi->cluster_size = s->cluster_size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDriver bdrv_qcow = {
|
BlockDriver bdrv_qcow = {
|
||||||
"qcow",
|
"qcow",
|
||||||
sizeof(BDRVQcowState),
|
sizeof( BDRVQcowState ),
|
||||||
qcow_probe,
|
qcow_probe,
|
||||||
qcow_open,
|
qcow_open,
|
||||||
qcow_read,
|
qcow_read,
|
||||||
|
|
744
src/block-raw.c
744
src/block-raw.c
File diff suppressed because it is too large
Load diff
3599
src/block-vvfat.c
3599
src/block-vvfat.c
File diff suppressed because it is too large
Load diff
913
src/block.c
913
src/block.c
File diff suppressed because it is too large
Load diff
67
src/block.h
67
src/block.h
|
@ -6,65 +6,62 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define BDRV_O_RDONLY 0x0000
|
#define BDRV_O_RDONLY 0x0000
|
||||||
#define BDRV_O_RDWR 0x0002
|
#define BDRV_O_RDWR 0x0002
|
||||||
#define BDRV_O_ACCESS 0x0003
|
#define BDRV_O_ACCESS 0x0003
|
||||||
#define BDRV_O_CREAT 0x0004 /* create an empty file */
|
#define BDRV_O_CREAT 0x0004 /* create an empty file */
|
||||||
#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save
|
#define BDRV_O_SNAPSHOT \
|
||||||
writes in a snapshot */
|
0x0008 /* open the file read only and save \
|
||||||
#define BDRV_O_FILE 0x0010 /* open as a raw file (do not try to
|
writes in a snapshot */
|
||||||
use a disk image format on top of
|
#define BDRV_O_FILE \
|
||||||
it (default for
|
0x0010 /* open as a raw file (do not try to \
|
||||||
bdrv_file_open()) */
|
use a disk image format on top of \
|
||||||
|
it (default for \
|
||||||
|
bdrv_file_open()) */
|
||||||
|
|
||||||
typedef struct BlockDriver BlockDriver;
|
typedef struct BlockDriver BlockDriver;
|
||||||
typedef struct SnapshotInfo QEMUSnapshotInfo;
|
typedef struct SnapshotInfo QEMUSnapshotInfo;
|
||||||
typedef struct BlockDriverInfo BlockDriverInfo;
|
typedef struct BlockDriverInfo BlockDriverInfo;
|
||||||
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
|
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
|
||||||
typedef void BlockDriverCompletionFunc(void *opaque, int ret);
|
typedef void BlockDriverCompletionFunc( void* opaque, int ret );
|
||||||
|
|
||||||
extern BlockDriver bdrv_raw;
|
extern BlockDriver bdrv_raw;
|
||||||
extern BlockDriver bdrv_host_device;
|
extern BlockDriver bdrv_host_device;
|
||||||
extern BlockDriver bdrv_qcow;
|
extern BlockDriver bdrv_qcow;
|
||||||
extern BlockDriver bdrv_vvfat;
|
extern BlockDriver bdrv_vvfat;
|
||||||
|
|
||||||
void bdrv_init(void);
|
void bdrv_init( void );
|
||||||
int bdrv_create(BlockDriver *drv,
|
int bdrv_create( BlockDriver* drv, const char* filename, int64_t size_in_sectors, const char* backing_file, int flags );
|
||||||
const char *filename, int64_t size_in_sectors,
|
BlockDriverState* bdrv_new( const char* device_name );
|
||||||
const char *backing_file, int flags);
|
void bdrv_delete( BlockDriverState* bs );
|
||||||
BlockDriverState *bdrv_new(const char *device_name);
|
int bdrv_file_open( BlockDriverState** pbs, const char* filename, int flags );
|
||||||
void bdrv_delete(BlockDriverState *bs);
|
int bdrv_open( BlockDriverState* bs, const char* filename, int flags );
|
||||||
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
|
|
||||||
int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
|
|
||||||
|
|
||||||
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
|
int bdrv_read( BlockDriverState* bs, int64_t sector_num, uint8_t* buf, int nb_sectors );
|
||||||
uint8_t *buf, int nb_sectors);
|
int bdrv_pread( BlockDriverState* bs, int64_t offset, void* buf, int count );
|
||||||
int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
int bdrv_pwrite( BlockDriverState* bs, int64_t offset, const void* buf, int count );
|
||||||
void *buf, int count);
|
|
||||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
|
||||||
const void *buf, int count);
|
|
||||||
|
|
||||||
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
int bdrv_truncate( BlockDriverState* bs, int64_t offset );
|
||||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
int64_t bdrv_getlength( BlockDriverState* bs );
|
||||||
void bdrv_flush(BlockDriverState *bs);
|
void bdrv_flush( BlockDriverState* bs );
|
||||||
|
|
||||||
/* timers */
|
/* timers */
|
||||||
|
|
||||||
typedef struct QEMUClock QEMUClock;
|
typedef struct QEMUClock QEMUClock;
|
||||||
typedef void QEMUTimerCB(void *opaque);
|
typedef void QEMUTimerCB( void* opaque );
|
||||||
|
|
||||||
/* The real time clock should be used only for stuff which does not
|
/* The real time clock should be used only for stuff which does not
|
||||||
change the virtual machine state, as it is run even if the virtual
|
change the virtual machine state, as it is run even if the virtual
|
||||||
machine is stopped. The real time clock has a frequency of 1000
|
machine is stopped. The real time clock has a frequency of 1000
|
||||||
Hz. */
|
Hz. */
|
||||||
extern QEMUClock *rt_clock;
|
extern QEMUClock* rt_clock;
|
||||||
|
|
||||||
int64_t qemu_get_clock(QEMUClock *clock);
|
int64_t qemu_get_clock( QEMUClock* clock );
|
||||||
|
|
||||||
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
|
QEMUTimer* qemu_new_timer( QEMUClock* clock, QEMUTimerCB* cb, void* opaque );
|
||||||
void qemu_del_timer(QEMUTimer *ts);
|
void qemu_del_timer( QEMUTimer* ts );
|
||||||
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
|
void qemu_mod_timer( QEMUTimer* ts, int64_t expire_time );
|
||||||
int qemu_timer_pending(QEMUTimer *ts);
|
int qemu_timer_pending( QEMUTimer* ts );
|
||||||
|
|
||||||
extern int64_t ticks_per_sec;
|
extern int64_t ticks_per_sec;
|
||||||
|
|
||||||
|
|
|
@ -24,84 +24,77 @@
|
||||||
#ifndef BLOCK_INT_H
|
#ifndef BLOCK_INT_H
|
||||||
#define BLOCK_INT_H
|
#define BLOCK_INT_H
|
||||||
|
|
||||||
# include "qemu-git/qemu-common.h"
|
#include "qemu-git/qemu-common.h"
|
||||||
# include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
struct BlockDriver {
|
struct BlockDriver {
|
||||||
const char *format_name;
|
const char* format_name;
|
||||||
int instance_size;
|
int instance_size;
|
||||||
int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
|
int ( *bdrv_probe )( const uint8_t* buf, int buf_size, const char* filename );
|
||||||
int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
|
int ( *bdrv_open )( BlockDriverState* bs, const char* filename, int flags );
|
||||||
int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
|
int ( *bdrv_read )( BlockDriverState* bs, int64_t sector_num, uint8_t* buf, int nb_sectors );
|
||||||
uint8_t *buf, int nb_sectors);
|
int ( *bdrv_write )( BlockDriverState* bs, int64_t sector_num, const uint8_t* buf, int nb_sectors );
|
||||||
int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
|
void ( *bdrv_close )( BlockDriverState* bs );
|
||||||
const uint8_t *buf, int nb_sectors);
|
int ( *bdrv_create )( const char* filename, int64_t total_sectors, const char* backing_file, int flags );
|
||||||
void (*bdrv_close)(BlockDriverState *bs);
|
void ( *bdrv_flush )( BlockDriverState* bs );
|
||||||
int (*bdrv_create)(const char *filename, int64_t total_sectors,
|
int ( *bdrv_is_allocated )( BlockDriverState* bs, int64_t sector_num, int nb_sectors, int* pnum );
|
||||||
const char *backing_file, int flags);
|
int ( *bdrv_set_key )( BlockDriverState* bs, const char* key );
|
||||||
void (*bdrv_flush)(BlockDriverState *bs);
|
int ( *bdrv_make_empty )( BlockDriverState* bs );
|
||||||
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
int nb_sectors, int *pnum);
|
|
||||||
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
|
|
||||||
int (*bdrv_make_empty)(BlockDriverState *bs);
|
|
||||||
|
|
||||||
const char *protocol_name;
|
const char* protocol_name;
|
||||||
int (*bdrv_pread)(BlockDriverState *bs, int64_t offset,
|
int ( *bdrv_pread )( BlockDriverState* bs, int64_t offset, uint8_t* buf, int count );
|
||||||
uint8_t *buf, int count);
|
int ( *bdrv_pwrite )( BlockDriverState* bs, int64_t offset, const uint8_t* buf, int count );
|
||||||
int (*bdrv_pwrite)(BlockDriverState *bs, int64_t offset,
|
int ( *bdrv_truncate )( BlockDriverState* bs, int64_t offset );
|
||||||
const uint8_t *buf, int count);
|
int64_t ( *bdrv_getlength )( BlockDriverState* bs );
|
||||||
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
|
int ( *bdrv_write_compressed )( BlockDriverState* bs, int64_t sector_num, const uint8_t* buf, int nb_sectors );
|
||||||
int64_t (*bdrv_getlength)(BlockDriverState *bs);
|
|
||||||
int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
const uint8_t *buf, int nb_sectors);
|
|
||||||
|
|
||||||
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
|
int ( *bdrv_get_info )( BlockDriverState* bs, BlockDriverInfo* bdi );
|
||||||
|
|
||||||
/* removable device specific */
|
/* removable device specific */
|
||||||
int (*bdrv_is_inserted)(BlockDriverState *bs);
|
int ( *bdrv_is_inserted )( BlockDriverState* bs );
|
||||||
int (*bdrv_media_changed)(BlockDriverState *bs);
|
int ( *bdrv_media_changed )( BlockDriverState* bs );
|
||||||
int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
|
int ( *bdrv_eject )( BlockDriverState* bs, int eject_flag );
|
||||||
int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
|
int ( *bdrv_set_locked )( BlockDriverState* bs, int locked );
|
||||||
|
|
||||||
struct BlockDriver *next;
|
struct BlockDriver* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockDriverState {
|
struct BlockDriverState {
|
||||||
int64_t total_sectors; /* if we are reading a disk image, give its
|
int64_t total_sectors; /* if we are reading a disk image, give its
|
||||||
size in sectors */
|
size in sectors */
|
||||||
int read_only; /* if true, the media is read only */
|
int read_only; /* if true, the media is read only */
|
||||||
int removable; /* if true, the media can be removed */
|
int removable; /* if true, the media can be removed */
|
||||||
int locked; /* if true, the media cannot temporarily be ejected */
|
int locked; /* if true, the media cannot temporarily be ejected */
|
||||||
int encrypted; /* if true, the media is encrypted */
|
int encrypted; /* if true, the media is encrypted */
|
||||||
/* event callback when inserting/removing */
|
/* event callback when inserting/removing */
|
||||||
void (*change_cb)(void *opaque);
|
void ( *change_cb )( void* opaque );
|
||||||
void *change_opaque;
|
void* change_opaque;
|
||||||
|
|
||||||
BlockDriver *drv; /* NULL means no media */
|
BlockDriver* drv; /* NULL means no media */
|
||||||
void *opaque;
|
void* opaque;
|
||||||
|
|
||||||
int boot_sector_enabled;
|
int boot_sector_enabled;
|
||||||
uint8_t boot_sector_data[512];
|
uint8_t boot_sector_data[ 512 ];
|
||||||
|
|
||||||
char filename[1024];
|
char filename[ 1024 ];
|
||||||
char backing_file[1024]; /* if non zero, the image is a diff of
|
char backing_file[ 1024 ]; /* if non zero, the image is a diff of
|
||||||
this file image */
|
this file image */
|
||||||
int is_temporary;
|
int is_temporary;
|
||||||
int media_changed;
|
int media_changed;
|
||||||
|
|
||||||
BlockDriverState *backing_hd;
|
BlockDriverState* backing_hd;
|
||||||
/* async read/write emulation */
|
/* async read/write emulation */
|
||||||
|
|
||||||
void *sync_aiocb;
|
void* sync_aiocb;
|
||||||
|
|
||||||
/* NOTE: the following infos are only hints for real hardware
|
/* NOTE: the following infos are only hints for real hardware
|
||||||
drivers. They are not used by the block driver */
|
drivers. They are not used by the block driver */
|
||||||
int cyls, heads, secs, translation;
|
int cyls, heads, secs, translation;
|
||||||
int type;
|
int type;
|
||||||
char device_name[32];
|
char device_name[ 32 ];
|
||||||
BlockDriverState *next;
|
BlockDriverState* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_tmp_filename(char *filename, int size);
|
void get_tmp_filename( char* filename, int size );
|
||||||
|
|
||||||
#endif /* BLOCK_INT_H */
|
#endif /* BLOCK_INT_H */
|
||||||
|
|
|
@ -6,86 +6,75 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
static __inline__ uint16_t swab16(uint16_t x)
|
static __inline__ uint16_t swab16( uint16_t x ) { return ( ( x & 0xff00 ) >> 8 ) | ( ( x & 0x00ff ) << 8 ); }
|
||||||
{
|
|
||||||
return ((x & 0xff00) >> 8) |
|
|
||||||
((x & 0x00ff) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ uint32_t swab32(uint32_t x)
|
static __inline__ uint32_t swab32( uint32_t x )
|
||||||
{
|
{
|
||||||
return ((x & 0xff000000) >> 24) |
|
return ( ( x & 0xff000000 ) >> 24 ) | ( ( x & 0x00ff0000 ) >> 8 ) | ( ( x & 0x0000ff00 ) << 8 ) | ( ( x & 0x000000ff ) << 24 );
|
||||||
((x & 0x00ff0000) >> 8) |
|
|
||||||
((x & 0x0000ff00) << 8) |
|
|
||||||
((x & 0x000000ff) << 24);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
|
|
||||||
#define ASI_PL 0x88 /* Primary, implicit, little endian. */
|
# define ASI_PL 0x88 /* Primary, implicit, little endian. */
|
||||||
|
|
||||||
static __inline__ uint16_t __load_le16(const uint16_t *p)
|
static __inline__ uint16_t __load_le16( const uint16_t* p )
|
||||||
{
|
{
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
|
|
||||||
__asm__ __volatile__ ("lduha [%1] %2, %0"
|
__asm__ __volatile__( "lduha [%1] %2, %0" : "=r"( x ) : "r"( p ), "i"( ASI_PL ) );
|
||||||
: "=r" (x)
|
return x;
|
||||||
: "r" (p), "i" (ASI_PL));
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ uint32_t __load_le32(const uint32_t *p)
|
static __inline__ uint32_t __load_le32( const uint32_t* p )
|
||||||
{
|
{
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
|
||||||
__asm__ __volatile__ ("lduwa [%1] %2, %0"
|
__asm__ __volatile__( "lduwa [%1] %2, %0" : "=r"( x ) : "r"( p ), "i"( ASI_PL ) );
|
||||||
: "=r" (x)
|
return x;
|
||||||
: "r" (p), "i" (ASI_PL));
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void __store_le16(uint16_t *p, uint16_t x)
|
static __inline__ void __store_le16( uint16_t* p, uint16_t x )
|
||||||
{
|
{
|
||||||
__asm__ __volatile__ ("stha %0, [%1] %2"
|
__asm__ __volatile__( "stha %0, [%1] %2"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "r" (x), "r" (p), "i" (ASI_PL));
|
: "r"( x ), "r"( p ), "i"( ASI_PL ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void __store_le32(uint32_t *p, uint32_t x)
|
static __inline__ void __store_le32( uint32_t* p, uint32_t x )
|
||||||
{
|
{
|
||||||
__asm__ __volatile__ ("stwa %0, [%1] %2"
|
__asm__ __volatile__( "stwa %0, [%1] %2"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "r" (x), "r" (p), "i" (ASI_PL));
|
: "r"( x ), "r"( p ), "i"( ASI_PL ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __sparc__ */
|
#endif /* __sparc__ */
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
|
||||||
#define le16_to_cpu(x) (x)
|
# define le16_to_cpu( x ) ( x )
|
||||||
#define cpu_to_le16(x) (x)
|
# define cpu_to_le16( x ) ( x )
|
||||||
#define le32_to_cpu(x) (x)
|
# define le32_to_cpu( x ) ( x )
|
||||||
#define cpu_to_le32(x) (x)
|
# define cpu_to_le32( x ) ( x )
|
||||||
|
|
||||||
#define load_le16(p) (*(p))
|
# define load_le16( p ) ( *( p ) )
|
||||||
#define store_le16(p, x) (*(p) = (x))
|
# define store_le16( p, x ) ( *( p ) = ( x ) )
|
||||||
#define load_le32(p) (*(p))
|
# define load_le32( p ) ( *( p ) )
|
||||||
#define store_le32(p, x) (*(p) = (x))
|
# define store_le32( p, x ) ( *( p ) = ( x ) )
|
||||||
|
|
||||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
|
||||||
#define le16_to_cpu(x) swab16(x)
|
# define le16_to_cpu( x ) swab16( x )
|
||||||
#define cpu_to_le16(x) swab16(x)
|
# define cpu_to_le16( x ) swab16( x )
|
||||||
#define le32_to_cpu(x) swab32(x)
|
# define le32_to_cpu( x ) swab32( x )
|
||||||
#define cpu_to_le32(x) swab32(x)
|
# define cpu_to_le32( x ) swab32( x )
|
||||||
|
|
||||||
#define load_le16(p) __load_le16(p)
|
# define load_le16( p ) __load_le16( p )
|
||||||
#define store_le16(p, x) __store_le16(p, x)
|
# define store_le16( p, x ) __store_le16( p, x )
|
||||||
#define load_le32(p) __load_le32(p)
|
# define load_le32( p ) __load_le32( p )
|
||||||
#define store_le32(p, x) __store_le32(p, x)
|
# define store_le32( p, x ) __store_le32( p, x )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Cannot determine host byteorder"
|
# error "Cannot determine host byteorder"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !(_X49GP_BYTEORDER_H) */
|
#endif /* !(_X49GP_BYTEORDER_H) */
|
||||||
|
|
1163
src/flash.c
1163
src/flash.c
File diff suppressed because it is too large
Load diff
1604
src/gdbstub.c
1604
src/gdbstub.c
File diff suppressed because it is too large
Load diff
|
@ -6,33 +6,30 @@
|
||||||
#define DEFAULT_GDBSTUB_PORT 1234
|
#define DEFAULT_GDBSTUB_PORT 1234
|
||||||
|
|
||||||
/* GDB breakpoint/watchpoint types */
|
/* GDB breakpoint/watchpoint types */
|
||||||
#define GDB_BREAKPOINT_SW 0
|
#define GDB_BREAKPOINT_SW 0
|
||||||
#define GDB_BREAKPOINT_HW 1
|
#define GDB_BREAKPOINT_HW 1
|
||||||
#define GDB_WATCHPOINT_WRITE 2
|
#define GDB_WATCHPOINT_WRITE 2
|
||||||
#define GDB_WATCHPOINT_READ 3
|
#define GDB_WATCHPOINT_READ 3
|
||||||
#define GDB_WATCHPOINT_ACCESS 4
|
#define GDB_WATCHPOINT_ACCESS 4
|
||||||
|
|
||||||
typedef void (*gdb_syscall_complete_cb)(CPUState *env,
|
typedef void ( *gdb_syscall_complete_cb )( CPUState* env, target_ulong ret, target_ulong err );
|
||||||
target_ulong ret, target_ulong err);
|
|
||||||
|
|
||||||
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
|
void gdb_do_syscall( gdb_syscall_complete_cb cb, const char* fmt, ... );
|
||||||
int use_gdb_syscalls(void);
|
int use_gdb_syscalls( void );
|
||||||
void gdb_set_stop_cpu(CPUState *env);
|
void gdb_set_stop_cpu( CPUState* env );
|
||||||
|
|
||||||
int gdb_poll(CPUState *);
|
int gdb_poll( CPUState* );
|
||||||
|
|
||||||
int gdb_queuesig (void);
|
int gdb_queuesig( void );
|
||||||
int gdb_handlesig (CPUState *, int);
|
int gdb_handlesig( CPUState*, int );
|
||||||
void gdb_exit(CPUState *, int);
|
void gdb_exit( CPUState*, int );
|
||||||
void gdb_signalled(CPUState *, int);
|
void gdb_signalled( CPUState*, int );
|
||||||
int gdbserver_start(int);
|
int gdbserver_start( int );
|
||||||
void gdbserver_fork(CPUState *);
|
void gdbserver_fork( CPUState* );
|
||||||
|
|
||||||
/* Get or set a register. Returns the size of the register. */
|
/* Get or set a register. Returns the size of the register. */
|
||||||
typedef int (*gdb_reg_cb)(CPUState *env, uint8_t *buf, int reg);
|
typedef int ( *gdb_reg_cb )( CPUState* env, uint8_t* buf, int reg );
|
||||||
void gdb_register_coprocessor(CPUState *env,
|
void gdb_register_coprocessor( CPUState* env, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char* xml, int g_pos );
|
||||||
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
|
||||||
int num_regs, const char *xml, int g_pos);
|
|
||||||
|
|
||||||
int gdbserver_isactive();
|
int gdbserver_isactive();
|
||||||
|
|
||||||
|
|
449
src/glyphname.h
449
src/glyphname.h
|
@ -5,234 +5,233 @@
|
||||||
#define _X49GP_GLYPHNAME_H 1
|
#define _X49GP_GLYPHNAME_H 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char* name;
|
||||||
gunichar unichar;
|
gunichar unichar;
|
||||||
} x49gp_glyph_t;
|
} x49gp_glyph_t;
|
||||||
|
|
||||||
static const x49gp_glyph_t x49gp_glyphs[] =
|
static const x49gp_glyph_t x49gp_glyphs[] = {
|
||||||
{
|
{"exclamdown", 0x00a1},
|
||||||
{ "exclamdown", 0x00a1 },
|
{"cent", 0x00a2},
|
||||||
{ "cent", 0x00a2 },
|
{"sterling", 0x00a3},
|
||||||
{ "sterling", 0x00a3 },
|
{"fraction", 0x2044},
|
||||||
{ "fraction", 0x2044 },
|
{"yen", 0x00a5},
|
||||||
{ "yen", 0x00a5 },
|
{"florin", 0x0192},
|
||||||
{ "florin", 0x0192 },
|
{"section", 0x00a7},
|
||||||
{ "section", 0x00a7 },
|
{"currency", 0x00a4},
|
||||||
{ "currency", 0x00a4 },
|
{"quotesingle", 0x0027},
|
||||||
{ "quotesingle", 0x0027 },
|
{"quotedblleft", 0x201c},
|
||||||
{ "quotedblleft", 0x201c },
|
{"guillemotleft", 0x00ab},
|
||||||
{ "guillemotleft", 0x00ab },
|
{"guilsinglleft", 0x2039},
|
||||||
{ "guilsinglleft", 0x2039 },
|
{"guilsinglright", 0x203a},
|
||||||
{ "guilsinglright", 0x203a },
|
{"fi", 0xfb01},
|
||||||
{ "fi", 0xfb01 },
|
{"fl", 0xfb02},
|
||||||
{ "fl", 0xfb02 },
|
{"endash", 0x2013},
|
||||||
{ "endash", 0x2013 },
|
{"dagger", 0x2020},
|
||||||
{ "dagger", 0x2020 },
|
{"daggerdbl", 0x2021},
|
||||||
{ "daggerdbl", 0x2021 },
|
{"periodcentered", 0x00b7},
|
||||||
{ "periodcentered", 0x00b7 },
|
{"paragraph", 0x00b6},
|
||||||
{ "paragraph", 0x00b6 },
|
{"bullet", 0x2022},
|
||||||
{ "bullet", 0x2022 },
|
{"quotesinglbase", 0x201a},
|
||||||
{ "quotesinglbase", 0x201a },
|
{"quotedblbase", 0x201e},
|
||||||
{ "quotedblbase", 0x201e },
|
{"quotedblright", 0x201d},
|
||||||
{ "quotedblright", 0x201d },
|
{"guillemotright", 0x00bb},
|
||||||
{ "guillemotright", 0x00bb },
|
{"ellipsis", 0x2026},
|
||||||
{ "ellipsis", 0x2026 },
|
{"perthousand", 0x2030},
|
||||||
{ "perthousand", 0x2030 },
|
{"questiondown", 0x00bf},
|
||||||
{ "questiondown", 0x00bf },
|
{"grave", 0x0060},
|
||||||
{ "grave", 0x0060 },
|
{"acute", 0x00b4},
|
||||||
{ "acute", 0x00b4 },
|
{"circumflex", 0x02c6},
|
||||||
{ "circumflex", 0x02c6 },
|
{"tilde", 0x02dc},
|
||||||
{ "tilde", 0x02dc },
|
{"macron", 0x00af},
|
||||||
{ "macron", 0x00af },
|
{"breve", 0x02d8},
|
||||||
{ "breve", 0x02d8 },
|
{"dotaccent", 0x02d9},
|
||||||
{ "dotaccent", 0x02d9 },
|
{"dieresis", 0x00a8},
|
||||||
{ "dieresis", 0x00a8 },
|
{"ring", 0x02da},
|
||||||
{ "ring", 0x02da },
|
{"cedilla", 0x00b8},
|
||||||
{ "cedilla", 0x00b8 },
|
{"hungarumlaut", 0x02dd},
|
||||||
{ "hungarumlaut", 0x02dd },
|
{"ogonek", 0x02db},
|
||||||
{ "ogonek", 0x02db },
|
{"caron", 0x02c7},
|
||||||
{ "caron", 0x02c7 },
|
{"emdash", 0x2014},
|
||||||
{ "emdash", 0x2014 },
|
{"AE", 0x00c6},
|
||||||
{ "AE", 0x00c6 },
|
{"ordfeminine", 0x00aa},
|
||||||
{ "ordfeminine", 0x00aa },
|
{"Lslash", 0x0141},
|
||||||
{ "Lslash", 0x0141 },
|
{"Oslash", 0x00d8},
|
||||||
{ "Oslash", 0x00d8 },
|
{"OE", 0x0152},
|
||||||
{ "OE", 0x0152 },
|
{"ordmasculine", 0x00ba},
|
||||||
{ "ordmasculine", 0x00ba },
|
{"ae", 0x00e6},
|
||||||
{ "ae", 0x00e6 },
|
{"dotlessi", 0x0131},
|
||||||
{ "dotlessi", 0x0131 },
|
{"lslash", 0x0142},
|
||||||
{ "lslash", 0x0142 },
|
{"oslash", 0x00f8},
|
||||||
{ "oslash", 0x00f8 },
|
{"oe", 0x0153},
|
||||||
{ "oe", 0x0153 },
|
{"germandbls", 0x00df},
|
||||||
{ "germandbls", 0x00df },
|
{"Udieresis", 0x00dc},
|
||||||
{ "Udieresis", 0x00dc },
|
{"Uacute", 0x00da},
|
||||||
{ "Uacute", 0x00da },
|
{"Scedilla", 0x015e},
|
||||||
{ "Scedilla", 0x015e },
|
{"Tcaron", 0x0164},
|
||||||
{ "Tcaron", 0x0164 },
|
{"Scaron", 0x0160},
|
||||||
{ "Scaron", 0x0160 },
|
{"Rcaron", 0x0158},
|
||||||
{ "Rcaron", 0x0158 },
|
{"Racute", 0x0154},
|
||||||
{ "Racute", 0x0154 },
|
{"Sacute", 0x015a},
|
||||||
{ "Sacute", 0x015a },
|
{"Otilde", 0x00d5},
|
||||||
{ "Otilde", 0x00d5 },
|
{"ucircumflex", 0x00fb},
|
||||||
{ "ucircumflex", 0x00fb },
|
{"Ohungarumlaut", 0x0150},
|
||||||
{ "Ohungarumlaut", 0x0150 },
|
{"Uhungarumlaut", 0x0170},
|
||||||
{ "Uhungarumlaut", 0x0170 },
|
{"Yacute", 0x00dd},
|
||||||
{ "Yacute", 0x00dd },
|
{"Eth", 0x00d0},
|
||||||
{ "Eth", 0x00d0 },
|
{"Dcroat", 0x0110},
|
||||||
{ "Dcroat", 0x0110 },
|
{"Zacute", 0x0179},
|
||||||
{ "Zacute", 0x0179 },
|
{"Uring", 0x016e},
|
||||||
{ "Uring", 0x016e },
|
{"gbreve", 0x011f},
|
||||||
{ "gbreve", 0x011f },
|
{"eogonek", 0x0119},
|
||||||
{ "eogonek", 0x0119 },
|
{"edotaccent", 0x0117},
|
||||||
{ "edotaccent", 0x0117 },
|
{"ecaron", 0x011b},
|
||||||
{ "ecaron", 0x011b },
|
{"Ugrave", 0x00d9},
|
||||||
{ "Ugrave", 0x00d9 },
|
{"Thorn", 0x00de},
|
||||||
{ "Thorn", 0x00de },
|
{"eacute", 0x00e9},
|
||||||
{ "eacute", 0x00e9 },
|
{"edieresis", 0x00eb},
|
||||||
{ "edieresis", 0x00eb },
|
{"dcaron", 0x010f},
|
||||||
{ "dcaron", 0x010f },
|
{"ccedilla", 0x00e7},
|
||||||
{ "ccedilla", 0x00e7 },
|
{"ccaron", 0x010d},
|
||||||
{ "ccaron", 0x010d },
|
{"cacute", 0x0107},
|
||||||
{ "cacute", 0x0107 },
|
{"aogonek", 0x0105},
|
||||||
{ "aogonek", 0x0105 },
|
{"aring", 0x00e5},
|
||||||
{ "aring", 0x00e5 },
|
{"atilde", 0x00e3},
|
||||||
{ "atilde", 0x00e3 },
|
{"abreve", 0x0103},
|
||||||
{ "abreve", 0x0103 },
|
{"egrave", 0x00e8},
|
||||||
{ "egrave", 0x00e8 },
|
{"agrave", 0x00e0},
|
||||||
{ "agrave", 0x00e0 },
|
{"aacute", 0x00e1},
|
||||||
{ "aacute", 0x00e1 },
|
{"adieresis", 0x00e4},
|
||||||
{ "adieresis", 0x00e4 },
|
{"Uogonek", 0x0172},
|
||||||
{ "Uogonek", 0x0172 },
|
{"ugrave", 0x00f9},
|
||||||
{ "ugrave", 0x00f9 },
|
{"uacute", 0x00fa},
|
||||||
{ "uacute", 0x00fa },
|
{"udieresis", 0x00fc},
|
||||||
{ "udieresis", 0x00fc },
|
{"tcaron", 0x0165},
|
||||||
{ "tcaron", 0x0165 },
|
{"scommaaccent", 0x0219},
|
||||||
{ "scommaaccent", 0x0219 },
|
{"Zcaron", 0x017d},
|
||||||
{ "Zcaron", 0x017d },
|
{"ecircumflex", 0x00ea},
|
||||||
{ "ecircumflex", 0x00ea },
|
{"Ucircumflex", 0x00db},
|
||||||
{ "Ucircumflex", 0x00db },
|
{"acircumflex", 0x00e2},
|
||||||
{ "acircumflex", 0x00e2 },
|
{"Zdotaccent", 0x017b},
|
||||||
{ "Zdotaccent", 0x017b },
|
{"scaron", 0x0161},
|
||||||
{ "scaron", 0x0161 },
|
{"Amacron", 0x0100},
|
||||||
{ "Amacron", 0x0100 },
|
{"sacute", 0x015b},
|
||||||
{ "sacute", 0x015b },
|
{"Tcommaaccent", 0x0162},
|
||||||
{ "Tcommaaccent", 0x0162 },
|
{"Ydieresis", 0x0178},
|
||||||
{ "Ydieresis", 0x0178 },
|
{"thorn", 0x00fe},
|
||||||
{ "thorn", 0x00fe },
|
{"Emacron", 0x0112},
|
||||||
{ "Emacron", 0x0112 },
|
{"Ograve", 0x00d2},
|
||||||
{ "Ograve", 0x00d2 },
|
{"Oacute", 0x00d3},
|
||||||
{ "Oacute", 0x00d3 },
|
{"Odieresis", 0x00d6},
|
||||||
{ "Odieresis", 0x00d6 },
|
{"Ntilde", 0x00d1},
|
||||||
{ "Ntilde", 0x00d1 },
|
{"Ncaron", 0x0147},
|
||||||
{ "Ncaron", 0x0147 },
|
{"Nacute", 0x0143},
|
||||||
{ "Nacute", 0x0143 },
|
{"Lcaron", 0x013d},
|
||||||
{ "Lcaron", 0x013d },
|
{"Lacute", 0x0139},
|
||||||
{ "Lacute", 0x0139 },
|
{"Idotaccent", 0x0130},
|
||||||
{ "Idotaccent", 0x0130 },
|
{"racute", 0x0155},
|
||||||
{ "racute", 0x0155 },
|
{"Icircumflex", 0x00ce},
|
||||||
{ "Icircumflex", 0x00ce },
|
{"ohungarumlaut", 0x0151},
|
||||||
{ "ohungarumlaut", 0x0151 },
|
{"otilde", 0x00f5},
|
||||||
{ "otilde", 0x00f5 },
|
{"Euro", 0x20ac},
|
||||||
{ "Euro", 0x20ac },
|
{"ocircumflex", 0x00f4},
|
||||||
{ "ocircumflex", 0x00f4 },
|
{"onesuperior", 0x00b9},
|
||||||
{ "onesuperior", 0x00b9 },
|
{"twosuperior", 0x00b2},
|
||||||
{ "twosuperior", 0x00b2 },
|
{"threesuperior", 0x00b3},
|
||||||
{ "threesuperior", 0x00b3 },
|
{"Igrave", 0x00cc},
|
||||||
{ "Igrave", 0x00cc },
|
{"Iacute", 0x00cd},
|
||||||
{ "Iacute", 0x00cd },
|
{"Imacron", 0x012a},
|
||||||
{ "Imacron", 0x012a },
|
{"Iogonek", 0x012e},
|
||||||
{ "Iogonek", 0x012e },
|
{"Idieresis", 0x00cf},
|
||||||
{ "Idieresis", 0x00cf },
|
{"Gbreve", 0x011e},
|
||||||
{ "Gbreve", 0x011e },
|
{"Umacron", 0x016a},
|
||||||
{ "Umacron", 0x016a },
|
{"Kcommaaccent", 0x0136},
|
||||||
{ "Kcommaaccent", 0x0136 },
|
{"ograve", 0x00f2},
|
||||||
{ "ograve", 0x00f2 },
|
{"Scommaaccent", 0x0218},
|
||||||
{ "Scommaaccent", 0x0218 },
|
{"Eogonek", 0x0118},
|
||||||
{ "Eogonek", 0x0118 },
|
{"oacute", 0x00f3},
|
||||||
{ "oacute", 0x00f3 },
|
{"Edotaccent", 0x0116},
|
||||||
{ "Edotaccent", 0x0116 },
|
{"iogonek", 0x012f},
|
||||||
{ "iogonek", 0x012f },
|
{"gcommaaccent", 0x0123},
|
||||||
{ "gcommaaccent", 0x0123 },
|
{"odieresis", 0x00f6},
|
||||||
{ "odieresis", 0x00f6 },
|
{"ntilde", 0x00f1},
|
||||||
{ "ntilde", 0x00f1 },
|
{"ncaron", 0x0148},
|
||||||
{ "ncaron", 0x0148 },
|
{"Ecaron", 0x011a},
|
||||||
{ "Ecaron", 0x011a },
|
{"Ecircumflex", 0x00ca},
|
||||||
{ "Ecircumflex", 0x00ca },
|
{"scedilla", 0x015f},
|
||||||
{ "scedilla", 0x015f },
|
{"rcaron", 0x0159},
|
||||||
{ "rcaron", 0x0159 },
|
{"Egrave", 0x00c8},
|
||||||
{ "Egrave", 0x00c8 },
|
{"Eacute", 0x00c9},
|
||||||
{ "Eacute", 0x00c9 },
|
{"Gcommaaccent", 0x0122},
|
||||||
{ "Gcommaaccent", 0x0122 },
|
{"Rcommaaccent", 0x0156},
|
||||||
{ "Rcommaaccent", 0x0156 },
|
{"Edieresis", 0x00cb},
|
||||||
{ "Edieresis", 0x00cb },
|
{"nacute", 0x0144},
|
||||||
{ "nacute", 0x0144 },
|
{"uogonek", 0x0173},
|
||||||
{ "uogonek", 0x0173 },
|
{"umacron", 0x016b},
|
||||||
{ "umacron", 0x016b },
|
{"Dcaron", 0x010e},
|
||||||
{ "Dcaron", 0x010e },
|
{"lcaron", 0x013e},
|
||||||
{ "lcaron", 0x013e },
|
{"Ccaron", 0x010c},
|
||||||
{ "Ccaron", 0x010c },
|
{"Cacute", 0x0106},
|
||||||
{ "Cacute", 0x0106 },
|
{"Ccedilla", 0x00c7},
|
||||||
{ "Ccedilla", 0x00c7 },
|
{"degree", 0x00b0},
|
||||||
{ "degree", 0x00b0 },
|
{"Aogonek", 0x0104},
|
||||||
{ "Aogonek", 0x0104 },
|
{"minus", 0x2212},
|
||||||
{ "minus", 0x2212 },
|
{"multiply", 0x00d7},
|
||||||
{ "multiply", 0x00d7 },
|
{"divide", 0x00f7},
|
||||||
{ "divide", 0x00f7 },
|
{"Aring", 0x00c5},
|
||||||
{ "Aring", 0x00c5 },
|
{"trademark", 0x2122},
|
||||||
{ "trademark", 0x2122 },
|
{"rcommaaccent", 0x0157},
|
||||||
{ "rcommaaccent", 0x0157 },
|
{"lacute", 0x013a},
|
||||||
{ "lacute", 0x013a },
|
{"omacron", 0x014d},
|
||||||
{ "omacron", 0x014d },
|
{"Atilde", 0x00c3},
|
||||||
{ "Atilde", 0x00c3 },
|
{"icircumflex", 0x00ee},
|
||||||
{ "icircumflex", 0x00ee },
|
{"igrave", 0x00ec},
|
||||||
{ "igrave", 0x00ec },
|
{"ncommaaccent", 0x0146},
|
||||||
{ "ncommaaccent", 0x0146 },
|
{"lcommaaccent", 0x013c},
|
||||||
{ "lcommaaccent", 0x013c },
|
{"plusminus", 0x00b1},
|
||||||
{ "plusminus", 0x00b1 },
|
{"onehalf", 0x00bd},
|
||||||
{ "onehalf", 0x00bd },
|
{"onequarter", 0x00bc},
|
||||||
{ "onequarter", 0x00bc },
|
{"threequarters", 0x00be},
|
||||||
{ "threequarters", 0x00be },
|
{"iacute", 0x00ed},
|
||||||
{ "iacute", 0x00ed },
|
{"Abreve", 0x0102},
|
||||||
{ "Abreve", 0x0102 },
|
{"kcommaaccent", 0x0137},
|
||||||
{ "kcommaaccent", 0x0137 },
|
{"Omacron", 0x014c},
|
||||||
{ "Omacron", 0x014c },
|
{"imacron", 0x012b},
|
||||||
{ "imacron", 0x012b },
|
{"emacron", 0x0113},
|
||||||
{ "emacron", 0x0113 },
|
{"amacron", 0x0101},
|
||||||
{ "amacron", 0x0101 },
|
{"tcommaaccent", 0x0163},
|
||||||
{ "tcommaaccent", 0x0163 },
|
{"ydieresis", 0x00ff},
|
||||||
{ "ydieresis", 0x00ff },
|
{"zdotaccent", 0x017c},
|
||||||
{ "zdotaccent", 0x017c },
|
{"zcaron", 0x017e},
|
||||||
{ "zcaron", 0x017e },
|
{"zacute", 0x017a},
|
||||||
{ "zacute", 0x017a },
|
{"yacute", 0x00fd},
|
||||||
{ "yacute", 0x00fd },
|
{"uhungarumlaut", 0x0171},
|
||||||
{ "uhungarumlaut", 0x0171 },
|
{"eth", 0x00f0},
|
||||||
{ "eth", 0x00f0 },
|
{"uring", 0x016f},
|
||||||
{ "uring", 0x016f },
|
{"Ocircumflex", 0x00d4},
|
||||||
{ "Ocircumflex", 0x00d4 },
|
{"commaaccent", 0xf6c3},
|
||||||
{ "commaaccent", 0xf6c3 },
|
{"copyright", 0x00a9},
|
||||||
{ "copyright", 0x00a9 },
|
{"registered", 0x00ae},
|
||||||
{ "registered", 0x00ae },
|
{"Acircumflex", 0x00c2},
|
||||||
{ "Acircumflex", 0x00c2 },
|
{"idieresis", 0x00ef},
|
||||||
{ "idieresis", 0x00ef },
|
{"lozenge", 0x25ca},
|
||||||
{ "lozenge", 0x25ca },
|
{"Delta", 0x2206},
|
||||||
{ "Delta", 0x2206 },
|
{"notequal", 0x2260},
|
||||||
{ "notequal", 0x2260 },
|
{"radical", 0x221a},
|
||||||
{ "radical", 0x221a },
|
{"Agrave", 0x00c0},
|
||||||
{ "Agrave", 0x00c0 },
|
{"Aacute", 0x00c1},
|
||||||
{ "Aacute", 0x00c1 },
|
{"lessequal", 0x2264},
|
||||||
{ "lessequal", 0x2264 },
|
{"greaterequal", 0x2265},
|
||||||
{ "greaterequal", 0x2265 },
|
{"logicalnot", 0x00ac},
|
||||||
{ "logicalnot", 0x00ac },
|
{"summation", 0x2211},
|
||||||
{ "summation", 0x2211 },
|
{"partialdiff", 0x2202},
|
||||||
{ "partialdiff", 0x2202 },
|
{"Ncommaaccent", 0x0145},
|
||||||
{ "Ncommaaccent", 0x0145 },
|
{"dcroat", 0x0111},
|
||||||
{ "dcroat", 0x0111 },
|
{"brokenbar", 0x00a6},
|
||||||
{ "brokenbar", 0x00a6 },
|
{"Lcommaaccent", 0x013b},
|
||||||
{ "Lcommaaccent", 0x013b },
|
{"Adieresis", 0x00c4},
|
||||||
{ "Adieresis", 0x00c4 },
|
{"mu", 0x00b5}
|
||||||
{ "mu", 0x00b5 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NR_GLYPHNAMES (sizeof(x49gp_glyphs) / sizeof(x49gp_glyphs[0]))
|
#define NR_GLYPHNAMES ( sizeof( x49gp_glyphs ) / sizeof( x49gp_glyphs[ 0 ] ) )
|
||||||
|
|
||||||
#endif /* !(_X49GP_GLYPHNAME_H) */
|
#endif /* !(_X49GP_GLYPHNAME_H) */
|
||||||
|
|
149
src/hex2bin.c
149
src/hex2bin.c
|
@ -26,92 +26,89 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
int
|
int main( int argc, char** argv )
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
unsigned char *input, *p;
|
unsigned char *input, *p;
|
||||||
unsigned char *memory = NULL;
|
unsigned char* memory = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
int in, out;
|
int in, out;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (argc < 3) {
|
if ( argc < 3 ) {
|
||||||
fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
|
fprintf( stderr, "usage: %s <infile> <outfile>\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[1], "-"))
|
if ( !strcmp( argv[ 1 ], "-" ) )
|
||||||
in = 0;
|
in = 0;
|
||||||
else {
|
else {
|
||||||
in = open(argv[1], O_RDONLY);
|
in = open( argv[ 1 ], O_RDONLY );
|
||||||
if (in < 0) {
|
if ( in < 0 ) {
|
||||||
perror(argv[1]);
|
perror( argv[ 1 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[2], "-"))
|
if ( !strcmp( argv[ 2 ], "-" ) )
|
||||||
out = 1;
|
out = 1;
|
||||||
else {
|
else {
|
||||||
out = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
out = open( argv[ 2 ], O_WRONLY | O_CREAT | O_TRUNC, 0666 );
|
||||||
if (out < 0) {
|
if ( out < 0 ) {
|
||||||
perror(argv[2]);
|
perror( argv[ 2 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size = lseek(in, 0, SEEK_END);
|
size = lseek( in, 0, SEEK_END );
|
||||||
lseek(in, 0, SEEK_SET);
|
lseek( in, 0, SEEK_SET );
|
||||||
|
|
||||||
input = (unsigned char *)malloc(size);
|
input = ( unsigned char* )malloc( size );
|
||||||
if (!input) {
|
if ( !input ) {
|
||||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
fprintf( stderr, "%s: out of memory\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(in, input, size) != size) {
|
if ( read( in, input, size ) != size ) {
|
||||||
perror("read");
|
perror( "read" );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
close(in);
|
close( in );
|
||||||
|
|
||||||
memory = malloc(size >> 1);
|
memory = malloc( size >> 1 );
|
||||||
if (!memory) {
|
if ( !memory ) {
|
||||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
fprintf( stderr, "%s: out of memory\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
p = input;
|
p = input;
|
||||||
for (i = 0; i < (size >> 1); i++) {
|
for ( i = 0; i < ( size >> 1 ); i++ ) {
|
||||||
if ('0' <= *p && *p <= '9')
|
if ( '0' <= *p && *p <= '9' )
|
||||||
memory[i] = (*p - '0') << 0;
|
memory[ i ] = ( *p - '0' ) << 0;
|
||||||
else if ('a' <= *p && *p <= 'f')
|
else if ( 'a' <= *p && *p <= 'f' )
|
||||||
memory[i] = (*p - 'a' + 10) << 0;
|
memory[ i ] = ( *p - 'a' + 10 ) << 0;
|
||||||
else if ('A' <= *p && *p <= 'F')
|
else if ( 'A' <= *p && *p <= 'F' )
|
||||||
memory[i] = (*p - 'A' + 10) << 0;
|
memory[ i ] = ( *p - 'A' + 10 ) << 0;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s: parse error at byte %d\n",
|
fprintf( stderr, "%s: parse error at byte %d\n", argv[ 0 ], i );
|
||||||
argv[0], i);
|
exit( 1 );
|
||||||
exit(1);
|
}
|
||||||
}
|
p++;
|
||||||
p++;
|
if ( '0' <= *p && *p <= '9' )
|
||||||
if ('0' <= *p && *p <= '9')
|
memory[ i ] |= ( *p - '0' ) << 4;
|
||||||
memory[i] |= (*p - '0') << 4;
|
else if ( 'a' <= *p && *p <= 'f' )
|
||||||
else if ('a' <= *p && *p <= 'f')
|
memory[ i ] |= ( *p - 'a' + 10 ) << 4;
|
||||||
memory[i] |= (*p - 'a' + 10) << 4;
|
else if ( 'A' <= *p && *p <= 'F' )
|
||||||
else if ('A' <= *p && *p <= 'F')
|
memory[ i ] |= ( *p - 'A' + 10 ) << 4;
|
||||||
memory[i] |= (*p - 'A' + 10) << 4;
|
else {
|
||||||
else {
|
fprintf( stderr, "%s: parse error at byte %d\n", argv[ 0 ], i );
|
||||||
fprintf(stderr, "%s: parse error at byte %d\n",
|
exit( 1 );
|
||||||
argv[0], i);
|
}
|
||||||
exit(1);
|
p++;
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
write(out, memory, size >> 1);
|
write( out, memory, size >> 1 );
|
||||||
close(out);
|
close( out );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,92 +26,89 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
int
|
int main( int argc, char** argv )
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
unsigned char *input, *p;
|
unsigned char *input, *p;
|
||||||
unsigned char *memory = NULL;
|
unsigned char* memory = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
int in, out;
|
int in, out;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (argc < 3) {
|
if ( argc < 3 ) {
|
||||||
fprintf(stderr, "usage: %s <infile> <outfile>\n", argv[0]);
|
fprintf( stderr, "usage: %s <infile> <outfile>\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[1], "-"))
|
if ( !strcmp( argv[ 1 ], "-" ) )
|
||||||
in = 0;
|
in = 0;
|
||||||
else {
|
else {
|
||||||
in = open(argv[1], O_RDONLY);
|
in = open( argv[ 1 ], O_RDONLY );
|
||||||
if (in < 0) {
|
if ( in < 0 ) {
|
||||||
perror(argv[1]);
|
perror( argv[ 1 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[2], "-"))
|
if ( !strcmp( argv[ 2 ], "-" ) )
|
||||||
out = 1;
|
out = 1;
|
||||||
else {
|
else {
|
||||||
out = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
out = open( argv[ 2 ], O_WRONLY | O_CREAT | O_TRUNC, 0666 );
|
||||||
if (out < 0) {
|
if ( out < 0 ) {
|
||||||
perror(argv[2]);
|
perror( argv[ 2 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size = lseek(in, 0, SEEK_END);
|
size = lseek( in, 0, SEEK_END );
|
||||||
lseek(in, 0, SEEK_SET);
|
lseek( in, 0, SEEK_SET );
|
||||||
|
|
||||||
input = (unsigned char *)malloc(size);
|
input = ( unsigned char* )malloc( size );
|
||||||
if (!input) {
|
if ( !input ) {
|
||||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
fprintf( stderr, "%s: out of memory\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(in, input, size) != size) {
|
if ( read( in, input, size ) != size ) {
|
||||||
perror("read");
|
perror( "read" );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
close(in);
|
close( in );
|
||||||
|
|
||||||
memory = malloc(size >> 1);
|
memory = malloc( size >> 1 );
|
||||||
if (!memory) {
|
if ( !memory ) {
|
||||||
fprintf(stderr, "%s: out of memory\n", argv[0]);
|
fprintf( stderr, "%s: out of memory\n", argv[ 0 ] );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
p = input;
|
p = input;
|
||||||
for (i = 0; i < (size >> 1); i++) {
|
for ( i = 0; i < ( size >> 1 ); i++ ) {
|
||||||
if ('0' <= *p && *p <= '9')
|
if ( '0' <= *p && *p <= '9' )
|
||||||
memory[(i & ~3) + 3 - (i & 3)] = (*p - '0') << 0;
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] = ( *p - '0' ) << 0;
|
||||||
else if ('a' <= *p && *p <= 'f')
|
else if ( 'a' <= *p && *p <= 'f' )
|
||||||
memory[(i & ~3) + 3 - (i & 3)] = (*p - 'a' + 10) << 0;
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] = ( *p - 'a' + 10 ) << 0;
|
||||||
else if ('A' <= *p && *p <= 'F')
|
else if ( 'A' <= *p && *p <= 'F' )
|
||||||
memory[(i & ~3) + 3 - (i & 3)] = (*p - 'A' + 10) << 0;
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] = ( *p - 'A' + 10 ) << 0;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "%s: parse error at byte %d\n",
|
fprintf( stderr, "%s: parse error at byte %d\n", argv[ 0 ], i );
|
||||||
argv[0], i);
|
exit( 1 );
|
||||||
exit(1);
|
}
|
||||||
}
|
p++;
|
||||||
p++;
|
if ( '0' <= *p && *p <= '9' )
|
||||||
if ('0' <= *p && *p <= '9')
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] |= ( *p - '0' ) << 4;
|
||||||
memory[(i & ~3) + 3 - (i & 3)] |= (*p - '0') << 4;
|
else if ( 'a' <= *p && *p <= 'f' )
|
||||||
else if ('a' <= *p && *p <= 'f')
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] |= ( *p - 'a' + 10 ) << 4;
|
||||||
memory[(i & ~3) + 3 - (i & 3)] |= (*p - 'a' + 10) << 4;
|
else if ( 'A' <= *p && *p <= 'F' )
|
||||||
else if ('A' <= *p && *p <= 'F')
|
memory[ ( i & ~3 ) + 3 - ( i & 3 ) ] |= ( *p - 'A' + 10 ) << 4;
|
||||||
memory[(i & ~3) + 3 - (i & 3)] |= (*p - 'A' + 10) << 4;
|
else {
|
||||||
else {
|
fprintf( stderr, "%s: parse error at byte %d\n", argv[ 0 ], i );
|
||||||
fprintf(stderr, "%s: parse error at byte %d\n",
|
exit( 1 );
|
||||||
argv[0], i);
|
}
|
||||||
exit(1);
|
p++;
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
write(out, memory, size >> 1);
|
write( out, memory, size >> 1 );
|
||||||
close(out);
|
close( out );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
412
src/list.h
412
src/list.h
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
static inline void prefetch(const void *x) {;}
|
static inline void prefetch( const void* x ) { ; }
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
# define offsetof( TYPE, MEMBER ) ( ( size_t )&( ( TYPE* )0 )->MEMBER )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -14,8 +14,8 @@ static inline void prefetch(const void *x) {;}
|
||||||
* under normal circumstances, used to verify that nobody uses
|
* under normal circumstances, used to verify that nobody uses
|
||||||
* non-initialized list entries.
|
* non-initialized list entries.
|
||||||
*/
|
*/
|
||||||
#define LIST_POISON1 ((void *) 0x00100100)
|
#define LIST_POISON1 ( ( void* )0x00100100 )
|
||||||
#define LIST_POISON2 ((void *) 0x00200200)
|
#define LIST_POISON2 ( ( void* )0x00200200 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple doubly linked list implementation.
|
* Simple doubly linked list implementation.
|
||||||
|
@ -28,17 +28,18 @@ static inline void prefetch(const void *x) {;}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct list_head {
|
struct list_head {
|
||||||
struct list_head *next, *prev;
|
struct list_head *next, *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
#define LIST_HEAD_INIT( name ) { &( name ), &( name ) }
|
||||||
|
|
||||||
#define LIST_HEAD(name) \
|
#define LIST_HEAD( name ) struct list_head name = LIST_HEAD_INIT( name )
|
||||||
struct list_head name = LIST_HEAD_INIT(name)
|
|
||||||
|
|
||||||
#define INIT_LIST_HEAD(ptr) do { \
|
#define INIT_LIST_HEAD( ptr ) \
|
||||||
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
do { \
|
||||||
} while (0)
|
( ptr )->next = ( ptr ); \
|
||||||
|
( ptr )->prev = ( ptr ); \
|
||||||
|
} while ( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a new entry between two known consecutive entries.
|
* Insert a new entry between two known consecutive entries.
|
||||||
|
@ -46,14 +47,12 @@ struct list_head {
|
||||||
* This is only for internal list manipulation where we know
|
* This is only for internal list manipulation where we know
|
||||||
* the prev/next entries already!
|
* the prev/next entries already!
|
||||||
*/
|
*/
|
||||||
static inline void __list_add(struct list_head *new,
|
static inline void __list_add( struct list_head* new, struct list_head* prev, struct list_head* next )
|
||||||
struct list_head *prev,
|
|
||||||
struct list_head *next)
|
|
||||||
{
|
{
|
||||||
next->prev = new;
|
next->prev = new;
|
||||||
new->next = next;
|
new->next = next;
|
||||||
new->prev = prev;
|
new->prev = prev;
|
||||||
prev->next = new;
|
prev->next = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,10 +63,7 @@ static inline void __list_add(struct list_head *new,
|
||||||
* Insert a new entry after the specified head.
|
* Insert a new entry after the specified head.
|
||||||
* This is good for implementing stacks.
|
* This is good for implementing stacks.
|
||||||
*/
|
*/
|
||||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
static inline void list_add( struct list_head* new, struct list_head* head ) { __list_add( new, head, head->next ); }
|
||||||
{
|
|
||||||
__list_add(new, head, head->next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_add_tail - add a new entry
|
* list_add_tail - add a new entry
|
||||||
|
@ -77,10 +73,7 @@ static inline void list_add(struct list_head *new, struct list_head *head)
|
||||||
* Insert a new entry before the specified head.
|
* Insert a new entry before the specified head.
|
||||||
* This is useful for implementing queues.
|
* This is useful for implementing queues.
|
||||||
*/
|
*/
|
||||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
static inline void list_add_tail( struct list_head* new, struct list_head* head ) { __list_add( new, head->prev, head ); }
|
||||||
{
|
|
||||||
__list_add(new, head->prev, head);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete a list entry by making the prev/next entries
|
* Delete a list entry by making the prev/next entries
|
||||||
|
@ -89,10 +82,10 @@ static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||||
* This is only for internal list manipulation where we know
|
* This is only for internal list manipulation where we know
|
||||||
* the prev/next entries already!
|
* the prev/next entries already!
|
||||||
*/
|
*/
|
||||||
static inline void __list_del(struct list_head * prev, struct list_head * next)
|
static inline void __list_del( struct list_head* prev, struct list_head* next )
|
||||||
{
|
{
|
||||||
next->prev = prev;
|
next->prev = prev;
|
||||||
prev->next = next;
|
prev->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,21 +94,21 @@ static inline void __list_del(struct list_head * prev, struct list_head * next)
|
||||||
* Note: list_empty on entry does not return true after this, the entry is
|
* Note: list_empty on entry does not return true after this, the entry is
|
||||||
* in an undefined state.
|
* in an undefined state.
|
||||||
*/
|
*/
|
||||||
static inline void list_del(struct list_head *entry)
|
static inline void list_del( struct list_head* entry )
|
||||||
{
|
{
|
||||||
__list_del(entry->prev, entry->next);
|
__list_del( entry->prev, entry->next );
|
||||||
entry->next = LIST_POISON1;
|
entry->next = LIST_POISON1;
|
||||||
entry->prev = LIST_POISON2;
|
entry->prev = LIST_POISON2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_del_init - deletes entry from list and reinitialize it.
|
* list_del_init - deletes entry from list and reinitialize it.
|
||||||
* @entry: the element to delete from the list.
|
* @entry: the element to delete from the list.
|
||||||
*/
|
*/
|
||||||
static inline void list_del_init(struct list_head *entry)
|
static inline void list_del_init( struct list_head* entry )
|
||||||
{
|
{
|
||||||
__list_del(entry->prev, entry->next);
|
__list_del( entry->prev, entry->next );
|
||||||
INIT_LIST_HEAD(entry);
|
INIT_LIST_HEAD( entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,10 +116,10 @@ static inline void list_del_init(struct list_head *entry)
|
||||||
* @list: the entry to move
|
* @list: the entry to move
|
||||||
* @head: the head that will precede our entry
|
* @head: the head that will precede our entry
|
||||||
*/
|
*/
|
||||||
static inline void list_move(struct list_head *list, struct list_head *head)
|
static inline void list_move( struct list_head* list, struct list_head* head )
|
||||||
{
|
{
|
||||||
__list_del(list->prev, list->next);
|
__list_del( list->prev, list->next );
|
||||||
list_add(list, head);
|
list_add( list, head );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,21 +127,17 @@ static inline void list_move(struct list_head *list, struct list_head *head)
|
||||||
* @list: the entry to move
|
* @list: the entry to move
|
||||||
* @head: the head that will follow our entry
|
* @head: the head that will follow our entry
|
||||||
*/
|
*/
|
||||||
static inline void list_move_tail(struct list_head *list,
|
static inline void list_move_tail( struct list_head* list, struct list_head* head )
|
||||||
struct list_head *head)
|
|
||||||
{
|
{
|
||||||
__list_del(list->prev, list->next);
|
__list_del( list->prev, list->next );
|
||||||
list_add_tail(list, head);
|
list_add_tail( list, head );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_empty - tests whether a list is empty
|
* list_empty - tests whether a list is empty
|
||||||
* @head: the list to test.
|
* @head: the list to test.
|
||||||
*/
|
*/
|
||||||
static inline int list_empty(const struct list_head *head)
|
static inline int list_empty( const struct list_head* head ) { return head->next == head; }
|
||||||
{
|
|
||||||
return head->next == head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_empty_careful - tests whether a list is
|
* list_empty_careful - tests whether a list is
|
||||||
|
@ -162,24 +151,23 @@ static inline int list_empty(const struct list_head *head)
|
||||||
*
|
*
|
||||||
* @head: the list to test.
|
* @head: the list to test.
|
||||||
*/
|
*/
|
||||||
static inline int list_empty_careful(const struct list_head *head)
|
static inline int list_empty_careful( const struct list_head* head )
|
||||||
{
|
{
|
||||||
struct list_head *next = head->next;
|
struct list_head* next = head->next;
|
||||||
return (next == head) && (next == head->prev);
|
return ( next == head ) && ( next == head->prev );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __list_splice(struct list_head *list,
|
static inline void __list_splice( struct list_head* list, struct list_head* head )
|
||||||
struct list_head *head)
|
|
||||||
{
|
{
|
||||||
struct list_head *first = list->next;
|
struct list_head* first = list->next;
|
||||||
struct list_head *last = list->prev;
|
struct list_head* last = list->prev;
|
||||||
struct list_head *at = head->next;
|
struct list_head* at = head->next;
|
||||||
|
|
||||||
first->prev = head;
|
first->prev = head;
|
||||||
head->next = first;
|
head->next = first;
|
||||||
|
|
||||||
last->next = at;
|
last->next = at;
|
||||||
at->prev = last;
|
at->prev = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,10 +175,10 @@ static inline void __list_splice(struct list_head *list,
|
||||||
* @list: the new list to add.
|
* @list: the new list to add.
|
||||||
* @head: the place to add it in the first list.
|
* @head: the place to add it in the first list.
|
||||||
*/
|
*/
|
||||||
static inline void list_splice(struct list_head *list, struct list_head *head)
|
static inline void list_splice( struct list_head* list, struct list_head* head )
|
||||||
{
|
{
|
||||||
if (!list_empty(list))
|
if ( !list_empty( list ) )
|
||||||
__list_splice(list, head);
|
__list_splice( list, head );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,13 +188,12 @@ static inline void list_splice(struct list_head *list, struct list_head *head)
|
||||||
*
|
*
|
||||||
* The list at @list is reinitialised
|
* The list at @list is reinitialised
|
||||||
*/
|
*/
|
||||||
static inline void list_splice_init(struct list_head *list,
|
static inline void list_splice_init( struct list_head* list, struct list_head* head )
|
||||||
struct list_head *head)
|
|
||||||
{
|
{
|
||||||
if (!list_empty(list)) {
|
if ( !list_empty( list ) ) {
|
||||||
__list_splice(list, head);
|
__list_splice( list, head );
|
||||||
INIT_LIST_HEAD(list);
|
INIT_LIST_HEAD( list );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,17 +202,14 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @type: the type of the struct this is embedded in.
|
* @type: the type of the struct this is embedded in.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry( ptr, type, member ) container_of( ptr, type, member )
|
||||||
container_of(ptr, type, member)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each - iterate over a list
|
* list_for_each - iterate over a list
|
||||||
* @pos: the &struct list_head to use as a loop counter.
|
* @pos: the &struct list_head to use as a loop counter.
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
*/
|
*/
|
||||||
#define list_for_each(pos, head) \
|
#define list_for_each( pos, head ) for ( pos = ( head )->next; prefetch( pos->next ), pos != ( head ); pos = pos->next )
|
||||||
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
|
|
||||||
pos = pos->next)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __list_for_each - iterate over a list
|
* __list_for_each - iterate over a list
|
||||||
|
@ -237,17 +221,14 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* Use this for code that knows the list to be very short (empty
|
* Use this for code that knows the list to be very short (empty
|
||||||
* or 1 entry) most of the time.
|
* or 1 entry) most of the time.
|
||||||
*/
|
*/
|
||||||
#define __list_for_each(pos, head) \
|
#define __list_for_each( pos, head ) for ( pos = ( head )->next; pos != ( head ); pos = pos->next )
|
||||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_prev - iterate over a list backwards
|
* list_for_each_prev - iterate over a list backwards
|
||||||
* @pos: the &struct list_head to use as a loop counter.
|
* @pos: the &struct list_head to use as a loop counter.
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_prev(pos, head) \
|
#define list_for_each_prev( pos, head ) for ( pos = ( head )->prev; prefetch( pos->prev ), pos != ( head ); pos = pos->prev )
|
||||||
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
|
|
||||||
pos = pos->prev)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_safe - iterate over a list safe against removal of list entry
|
* list_for_each_safe - iterate over a list safe against removal of list entry
|
||||||
|
@ -255,9 +236,7 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @n: another &struct list_head to use as temporary storage
|
* @n: another &struct list_head to use as temporary storage
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_safe(pos, n, head) \
|
#define list_for_each_safe( pos, n, head ) for ( pos = ( head )->next, n = pos->next; pos != ( head ); pos = n, n = pos->next )
|
||||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
|
||||||
pos = n, n = pos->next)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry - iterate over list of given type
|
* list_for_each_entry - iterate over list of given type
|
||||||
|
@ -265,10 +244,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry(pos, head, member) \
|
#define list_for_each_entry( pos, head, member ) \
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
for ( pos = list_entry( ( head )->next, typeof( *pos ), member ); prefetch( pos->member.next ), &pos->member != ( head ); \
|
||||||
prefetch(pos->member.next), &pos->member != (head); \
|
pos = list_entry( pos->member.next, typeof( *pos ), member ) )
|
||||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_reverse - iterate backwards over list of given type.
|
* list_for_each_entry_reverse - iterate backwards over list of given type.
|
||||||
|
@ -276,10 +254,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_reverse(pos, head, member) \
|
#define list_for_each_entry_reverse( pos, head, member ) \
|
||||||
for (pos = list_entry((head)->prev, typeof(*pos), member); \
|
for ( pos = list_entry( ( head )->prev, typeof( *pos ), member ); prefetch( pos->member.prev ), &pos->member != ( head ); \
|
||||||
prefetch(pos->member.prev), &pos->member != (head); \
|
pos = list_entry( pos->member.prev, typeof( *pos ), member ) )
|
||||||
pos = list_entry(pos->member.prev, typeof(*pos), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_prepare_entry - prepare a pos entry for use as a start point in
|
* list_prepare_entry - prepare a pos entry for use as a start point in
|
||||||
|
@ -288,8 +265,7 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head of the list
|
* @head: the head of the list
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_prepare_entry(pos, head, member) \
|
#define list_prepare_entry( pos, head, member ) ( ( pos ) ?: list_entry( head, typeof( *pos ), member ) )
|
||||||
((pos) ? : list_entry(head, typeof(*pos), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_continue - iterate over list of given type
|
* list_for_each_entry_continue - iterate over list of given type
|
||||||
|
@ -298,10 +274,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_continue(pos, head, member) \
|
#define list_for_each_entry_continue( pos, head, member ) \
|
||||||
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
|
for ( pos = list_entry( pos->member.next, typeof( *pos ), member ); prefetch( pos->member.next ), &pos->member != ( head ); \
|
||||||
prefetch(pos->member.next), &pos->member != (head); \
|
pos = list_entry( pos->member.next, typeof( *pos ), member ) )
|
||||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||||
|
@ -310,11 +285,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
#define list_for_each_entry_safe( pos, n, head, member ) \
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
for ( pos = list_entry( ( head )->next, typeof( *pos ), member ), n = list_entry( pos->member.next, typeof( *pos ), member ); \
|
||||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
&pos->member != ( head ); pos = n, n = list_entry( n->member.next, typeof( *n ), member ) )
|
||||||
&pos->member != (head); \
|
|
||||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against removal of list entry.
|
* list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against removal of list entry.
|
||||||
|
@ -323,11 +296,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @member: the name of the list_struct within the struct.
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
|
#define list_for_each_entry_safe_reverse( pos, n, head, member ) \
|
||||||
for (pos = list_entry((head)->prev, typeof(*pos), member), \
|
for ( pos = list_entry( ( head )->prev, typeof( *pos ), member ), n = list_entry( pos->member.prev, typeof( *pos ), member ); \
|
||||||
n = list_entry(pos->member.prev, typeof(*pos), member); \
|
prefetch( pos->member.prev ), &pos->member != ( head ); pos = n, n = list_entry( n->member.prev, typeof( *n ), member ) )
|
||||||
prefetch(pos->member.prev), &pos->member != (head); \
|
|
||||||
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_rcu - iterate over an rcu-protected list
|
* list_for_each_rcu - iterate over an rcu-protected list
|
||||||
|
@ -338,13 +309,10 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||||
* as long as the traversal is guarded by rcu_read_lock().
|
* as long as the traversal is guarded by rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
#define list_for_each_rcu(pos, head) \
|
#define list_for_each_rcu( pos, head ) \
|
||||||
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
|
for ( pos = ( head )->next; prefetch( pos->next ), pos != ( head ); pos = rcu_dereference( pos->next ) )
|
||||||
pos = rcu_dereference(pos->next))
|
|
||||||
|
|
||||||
#define __list_for_each_rcu(pos, head) \
|
#define __list_for_each_rcu( pos, head ) for ( pos = ( head )->next; pos != ( head ); pos = rcu_dereference( pos->next ) )
|
||||||
for (pos = (head)->next; pos != (head); \
|
|
||||||
pos = rcu_dereference(pos->next))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_safe_rcu - iterate over an rcu-protected list safe
|
* list_for_each_safe_rcu - iterate over an rcu-protected list safe
|
||||||
|
@ -357,9 +325,8 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||||
* as long as the traversal is guarded by rcu_read_lock().
|
* as long as the traversal is guarded by rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
#define list_for_each_safe_rcu(pos, n, head) \
|
#define list_for_each_safe_rcu( pos, n, head ) \
|
||||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
for ( pos = ( head )->next, n = pos->next; pos != ( head ); pos = rcu_dereference( n ), n = pos->next )
|
||||||
pos = rcu_dereference(n), n = pos->next)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_entry_rcu - iterate over rcu list of given type
|
* list_for_each_entry_rcu - iterate over rcu list of given type
|
||||||
|
@ -371,12 +338,9 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||||
* as long as the traversal is guarded by rcu_read_lock().
|
* as long as the traversal is guarded by rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_rcu(pos, head, member) \
|
#define list_for_each_entry_rcu( pos, head, member ) \
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
for ( pos = list_entry( ( head )->next, typeof( *pos ), member ); prefetch( pos->member.next ), &pos->member != ( head ); \
|
||||||
prefetch(pos->member.next), &pos->member != (head); \
|
pos = rcu_dereference( list_entry( pos->member.next, typeof( *pos ), member ) ) )
|
||||||
pos = rcu_dereference(list_entry(pos->member.next, \
|
|
||||||
typeof(*pos), member)))
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list_for_each_continue_rcu - iterate over an rcu-protected list
|
* list_for_each_continue_rcu - iterate over an rcu-protected list
|
||||||
|
@ -388,9 +352,8 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||||
* as long as the traversal is guarded by rcu_read_lock().
|
* as long as the traversal is guarded by rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
#define list_for_each_continue_rcu(pos, head) \
|
#define list_for_each_continue_rcu( pos, head ) \
|
||||||
for ((pos) = (pos)->next; prefetch((pos)->next), (pos) != (head); \
|
for ( ( pos ) = ( pos )->next; prefetch( ( pos )->next ), ( pos ) != ( head ); ( pos ) = rcu_dereference( ( pos )->next ) )
|
||||||
(pos) = rcu_dereference((pos)->next))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Double linked lists with a single pointer list head.
|
* Double linked lists with a single pointer list head.
|
||||||
|
@ -400,42 +363,36 @@ static inline void list_splice_init(struct list_head *list,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hlist_head {
|
struct hlist_head {
|
||||||
struct hlist_node *first;
|
struct hlist_node* first;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hlist_node {
|
struct hlist_node {
|
||||||
struct hlist_node *next, **pprev;
|
struct hlist_node *next, **pprev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HLIST_HEAD_INIT { .first = NULL }
|
#define HLIST_HEAD_INIT { .first = NULL }
|
||||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
#define HLIST_HEAD( name ) struct hlist_head name = { .first = NULL }
|
||||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
#define INIT_HLIST_HEAD( ptr ) ( ( ptr )->first = NULL )
|
||||||
#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
|
#define INIT_HLIST_NODE( ptr ) ( ( ptr )->next = NULL, ( ptr )->pprev = NULL )
|
||||||
|
|
||||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
static inline int hlist_unhashed( const struct hlist_node* h ) { return !h->pprev; }
|
||||||
|
|
||||||
|
static inline int hlist_empty( const struct hlist_head* h ) { return !h->first; }
|
||||||
|
|
||||||
|
static inline void __hlist_del( struct hlist_node* n )
|
||||||
{
|
{
|
||||||
return !h->pprev;
|
struct hlist_node* next = n->next;
|
||||||
|
struct hlist_node** pprev = n->pprev;
|
||||||
|
*pprev = next;
|
||||||
|
if ( next )
|
||||||
|
next->pprev = pprev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int hlist_empty(const struct hlist_head *h)
|
static inline void hlist_del( struct hlist_node* n )
|
||||||
{
|
{
|
||||||
return !h->first;
|
__hlist_del( n );
|
||||||
}
|
n->next = LIST_POISON1;
|
||||||
|
n->pprev = LIST_POISON2;
|
||||||
static inline void __hlist_del(struct hlist_node *n)
|
|
||||||
{
|
|
||||||
struct hlist_node *next = n->next;
|
|
||||||
struct hlist_node **pprev = n->pprev;
|
|
||||||
*pprev = next;
|
|
||||||
if (next)
|
|
||||||
next->pprev = pprev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hlist_del(struct hlist_node *n)
|
|
||||||
{
|
|
||||||
__hlist_del(n);
|
|
||||||
n->next = LIST_POISON1;
|
|
||||||
n->pprev = LIST_POISON2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -457,64 +414,71 @@ static inline void hlist_del(struct hlist_node *n)
|
||||||
* the _rcu list-traversal primitives, such as
|
* the _rcu list-traversal primitives, such as
|
||||||
* hlist_for_each_entry().
|
* hlist_for_each_entry().
|
||||||
*/
|
*/
|
||||||
static inline void hlist_del_rcu(struct hlist_node *n)
|
static inline void hlist_del_rcu( struct hlist_node* n )
|
||||||
{
|
{
|
||||||
__hlist_del(n);
|
__hlist_del( n );
|
||||||
n->pprev = LIST_POISON2;
|
n->pprev = LIST_POISON2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hlist_del_init(struct hlist_node *n)
|
static inline void hlist_del_init( struct hlist_node* n )
|
||||||
{
|
{
|
||||||
if (n->pprev) {
|
if ( n->pprev ) {
|
||||||
__hlist_del(n);
|
__hlist_del( n );
|
||||||
INIT_HLIST_NODE(n);
|
INIT_HLIST_NODE( n );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
static inline void hlist_add_head( struct hlist_node* n, struct hlist_head* h )
|
||||||
{
|
{
|
||||||
struct hlist_node *first = h->first;
|
struct hlist_node* first = h->first;
|
||||||
n->next = first;
|
n->next = first;
|
||||||
if (first)
|
if ( first )
|
||||||
first->pprev = &n->next;
|
first->pprev = &n->next;
|
||||||
h->first = n;
|
h->first = n;
|
||||||
n->pprev = &h->first;
|
n->pprev = &h->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next must be != NULL */
|
/* next must be != NULL */
|
||||||
static inline void hlist_add_before(struct hlist_node *n,
|
static inline void hlist_add_before( struct hlist_node* n, struct hlist_node* next )
|
||||||
struct hlist_node *next)
|
|
||||||
{
|
{
|
||||||
n->pprev = next->pprev;
|
n->pprev = next->pprev;
|
||||||
n->next = next;
|
n->next = next;
|
||||||
next->pprev = &n->next;
|
next->pprev = &n->next;
|
||||||
*(n->pprev) = n;
|
*( n->pprev ) = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hlist_add_after(struct hlist_node *n,
|
static inline void hlist_add_after( struct hlist_node* n, struct hlist_node* next )
|
||||||
struct hlist_node *next)
|
|
||||||
{
|
{
|
||||||
next->next = n->next;
|
next->next = n->next;
|
||||||
n->next = next;
|
n->next = next;
|
||||||
next->pprev = &n->next;
|
next->pprev = &n->next;
|
||||||
|
|
||||||
if(next->next)
|
if ( next->next )
|
||||||
next->next->pprev = &next->next;
|
next->next->pprev = &next->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
#define hlist_entry( ptr, type, member ) container_of( ptr, type, member )
|
||||||
|
|
||||||
#define hlist_for_each(pos, head) \
|
#define hlist_for_each( pos, head ) \
|
||||||
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
|
for ( pos = ( head )->first; pos && ( { \
|
||||||
pos = pos->next)
|
prefetch( pos->next ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = pos->next )
|
||||||
|
|
||||||
#define hlist_for_each_safe(pos, n, head) \
|
#define hlist_for_each_safe( pos, n, head ) \
|
||||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
for ( pos = ( head )->first; pos && ( { \
|
||||||
pos = n)
|
n = pos->next; \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = n )
|
||||||
|
|
||||||
#define hlist_for_each_rcu(pos, head) \
|
#define hlist_for_each_rcu( pos, head ) \
|
||||||
for ((pos) = (head)->first; pos && ({ prefetch((pos)->next); 1; }); \
|
for ( ( pos ) = ( head )->first; pos && ( { \
|
||||||
(pos) = rcu_dereference((pos)->next))
|
prefetch( ( pos )->next ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
( pos ) = rcu_dereference( ( pos )->next ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hlist_for_each_entry - iterate over list of given type
|
* hlist_for_each_entry - iterate over list of given type
|
||||||
|
@ -523,11 +487,16 @@ static inline void hlist_add_after(struct hlist_node *n,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the hlist_node within the struct.
|
* @member: the name of the hlist_node within the struct.
|
||||||
*/
|
*/
|
||||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
#define hlist_for_each_entry( tpos, pos, head, member ) \
|
||||||
for (pos = (head)->first; \
|
for ( pos = ( head )->first; pos && ( { \
|
||||||
pos && ({ prefetch(pos->next); 1;}) && \
|
prefetch( pos->next ); \
|
||||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
1; \
|
||||||
pos = pos->next)
|
} ) && \
|
||||||
|
( { \
|
||||||
|
tpos = hlist_entry( pos, typeof( *tpos ), member ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = pos->next )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
|
* hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
|
||||||
|
@ -535,11 +504,16 @@ static inline void hlist_add_after(struct hlist_node *n,
|
||||||
* @pos: the &struct hlist_node to use as a loop counter.
|
* @pos: the &struct hlist_node to use as a loop counter.
|
||||||
* @member: the name of the hlist_node within the struct.
|
* @member: the name of the hlist_node within the struct.
|
||||||
*/
|
*/
|
||||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
#define hlist_for_each_entry_continue( tpos, pos, member ) \
|
||||||
for (pos = (pos)->next; \
|
for ( pos = ( pos )->next; pos && ( { \
|
||||||
pos && ({ prefetch(pos->next); 1;}) && \
|
prefetch( pos->next ); \
|
||||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
1; \
|
||||||
pos = pos->next)
|
} ) && \
|
||||||
|
( { \
|
||||||
|
tpos = hlist_entry( pos, typeof( *tpos ), member ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = pos->next )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hlist_for_each_entry_from - iterate over a hlist continuing from existing point
|
* hlist_for_each_entry_from - iterate over a hlist continuing from existing point
|
||||||
|
@ -547,10 +521,16 @@ static inline void hlist_add_after(struct hlist_node *n,
|
||||||
* @pos: the &struct hlist_node to use as a loop counter.
|
* @pos: the &struct hlist_node to use as a loop counter.
|
||||||
* @member: the name of the hlist_node within the struct.
|
* @member: the name of the hlist_node within the struct.
|
||||||
*/
|
*/
|
||||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
#define hlist_for_each_entry_from( tpos, pos, member ) \
|
||||||
for (; pos && ({ prefetch(pos->next); 1;}) && \
|
for ( ; pos && ( { \
|
||||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
prefetch( pos->next ); \
|
||||||
pos = pos->next)
|
1; \
|
||||||
|
} ) && \
|
||||||
|
( { \
|
||||||
|
tpos = hlist_entry( pos, typeof( *tpos ), member ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = pos->next )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||||
|
@ -560,11 +540,16 @@ static inline void hlist_add_after(struct hlist_node *n,
|
||||||
* @head: the head for your list.
|
* @head: the head for your list.
|
||||||
* @member: the name of the hlist_node within the struct.
|
* @member: the name of the hlist_node within the struct.
|
||||||
*/
|
*/
|
||||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
#define hlist_for_each_entry_safe( tpos, pos, n, head, member ) \
|
||||||
for (pos = (head)->first; \
|
for ( pos = ( head )->first; pos && ( { \
|
||||||
pos && ({ n = pos->next; 1; }) && \
|
n = pos->next; \
|
||||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
1; \
|
||||||
pos = n)
|
} ) && \
|
||||||
|
( { \
|
||||||
|
tpos = hlist_entry( pos, typeof( *tpos ), member ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = n )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hlist_for_each_entry_rcu - iterate over rcu list of given type
|
* hlist_for_each_entry_rcu - iterate over rcu list of given type
|
||||||
|
@ -577,10 +562,15 @@ static inline void hlist_add_after(struct hlist_node *n,
|
||||||
* the _rcu list-mutation primitives such as hlist_add_head_rcu()
|
* the _rcu list-mutation primitives such as hlist_add_head_rcu()
|
||||||
* as long as the traversal is guarded by rcu_read_lock().
|
* as long as the traversal is guarded by rcu_read_lock().
|
||||||
*/
|
*/
|
||||||
#define hlist_for_each_entry_rcu(tpos, pos, head, member) \
|
#define hlist_for_each_entry_rcu( tpos, pos, head, member ) \
|
||||||
for (pos = (head)->first; \
|
for ( pos = ( head )->first; pos && ( { \
|
||||||
pos && ({ prefetch(pos->next); 1;}) && \
|
prefetch( pos->next ); \
|
||||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
1; \
|
||||||
pos = rcu_dereference(pos->next))
|
} ) && \
|
||||||
|
( { \
|
||||||
|
tpos = hlist_entry( pos, typeof( *tpos ), member ); \
|
||||||
|
1; \
|
||||||
|
} ); \
|
||||||
|
pos = rcu_dereference( pos->next ) )
|
||||||
|
|
||||||
#endif /* _LINUX_LIST_H */
|
#endif /* _LINUX_LIST_H */
|
||||||
|
|
891
src/main.c
891
src/main.c
File diff suppressed because it is too large
Load diff
609
src/module.c
609
src/module.c
|
@ -11,493 +11,434 @@
|
||||||
|
|
||||||
#include "x49gp.h"
|
#include "x49gp.h"
|
||||||
|
|
||||||
int
|
int x49gp_modules_init( x49gp_t* x49gp )
|
||||||
x49gp_modules_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u:\n", __FUNCTION__, __LINE__);
|
printf( "%s:%u:\n", __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
phys_ram_size = 0;
|
phys_ram_size = 0;
|
||||||
|
|
||||||
list_for_each_entry(module, &x49gp->modules, list) {
|
list_for_each_entry( module, &x49gp->modules, list )
|
||||||
error = module->init(module);
|
{
|
||||||
if (error) {
|
error = module->init( module );
|
||||||
return error;
|
if ( error ) {
|
||||||
}
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
phys_ram_base = mmap(0, phys_ram_size, PROT_NONE, MAP_SHARED | MAP_ANON, -1, 0);
|
phys_ram_base = mmap( 0, phys_ram_size, PROT_NONE, MAP_SHARED | MAP_ANON, -1, 0 );
|
||||||
if (phys_ram_base == (uint8_t *) -1) {
|
if ( phys_ram_base == ( uint8_t* )-1 ) {
|
||||||
fprintf(stderr, "%s: can't mmap %08x anonymous bytes\n",
|
fprintf( stderr, "%s: can't mmap %08x anonymous bytes\n", __FUNCTION__, phys_ram_size );
|
||||||
__FUNCTION__, phys_ram_size);
|
exit( 1 );
|
||||||
exit(1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base);
|
printf( "%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
|
phys_ram_dirty = qemu_vmalloc( phys_ram_size >> TARGET_PAGE_BITS );
|
||||||
memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
|
memset( phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS );
|
||||||
|
|
||||||
ram_addr_t x49gp_ram_alloc(ram_addr_t size, uint8_t *base);
|
ram_addr_t x49gp_ram_alloc( ram_addr_t size, uint8_t* base );
|
||||||
x49gp_ram_alloc(phys_ram_size, phys_ram_base);
|
x49gp_ram_alloc( phys_ram_size, phys_ram_base );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_modules_exit( x49gp_t* x49gp )
|
||||||
x49gp_modules_exit(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module, *next;
|
x49gp_module_t *module, *next;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u:\n", __FUNCTION__, __LINE__);
|
printf( "%s:%u:\n", __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_for_each_entry_safe_reverse(module, next, &x49gp->modules, list) {
|
list_for_each_entry_safe_reverse( module, next, &x49gp->modules, list )
|
||||||
error = module->exit(module);
|
{
|
||||||
if (error) {
|
error = module->exit( module );
|
||||||
return error;
|
if ( error ) {
|
||||||
}
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_modules_reset( x49gp_t* x49gp, x49gp_reset_t reset )
|
||||||
x49gp_modules_reset(x49gp_t *x49gp, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u:\n", __FUNCTION__, __LINE__);
|
printf( "%s:%u:\n", __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_for_each_entry(module, &x49gp->modules, list) {
|
list_for_each_entry( module, &x49gp->modules, list )
|
||||||
error = module->reset(module, reset);
|
{
|
||||||
if (error) {
|
error = module->reset( module, reset );
|
||||||
return error;
|
if ( error ) {
|
||||||
}
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_modules_load( x49gp_t* x49gp, const char* filename )
|
||||||
x49gp_modules_load(x49gp_t *x49gp, const char *filename)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
GError *gerror = NULL;
|
GError* gerror = NULL;
|
||||||
int error, result;
|
int error, result;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u:\n", __FUNCTION__, __LINE__);
|
printf( "%s:%u:\n", __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_mkdir_with_parents(x49gp->basename, 0755)) {
|
if ( g_mkdir_with_parents( x49gp->basename, 0755 ) ) {
|
||||||
error = -errno;
|
error = -errno;
|
||||||
fprintf(stderr, "%s:%u: g_mkdir_with_parents: %s\n",
|
fprintf( stderr, "%s:%u: g_mkdir_with_parents: %s\n", __FUNCTION__, __LINE__, strerror( errno ) );
|
||||||
__FUNCTION__, __LINE__, strerror(errno));
|
return error;
|
||||||
return error;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
x49gp->config = g_key_file_new();
|
x49gp->config = g_key_file_new();
|
||||||
if (NULL == x49gp->config) {
|
if ( NULL == x49gp->config ) {
|
||||||
fprintf(stderr, "%s:%u: g_key_file_new: Out of memory\n",
|
fprintf( stderr, "%s:%u: g_key_file_new: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (! g_key_file_load_from_file(x49gp->config, filename,
|
if ( !g_key_file_load_from_file( x49gp->config, filename, G_KEY_FILE_KEEP_COMMENTS, &gerror ) &&
|
||||||
G_KEY_FILE_KEEP_COMMENTS, &gerror)
|
!g_error_matches( gerror, G_FILE_ERROR, G_FILE_ERROR_NOENT ) ) {
|
||||||
&& ! g_error_matches(gerror, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
|
fprintf( stderr, "%s:%u: g_key_file_load_from_file: %s\n", __FUNCTION__, __LINE__, gerror->message );
|
||||||
fprintf(stderr, "%s:%u: g_key_file_load_from_file: %s\n",
|
g_key_file_free( x49gp->config );
|
||||||
__FUNCTION__, __LINE__, gerror->message);
|
return -EIO;
|
||||||
g_key_file_free(x49gp->config);
|
}
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
list_for_each_entry(module, &x49gp->modules, list) {
|
list_for_each_entry( module, &x49gp->modules, list )
|
||||||
error = module->load(module, x49gp->config);
|
{
|
||||||
if (error) {
|
error = module->load( module, x49gp->config );
|
||||||
if (error == -EAGAIN) {
|
if ( error ) {
|
||||||
result = -EAGAIN;
|
if ( error == -EAGAIN ) {
|
||||||
} else {
|
result = -EAGAIN;
|
||||||
return error;
|
} else {
|
||||||
}
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
extern unsigned char *phys_ram_base;
|
extern unsigned char* phys_ram_base;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base);
|
printf( "%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base );
|
||||||
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", phys_ram_base[ 0 ], phys_ram_base[ 1 ], phys_ram_base[ 2 ],
|
||||||
phys_ram_base[0],
|
phys_ram_base[ 3 ], phys_ram_base[ 4 ], phys_ram_base[ 5 ], phys_ram_base[ 6 ], phys_ram_base[ 7 ] );
|
||||||
phys_ram_base[1],
|
|
||||||
phys_ram_base[2],
|
|
||||||
phys_ram_base[3],
|
|
||||||
phys_ram_base[4],
|
|
||||||
phys_ram_base[5],
|
|
||||||
phys_ram_base[6],
|
|
||||||
phys_ram_base[7]);
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
int x49gp_modules_save( x49gp_t* x49gp, const char* filename )
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
x49gp_modules_save(x49gp_t *x49gp, const char *filename)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
GError *gerror = NULL;
|
GError* gerror = NULL;
|
||||||
gchar *data;
|
gchar* data;
|
||||||
gsize length;
|
gsize length;
|
||||||
int error;
|
int error;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u:\n", __FUNCTION__, __LINE__);
|
printf( "%s:%u:\n", __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_for_each_entry(module, &x49gp->modules, list) {
|
list_for_each_entry( module, &x49gp->modules, list )
|
||||||
error = module->save(module, x49gp->config);
|
{
|
||||||
if (error) {
|
error = module->save( module, x49gp->config );
|
||||||
return error;
|
if ( error ) {
|
||||||
}
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data = g_key_file_to_data(x49gp->config, &length, &gerror);
|
data = g_key_file_to_data( x49gp->config, &length, &gerror );
|
||||||
if (NULL == data) {
|
if ( NULL == data ) {
|
||||||
fprintf(stderr, "%s:%u: g_key_file_to_data: %s\n",
|
fprintf( stderr, "%s:%u: g_key_file_to_data: %s\n", __FUNCTION__, __LINE__, gerror->message );
|
||||||
__FUNCTION__, __LINE__, gerror->message);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
fd = open( filename, O_WRONLY | O_CREAT | O_TRUNC, 0644 );
|
||||||
if (fd < 0) {
|
if ( fd < 0 ) {
|
||||||
error = -errno;
|
error = -errno;
|
||||||
fprintf(stderr, "%s:%u: open %s: %s\n",
|
fprintf( stderr, "%s:%u: open %s: %s\n", __FUNCTION__, __LINE__, filename, strerror( errno ) );
|
||||||
__FUNCTION__, __LINE__, filename, strerror(errno));
|
g_free( data );
|
||||||
g_free(data);
|
return error;
|
||||||
return error;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if ( write( fd, data, length ) != length ) {
|
||||||
|
error = -errno;
|
||||||
|
fprintf( stderr, "%s:%u: write %s: %s\n", __FUNCTION__, __LINE__, filename, strerror( errno ) );
|
||||||
|
close( fd );
|
||||||
|
g_free( data );
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
if (write(fd, data, length) != length) {
|
close( fd );
|
||||||
error = -errno;
|
g_free( data );
|
||||||
fprintf(stderr, "%s:%u: write %s: %s\n",
|
|
||||||
__FUNCTION__, __LINE__, filename, strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
g_free(data);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
return 0;
|
||||||
g_free(data);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_register( x49gp_module_t* module )
|
||||||
x49gp_module_register(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
x49gp_t *x49gp = module->x49gp;
|
x49gp_t* x49gp = module->x49gp;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u: %s\n", __FUNCTION__, __LINE__, module->name);
|
printf( "%s:%u: %s\n", __FUNCTION__, __LINE__, module->name );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_add_tail(&module->list, &x49gp->modules);
|
list_add_tail( &module->list, &x49gp->modules );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_unregister( x49gp_module_t* module )
|
||||||
x49gp_module_unregister(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s:%u: %s\n", __FUNCTION__, __LINE__, module->name);
|
printf( "%s:%u: %s\n", __FUNCTION__, __LINE__, module->name );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_del(&module->list);
|
list_del( &module->list );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_filename( x49gp_module_t* module, GKeyFile* key, const char* name, char* reset, char** valuep, char** path )
|
||||||
x49gp_module_get_filename(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, char *reset, char **valuep,
|
|
||||||
char **path)
|
|
||||||
{
|
{
|
||||||
x49gp_t *x49gp = module->x49gp;
|
x49gp_t* x49gp = module->x49gp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = x49gp_module_get_string(module, key, name, reset, valuep);
|
error = x49gp_module_get_string( module, key, name, reset, valuep );
|
||||||
|
|
||||||
if (g_path_is_absolute(*valuep)) {
|
if ( g_path_is_absolute( *valuep ) ) {
|
||||||
*path = g_strdup(*valuep);
|
*path = g_strdup( *valuep );
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
*path = g_build_filename(x49gp->basename, *valuep, NULL);
|
*path = g_build_filename( x49gp->basename, *valuep, NULL );
|
||||||
if (NULL == path) {
|
if ( NULL == path ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
module->name, __FUNCTION__, __LINE__);
|
g_free( *valuep );
|
||||||
g_free(*valuep);
|
*valuep = NULL;
|
||||||
*valuep = NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_set_filename( x49gp_module_t* module, GKeyFile* key, const char* name, const char* value )
|
||||||
x49gp_module_set_filename(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, const char *value)
|
|
||||||
{
|
{
|
||||||
return x49gp_module_set_string(module, key, name, value);
|
return x49gp_module_set_string( module, key, name, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_int( x49gp_module_t* module, GKeyFile* key, const char* name, int reset, int* valuep )
|
||||||
x49gp_module_get_int(x49gp_module_t *module, GKeyFile *key, const char *name,
|
|
||||||
int reset, int *valuep)
|
|
||||||
{
|
{
|
||||||
return x49gp_module_get_u32(module, key, name, reset,
|
return x49gp_module_get_u32( module, key, name, reset, ( uint32_t* )valuep );
|
||||||
(uint32_t *) valuep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_set_int( x49gp_module_t* module, GKeyFile* key, const char* name, int value )
|
||||||
x49gp_module_set_int(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, int value)
|
|
||||||
{
|
{
|
||||||
char data[16];
|
char data[ 16 ];
|
||||||
|
|
||||||
snprintf(data, sizeof(data), "%d", value);
|
snprintf( data, sizeof( data ), "%d", value );
|
||||||
|
|
||||||
g_key_file_set_value(key, module->name, name, data);
|
g_key_file_set_value( key, module->name, name, data );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_uint( x49gp_module_t* module, GKeyFile* key, const char* name, unsigned int reset, unsigned int* valuep )
|
||||||
x49gp_module_get_uint(x49gp_module_t *module, GKeyFile *key, const char *name,
|
|
||||||
unsigned int reset, unsigned int *valuep)
|
|
||||||
{
|
{
|
||||||
return x49gp_module_get_u32(module, key, name, reset, valuep);
|
return x49gp_module_get_u32( module, key, name, reset, valuep );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_set_uint( x49gp_module_t* module, GKeyFile* key, const char* name, unsigned int value )
|
||||||
x49gp_module_set_uint(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, unsigned int value)
|
|
||||||
{
|
{
|
||||||
char data[16];
|
char data[ 16 ];
|
||||||
|
|
||||||
snprintf(data, sizeof(data), "%u", value);
|
snprintf( data, sizeof( data ), "%u", value );
|
||||||
|
|
||||||
g_key_file_set_value(key, module->name, name, data);
|
g_key_file_set_value( key, module->name, name, data );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_u32( x49gp_module_t* module, GKeyFile* key, const char* name, uint32_t reset, uint32_t* valuep )
|
||||||
x49gp_module_get_u32(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, uint32_t reset, uint32_t *valuep)
|
|
||||||
{
|
{
|
||||||
GError *gerror = NULL;
|
GError* gerror = NULL;
|
||||||
char *data, *end;
|
char *data, *end;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
|
||||||
data = g_key_file_get_value(key, module->name, name, &gerror);
|
data = g_key_file_get_value( key, module->name, name, &gerror );
|
||||||
if (NULL == data) {
|
if ( NULL == data ) {
|
||||||
fprintf(stderr, "%s: %s:%u: key \"%s\" not found\n",
|
fprintf( stderr, "%s: %s:%u: key \"%s\" not found\n", module->name, __FUNCTION__, __LINE__, name );
|
||||||
module->name, __FUNCTION__, __LINE__, name);
|
*valuep = reset;
|
||||||
*valuep = reset;
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
value = strtoul(data, &end, 0);
|
value = strtoul( data, &end, 0 );
|
||||||
if ((end == data) || (*end != '\0')) {
|
if ( ( end == data ) || ( *end != '\0' ) ) {
|
||||||
*valuep = reset;
|
*valuep = reset;
|
||||||
g_free(data);
|
g_free( data );
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*valuep = value;
|
*valuep = value;
|
||||||
|
|
||||||
g_free(data);
|
g_free( data );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_set_u32( x49gp_module_t* module, GKeyFile* key, const char* name, uint32_t value )
|
||||||
x49gp_module_set_u32(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, uint32_t value)
|
|
||||||
{
|
{
|
||||||
char data[16];
|
char data[ 16 ];
|
||||||
|
|
||||||
snprintf(data, sizeof(data), "0x%08x", value);
|
snprintf( data, sizeof( data ), "0x%08x", value );
|
||||||
|
|
||||||
g_key_file_set_value(key, module->name, name, data);
|
g_key_file_set_value( key, module->name, name, data );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_set_u64( x49gp_module_t* module, GKeyFile* key, const char* name, uint64_t value )
|
||||||
x49gp_module_set_u64(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, uint64_t value)
|
|
||||||
{
|
{
|
||||||
char data[32];
|
char data[ 32 ];
|
||||||
|
|
||||||
snprintf(data, sizeof(data), "0x%016" PRIx64 "", value);
|
snprintf( data, sizeof( data ), "0x%016" PRIx64 "", value );
|
||||||
|
|
||||||
g_key_file_set_value(key, module->name, name, data);
|
g_key_file_set_value( key, module->name, name, data );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_u64( x49gp_module_t* module, GKeyFile* key, const char* name, uint64_t reset, uint64_t* valuep )
|
||||||
x49gp_module_get_u64(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, uint64_t reset, uint64_t *valuep)
|
|
||||||
{
|
{
|
||||||
GError *gerror = NULL;
|
GError* gerror = NULL;
|
||||||
char *data, *end;
|
char *data, *end;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
data = g_key_file_get_value(key, module->name, name, &gerror);
|
data = g_key_file_get_value( key, module->name, name, &gerror );
|
||||||
if (NULL == data) {
|
if ( NULL == data ) {
|
||||||
fprintf(stderr, "%s: %s:%u: key \"%s\" not found\n",
|
fprintf( stderr, "%s: %s:%u: key \"%s\" not found\n", module->name, __FUNCTION__, __LINE__, name );
|
||||||
module->name, __FUNCTION__, __LINE__, name);
|
*valuep = reset;
|
||||||
*valuep = reset;
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
value = strtoull(data, &end, 0);
|
value = strtoull( data, &end, 0 );
|
||||||
if ((end == data) || (*end != '\0')) {
|
if ( ( end == data ) || ( *end != '\0' ) ) {
|
||||||
*valuep = reset;
|
*valuep = reset;
|
||||||
g_free(data);
|
g_free( data );
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*valuep = value;
|
*valuep = value;
|
||||||
|
|
||||||
g_free(data);
|
g_free( data );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_get_string( x49gp_module_t* module, GKeyFile* key, const char* name, char* reset, char** valuep )
|
||||||
x49gp_module_get_string(x49gp_module_t *module, GKeyFile *key,
|
|
||||||
const char *name, char *reset, char **valuep)
|
|
||||||
{
|
{
|
||||||
GError *gerror = NULL;
|
GError* gerror = NULL;
|
||||||
char *data;
|
char* data;
|
||||||
|
|
||||||
data = g_key_file_get_value(key, module->name, name, &gerror);
|
data = g_key_file_get_value( key, module->name, name, &gerror );
|
||||||
if (NULL == data) {
|
if ( NULL == data ) {
|
||||||
fprintf(stderr, "%s: %s:%u: key \"%s\" not found\n",
|
fprintf( stderr, "%s: %s:%u: key \"%s\" not found\n", module->name, __FUNCTION__, __LINE__, name );
|
||||||
module->name, __FUNCTION__, __LINE__, name);
|
*valuep = g_strdup( reset );
|
||||||
*valuep = g_strdup(reset);
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*valuep = data;
|
*valuep = data;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x49gp_module_set_string(x49gp_module_t *module, GKeyFile *key,
|
int x49gp_module_set_string( x49gp_module_t* module, GKeyFile* key, const char* name, const char* value )
|
||||||
const char *name, const char *value)
|
|
||||||
{
|
{
|
||||||
g_key_file_set_value(key, module->name, name, value);
|
g_key_file_set_value( key, module->name, name, value );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_open_rodata( x49gp_module_t* module, const char* name, char** path )
|
||||||
x49gp_module_open_rodata(x49gp_module_t *module, const char *name,
|
|
||||||
char **path)
|
|
||||||
{
|
{
|
||||||
x49gp_t *x49gp = module->x49gp;
|
x49gp_t* x49gp = module->x49gp;
|
||||||
int fd;
|
int fd;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
*path = g_build_filename(x49gp->progpath, name, NULL);
|
*path = g_build_filename( x49gp->progpath, name, NULL );
|
||||||
if (NULL == *path) {
|
if ( NULL == *path ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
module->name, __FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(*path, O_RDONLY);
|
fd = open( *path, O_RDONLY );
|
||||||
|
|
||||||
#ifdef X49GP_DATADIR
|
#ifdef X49GP_DATADIR
|
||||||
if (fd < 0 && (errno == EACCES || errno == ENOENT)) {
|
if ( fd < 0 && ( errno == EACCES || errno == ENOENT ) ) {
|
||||||
g_free(*path);
|
g_free( *path );
|
||||||
|
|
||||||
*path = g_build_filename(X49GP_DATADIR, name, NULL);
|
*path = g_build_filename( X49GP_DATADIR, name, NULL );
|
||||||
if (NULL == *path) {
|
if ( NULL == *path ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
module->name, __FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(*path, O_RDONLY);
|
fd = open( *path, O_RDONLY );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fd < 0) {
|
if ( fd < 0 ) {
|
||||||
error = -errno;
|
error = -errno;
|
||||||
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
|
fprintf( stderr, "%s: %s:%u: open %s: %s\n", module->name, __FUNCTION__, __LINE__, *path, strerror( errno ) );
|
||||||
module->name, __FUNCTION__, __LINE__,
|
g_free( *path );
|
||||||
*path, strerror(errno));
|
*path = NULL;
|
||||||
g_free(*path);
|
return error;
|
||||||
*path = NULL;
|
}
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_module_init( x49gp_t* x49gp, const char* name, int ( *init )( x49gp_module_t* ), int ( *exit )( x49gp_module_t* ),
|
||||||
x49gp_module_init(x49gp_t *x49gp, const char *name,
|
int ( *reset )( x49gp_module_t*, x49gp_reset_t ), int ( *load )( x49gp_module_t*, GKeyFile* ),
|
||||||
int (*init)(x49gp_module_t *),
|
int ( *save )( x49gp_module_t*, GKeyFile* ), void* user_data, x49gp_module_t** modulep )
|
||||||
int (*exit)(x49gp_module_t *),
|
|
||||||
int (*reset)(x49gp_module_t *, x49gp_reset_t),
|
|
||||||
int (*load)(x49gp_module_t *, GKeyFile *),
|
|
||||||
int (*save)(x49gp_module_t *, GKeyFile *),
|
|
||||||
void *user_data, x49gp_module_t **modulep)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
module = malloc(sizeof(x49gp_module_t));
|
module = malloc( sizeof( x49gp_module_t ) );
|
||||||
if (NULL == module) {
|
if ( NULL == module ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", name, __FUNCTION__, __LINE__ );
|
||||||
name, __FUNCTION__, __LINE__);
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
memset( module, 0, sizeof( x49gp_module_t ) );
|
||||||
memset(module, 0, sizeof(x49gp_module_t));
|
|
||||||
|
|
||||||
module->name = name;
|
module->name = name;
|
||||||
|
|
||||||
module->init = init;
|
module->init = init;
|
||||||
module->exit = exit;
|
module->exit = exit;
|
||||||
module->reset = reset;
|
module->reset = reset;
|
||||||
module->load = load;
|
module->load = load;
|
||||||
module->save = save;
|
module->save = save;
|
||||||
|
|
||||||
module->user_data = user_data;
|
module->user_data = user_data;
|
||||||
|
|
||||||
// module->mutex = g_mutex_new();
|
// module->mutex = g_mutex_new();
|
||||||
module->x49gp = x49gp;
|
module->x49gp = x49gp;
|
||||||
|
|
||||||
*modulep = module;
|
*modulep = module;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,34 +34,29 @@
|
||||||
* SPI Interface: 0x59000000
|
* SPI Interface: 0x59000000
|
||||||
* SDI Interface: 0x5a000000
|
* SDI Interface: 0x5a000000
|
||||||
*/
|
*/
|
||||||
int
|
int x49gp_s3c2410_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_s3c2410_sram_init(x49gp);
|
x49gp_s3c2410_sram_init( x49gp );
|
||||||
x49gp_s3c2410_memc_init(x49gp);
|
x49gp_s3c2410_memc_init( x49gp );
|
||||||
/* x49gp_s3c2410_usbhost_init(x49gp); */
|
/* x49gp_s3c2410_usbhost_init(x49gp); */
|
||||||
x49gp_s3c2410_intc_init(x49gp);
|
x49gp_s3c2410_intc_init( x49gp );
|
||||||
/* x49gp_s3c2410_dma_init(x49gp); */
|
/* x49gp_s3c2410_dma_init(x49gp); */
|
||||||
x49gp_s3c2410_power_init(x49gp);
|
x49gp_s3c2410_power_init( x49gp );
|
||||||
x49gp_s3c2410_lcd_init(x49gp);
|
x49gp_s3c2410_lcd_init( x49gp );
|
||||||
x49gp_s3c2410_nand_init(x49gp);
|
x49gp_s3c2410_nand_init( x49gp );
|
||||||
x49gp_s3c2410_uart_init(x49gp);
|
x49gp_s3c2410_uart_init( x49gp );
|
||||||
x49gp_s3c2410_timer_init(x49gp);
|
x49gp_s3c2410_timer_init( x49gp );
|
||||||
x49gp_s3c2410_usbdev_init(x49gp);
|
x49gp_s3c2410_usbdev_init( x49gp );
|
||||||
x49gp_s3c2410_watchdog_init(x49gp);
|
x49gp_s3c2410_watchdog_init( x49gp );
|
||||||
/* x49gp_s3c2410_i2c_init(x49gp); */
|
/* x49gp_s3c2410_i2c_init(x49gp); */
|
||||||
/* x49gp_s3c2410_iis_init(x49gp); */
|
/* x49gp_s3c2410_iis_init(x49gp); */
|
||||||
x49gp_s3c2410_io_port_init(x49gp);
|
x49gp_s3c2410_io_port_init( x49gp );
|
||||||
x49gp_s3c2410_rtc_init(x49gp);
|
x49gp_s3c2410_rtc_init( x49gp );
|
||||||
x49gp_s3c2410_adc_init(x49gp);
|
x49gp_s3c2410_adc_init( x49gp );
|
||||||
x49gp_s3c2410_spi_init(x49gp);
|
x49gp_s3c2410_spi_init( x49gp );
|
||||||
x49gp_s3c2410_sdi_init(x49gp);
|
x49gp_s3c2410_sdi_init( x49gp );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int s3c2410_exit( x49gp_t* x49gp ) { return 0; }
|
||||||
s3c2410_exit(x49gp_t *x49gp)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,250 +12,216 @@
|
||||||
#include "x49gp.h"
|
#include "x49gp.h"
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t adccon;
|
uint32_t adccon;
|
||||||
uint32_t adctsc;
|
uint32_t adctsc;
|
||||||
uint32_t adcdly;
|
uint32_t adcdly;
|
||||||
uint32_t adcdat0;
|
uint32_t adcdat0;
|
||||||
uint32_t adcdat1;
|
uint32_t adcdat1;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
} s3c2410_adc_t;
|
} s3c2410_adc_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_data_init( s3c2410_adc_t* adc )
|
||||||
s3c2410_adc_data_init(s3c2410_adc_t *adc)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = {
|
||||||
S3C2410_OFFSET(ADC, ADCCON, 0x00003fc4, adc->adccon),
|
S3C2410_OFFSET( ADC, ADCCON, 0x00003fc4, adc->adccon ), S3C2410_OFFSET( ADC, ADCTSC, 0x00000058, adc->adctsc ),
|
||||||
S3C2410_OFFSET(ADC, ADCTSC, 0x00000058, adc->adctsc),
|
S3C2410_OFFSET( ADC, ADCDLY, 0x000000ff, adc->adcdly ), S3C2410_OFFSET( ADC, ADCDAT0, 0x3ff, adc->adcdat0 ),
|
||||||
S3C2410_OFFSET(ADC, ADCDLY, 0x000000ff, adc->adcdly),
|
S3C2410_OFFSET( ADC, ADCDAT1, 0x3ff, adc->adcdat1 ),
|
||||||
S3C2410_OFFSET(ADC, ADCDAT0, 0x3ff, adc->adcdat0),
|
};
|
||||||
S3C2410_OFFSET(ADC, ADCDAT1, 0x3ff, adc->adcdat1),
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(adc, 0, sizeof(s3c2410_adc_t));
|
memset( adc, 0, sizeof( s3c2410_adc_t ) );
|
||||||
|
|
||||||
adc->regs = malloc(sizeof(regs));
|
adc->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == adc->regs) {
|
if ( NULL == adc->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(adc->regs, regs, sizeof(regs));
|
memcpy( adc->regs, regs, sizeof( regs ) );
|
||||||
adc->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
adc->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_adc_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_adc_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc = opaque;
|
s3c2410_adc_t* adc = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(adc, offset)) {
|
if ( !S3C2410_OFFSET_OK( adc, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(adc, offset);
|
reg = S3C2410_OFFSET_ENTRY( adc, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_ADC
|
#ifdef DEBUG_S3C2410_ADC
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-adc", S3C2410_ADC_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-adc", S3C2410_ADC_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_ADC_ADCCON:
|
case S3C2410_ADC_ADCCON:
|
||||||
*(reg->datap) &= ~(0x0001);
|
*( reg->datap ) &= ~( 0x0001 );
|
||||||
*(reg->datap) |= 0x8000;
|
*( reg->datap ) |= 0x8000;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_adc_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_adc_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc = opaque;
|
s3c2410_adc_t* adc = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(adc, offset)) {
|
if ( !S3C2410_OFFSET_OK( adc, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(adc, offset);
|
reg = S3C2410_OFFSET_ENTRY( adc, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_ADC
|
#ifdef DEBUG_S3C2410_ADC
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-adc", S3C2410_ADC_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-adc", S3C2410_ADC_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_adc_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc = module->user_data;
|
s3c2410_adc_t* adc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < adc->nr_regs; i++) {
|
for ( i = 0; i < adc->nr_regs; i++ ) {
|
||||||
reg = &adc->regs[i];
|
reg = &adc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_adc_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc = module->user_data;
|
s3c2410_adc_t* adc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < adc->nr_regs; i++) {
|
for ( i = 0; i < adc->nr_regs; i++ ) {
|
||||||
reg = &adc->regs[i];
|
reg = &adc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_adc_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc = module->user_data;
|
s3c2410_adc_t* adc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < adc->nr_regs; i++) {
|
for ( i = 0; i < adc->nr_regs; i++ ) {
|
||||||
reg = &adc->regs[i];
|
reg = &adc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_adc_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_adc_readfn[] = { s3c2410_adc_read, s3c2410_adc_read, s3c2410_adc_read };
|
||||||
{
|
|
||||||
s3c2410_adc_read,
|
|
||||||
s3c2410_adc_read,
|
|
||||||
s3c2410_adc_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_adc_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_adc_writefn[] = { s3c2410_adc_write, s3c2410_adc_write, s3c2410_adc_write };
|
||||||
{
|
|
||||||
s3c2410_adc_write,
|
|
||||||
s3c2410_adc_write,
|
|
||||||
s3c2410_adc_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_init( x49gp_module_t* module )
|
||||||
s3c2410_adc_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc;
|
s3c2410_adc_t* adc;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
adc = malloc(sizeof(s3c2410_adc_t));
|
adc = malloc( sizeof( s3c2410_adc_t ) );
|
||||||
if (NULL == adc) {
|
if ( NULL == adc ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_adc_data_init( adc ) ) {
|
||||||
if (s3c2410_adc_data_init(adc)) {
|
free( adc );
|
||||||
free(adc);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = adc;
|
module->user_data = adc;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_adc_readfn,
|
iotype = cpu_register_io_memory( s3c2410_adc_readfn, s3c2410_adc_writefn, adc );
|
||||||
s3c2410_adc_writefn, adc);
|
|
||||||
#ifdef DEBUG_S3C2410_ADC
|
#ifdef DEBUG_S3C2410_ADC
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_ADC_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_ADC_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_adc_exit( x49gp_module_t* module )
|
||||||
s3c2410_adc_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_adc_t *adc;
|
s3c2410_adc_t* adc;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
adc = module->user_data;
|
adc = module->user_data;
|
||||||
if (adc->regs)
|
if ( adc->regs )
|
||||||
free(adc->regs);
|
free( adc->regs );
|
||||||
free(adc);
|
free( adc );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_adc_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_adc_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-adc",
|
if ( x49gp_module_init( x49gp, "s3c2410-adc", s3c2410_adc_init, s3c2410_adc_exit, s3c2410_adc_reset, s3c2410_adc_load, s3c2410_adc_save,
|
||||||
s3c2410_adc_init,
|
NULL, &module ) ) {
|
||||||
s3c2410_adc_exit,
|
return -1;
|
||||||
s3c2410_adc_reset,
|
}
|
||||||
s3c2410_adc_load,
|
|
||||||
s3c2410_adc_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* $Id: s3c2410_arm.c,v 1.7 2008/12/11 12:18:17 ecd Exp $
|
/* $Id: s3c2410_arm.c,v 1.7 2008/12/11 12:18:17 ecd Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -15,260 +14,247 @@
|
||||||
|
|
||||||
#include "qemu-git/cpu-all.h"
|
#include "qemu-git/cpu-all.h"
|
||||||
|
|
||||||
static int
|
static int s3c2410_arm_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_arm_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
struct CPUARMState *env = module->user_data;
|
struct CPUARMState* env = module->user_data;
|
||||||
char name[32];
|
char name[ 32 ];
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_reset(env);
|
cpu_reset( env );
|
||||||
tlb_flush(env, 1);
|
tlb_flush( env, 1 );
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(env->regs) / sizeof(env->regs[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->regs ) / sizeof( env->regs[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "reg-%02u", i);
|
sprintf( name, "reg-%02u", i );
|
||||||
if (x49gp_module_get_u32(module, key, name, 0, &env->regs[i]))
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->regs[ i ] ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
}
|
}
|
||||||
if (x49gp_module_get_u32(module, key, "cpsr", 0, &env->uncached_cpsr))
|
if ( x49gp_module_get_u32( module, key, "cpsr", 0, &env->uncached_cpsr ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "spsr", 0, &env->spsr))
|
if ( x49gp_module_get_u32( module, key, "spsr", 0, &env->spsr ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
for (i = 0; i < (sizeof(env->banked_spsr) / sizeof(env->banked_spsr[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_spsr ) / sizeof( env->banked_spsr[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-spsr-%02u", i);
|
sprintf( name, "banked-spsr-%02u", i );
|
||||||
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_spsr[i]))
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->banked_spsr[ i ] ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->banked_r13) / sizeof(env->banked_r13[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_r13 ) / sizeof( env->banked_r13[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-r13-%02u", i);
|
sprintf( name, "banked-r13-%02u", i );
|
||||||
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_r13[i]))
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->banked_r13[ i ] ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->banked_r14) / sizeof(env->banked_r14[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_r14 ) / sizeof( env->banked_r14[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-r14-%02u", i);
|
sprintf( name, "banked-r14-%02u", i );
|
||||||
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_r14[i]))
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->banked_r14[ i ] ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->usr_regs) / sizeof(env->usr_regs[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->usr_regs ) / sizeof( env->usr_regs[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "reg-usr-%02u", i);
|
sprintf( name, "reg-usr-%02u", i );
|
||||||
if (x49gp_module_get_u32(module, key, name,
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->usr_regs[ i ] ) )
|
||||||
0, &env->usr_regs[i]))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
for ( i = 0; i < ( sizeof( env->fiq_regs ) / sizeof( env->fiq_regs[ 0 ] ) ); i++ ) {
|
||||||
for (i = 0; i < (sizeof(env->fiq_regs) / sizeof(env->fiq_regs[0])); i++) {
|
sprintf( name, "reg-fiq-%02u", i );
|
||||||
sprintf(name, "reg-fiq-%02u", i);
|
if ( x49gp_module_get_u32( module, key, name, 0, &env->fiq_regs[ i ] ) )
|
||||||
if (x49gp_module_get_u32(module, key, name,
|
error = -EAGAIN;
|
||||||
0, &env->fiq_regs[i]))
|
}
|
||||||
error = -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, "CF", 0, &env->CF))
|
if ( x49gp_module_get_u32( module, key, "CF", 0, &env->CF ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "VF", 0, &env->VF))
|
if ( x49gp_module_get_u32( module, key, "VF", 0, &env->VF ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "NF", 0, &env->NF))
|
if ( x49gp_module_get_u32( module, key, "NF", 0, &env->NF ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "ZF", 0, &env->ZF))
|
if ( x49gp_module_get_u32( module, key, "ZF", 0, &env->ZF ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "QF", 0, &env->QF))
|
if ( x49gp_module_get_u32( module, key, "QF", 0, &env->QF ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "thumb", 0, &env->thumb))
|
if ( x49gp_module_get_u32( module, key, "thumb", 0, &env->thumb ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c0-cpuid", 0, &env->cp15.c0_cpuid))
|
if ( x49gp_module_get_u32( module, key, "cp15-c0-cpuid", 0, &env->cp15.c0_cpuid ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c1-sys", 0, &env->cp15.c1_sys))
|
if ( x49gp_module_get_u32( module, key, "cp15-c1-sys", 0, &env->cp15.c1_sys ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c1-coproc", 0, &env->cp15.c1_coproc))
|
if ( x49gp_module_get_u32( module, key, "cp15-c1-coproc", 0, &env->cp15.c1_coproc ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-base0", 0, &env->cp15.c2_base0))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-base0", 0, &env->cp15.c2_base0 ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-base1", 0, &env->cp15.c2_base1))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-base1", 0, &env->cp15.c2_base1 ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-control", 0, &env->cp15.c2_control))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-control", 0, &env->cp15.c2_control ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-mask", 0, &env->cp15.c2_mask))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-mask", 0, &env->cp15.c2_mask ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-base-mask", 0, &env->cp15.c2_base_mask))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-base-mask", 0, &env->cp15.c2_base_mask ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-data", 0, &env->cp15.c2_data))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-data", 0, &env->cp15.c2_data ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c2-insn", 0, &env->cp15.c2_insn))
|
if ( x49gp_module_get_u32( module, key, "cp15-c2-insn", 0, &env->cp15.c2_insn ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c3", 0, &env->cp15.c3))
|
if ( x49gp_module_get_u32( module, key, "cp15-c3", 0, &env->cp15.c3 ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c5-insn", 0, &env->cp15.c5_insn))
|
if ( x49gp_module_get_u32( module, key, "cp15-c5-insn", 0, &env->cp15.c5_insn ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c5-data", 0, &env->cp15.c5_data))
|
if ( x49gp_module_get_u32( module, key, "cp15-c5-data", 0, &env->cp15.c5_data ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c6-insn", 0, &env->cp15.c6_insn))
|
if ( x49gp_module_get_u32( module, key, "cp15-c6-insn", 0, &env->cp15.c6_insn ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c6-data", 0, &env->cp15.c6_data))
|
if ( x49gp_module_get_u32( module, key, "cp15-c6-data", 0, &env->cp15.c6_data ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c9-insn", 0, &env->cp15.c9_insn))
|
if ( x49gp_module_get_u32( module, key, "cp15-c9-insn", 0, &env->cp15.c9_insn ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c9-data", 0, &env->cp15.c9_data))
|
if ( x49gp_module_get_u32( module, key, "cp15-c9-data", 0, &env->cp15.c9_data ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c13-fcse", 0, &env->cp15.c13_fcse))
|
if ( x49gp_module_get_u32( module, key, "cp15-c13-fcse", 0, &env->cp15.c13_fcse ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "cp15-c13-context", 0, &env->cp15.c13_context))
|
if ( x49gp_module_get_u32( module, key, "cp15-c13-context", 0, &env->cp15.c13_context ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, "features", 0, &env->features))
|
if ( x49gp_module_get_u32( module, key, "features", 0, &env->features ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
|
|
||||||
if (x49gp_module_get_int(module, key, "exception-index", 0, &env->exception_index))
|
if ( x49gp_module_get_int( module, key, "exception-index", 0, &env->exception_index ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "interrupt-request", 0, &env->interrupt_request))
|
if ( x49gp_module_get_u32( module, key, "interrupt-request", 0, &env->interrupt_request ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
if (x49gp_module_get_u32(module, key, "halted", 0, &env->halted))
|
if ( x49gp_module_get_u32( module, key, "halted", 0, &env->halted ) )
|
||||||
error = -EAGAIN;
|
error = -EAGAIN;
|
||||||
|
|
||||||
env->exception_index = -1;
|
env->exception_index = -1;
|
||||||
|
|
||||||
if (0 == error) {
|
if ( 0 == error ) {
|
||||||
if (env->halted)
|
if ( env->halted )
|
||||||
module->x49gp->arm_idle = 1;
|
module->x49gp->arm_idle = 1;
|
||||||
} else {
|
} else {
|
||||||
memset(&env->cp15, 0, sizeof(env->cp15));
|
memset( &env->cp15, 0, sizeof( env->cp15 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// s3c2410_arm_dump_state(state);
|
// s3c2410_arm_dump_state(state);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_arm_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_arm_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
struct CPUARMState *env = module->user_data;
|
struct CPUARMState* env = module->user_data;
|
||||||
char name[32];
|
char name[ 32 ];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(env->regs) / sizeof(env->regs[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->regs ) / sizeof( env->regs[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "reg-%02u", i);
|
sprintf( name, "reg-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->regs[i]);
|
x49gp_module_set_u32( module, key, name, env->regs[ i ] );
|
||||||
}
|
}
|
||||||
x49gp_module_set_u32(module, key, "cpsr", env->uncached_cpsr);
|
x49gp_module_set_u32( module, key, "cpsr", env->uncached_cpsr );
|
||||||
x49gp_module_set_u32(module, key, "spsr", env->spsr);
|
x49gp_module_set_u32( module, key, "spsr", env->spsr );
|
||||||
for (i = 0; i < (sizeof(env->banked_spsr) / sizeof(env->banked_spsr[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_spsr ) / sizeof( env->banked_spsr[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-spsr-%02u", i);
|
sprintf( name, "banked-spsr-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->banked_spsr[i]);
|
x49gp_module_set_u32( module, key, name, env->banked_spsr[ i ] );
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->banked_r13) / sizeof(env->banked_r13[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_r13 ) / sizeof( env->banked_r13[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-r13-%02u", i);
|
sprintf( name, "banked-r13-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->banked_r13[i]);
|
x49gp_module_set_u32( module, key, name, env->banked_r13[ i ] );
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->banked_r14) / sizeof(env->banked_r14[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->banked_r14 ) / sizeof( env->banked_r14[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "banked-r14-%02u", i);
|
sprintf( name, "banked-r14-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->banked_r14[i]);
|
x49gp_module_set_u32( module, key, name, env->banked_r14[ i ] );
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->usr_regs) / sizeof(env->usr_regs[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->usr_regs ) / sizeof( env->usr_regs[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "reg-usr-%02u", i);
|
sprintf( name, "reg-usr-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->usr_regs[i]);
|
x49gp_module_set_u32( module, key, name, env->usr_regs[ i ] );
|
||||||
}
|
}
|
||||||
for (i = 0; i < (sizeof(env->fiq_regs) / sizeof(env->fiq_regs[0])); i++) {
|
for ( i = 0; i < ( sizeof( env->fiq_regs ) / sizeof( env->fiq_regs[ 0 ] ) ); i++ ) {
|
||||||
sprintf(name, "reg-fiq-%02u", i);
|
sprintf( name, "reg-fiq-%02u", i );
|
||||||
x49gp_module_set_u32(module, key, name, env->fiq_regs[i]);
|
x49gp_module_set_u32( module, key, name, env->fiq_regs[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, "CF", env->CF);
|
x49gp_module_set_u32( module, key, "CF", env->CF );
|
||||||
x49gp_module_set_u32(module, key, "VF", env->VF);
|
x49gp_module_set_u32( module, key, "VF", env->VF );
|
||||||
x49gp_module_set_u32(module, key, "NF", env->NF);
|
x49gp_module_set_u32( module, key, "NF", env->NF );
|
||||||
x49gp_module_set_u32(module, key, "ZF", env->ZF);
|
x49gp_module_set_u32( module, key, "ZF", env->ZF );
|
||||||
x49gp_module_set_u32(module, key, "QF", env->QF);
|
x49gp_module_set_u32( module, key, "QF", env->QF );
|
||||||
x49gp_module_set_int(module, key, "thumb", env->thumb);
|
x49gp_module_set_int( module, key, "thumb", env->thumb );
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, "cp15-c0-cpuid", env->cp15.c0_cpuid);
|
x49gp_module_set_u32( module, key, "cp15-c0-cpuid", env->cp15.c0_cpuid );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c1-sys", env->cp15.c1_sys);
|
x49gp_module_set_u32( module, key, "cp15-c1-sys", env->cp15.c1_sys );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c1-coproc", env->cp15.c1_coproc);
|
x49gp_module_set_u32( module, key, "cp15-c1-coproc", env->cp15.c1_coproc );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-base0", env->cp15.c2_base0);
|
x49gp_module_set_u32( module, key, "cp15-c2-base0", env->cp15.c2_base0 );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-base1", env->cp15.c2_base1);
|
x49gp_module_set_u32( module, key, "cp15-c2-base1", env->cp15.c2_base1 );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-control", env->cp15.c2_control);
|
x49gp_module_set_u32( module, key, "cp15-c2-control", env->cp15.c2_control );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-mask", env->cp15.c2_mask);
|
x49gp_module_set_u32( module, key, "cp15-c2-mask", env->cp15.c2_mask );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-base-mask", env->cp15.c2_base_mask);
|
x49gp_module_set_u32( module, key, "cp15-c2-base-mask", env->cp15.c2_base_mask );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-data", env->cp15.c2_data);
|
x49gp_module_set_u32( module, key, "cp15-c2-data", env->cp15.c2_data );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c2-insn", env->cp15.c2_insn);
|
x49gp_module_set_u32( module, key, "cp15-c2-insn", env->cp15.c2_insn );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c3", env->cp15.c3);
|
x49gp_module_set_u32( module, key, "cp15-c3", env->cp15.c3 );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c5-insn", env->cp15.c5_insn);
|
x49gp_module_set_u32( module, key, "cp15-c5-insn", env->cp15.c5_insn );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c5-data", env->cp15.c5_data);
|
x49gp_module_set_u32( module, key, "cp15-c5-data", env->cp15.c5_data );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c6-insn", env->cp15.c6_insn);
|
x49gp_module_set_u32( module, key, "cp15-c6-insn", env->cp15.c6_insn );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c6-data", env->cp15.c6_data);
|
x49gp_module_set_u32( module, key, "cp15-c6-data", env->cp15.c6_data );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c9-insn", env->cp15.c9_insn);
|
x49gp_module_set_u32( module, key, "cp15-c9-insn", env->cp15.c9_insn );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c9-data", env->cp15.c9_data);
|
x49gp_module_set_u32( module, key, "cp15-c9-data", env->cp15.c9_data );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c13-fcse", env->cp15.c13_fcse);
|
x49gp_module_set_u32( module, key, "cp15-c13-fcse", env->cp15.c13_fcse );
|
||||||
x49gp_module_set_u32(module, key, "cp15-c13-context", env->cp15.c13_context);
|
x49gp_module_set_u32( module, key, "cp15-c13-context", env->cp15.c13_context );
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, "features", env->features);
|
x49gp_module_set_u32( module, key, "features", env->features );
|
||||||
|
|
||||||
x49gp_module_set_int(module, key, "exception-index", env->exception_index);
|
x49gp_module_set_int( module, key, "exception-index", env->exception_index );
|
||||||
x49gp_module_set_int(module, key, "interrupt-request", env->interrupt_request);
|
x49gp_module_set_int( module, key, "interrupt-request", env->interrupt_request );
|
||||||
x49gp_module_set_int(module, key, "halted", env->halted);
|
x49gp_module_set_int( module, key, "halted", env->halted );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_arm_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_arm_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
struct CPUARMState *env = module->user_data;
|
struct CPUARMState* env = module->user_data;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_reset(env);
|
cpu_reset( env );
|
||||||
tlb_flush(env, 1);
|
tlb_flush( env, 1 );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_arm_init( x49gp_module_t* module )
|
||||||
s3c2410_arm_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
x49gp_t *x49gp = module->x49gp;
|
x49gp_t* x49gp = module->x49gp;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
module->user_data = x49gp->env;
|
module->user_data = x49gp->env;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_arm_exit( x49gp_module_t* module )
|
||||||
s3c2410_arm_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_arm_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_arm_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-arm",
|
if ( x49gp_module_init( x49gp, "s3c2410-arm", s3c2410_arm_init, s3c2410_arm_exit, s3c2410_arm_reset, s3c2410_arm_load, s3c2410_arm_save,
|
||||||
s3c2410_arm_init,
|
NULL, &module ) ) {
|
||||||
s3c2410_arm_exit,
|
return -1;
|
||||||
s3c2410_arm_reset,
|
}
|
||||||
s3c2410_arm_load,
|
|
||||||
s3c2410_arm_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,69 +4,69 @@
|
||||||
#ifndef _X49GP_S3C2410_INTC_H
|
#ifndef _X49GP_S3C2410_INTC_H
|
||||||
#define _X49GP_S3C2410_INTC_H 1
|
#define _X49GP_S3C2410_INTC_H 1
|
||||||
|
|
||||||
#define INT_ADC 31
|
#define INT_ADC 31
|
||||||
#define INT_RTC 30
|
#define INT_RTC 30
|
||||||
#define INT_SPI1 29
|
#define INT_SPI1 29
|
||||||
#define INT_UART0 28
|
#define INT_UART0 28
|
||||||
#define INT_IIC 27
|
#define INT_IIC 27
|
||||||
#define INT_USBH 26
|
#define INT_USBH 26
|
||||||
#define INT_USBD 25
|
#define INT_USBD 25
|
||||||
#define INT_UART1 23
|
#define INT_UART1 23
|
||||||
#define INT_SPI0 22
|
#define INT_SPI0 22
|
||||||
#define INT_SDI 21
|
#define INT_SDI 21
|
||||||
#define INT_DMA3 20
|
#define INT_DMA3 20
|
||||||
#define INT_DMA2 19
|
#define INT_DMA2 19
|
||||||
#define INT_DMA1 18
|
#define INT_DMA1 18
|
||||||
#define INT_DMA0 17
|
#define INT_DMA0 17
|
||||||
#define INT_LCD 16
|
#define INT_LCD 16
|
||||||
#define INT_UART2 15
|
#define INT_UART2 15
|
||||||
#define INT_TIMER4 14
|
#define INT_TIMER4 14
|
||||||
#define INT_TIMER3 13
|
#define INT_TIMER3 13
|
||||||
#define INT_TIMER2 12
|
#define INT_TIMER2 12
|
||||||
#define INT_TIMER1 11
|
#define INT_TIMER1 11
|
||||||
#define INT_TIMER0 10
|
#define INT_TIMER0 10
|
||||||
#define INT_WDT 9
|
#define INT_WDT 9
|
||||||
#define INT_TICK 8
|
#define INT_TICK 8
|
||||||
#define nBATT_FLT 7
|
#define nBATT_FLT 7
|
||||||
#define EINT8_23 5
|
#define EINT8_23 5
|
||||||
#define EINT4_7 4
|
#define EINT4_7 4
|
||||||
#define EINT3 3
|
#define EINT3 3
|
||||||
#define EINT2 2
|
#define EINT2 2
|
||||||
#define EINT1 1
|
#define EINT1 1
|
||||||
#define EINT0 0
|
#define EINT0 0
|
||||||
|
|
||||||
#define SUB_INT_ADC 10
|
#define SUB_INT_ADC 10
|
||||||
#define SUB_INT_TC 9
|
#define SUB_INT_TC 9
|
||||||
#define SUB_INT_ERR2 8
|
#define SUB_INT_ERR2 8
|
||||||
#define SUB_INT_TXD2 7
|
#define SUB_INT_TXD2 7
|
||||||
#define SUB_INT_RXD2 6
|
#define SUB_INT_RXD2 6
|
||||||
#define SUB_INT_ERR1 5
|
#define SUB_INT_ERR1 5
|
||||||
#define SUB_INT_TXD1 4
|
#define SUB_INT_TXD1 4
|
||||||
#define SUB_INT_RXD1 3
|
#define SUB_INT_RXD1 3
|
||||||
#define SUB_INT_ERR0 2
|
#define SUB_INT_ERR0 2
|
||||||
#define SUB_INT_TXD0 1
|
#define SUB_INT_TXD0 1
|
||||||
#define SUB_INT_RXD0 0
|
#define SUB_INT_RXD0 0
|
||||||
|
|
||||||
#define ARB0_MODE (1 << 0)
|
#define ARB0_MODE ( 1 << 0 )
|
||||||
#define ARB1_MODE (1 << 1)
|
#define ARB1_MODE ( 1 << 1 )
|
||||||
#define ARB2_MODE (1 << 2)
|
#define ARB2_MODE ( 1 << 2 )
|
||||||
#define ARB3_MODE (1 << 3)
|
#define ARB3_MODE ( 1 << 3 )
|
||||||
#define ARB4_MODE (1 << 4)
|
#define ARB4_MODE ( 1 << 4 )
|
||||||
#define ARB5_MODE (1 << 5)
|
#define ARB5_MODE ( 1 << 5 )
|
||||||
#define ARB6_MODE (1 << 6)
|
#define ARB6_MODE ( 1 << 6 )
|
||||||
#define ARB0_SEL_SHIFT 7
|
#define ARB0_SEL_SHIFT 7
|
||||||
#define ARB1_SEL_SHIFT 9
|
#define ARB1_SEL_SHIFT 9
|
||||||
#define ARB2_SEL_SHIFT 11
|
#define ARB2_SEL_SHIFT 11
|
||||||
#define ARB3_SEL_SHIFT 13
|
#define ARB3_SEL_SHIFT 13
|
||||||
#define ARB4_SEL_SHIFT 15
|
#define ARB4_SEL_SHIFT 15
|
||||||
#define ARB5_SEL_SHIFT 17
|
#define ARB5_SEL_SHIFT 17
|
||||||
#define ARB6_SEL_SHIFT 19
|
#define ARB6_SEL_SHIFT 19
|
||||||
#define ARBx_SEL_MASK 3
|
#define ARBx_SEL_MASK 3
|
||||||
|
|
||||||
void s3c2410_intc_sub_assert(x49gp_t *x49gp, int sub_irq, int level);
|
void s3c2410_intc_sub_assert( x49gp_t* x49gp, int sub_irq, int level );
|
||||||
void s3c2410_intc_sub_deassert(x49gp_t *x49gp, int sub_irq);
|
void s3c2410_intc_sub_deassert( x49gp_t* x49gp, int sub_irq );
|
||||||
|
|
||||||
void s3c2410_intc_assert(x49gp_t *x49gp, int irq, int level);
|
void s3c2410_intc_assert( x49gp_t* x49gp, int irq, int level );
|
||||||
void s3c2410_intc_deassert(x49gp_t *x49gp, int irq);
|
void s3c2410_intc_deassert( x49gp_t* x49gp, int irq );
|
||||||
|
|
||||||
#endif /* !(_X49GP_S3C2410_INTC_H) */
|
#endif /* !(_X49GP_S3C2410_INTC_H) */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,402 +15,348 @@
|
||||||
#include "x49gp_ui.h"
|
#include "x49gp_ui.h"
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t lcdcon1;
|
uint32_t lcdcon1;
|
||||||
uint32_t lcdcon2;
|
uint32_t lcdcon2;
|
||||||
uint32_t lcdcon3;
|
uint32_t lcdcon3;
|
||||||
uint32_t lcdcon4;
|
uint32_t lcdcon4;
|
||||||
uint32_t lcdcon5;
|
uint32_t lcdcon5;
|
||||||
uint32_t lcdsaddr1;
|
uint32_t lcdsaddr1;
|
||||||
uint32_t lcdsaddr2;
|
uint32_t lcdsaddr2;
|
||||||
uint32_t lcdsaddr3;
|
uint32_t lcdsaddr3;
|
||||||
uint32_t redlut;
|
uint32_t redlut;
|
||||||
uint32_t greenlut;
|
uint32_t greenlut;
|
||||||
uint32_t bluelut;
|
uint32_t bluelut;
|
||||||
uint32_t dithmode;
|
uint32_t dithmode;
|
||||||
uint32_t tpal;
|
uint32_t tpal;
|
||||||
uint32_t lcdintpnd;
|
uint32_t lcdintpnd;
|
||||||
uint32_t lcdsrcpnd;
|
uint32_t lcdsrcpnd;
|
||||||
uint32_t lcdintmsk;
|
uint32_t lcdintmsk;
|
||||||
uint32_t lpcsel;
|
uint32_t lpcsel;
|
||||||
uint32_t __unknown_68;
|
uint32_t __unknown_68;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
} s3c2410_lcd_t;
|
} s3c2410_lcd_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_lcd_data_init( s3c2410_lcd_t* lcd )
|
||||||
s3c2410_lcd_data_init(s3c2410_lcd_t *lcd)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = {
|
||||||
S3C2410_OFFSET(LCD, LCDCON1, 0x00000000, lcd->lcdcon1),
|
S3C2410_OFFSET( LCD, LCDCON1, 0x00000000, lcd->lcdcon1 ), S3C2410_OFFSET( LCD, LCDCON2, 0x00000000, lcd->lcdcon2 ),
|
||||||
S3C2410_OFFSET(LCD, LCDCON2, 0x00000000, lcd->lcdcon2),
|
S3C2410_OFFSET( LCD, LCDCON3, 0x00000000, lcd->lcdcon3 ), S3C2410_OFFSET( LCD, LCDCON4, 0x00000000, lcd->lcdcon4 ),
|
||||||
S3C2410_OFFSET(LCD, LCDCON3, 0x00000000, lcd->lcdcon3),
|
S3C2410_OFFSET( LCD, LCDCON5, 0x00000000, lcd->lcdcon5 ), S3C2410_OFFSET( LCD, LCDSADDR1, 0x00000000, lcd->lcdsaddr1 ),
|
||||||
S3C2410_OFFSET(LCD, LCDCON4, 0x00000000, lcd->lcdcon4),
|
S3C2410_OFFSET( LCD, LCDSADDR2, 0x00000000, lcd->lcdsaddr2 ), S3C2410_OFFSET( LCD, LCDSADDR3, 0x00000000, lcd->lcdsaddr3 ),
|
||||||
S3C2410_OFFSET(LCD, LCDCON5, 0x00000000, lcd->lcdcon5),
|
S3C2410_OFFSET( LCD, REDLUT, 0x00000000, lcd->redlut ), S3C2410_OFFSET( LCD, GREENLUT, 0x00000000, lcd->greenlut ),
|
||||||
S3C2410_OFFSET(LCD, LCDSADDR1, 0x00000000, lcd->lcdsaddr1),
|
S3C2410_OFFSET( LCD, BLUELUT, 0x00000000, lcd->bluelut ), S3C2410_OFFSET( LCD, DITHMODE, 0x00000000, lcd->dithmode ),
|
||||||
S3C2410_OFFSET(LCD, LCDSADDR2, 0x00000000, lcd->lcdsaddr2),
|
S3C2410_OFFSET( LCD, TPAL, 0x00000000, lcd->tpal ), S3C2410_OFFSET( LCD, LCDINTPND, 0x00000000, lcd->lcdintpnd ),
|
||||||
S3C2410_OFFSET(LCD, LCDSADDR3, 0x00000000, lcd->lcdsaddr3),
|
S3C2410_OFFSET( LCD, LCDSRCPND, 0x00000000, lcd->lcdsrcpnd ), S3C2410_OFFSET( LCD, LCDINTMSK, 0x00000003, lcd->lcdintmsk ),
|
||||||
S3C2410_OFFSET(LCD, REDLUT, 0x00000000, lcd->redlut),
|
S3C2410_OFFSET( LCD, LPCSEL, 0x00000004, lcd->lpcsel ), S3C2410_OFFSET( LCD, UNKNOWN_68, 0x00000000, lcd->__unknown_68 ) };
|
||||||
S3C2410_OFFSET(LCD, GREENLUT, 0x00000000, lcd->greenlut),
|
|
||||||
S3C2410_OFFSET(LCD, BLUELUT, 0x00000000, lcd->bluelut),
|
|
||||||
S3C2410_OFFSET(LCD, DITHMODE, 0x00000000, lcd->dithmode),
|
|
||||||
S3C2410_OFFSET(LCD, TPAL, 0x00000000, lcd->tpal),
|
|
||||||
S3C2410_OFFSET(LCD, LCDINTPND, 0x00000000, lcd->lcdintpnd),
|
|
||||||
S3C2410_OFFSET(LCD, LCDSRCPND, 0x00000000, lcd->lcdsrcpnd),
|
|
||||||
S3C2410_OFFSET(LCD, LCDINTMSK, 0x00000003, lcd->lcdintmsk),
|
|
||||||
S3C2410_OFFSET(LCD, LPCSEL, 0x00000004, lcd->lpcsel),
|
|
||||||
S3C2410_OFFSET(LCD, UNKNOWN_68, 0x00000000, lcd->__unknown_68)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(lcd, 0, sizeof(s3c2410_lcd_t));
|
memset( lcd, 0, sizeof( s3c2410_lcd_t ) );
|
||||||
|
|
||||||
lcd->regs = malloc(sizeof(regs));
|
lcd->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == lcd->regs) {
|
if ( NULL == lcd->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(lcd->regs, regs, sizeof(regs));
|
memcpy( lcd->regs, regs, sizeof( regs ) );
|
||||||
lcd->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
lcd->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void x49gp_schedule_lcd_update( x49gp_t* x49gp )
|
||||||
x49gp_schedule_lcd_update(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
if (! x49gp_timer_pending(x49gp->lcd_timer)) {
|
if ( !x49gp_timer_pending( x49gp->lcd_timer ) ) {
|
||||||
x49gp_mod_timer(x49gp->lcd_timer,
|
x49gp_mod_timer( x49gp->lcd_timer, x49gp_get_clock() + X49GP_LCD_REFRESH_INTERVAL );
|
||||||
x49gp_get_clock() + X49GP_LCD_REFRESH_INTERVAL);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int x49gp_get_pixel_color( s3c2410_lcd_t* lcd, int x, int y )
|
||||||
x49gp_get_pixel_color(s3c2410_lcd_t *lcd, int x, int y)
|
|
||||||
{
|
{
|
||||||
uint32_t bank, addr, data, offset, pixel_offset;
|
uint32_t bank, addr, data, offset, pixel_offset;
|
||||||
int bits_per_pixel = lcd->lcdcon5 > 2 ? 1 : 4 >> lcd->lcdcon5;
|
int bits_per_pixel = lcd->lcdcon5 > 2 ? 1 : 4 >> lcd->lcdcon5;
|
||||||
|
|
||||||
bank = (lcd->lcdsaddr1 << 1) & 0x7fc00000;
|
bank = ( lcd->lcdsaddr1 << 1 ) & 0x7fc00000;
|
||||||
addr = bank | ((lcd->lcdsaddr1 << 1) & 0x003ffffe);
|
addr = bank | ( ( lcd->lcdsaddr1 << 1 ) & 0x003ffffe );
|
||||||
|
|
||||||
pixel_offset = (160 * y + x) * bits_per_pixel;
|
pixel_offset = ( 160 * y + x ) * bits_per_pixel;
|
||||||
offset = (pixel_offset >> 3) & 0xfffffffc;
|
offset = ( pixel_offset >> 3 ) & 0xfffffffc;
|
||||||
|
|
||||||
data = ldl_phys(addr + offset);
|
data = ldl_phys( addr + offset );
|
||||||
data >>= pixel_offset & 31;
|
data >>= pixel_offset & 31;
|
||||||
data &= (1 << bits_per_pixel) - 1;
|
data &= ( 1 << bits_per_pixel ) - 1;
|
||||||
|
|
||||||
switch (bits_per_pixel) {
|
switch ( bits_per_pixel ) {
|
||||||
case 1:
|
case 1:
|
||||||
return 15 * data;
|
return 15 * data;
|
||||||
case 2:
|
case 2:
|
||||||
return 15 & (lcd->bluelut >> (4 * data));
|
return 15 & ( lcd->bluelut >> ( 4 * data ) );
|
||||||
default:
|
default:
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void x49gp_lcd_update( x49gp_t* x49gp )
|
||||||
x49gp_lcd_update(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_ui_t *ui = x49gp->ui;
|
x49gp_ui_t* ui = x49gp->ui;
|
||||||
s3c2410_lcd_t *lcd = x49gp->s3c2410_lcd;
|
s3c2410_lcd_t* lcd = x49gp->s3c2410_lcd;
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
GdkGC *gc;
|
GdkGC* gc;
|
||||||
int color, x, y;
|
int color, x, y;
|
||||||
|
|
||||||
if (!(lcd->lcdcon1 & 1)) {
|
if ( !( lcd->lcdcon1 & 1 ) ) {
|
||||||
gdk_draw_drawable(ui->lcd_pixmap, ui->window->style->bg_gc[0],
|
gdk_draw_drawable( ui->lcd_pixmap, ui->window->style->bg_gc[ 0 ], ui->bg_pixmap, ui->lcd_x_offset, ui->lcd_y_offset, 0, 0,
|
||||||
ui->bg_pixmap,
|
ui->lcd_width, ui->lcd_height );
|
||||||
ui->lcd_x_offset, ui->lcd_y_offset,
|
goto done;
|
||||||
0, 0, ui->lcd_width, ui->lcd_height);
|
}
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdk_draw_drawable(ui->lcd_pixmap, ui->window->style->bg_gc[0],
|
gdk_draw_drawable( ui->lcd_pixmap, ui->window->style->bg_gc[ 0 ], ui->bg_pixmap, ui->lcd_x_offset, ui->lcd_y_offset, 0, 0,
|
||||||
ui->bg_pixmap,
|
ui->lcd_width, ui->lcd_height );
|
||||||
ui->lcd_x_offset, ui->lcd_y_offset,
|
|
||||||
0, 0, ui->lcd_width, ui->lcd_height);
|
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 0);
|
color = x49gp_get_pixel_color( lcd, 131, 0 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_io_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_io_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_io_gc, TRUE, 236, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_io_gc, TRUE, 236, 0, 15, 12 );
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 1);
|
color = x49gp_get_pixel_color( lcd, 131, 1 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_left_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_left_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_left_gc, TRUE, 11, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_left_gc, TRUE, 11, 0, 15, 12 );
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 2);
|
color = x49gp_get_pixel_color( lcd, 131, 2 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_right_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_right_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_right_gc, TRUE, 56, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_right_gc, TRUE, 56, 0, 15, 12 );
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 3);
|
color = x49gp_get_pixel_color( lcd, 131, 3 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_alpha_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_alpha_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_alpha_gc, TRUE, 101, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_alpha_gc, TRUE, 101, 0, 15, 12 );
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 4);
|
color = x49gp_get_pixel_color( lcd, 131, 4 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_battery_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_battery_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_battery_gc, TRUE, 146, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_battery_gc, TRUE, 146, 0, 15, 12 );
|
||||||
|
|
||||||
color = x49gp_get_pixel_color(lcd, 131, 5);
|
color = x49gp_get_pixel_color( lcd, 131, 5 );
|
||||||
gdk_gc_set_rgb_fg_color(ui->ann_busy_gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( ui->ann_busy_gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, ui->ann_busy_gc, TRUE, 191, 0, 15, 12);
|
gdk_draw_rectangle( ui->lcd_pixmap, ui->ann_busy_gc, TRUE, 191, 0, 15, 12 );
|
||||||
|
|
||||||
gc = gdk_gc_new(ui->lcd_canvas->window);
|
gc = gdk_gc_new( ui->lcd_canvas->window );
|
||||||
|
|
||||||
for (y = 0; y < (ui->lcd_height - ui->lcd_top_margin) / 2; y++) {
|
for ( y = 0; y < ( ui->lcd_height - ui->lcd_top_margin ) / 2; y++ ) {
|
||||||
for (x = 0; x < ui->lcd_width / 2; x++) {
|
for ( x = 0; x < ui->lcd_width / 2; x++ ) {
|
||||||
color = x49gp_get_pixel_color(lcd, x, y);
|
color = x49gp_get_pixel_color( lcd, x, y );
|
||||||
gdk_gc_set_rgb_fg_color(gc, &(ui->colors[UI_COLOR_GRAYSCALE_0 + color]));
|
gdk_gc_set_rgb_fg_color( gc, &( ui->colors[ UI_COLOR_GRAYSCALE_0 + color ] ) );
|
||||||
gdk_draw_rectangle(ui->lcd_pixmap, gc, TRUE,
|
gdk_draw_rectangle( ui->lcd_pixmap, gc, TRUE, 2 * x, 2 * y + ui->lcd_top_margin, 2, 2 );
|
||||||
2 * x, 2 * y + ui->lcd_top_margin, 2, 2);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref(gc);
|
g_object_unref( gc );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
rect.x = 0;
|
rect.x = 0;
|
||||||
rect.y = 0;
|
rect.y = 0;
|
||||||
rect.width = ui->lcd_width;
|
rect.width = ui->lcd_width;
|
||||||
rect.height = ui->lcd_height;
|
rect.height = ui->lcd_height;
|
||||||
|
|
||||||
gdk_window_invalidate_rect(ui->lcd_canvas->window, &rect, FALSE);
|
gdk_window_invalidate_rect( ui->lcd_canvas->window, &rect, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t s3c2410_lcd_read( void* opaque, target_phys_addr_t offset )
|
||||||
static uint32_t
|
|
||||||
s3c2410_lcd_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd = opaque;
|
s3c2410_lcd_t* lcd = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
uint32_t linecnt;
|
uint32_t linecnt;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(lcd, offset)) {
|
if ( !S3C2410_OFFSET_OK( lcd, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(lcd, offset);
|
reg = S3C2410_OFFSET_ENTRY( lcd, offset );
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_LCD_LCDCON1:
|
case S3C2410_LCD_LCDCON1:
|
||||||
linecnt = (lcd->lcdcon1 >> 18) & 0x3ff;
|
linecnt = ( lcd->lcdcon1 >> 18 ) & 0x3ff;
|
||||||
if (linecnt > 0) {
|
if ( linecnt > 0 ) {
|
||||||
linecnt--;
|
linecnt--;
|
||||||
} else {
|
} else {
|
||||||
linecnt = (lcd->lcdcon2 >> 14) & 0x3ff;
|
linecnt = ( lcd->lcdcon2 >> 14 ) & 0x3ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd->lcdcon1 &= ~(0x3ff << 18);
|
lcd->lcdcon1 &= ~( 0x3ff << 18 );
|
||||||
lcd->lcdcon1 |= (linecnt << 18);
|
lcd->lcdcon1 |= ( linecnt << 18 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_LCD
|
#ifdef DEBUG_S3C2410_LCD
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-lcd", S3C2410_LCD_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-lcd", S3C2410_LCD_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_lcd_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_lcd_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd = opaque;
|
s3c2410_lcd_t* lcd = opaque;
|
||||||
x49gp_t *x49gp = lcd->x49gp;
|
x49gp_t* x49gp = lcd->x49gp;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(lcd, offset)) {
|
if ( !S3C2410_OFFSET_OK( lcd, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(lcd, offset);
|
reg = S3C2410_OFFSET_ENTRY( lcd, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_LCD
|
#ifdef DEBUG_S3C2410_LCD
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-lcd", S3C2410_LCD_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-lcd", S3C2410_LCD_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_LCD_LCDCON1:
|
case S3C2410_LCD_LCDCON1:
|
||||||
if ((lcd->lcdcon1 ^ data) & 1) {
|
if ( ( lcd->lcdcon1 ^ data ) & 1 ) {
|
||||||
x49gp_schedule_lcd_update(x49gp);
|
x49gp_schedule_lcd_update( x49gp );
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd->lcdcon1 = (lcd->lcdcon1 & (0x3ff << 18)) |
|
lcd->lcdcon1 = ( lcd->lcdcon1 & ( 0x3ff << 18 ) ) | ( data & ~( 0x3ff << 18 ) );
|
||||||
(data & ~(0x3ff << 18));
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
*( reg->datap ) = data;
|
||||||
*(reg->datap) = data;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int s3c2410_lcd_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
static int
|
|
||||||
s3c2410_lcd_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd = module->user_data;
|
s3c2410_lcd_t* lcd = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < lcd->nr_regs; i++) {
|
for ( i = 0; i < lcd->nr_regs; i++ ) {
|
||||||
reg = &lcd->regs[i];
|
reg = &lcd->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_lcd_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_lcd_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd = module->user_data;
|
s3c2410_lcd_t* lcd = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < lcd->nr_regs; i++) {
|
for ( i = 0; i < lcd->nr_regs; i++ ) {
|
||||||
reg = &lcd->regs[i];
|
reg = &lcd->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_lcd_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_lcd_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd = module->user_data;
|
s3c2410_lcd_t* lcd = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < lcd->nr_regs; i++) {
|
for ( i = 0; i < lcd->nr_regs; i++ ) {
|
||||||
reg = &lcd->regs[i];
|
reg = &lcd->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_lcd_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_lcd_readfn[] = { s3c2410_lcd_read, s3c2410_lcd_read, s3c2410_lcd_read };
|
||||||
{
|
|
||||||
s3c2410_lcd_read,
|
|
||||||
s3c2410_lcd_read,
|
|
||||||
s3c2410_lcd_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_lcd_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_lcd_writefn[] = { s3c2410_lcd_write, s3c2410_lcd_write, s3c2410_lcd_write };
|
||||||
{
|
|
||||||
s3c2410_lcd_write,
|
|
||||||
s3c2410_lcd_write,
|
|
||||||
s3c2410_lcd_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_lcd_init( x49gp_module_t* module )
|
||||||
s3c2410_lcd_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd;
|
s3c2410_lcd_t* lcd;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lcd = malloc(sizeof(s3c2410_lcd_t));
|
lcd = malloc( sizeof( s3c2410_lcd_t ) );
|
||||||
if (NULL == lcd) {
|
if ( NULL == lcd ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_lcd_data_init( lcd ) ) {
|
||||||
if (s3c2410_lcd_data_init(lcd)) {
|
free( lcd );
|
||||||
free(lcd);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = lcd;
|
module->user_data = lcd;
|
||||||
module->x49gp->s3c2410_lcd = lcd;
|
module->x49gp->s3c2410_lcd = lcd;
|
||||||
lcd->x49gp = module->x49gp;
|
lcd->x49gp = module->x49gp;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_lcd_readfn,
|
iotype = cpu_register_io_memory( s3c2410_lcd_readfn, s3c2410_lcd_writefn, lcd );
|
||||||
s3c2410_lcd_writefn, lcd);
|
|
||||||
#ifdef DEBUG_S3C2410_LCD
|
#ifdef DEBUG_S3C2410_LCD
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_LCD_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_LCD_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_lcd_exit( x49gp_module_t* module )
|
||||||
s3c2410_lcd_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_lcd_t *lcd;
|
s3c2410_lcd_t* lcd;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
lcd = module->user_data;
|
lcd = module->user_data;
|
||||||
if (lcd->regs)
|
if ( lcd->regs )
|
||||||
free(lcd->regs);
|
free( lcd->regs );
|
||||||
free(lcd);
|
free( lcd );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_lcd_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_lcd_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-lcd",
|
if ( x49gp_module_init( x49gp, "s3c2410-lcd", s3c2410_lcd_init, s3c2410_lcd_exit, s3c2410_lcd_reset, s3c2410_lcd_load, s3c2410_lcd_save,
|
||||||
s3c2410_lcd_init,
|
NULL, &module ) ) {
|
||||||
s3c2410_lcd_exit,
|
return -1;
|
||||||
s3c2410_lcd_reset,
|
}
|
||||||
s3c2410_lcd_load,
|
|
||||||
s3c2410_lcd_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,263 +12,231 @@
|
||||||
#include "x49gp.h"
|
#include "x49gp.h"
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t bwscon;
|
uint32_t bwscon;
|
||||||
uint32_t bankcon0;
|
uint32_t bankcon0;
|
||||||
uint32_t bankcon1;
|
uint32_t bankcon1;
|
||||||
uint32_t bankcon2;
|
uint32_t bankcon2;
|
||||||
uint32_t bankcon3;
|
uint32_t bankcon3;
|
||||||
uint32_t bankcon4;
|
uint32_t bankcon4;
|
||||||
uint32_t bankcon5;
|
uint32_t bankcon5;
|
||||||
uint32_t bankcon6;
|
uint32_t bankcon6;
|
||||||
uint32_t bankcon7;
|
uint32_t bankcon7;
|
||||||
uint32_t refresh;
|
uint32_t refresh;
|
||||||
uint32_t banksize;
|
uint32_t banksize;
|
||||||
uint32_t mrsrb6;
|
uint32_t mrsrb6;
|
||||||
uint32_t mrsrb7;
|
uint32_t mrsrb7;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
} s3c2410_memc_t;
|
} s3c2410_memc_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_data_init( s3c2410_memc_t* memc )
|
||||||
s3c2410_memc_data_init(s3c2410_memc_t *memc)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = {
|
||||||
S3C2410_OFFSET(MEMC, BWSCON, 0x00000000, memc->bwscon),
|
S3C2410_OFFSET( MEMC, BWSCON, 0x00000000, memc->bwscon ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON0, 0x00000700, memc->bankcon0),
|
S3C2410_OFFSET( MEMC, BANKCON0, 0x00000700, memc->bankcon0 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON1, 0x00000700, memc->bankcon1),
|
S3C2410_OFFSET( MEMC, BANKCON1, 0x00000700, memc->bankcon1 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON2, 0x00000700, memc->bankcon2),
|
S3C2410_OFFSET( MEMC, BANKCON2, 0x00000700, memc->bankcon2 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON3, 0x00000700, memc->bankcon3),
|
S3C2410_OFFSET( MEMC, BANKCON3, 0x00000700, memc->bankcon3 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON4, 0x00000700, memc->bankcon4),
|
S3C2410_OFFSET( MEMC, BANKCON4, 0x00000700, memc->bankcon4 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON5, 0x00000700, memc->bankcon5),
|
S3C2410_OFFSET( MEMC, BANKCON5, 0x00000700, memc->bankcon5 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON6, 0x00018008, memc->bankcon6),
|
S3C2410_OFFSET( MEMC, BANKCON6, 0x00018008, memc->bankcon6 ),
|
||||||
S3C2410_OFFSET(MEMC, BANKCON7, 0x00018008, memc->bankcon7),
|
S3C2410_OFFSET( MEMC, BANKCON7, 0x00018008, memc->bankcon7 ),
|
||||||
S3C2410_OFFSET(MEMC, REFRESH, 0x00ac0000, memc->refresh),
|
S3C2410_OFFSET( MEMC, REFRESH, 0x00ac0000, memc->refresh ),
|
||||||
S3C2410_OFFSET(MEMC, BANKSIZE, 0x00000000, memc->banksize),
|
S3C2410_OFFSET( MEMC, BANKSIZE, 0x00000000, memc->banksize ),
|
||||||
S3C2410_OFFSET(MEMC, MRSRB6, 0, memc->mrsrb6),
|
S3C2410_OFFSET( MEMC, MRSRB6, 0, memc->mrsrb6 ),
|
||||||
S3C2410_OFFSET(MEMC, MRSRB7, 0, memc->mrsrb7),
|
S3C2410_OFFSET( MEMC, MRSRB7, 0, memc->mrsrb7 ),
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(memc, 0, sizeof(s3c2410_memc_t));
|
memset( memc, 0, sizeof( s3c2410_memc_t ) );
|
||||||
|
|
||||||
memc->regs = malloc(sizeof(regs));
|
memc->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == memc->regs) {
|
if ( NULL == memc->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(memc->regs, regs, sizeof(regs));
|
memcpy( memc->regs, regs, sizeof( regs ) );
|
||||||
memc->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
memc->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_memc_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_memc_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc = opaque;
|
s3c2410_memc_t* memc = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(memc, offset)) {
|
if ( !S3C2410_OFFSET_OK( memc, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(memc, offset);
|
reg = S3C2410_OFFSET_ENTRY( memc, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_MEMC
|
#ifdef DEBUG_S3C2410_MEMC
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-memc", S3C2410_MEMC_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-memc", S3C2410_MEMC_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_memc_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_memc_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc = opaque;
|
s3c2410_memc_t* memc = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(memc, offset)) {
|
if ( !S3C2410_OFFSET_OK( memc, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(memc, offset);
|
reg = S3C2410_OFFSET_ENTRY( memc, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_MEMC
|
#ifdef DEBUG_S3C2410_MEMC
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-memc", S3C2410_MEMC_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-memc", S3C2410_MEMC_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_MEMC
|
#ifdef DEBUG_S3C2410_MEMC
|
||||||
printf("%s:%u: env %p\n", __FUNCTION__, __LINE__, memc->x49gp->env);
|
printf( "%s:%u: env %p\n", __FUNCTION__, __LINE__, memc->x49gp->env );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_memc_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc = module->user_data;
|
s3c2410_memc_t* memc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < memc->nr_regs; i++) {
|
for ( i = 0; i < memc->nr_regs; i++ ) {
|
||||||
reg = &memc->regs[i];
|
reg = &memc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_memc_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc = module->user_data;
|
s3c2410_memc_t* memc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < memc->nr_regs; i++) {
|
for ( i = 0; i < memc->nr_regs; i++ ) {
|
||||||
reg = &memc->regs[i];
|
reg = &memc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_memc_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc = module->user_data;
|
s3c2410_memc_t* memc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < memc->nr_regs; i++) {
|
for ( i = 0; i < memc->nr_regs; i++ ) {
|
||||||
reg = &memc->regs[i];
|
reg = &memc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_memc_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_memc_readfn[] = { s3c2410_memc_read, s3c2410_memc_read, s3c2410_memc_read };
|
||||||
{
|
|
||||||
s3c2410_memc_read,
|
|
||||||
s3c2410_memc_read,
|
|
||||||
s3c2410_memc_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_memc_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_memc_writefn[] = { s3c2410_memc_write, s3c2410_memc_write, s3c2410_memc_write };
|
||||||
{
|
|
||||||
s3c2410_memc_write,
|
|
||||||
s3c2410_memc_write,
|
|
||||||
s3c2410_memc_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_init( x49gp_module_t* module )
|
||||||
s3c2410_memc_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc;
|
s3c2410_memc_t* memc;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memc = malloc(sizeof(s3c2410_memc_t));
|
memc = malloc( sizeof( s3c2410_memc_t ) );
|
||||||
if (NULL == memc) {
|
if ( NULL == memc ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_memc_data_init( memc ) ) {
|
||||||
if (s3c2410_memc_data_init(memc)) {
|
free( memc );
|
||||||
free(memc);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = memc;
|
module->user_data = memc;
|
||||||
memc->x49gp = module->x49gp;
|
memc->x49gp = module->x49gp;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_memc_readfn,
|
iotype = cpu_register_io_memory( s3c2410_memc_readfn, s3c2410_memc_writefn, memc );
|
||||||
s3c2410_memc_writefn, memc);
|
|
||||||
#ifdef DEBUG_S3C2410_MEMC
|
#ifdef DEBUG_S3C2410_MEMC
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_MEMC_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_MEMC_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_memc_exit( x49gp_module_t* module )
|
||||||
s3c2410_memc_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_memc_t *memc;
|
s3c2410_memc_t* memc;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
memc = module->user_data;
|
memc = module->user_data;
|
||||||
if (memc->regs)
|
if ( memc->regs )
|
||||||
free(memc->regs);
|
free( memc->regs );
|
||||||
free(memc);
|
free( memc );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_memc_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_memc_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-memc",
|
if ( x49gp_module_init( x49gp, "s3c2410-memc", s3c2410_memc_init, s3c2410_memc_exit, s3c2410_memc_reset, s3c2410_memc_load,
|
||||||
s3c2410_memc_init,
|
s3c2410_memc_save, NULL, &module ) ) {
|
||||||
s3c2410_memc_exit,
|
return -1;
|
||||||
s3c2410_memc_reset,
|
}
|
||||||
s3c2410_memc_load,
|
|
||||||
s3c2410_memc_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,34 +4,34 @@
|
||||||
#ifndef _S3C2410_MMU_H
|
#ifndef _S3C2410_MMU_H
|
||||||
#define _S3C2410_MMU_H 1
|
#define _S3C2410_MMU_H 1
|
||||||
|
|
||||||
#define S3C2410_MMU_TLB_SIZE 64
|
#define S3C2410_MMU_TLB_SIZE 64
|
||||||
#define S3C2410_MMU_TLB_MASK (S3C2410_MMU_TLB_SIZE - 1)
|
#define S3C2410_MMU_TLB_MASK ( S3C2410_MMU_TLB_SIZE - 1 )
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t mva;
|
uint32_t mva;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
uint32_t pa;
|
uint32_t pa;
|
||||||
uint32_t dac;
|
uint32_t dac;
|
||||||
int valid;
|
int valid;
|
||||||
} TLB_entry_t;
|
} TLB_entry_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int victim;
|
int victim;
|
||||||
int base;
|
int base;
|
||||||
int index0;
|
int index0;
|
||||||
int index1;
|
int index1;
|
||||||
unsigned long hit0;
|
unsigned long hit0;
|
||||||
unsigned long hit1;
|
unsigned long hit1;
|
||||||
unsigned long search;
|
unsigned long search;
|
||||||
unsigned long nsearch;
|
unsigned long nsearch;
|
||||||
unsigned long walk;
|
unsigned long walk;
|
||||||
TLB_entry_t data[S3C2410_MMU_TLB_SIZE];
|
TLB_entry_t data[ S3C2410_MMU_TLB_SIZE ];
|
||||||
} TLB_t;
|
} TLB_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t MMUReg[16];
|
uint32_t MMUReg[ 16 ];
|
||||||
TLB_t iTLB;
|
TLB_t iTLB;
|
||||||
TLB_t dTLB;
|
TLB_t dTLB;
|
||||||
} s3c2410_mmu_t;
|
} s3c2410_mmu_t;
|
||||||
|
|
||||||
#endif /* !(_S3C2410_MMU_H) */
|
#endif /* !(_S3C2410_MMU_H) */
|
||||||
|
|
|
@ -12,244 +12,206 @@
|
||||||
#include "x49gp.h"
|
#include "x49gp.h"
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t nfconf;
|
uint32_t nfconf;
|
||||||
uint32_t nfcmd;
|
uint32_t nfcmd;
|
||||||
uint32_t nfaddr;
|
uint32_t nfaddr;
|
||||||
uint32_t nfdata;
|
uint32_t nfdata;
|
||||||
uint32_t nfstat;
|
uint32_t nfstat;
|
||||||
uint32_t nfecc;
|
uint32_t nfecc;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
} s3c2410_nand_t;
|
} s3c2410_nand_t;
|
||||||
|
|
||||||
|
static int s3c2410_nand_data_init( s3c2410_nand_t* nand )
|
||||||
static int
|
|
||||||
s3c2410_nand_data_init(s3c2410_nand_t *nand)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = {
|
||||||
S3C2410_OFFSET(NAND, NFCONF, 0x00000000, nand->nfconf),
|
S3C2410_OFFSET( NAND, NFCONF, 0x00000000, nand->nfconf ), S3C2410_OFFSET( NAND, NFCMD, 0x00000000, nand->nfcmd ),
|
||||||
S3C2410_OFFSET(NAND, NFCMD, 0x00000000, nand->nfcmd),
|
S3C2410_OFFSET( NAND, NFADDR, 0x00000000, nand->nfaddr ), S3C2410_OFFSET( NAND, NFDATA, 0x00000000, nand->nfdata ),
|
||||||
S3C2410_OFFSET(NAND, NFADDR, 0x00000000, nand->nfaddr),
|
S3C2410_OFFSET( NAND, NFSTAT, 0x00000000, nand->nfstat ), S3C2410_OFFSET( NAND, NFECC, 0x00000000, nand->nfecc ),
|
||||||
S3C2410_OFFSET(NAND, NFDATA, 0x00000000, nand->nfdata),
|
};
|
||||||
S3C2410_OFFSET(NAND, NFSTAT, 0x00000000, nand->nfstat),
|
|
||||||
S3C2410_OFFSET(NAND, NFECC, 0x00000000, nand->nfecc),
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(nand, 0, sizeof(s3c2410_nand_t));
|
memset( nand, 0, sizeof( s3c2410_nand_t ) );
|
||||||
|
|
||||||
nand->regs = malloc(sizeof(regs));
|
nand->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == nand->regs) {
|
if ( NULL == nand->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(nand->regs, regs, sizeof(regs));
|
memcpy( nand->regs, regs, sizeof( regs ) );
|
||||||
nand->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
nand->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t s3c2410_nand_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_nand_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand = opaque;
|
s3c2410_nand_t* nand = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(nand, offset)) {
|
if ( !S3C2410_OFFSET_OK( nand, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(nand, offset);
|
reg = S3C2410_OFFSET_ENTRY( nand, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_NAND
|
#ifdef DEBUG_S3C2410_NAND
|
||||||
printf("read %s [%08x] %s [%08x] data %08x\n",
|
printf( "read %s [%08x] %s [%08x] data %08x\n", "s3c2410-nand", S3C2410_NAND_BASE, reg->name, offset, *( reg->datap ) );
|
||||||
"s3c2410-nand", S3C2410_NAND_BASE,
|
|
||||||
reg->name, offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void s3c2410_nand_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_nand_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand = opaque;
|
s3c2410_nand_t* nand = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(nand, offset)) {
|
if ( !S3C2410_OFFSET_OK( nand, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(nand, offset);
|
reg = S3C2410_OFFSET_ENTRY( nand, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_NAND
|
#ifdef DEBUG_S3C2410_NAND
|
||||||
printf("write %s [%08x] %s [%08x] data %08x\n",
|
printf( "write %s [%08x] %s [%08x] data %08x\n", "s3c2410-nand", S3C2410_NAND_BASE, reg->name, offset, data );
|
||||||
"s3c2410-nand", S3C2410_NAND_BASE,
|
|
||||||
reg->name, offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int s3c2410_nand_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
static int
|
|
||||||
s3c2410_nand_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand = module->user_data;
|
s3c2410_nand_t* nand = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < nand->nr_regs; i++) {
|
for ( i = 0; i < nand->nr_regs; i++ ) {
|
||||||
reg = &nand->regs[i];
|
reg = &nand->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_nand_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_nand_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand = module->user_data;
|
s3c2410_nand_t* nand = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < nand->nr_regs; i++) {
|
for ( i = 0; i < nand->nr_regs; i++ ) {
|
||||||
reg = &nand->regs[i];
|
reg = &nand->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_nand_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_nand_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand = module->user_data;
|
s3c2410_nand_t* nand = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < nand->nr_regs; i++) {
|
for ( i = 0; i < nand->nr_regs; i++ ) {
|
||||||
reg = &nand->regs[i];
|
reg = &nand->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_nand_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_nand_readfn[] = { s3c2410_nand_read, s3c2410_nand_read, s3c2410_nand_read };
|
||||||
{
|
|
||||||
s3c2410_nand_read,
|
|
||||||
s3c2410_nand_read,
|
|
||||||
s3c2410_nand_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_nand_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_nand_writefn[] = { s3c2410_nand_write, s3c2410_nand_write, s3c2410_nand_write };
|
||||||
{
|
|
||||||
s3c2410_nand_write,
|
|
||||||
s3c2410_nand_write,
|
|
||||||
s3c2410_nand_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_nand_init( x49gp_module_t* module )
|
||||||
s3c2410_nand_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand;
|
s3c2410_nand_t* nand;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nand = malloc(sizeof(s3c2410_nand_t));
|
nand = malloc( sizeof( s3c2410_nand_t ) );
|
||||||
if (NULL == nand) {
|
if ( NULL == nand ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_nand_data_init( nand ) ) {
|
||||||
if (s3c2410_nand_data_init(nand)) {
|
free( nand );
|
||||||
free(nand);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = nand;
|
module->user_data = nand;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_nand_readfn,
|
iotype = cpu_register_io_memory( s3c2410_nand_readfn, s3c2410_nand_writefn, nand );
|
||||||
s3c2410_nand_writefn, nand);
|
|
||||||
#ifdef DEBUG_S3C2410_NAND
|
#ifdef DEBUG_S3C2410_NAND
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_NAND_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_NAND_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_nand_exit( x49gp_module_t* module )
|
||||||
s3c2410_nand_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_nand_t *nand;
|
s3c2410_nand_t* nand;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
nand = module->user_data;
|
nand = module->user_data;
|
||||||
if (nand->regs)
|
if ( nand->regs )
|
||||||
free(nand->regs);
|
free( nand->regs );
|
||||||
free(nand);
|
free( nand );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_nand_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_nand_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-nand",
|
if ( x49gp_module_init( x49gp, "s3c2410-nand", s3c2410_nand_init, s3c2410_nand_exit, s3c2410_nand_reset, s3c2410_nand_load,
|
||||||
s3c2410_nand_init,
|
s3c2410_nand_save, NULL, &module ) ) {
|
||||||
s3c2410_nand_exit,
|
return -1;
|
||||||
s3c2410_nand_reset,
|
}
|
||||||
s3c2410_nand_load,
|
|
||||||
s3c2410_nand_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,351 +16,311 @@
|
||||||
static const uint32_t EXTCLK = 12000000;
|
static const uint32_t EXTCLK = 12000000;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t locktime;
|
uint32_t locktime;
|
||||||
uint32_t mpllcon;
|
uint32_t mpllcon;
|
||||||
uint32_t upllcon;
|
uint32_t upllcon;
|
||||||
uint32_t clkcon;
|
uint32_t clkcon;
|
||||||
uint32_t clkslow;
|
uint32_t clkslow;
|
||||||
uint32_t clkdivn;
|
uint32_t clkdivn;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
} s3c2410_power_t;
|
} s3c2410_power_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_data_init( s3c2410_power_t* power )
|
||||||
s3c2410_power_data_init(s3c2410_power_t *power)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = {
|
||||||
S3C2410_OFFSET(POWER, LOCKTIME, 0x00ffffff, power->locktime),
|
S3C2410_OFFSET( POWER, LOCKTIME, 0x00ffffff, power->locktime ), S3C2410_OFFSET( POWER, MPLLCON, 0x0005c080, power->mpllcon ),
|
||||||
S3C2410_OFFSET(POWER, MPLLCON, 0x0005c080, power->mpllcon),
|
S3C2410_OFFSET( POWER, UPLLCON, 0x00028080, power->upllcon ), S3C2410_OFFSET( POWER, CLKCON, 0x0007fff0, power->clkcon ),
|
||||||
S3C2410_OFFSET(POWER, UPLLCON, 0x00028080, power->upllcon),
|
S3C2410_OFFSET( POWER, CLKSLOW, 0x00000004, power->clkslow ), S3C2410_OFFSET( POWER, CLKDIVN, 0x00000000, power->clkdivn ) };
|
||||||
S3C2410_OFFSET(POWER, CLKCON, 0x0007fff0, power->clkcon),
|
|
||||||
S3C2410_OFFSET(POWER, CLKSLOW, 0x00000004, power->clkslow),
|
|
||||||
S3C2410_OFFSET(POWER, CLKDIVN, 0x00000000, power->clkdivn)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(power, 0, sizeof(s3c2410_power_t));
|
memset( power, 0, sizeof( s3c2410_power_t ) );
|
||||||
|
|
||||||
power->regs = malloc(sizeof(regs));
|
power->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == power->regs) {
|
if ( NULL == power->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(power->regs, regs, sizeof(regs));
|
memcpy( power->regs, regs, sizeof( regs ) );
|
||||||
power->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
power->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_power_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_power_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power = opaque;
|
s3c2410_power_t* power = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(power, offset)) {
|
if ( !S3C2410_OFFSET_OK( power, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(power, offset);
|
reg = S3C2410_OFFSET_ENTRY( power, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-power", S3C2410_POWER_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-power", S3C2410_POWER_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_power_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_power_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power = opaque;
|
s3c2410_power_t* power = opaque;
|
||||||
x49gp_t *x49gp = power->x49gp;
|
x49gp_t* x49gp = power->x49gp;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
uint32_t mMdiv, mPdiv, mSdiv;
|
uint32_t mMdiv, mPdiv, mSdiv;
|
||||||
uint32_t uMdiv, uPdiv, uSdiv;
|
uint32_t uMdiv, uPdiv, uSdiv;
|
||||||
uint32_t slow_bit, slow_val;
|
uint32_t slow_bit, slow_val;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(power, offset)) {
|
if ( !S3C2410_OFFSET_OK( power, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(power, offset);
|
reg = S3C2410_OFFSET_ENTRY( power, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-power", S3C2410_POWER_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-power", S3C2410_POWER_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_POWER_CLKCON:
|
case S3C2410_POWER_CLKCON:
|
||||||
if (data & CLKCON_POWER_OFF) {
|
if ( data & CLKCON_POWER_OFF ) {
|
||||||
*(reg->datap) = 0x7fff0;
|
*( reg->datap ) = 0x7fff0;
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("POWER: enter POWER_OFF\n");
|
printf( "POWER: enter POWER_OFF\n" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_modules_reset(x49gp, X49GP_RESET_POWER_OFF);
|
x49gp_modules_reset( x49gp, X49GP_RESET_POWER_OFF );
|
||||||
|
|
||||||
// if (x49gp->arm->NresetSig != LOW) {
|
// if (x49gp->arm->NresetSig != LOW) {
|
||||||
// x49gp->arm->NresetSig = LOW;
|
// x49gp->arm->NresetSig = LOW;
|
||||||
// x49gp->arm->Exception++;
|
// x49gp->arm->Exception++;
|
||||||
// }
|
// }
|
||||||
x49gp_set_idle(x49gp, X49GP_ARM_OFF);
|
x49gp_set_idle( x49gp, X49GP_ARM_OFF );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(power->clkcon & CLKCON_IDLE) && (data & CLKCON_IDLE)) {
|
if ( !( power->clkcon & CLKCON_IDLE ) && ( data & CLKCON_IDLE ) ) {
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("POWER: enter IDLE\n");
|
printf( "POWER: enter IDLE\n" );
|
||||||
#endif
|
#endif
|
||||||
x49gp_set_idle(x49gp, X49GP_ARM_SLEEP);
|
x49gp_set_idle( x49gp, X49GP_ARM_SLEEP );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case S3C2410_POWER_LOCKTIME:
|
case S3C2410_POWER_LOCKTIME:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMdiv = (power->mpllcon >> 12) & 0xff;
|
mMdiv = ( power->mpllcon >> 12 ) & 0xff;
|
||||||
mPdiv = (power->mpllcon >> 4) & 0x3f;
|
mPdiv = ( power->mpllcon >> 4 ) & 0x3f;
|
||||||
mSdiv = (power->mpllcon >> 0) & 0x03;
|
mSdiv = ( power->mpllcon >> 0 ) & 0x03;
|
||||||
x49gp->MCLK = (((u64) EXTCLK) * ((u64) (mMdiv + 8))) / ((u64) ((mPdiv + 2) * (1 << mSdiv)));
|
x49gp->MCLK = ( ( ( u64 )EXTCLK ) * ( ( u64 )( mMdiv + 8 ) ) ) / ( ( u64 )( ( mPdiv + 2 ) * ( 1 << mSdiv ) ) );
|
||||||
|
|
||||||
uMdiv = (power->upllcon >> 12) & 0xff;
|
uMdiv = ( power->upllcon >> 12 ) & 0xff;
|
||||||
uPdiv = (power->upllcon >> 4) & 0x3f;
|
uPdiv = ( power->upllcon >> 4 ) & 0x3f;
|
||||||
uSdiv = (power->upllcon >> 0) & 0x03;
|
uSdiv = ( power->upllcon >> 0 ) & 0x03;
|
||||||
x49gp->UCLK = (((u64) EXTCLK) * ((u64) (uMdiv + 8))) / ((u64) ((uPdiv + 2) * (1 << uSdiv)));
|
x49gp->UCLK = ( ( ( u64 )EXTCLK ) * ( ( u64 )( uMdiv + 8 ) ) ) / ( ( u64 )( ( uPdiv + 2 ) * ( 1 << uSdiv ) ) );
|
||||||
|
|
||||||
slow_bit = (power->clkslow & 0x10);
|
slow_bit = ( power->clkslow & 0x10 );
|
||||||
if (slow_bit) {
|
if ( slow_bit ) {
|
||||||
slow_val = (power->clkslow >> 0) & 0x07;
|
slow_val = ( power->clkslow >> 0 ) & 0x07;
|
||||||
if (0 == slow_val)
|
if ( 0 == slow_val )
|
||||||
x49gp->FCLK = EXTCLK;
|
x49gp->FCLK = EXTCLK;
|
||||||
else
|
else
|
||||||
x49gp->FCLK = EXTCLK / (2 * slow_val);
|
x49gp->FCLK = EXTCLK / ( 2 * slow_val );
|
||||||
} else {
|
} else {
|
||||||
x49gp->FCLK = x49gp->MCLK;
|
x49gp->FCLK = x49gp->MCLK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (power->clkdivn & 4) {
|
if ( power->clkdivn & 4 ) {
|
||||||
x49gp->HCLK = x49gp->FCLK / 4;
|
x49gp->HCLK = x49gp->FCLK / 4;
|
||||||
x49gp->PCLK = x49gp->FCLK / 4;
|
x49gp->PCLK = x49gp->FCLK / 4;
|
||||||
x49gp->PCLK_ratio = 4;
|
x49gp->PCLK_ratio = 4;
|
||||||
} else {
|
} else {
|
||||||
switch (power->clkdivn & 3) {
|
switch ( power->clkdivn & 3 ) {
|
||||||
case 0:
|
case 0:
|
||||||
x49gp->HCLK = x49gp->FCLK;
|
x49gp->HCLK = x49gp->FCLK;
|
||||||
x49gp->PCLK = x49gp->HCLK;
|
x49gp->PCLK = x49gp->HCLK;
|
||||||
x49gp->PCLK_ratio = 1;
|
x49gp->PCLK_ratio = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
x49gp->HCLK = x49gp->FCLK;
|
x49gp->HCLK = x49gp->FCLK;
|
||||||
x49gp->PCLK = x49gp->HCLK / 2;
|
x49gp->PCLK = x49gp->HCLK / 2;
|
||||||
x49gp->PCLK_ratio = 2;
|
x49gp->PCLK_ratio = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
x49gp->HCLK = x49gp->FCLK / 2;
|
x49gp->HCLK = x49gp->FCLK / 2;
|
||||||
x49gp->PCLK = x49gp->HCLK;
|
x49gp->PCLK = x49gp->HCLK;
|
||||||
x49gp->PCLK_ratio = 2;
|
x49gp->PCLK_ratio = 2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
x49gp->HCLK = x49gp->FCLK / 2;
|
x49gp->HCLK = x49gp->FCLK / 2;
|
||||||
x49gp->PCLK = x49gp->HCLK / 2;
|
x49gp->PCLK = x49gp->HCLK / 2;
|
||||||
x49gp->PCLK_ratio = 4;
|
x49gp->PCLK_ratio = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("%s: EXTCLK %u, mdiv %u, pdiv %u, sdiv %u: MCLK %u\n",
|
printf( "%s: EXTCLK %u, mdiv %u, pdiv %u, sdiv %u: MCLK %u\n", __FUNCTION__, EXTCLK, mMdiv, mPdiv, mSdiv, x49gp->MCLK );
|
||||||
__FUNCTION__, EXTCLK, mMdiv, mPdiv, mSdiv, x49gp->MCLK);
|
printf( "%s: EXTCLK %u, mdiv %u, pdiv %u, sdiv %u: UCLK %u\n", __FUNCTION__, EXTCLK, uMdiv, uPdiv, uSdiv, x49gp->UCLK );
|
||||||
printf("%s: EXTCLK %u, mdiv %u, pdiv %u, sdiv %u: UCLK %u\n",
|
printf( "%s: FCLK %s: %u\n", __FUNCTION__, slow_bit ? "(slow)" : "", x49gp->FCLK );
|
||||||
__FUNCTION__, EXTCLK, uMdiv, uPdiv, uSdiv, x49gp->UCLK);
|
printf( "%s: HCLK %u, PCLK %u\n", __FUNCTION__, x49gp->HCLK, x49gp->PCLK );
|
||||||
printf("%s: FCLK %s: %u\n",
|
|
||||||
__FUNCTION__, slow_bit ? "(slow)" : "", x49gp->FCLK);
|
|
||||||
printf("%s: HCLK %u, PCLK %u\n",
|
|
||||||
__FUNCTION__, x49gp->HCLK, x49gp->PCLK);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_power_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power = module->user_data;
|
s3c2410_power_t* power = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < power->nr_regs; i++) {
|
for ( i = 0; i < power->nr_regs; i++ ) {
|
||||||
reg = &power->regs[i];
|
reg = &power->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
if ( error ) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
s3c2410_power_write(power, S3C2410_POWER_BASE | S3C2410_POWER_CLKDIVN,
|
s3c2410_power_write( power, S3C2410_POWER_BASE | S3C2410_POWER_CLKDIVN, power->clkdivn );
|
||||||
power->clkdivn);
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_power_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power = module->user_data;
|
s3c2410_power_t* power = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < power->nr_regs; i++) {
|
for ( i = 0; i < power->nr_regs; i++ ) {
|
||||||
reg = &power->regs[i];
|
reg = &power->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_power_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power = module->user_data;
|
s3c2410_power_t* power = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < power->nr_regs; i++) {
|
for ( i = 0; i < power->nr_regs; i++ ) {
|
||||||
reg = &power->regs[i];
|
reg = &power->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_power_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_power_readfn[] = { s3c2410_power_read, s3c2410_power_read, s3c2410_power_read };
|
||||||
{
|
|
||||||
s3c2410_power_read,
|
|
||||||
s3c2410_power_read,
|
|
||||||
s3c2410_power_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_power_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_power_writefn[] = { s3c2410_power_write, s3c2410_power_write, s3c2410_power_write };
|
||||||
{
|
|
||||||
s3c2410_power_write,
|
|
||||||
s3c2410_power_write,
|
|
||||||
s3c2410_power_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_init( x49gp_module_t* module )
|
||||||
s3c2410_power_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power;
|
s3c2410_power_t* power;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
power = malloc(sizeof(s3c2410_power_t));
|
power = malloc( sizeof( s3c2410_power_t ) );
|
||||||
if (NULL == power) {
|
if ( NULL == power ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_power_data_init( power ) ) {
|
||||||
if (s3c2410_power_data_init(power)) {
|
free( power );
|
||||||
free(power);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = power;
|
module->user_data = power;
|
||||||
power->x49gp = module->x49gp;
|
power->x49gp = module->x49gp;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_power_readfn,
|
iotype = cpu_register_io_memory( s3c2410_power_readfn, s3c2410_power_writefn, power );
|
||||||
s3c2410_power_writefn, power);
|
|
||||||
#ifdef DEBUG_S3C2410_POWER
|
#ifdef DEBUG_S3C2410_POWER
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_POWER_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_POWER_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_power_exit( x49gp_module_t* module )
|
||||||
s3c2410_power_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_power_t *power;
|
s3c2410_power_t* power;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
power = module->user_data;
|
power = module->user_data;
|
||||||
if (power->regs)
|
if ( power->regs )
|
||||||
free(power->regs);
|
free( power->regs );
|
||||||
free(power);
|
free( power );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_power_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_power_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-power",
|
if ( x49gp_module_init( x49gp, "s3c2410-power", s3c2410_power_init, s3c2410_power_exit, s3c2410_power_reset, s3c2410_power_load,
|
||||||
s3c2410_power_init,
|
s3c2410_power_save, NULL, &module ) ) {
|
||||||
s3c2410_power_exit,
|
return -1;
|
||||||
s3c2410_power_reset,
|
}
|
||||||
s3c2410_power_load,
|
|
||||||
s3c2410_power_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,24 +4,24 @@
|
||||||
#ifndef _S3C2410_POWER_H
|
#ifndef _S3C2410_POWER_H
|
||||||
#define _S3C2410_POWER_H 1
|
#define _S3C2410_POWER_H 1
|
||||||
|
|
||||||
#define CLKCON_SPI 0x00040000
|
#define CLKCON_SPI 0x00040000
|
||||||
#define CLKCON_IIS 0x00020000
|
#define CLKCON_IIS 0x00020000
|
||||||
#define CLKCON_IIC 0x00010000
|
#define CLKCON_IIC 0x00010000
|
||||||
#define CLKCON_ADC 0x00008000
|
#define CLKCON_ADC 0x00008000
|
||||||
#define CLKCON_RTC 0x00004000
|
#define CLKCON_RTC 0x00004000
|
||||||
#define CLKCON_GPIO 0x00002000
|
#define CLKCON_GPIO 0x00002000
|
||||||
#define CLKCON_UART2 0x00001000
|
#define CLKCON_UART2 0x00001000
|
||||||
#define CLKCON_UART1 0x00000800
|
#define CLKCON_UART1 0x00000800
|
||||||
#define CLKCON_UART0 0x00000400
|
#define CLKCON_UART0 0x00000400
|
||||||
#define CLKCON_SDI 0x00000200
|
#define CLKCON_SDI 0x00000200
|
||||||
#define CLKCON_TIMER 0x00000100
|
#define CLKCON_TIMER 0x00000100
|
||||||
#define CLKCON_USBD 0x00000080
|
#define CLKCON_USBD 0x00000080
|
||||||
#define CLKCON_USBH 0x00000040
|
#define CLKCON_USBH 0x00000040
|
||||||
#define CLKCON_LCD 0x00000020
|
#define CLKCON_LCD 0x00000020
|
||||||
#define CLKCON_NAND 0x00000010
|
#define CLKCON_NAND 0x00000010
|
||||||
#define CLKCON_POWER_OFF 0x00000008
|
#define CLKCON_POWER_OFF 0x00000008
|
||||||
#define CLKCON_IDLE 0x00000004
|
#define CLKCON_IDLE 0x00000004
|
||||||
#define CLKCON_SM_BIT 0x00000001
|
#define CLKCON_SM_BIT 0x00000001
|
||||||
|
|
||||||
extern int s3c2410_idle;
|
extern int s3c2410_idle;
|
||||||
|
|
||||||
|
|
|
@ -14,490 +14,435 @@
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
#include "s3c2410_intc.h"
|
#include "s3c2410_intc.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t rtccon;
|
uint32_t rtccon;
|
||||||
uint32_t ticnt;
|
uint32_t ticnt;
|
||||||
uint32_t rtcalm;
|
uint32_t rtcalm;
|
||||||
uint32_t almsec;
|
uint32_t almsec;
|
||||||
uint32_t almmin;
|
uint32_t almmin;
|
||||||
uint32_t almhour;
|
uint32_t almhour;
|
||||||
uint32_t almdate;
|
uint32_t almdate;
|
||||||
uint32_t almmon;
|
uint32_t almmon;
|
||||||
uint32_t almyear;
|
uint32_t almyear;
|
||||||
uint32_t rtcrst;
|
uint32_t rtcrst;
|
||||||
uint32_t bcdsec;
|
uint32_t bcdsec;
|
||||||
uint32_t bcdmin;
|
uint32_t bcdmin;
|
||||||
uint32_t bcdhour;
|
uint32_t bcdhour;
|
||||||
uint32_t bcddate;
|
uint32_t bcddate;
|
||||||
uint32_t bcdday;
|
uint32_t bcdday;
|
||||||
uint32_t bcdmon;
|
uint32_t bcdmon;
|
||||||
uint32_t bcdyear;
|
uint32_t bcdyear;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
x49gp_timer_t *tick_timer;
|
x49gp_timer_t* tick_timer;
|
||||||
x49gp_timer_t *alarm_timer;
|
x49gp_timer_t* alarm_timer;
|
||||||
int64_t interval; /* us */
|
int64_t interval; /* us */
|
||||||
int64_t expires; /* us */
|
int64_t expires; /* us */
|
||||||
} s3c2410_rtc_t;
|
} s3c2410_rtc_t;
|
||||||
|
|
||||||
|
static int s3c2410_rtc_data_init( s3c2410_rtc_t* rtc )
|
||||||
static int
|
|
||||||
s3c2410_rtc_data_init(s3c2410_rtc_t *rtc)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = { S3C2410_OFFSET( RTC, RTCCON, 0x00, rtc->rtccon ), S3C2410_OFFSET( RTC, TICNT, 0x00, rtc->ticnt ),
|
||||||
S3C2410_OFFSET(RTC, RTCCON, 0x00, rtc->rtccon),
|
S3C2410_OFFSET( RTC, RTCALM, 0x00, rtc->rtcalm ), S3C2410_OFFSET( RTC, ALMSEC, 0x00, rtc->almsec ),
|
||||||
S3C2410_OFFSET(RTC, TICNT, 0x00, rtc->ticnt),
|
S3C2410_OFFSET( RTC, ALMMIN, 0x00, rtc->almmin ), S3C2410_OFFSET( RTC, ALMHOUR, 0x00, rtc->almhour ),
|
||||||
S3C2410_OFFSET(RTC, RTCALM, 0x00, rtc->rtcalm),
|
S3C2410_OFFSET( RTC, ALMDATE, 0x01, rtc->almdate ), S3C2410_OFFSET( RTC, ALMMON, 0x01, rtc->almmon ),
|
||||||
S3C2410_OFFSET(RTC, ALMSEC, 0x00, rtc->almsec),
|
S3C2410_OFFSET( RTC, ALMYEAR, 0x00, rtc->almyear ), S3C2410_OFFSET( RTC, RTCRST, 0x00, rtc->rtcrst ),
|
||||||
S3C2410_OFFSET(RTC, ALMMIN, 0x00, rtc->almmin),
|
S3C2410_OFFSET( RTC, BCDSEC, 0, rtc->bcdsec ), S3C2410_OFFSET( RTC, BCDMIN, 0, rtc->bcdmin ),
|
||||||
S3C2410_OFFSET(RTC, ALMHOUR, 0x00, rtc->almhour),
|
S3C2410_OFFSET( RTC, BCDHOUR, 0, rtc->bcdhour ), S3C2410_OFFSET( RTC, BCDDATE, 0, rtc->bcddate ),
|
||||||
S3C2410_OFFSET(RTC, ALMDATE, 0x01, rtc->almdate),
|
S3C2410_OFFSET( RTC, BCDDAY, 0, rtc->bcdday ), S3C2410_OFFSET( RTC, BCDMON, 0, rtc->bcdmon ),
|
||||||
S3C2410_OFFSET(RTC, ALMMON, 0x01, rtc->almmon),
|
S3C2410_OFFSET( RTC, BCDYEAR, 0, rtc->bcdyear ) };
|
||||||
S3C2410_OFFSET(RTC, ALMYEAR, 0x00, rtc->almyear),
|
|
||||||
S3C2410_OFFSET(RTC, RTCRST, 0x00, rtc->rtcrst),
|
|
||||||
S3C2410_OFFSET(RTC, BCDSEC, 0, rtc->bcdsec),
|
|
||||||
S3C2410_OFFSET(RTC, BCDMIN, 0, rtc->bcdmin),
|
|
||||||
S3C2410_OFFSET(RTC, BCDHOUR, 0, rtc->bcdhour),
|
|
||||||
S3C2410_OFFSET(RTC, BCDDATE, 0, rtc->bcddate),
|
|
||||||
S3C2410_OFFSET(RTC, BCDDAY, 0, rtc->bcdday),
|
|
||||||
S3C2410_OFFSET(RTC, BCDMON, 0, rtc->bcdmon),
|
|
||||||
S3C2410_OFFSET(RTC, BCDYEAR, 0, rtc->bcdyear)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(rtc, 0, sizeof(s3c2410_rtc_t));
|
memset( rtc, 0, sizeof( s3c2410_rtc_t ) );
|
||||||
|
|
||||||
rtc->regs = malloc(sizeof(regs));
|
rtc->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == rtc->regs) {
|
if ( NULL == rtc->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(rtc->regs, regs, sizeof(regs));
|
memcpy( rtc->regs, regs, sizeof( regs ) );
|
||||||
rtc->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
rtc->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ uint32_t bin2bcd(uint32_t bin)
|
static __inline__ uint32_t bin2bcd( uint32_t bin ) { return ( ( bin / 10 ) << 4 ) | ( bin % 10 ); }
|
||||||
|
|
||||||
|
static __inline__ uint32_t bcd2bin( uint32_t bcd ) { return ( ( bcd >> 4 ) * 10 ) + ( bcd & 0x0f ); }
|
||||||
|
|
||||||
|
static void s3c2410_rtc_timeout( void* user_data )
|
||||||
{
|
{
|
||||||
return ((bin / 10) << 4) | (bin % 10);
|
s3c2410_rtc_t* rtc = user_data;
|
||||||
|
x49gp_t* x49gp = rtc->x49gp;
|
||||||
|
int64_t now, us;
|
||||||
|
|
||||||
|
if ( !( rtc->ticnt & 0x80 ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
|
printf( "RTC: assert TICK interrupt\n" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s3c2410_intc_assert( x49gp, INT_TICK, 0 );
|
||||||
|
|
||||||
|
now = x49gp_get_clock();
|
||||||
|
while ( rtc->expires <= now ) {
|
||||||
|
rtc->expires += rtc->interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
us = rtc->expires - now;
|
||||||
|
if ( us < 1000 )
|
||||||
|
us = 1000;
|
||||||
|
|
||||||
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
|
printf( "RTC: restart TICK timer (%llu us)\n", ( unsigned long long )us );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
x49gp_mod_timer( rtc->tick_timer, rtc->expires );
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ uint32_t bcd2bin(uint32_t bcd)
|
static int s3c2410_rtc_set_ticnt( s3c2410_rtc_t* rtc )
|
||||||
{
|
{
|
||||||
return ((bcd >> 4) * 10) + (bcd & 0x0f);
|
int64_t now, us;
|
||||||
|
|
||||||
|
if ( x49gp_timer_pending( rtc->tick_timer ) ) {
|
||||||
|
x49gp_del_timer( rtc->tick_timer );
|
||||||
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
|
printf( "RTC: stop TICK timer\n" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( rtc->ticnt & 0x80 ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
us = ( ( ( rtc->ticnt & 0x7f ) + 1 ) * 1000000 ) / 128;
|
||||||
|
|
||||||
|
rtc->interval = us;
|
||||||
|
if ( rtc->interval < 1000 )
|
||||||
|
rtc->interval = 1000;
|
||||||
|
|
||||||
|
now = x49gp_get_clock();
|
||||||
|
rtc->expires = now + rtc->interval;
|
||||||
|
|
||||||
|
us = rtc->expires - now;
|
||||||
|
if ( us < 1000 )
|
||||||
|
us = 1000;
|
||||||
|
|
||||||
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
|
printf( "RTC: start TICK timer (%lld us)\n", ( unsigned long long )us );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
x49gp_mod_timer( rtc->tick_timer, rtc->expires );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_rtc_alarm( void* user_data )
|
||||||
s3c2410_rtc_timeout(void * user_data)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc = user_data;
|
s3c2410_rtc_t* rtc = user_data;
|
||||||
x49gp_t *x49gp = rtc->x49gp;
|
x49gp_t* x49gp = rtc->x49gp;
|
||||||
int64_t now, us;
|
struct tm* tm;
|
||||||
|
struct timeval tv;
|
||||||
|
int64_t now, us;
|
||||||
|
int match = 1;
|
||||||
|
|
||||||
if (!(rtc->ticnt & 0x80)) {
|
if ( !( rtc->rtcalm & 0x40 ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gettimeofday( &tv, NULL );
|
||||||
|
tm = localtime( &tv.tv_sec );
|
||||||
|
|
||||||
|
now = x49gp_get_clock();
|
||||||
|
us = 1000000LL - tv.tv_usec;
|
||||||
|
|
||||||
|
if ( match && ( rtc->rtcalm & 0x01 ) ) {
|
||||||
|
if ( tm->tm_sec != bcd2bin( rtc->almsec ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
if ( match && ( rtc->rtcalm & 0x02 ) ) {
|
||||||
|
if ( tm->tm_min != bcd2bin( rtc->almmin ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
if ( match && ( rtc->rtcalm & 0x04 ) ) {
|
||||||
|
if ( tm->tm_hour != bcd2bin( rtc->almhour ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
if ( match && ( rtc->rtcalm & 0x08 ) ) {
|
||||||
|
if ( tm->tm_mday != bcd2bin( rtc->almdate ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
if ( match && ( rtc->rtcalm & 0x10 ) ) {
|
||||||
|
if ( ( tm->tm_mon + 1 ) != bcd2bin( rtc->almmon ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
if ( match && ( rtc->rtcalm & 0x20 ) ) {
|
||||||
|
if ( ( tm->tm_year % 100 ) != bcd2bin( rtc->almyear ) )
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( match ) {
|
||||||
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
|
printf( "RTC: assert ALARM interrupt\n" );
|
||||||
|
#endif
|
||||||
|
s3c2410_intc_assert( x49gp, INT_RTC, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
printf("RTC: assert TICK interrupt\n");
|
printf( "RTC: reload ALARM timer (%lld us)\n", ( unsigned long long )us );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s3c2410_intc_assert(x49gp, INT_TICK, 0);
|
x49gp_mod_timer( rtc->alarm_timer, now + us );
|
||||||
|
|
||||||
now = x49gp_get_clock();
|
|
||||||
while (rtc->expires <= now) {
|
|
||||||
rtc->expires += rtc->interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
us = rtc->expires - now;
|
|
||||||
if (us < 1000)
|
|
||||||
us = 1000;
|
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
|
||||||
printf("RTC: restart TICK timer (%llu us)\n", (unsigned long long) us);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
x49gp_mod_timer(rtc->tick_timer, rtc->expires);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_rtc_set_rtcalm( s3c2410_rtc_t* rtc )
|
||||||
s3c2410_rtc_set_ticnt(s3c2410_rtc_t *rtc)
|
|
||||||
{
|
{
|
||||||
int64_t now, us;
|
struct timeval tv;
|
||||||
|
int64_t now, us;
|
||||||
|
|
||||||
if (x49gp_timer_pending(rtc->tick_timer)) {
|
if ( !( rtc->rtcalm & 0x40 ) ) {
|
||||||
x49gp_del_timer(rtc->tick_timer);
|
x49gp_del_timer( rtc->alarm_timer );
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
return 0;
|
||||||
printf("RTC: stop TICK timer\n");
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(rtc->ticnt & 0x80)) {
|
gettimeofday( &tv, NULL );
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
us = (((rtc->ticnt & 0x7f) + 1) * 1000000) / 128;
|
now = x49gp_get_clock();
|
||||||
|
us = 1000000LL - tv.tv_usec;
|
||||||
rtc->interval = us;
|
|
||||||
if (rtc->interval < 1000)
|
|
||||||
rtc->interval = 1000;
|
|
||||||
|
|
||||||
now = x49gp_get_clock();
|
|
||||||
rtc->expires = now + rtc->interval;
|
|
||||||
|
|
||||||
us = rtc->expires - now;
|
|
||||||
if (us < 1000)
|
|
||||||
us = 1000;
|
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
printf("RTC: start TICK timer (%lld us)\n", (unsigned long long) us);
|
printf( "RTC: start ALARM timer (%lld us)\n", ( unsigned long long )us );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_mod_timer(rtc->tick_timer, rtc->expires);
|
x49gp_mod_timer( rtc->alarm_timer, now + us );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static uint32_t s3c2410_rtc_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_rtc_alarm(void * user_data)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc = user_data;
|
s3c2410_rtc_t* rtc = opaque;
|
||||||
x49gp_t *x49gp = rtc->x49gp;
|
s3c2410_offset_t* reg;
|
||||||
struct tm *tm;
|
|
||||||
struct timeval tv;
|
|
||||||
int64_t now, us;
|
|
||||||
int match = 1;
|
|
||||||
|
|
||||||
if (!(rtc->rtcalm & 0x40)) {
|
if ( !S3C2410_OFFSET_OK( rtc, offset ) ) {
|
||||||
return;
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
reg = S3C2410_OFFSET_ENTRY( rtc, offset );
|
||||||
tm = localtime(&tv.tv_sec);
|
|
||||||
|
|
||||||
now = x49gp_get_clock();
|
if ( S3C2410_RTC_BCDSEC <= offset && offset <= S3C2410_RTC_BCDYEAR ) {
|
||||||
us = 1000000LL - tv.tv_usec;
|
struct tm* tm;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
if (match && (rtc->rtcalm & 0x01)) {
|
gettimeofday( &tv, NULL );
|
||||||
if (tm->tm_sec != bcd2bin(rtc->almsec))
|
tm = localtime( &tv.tv_sec );
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
if (match && (rtc->rtcalm & 0x02)) {
|
|
||||||
if (tm->tm_min != bcd2bin(rtc->almmin))
|
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
if (match && (rtc->rtcalm & 0x04)) {
|
|
||||||
if (tm->tm_hour != bcd2bin(rtc->almhour))
|
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
if (match && (rtc->rtcalm & 0x08)) {
|
|
||||||
if (tm->tm_mday != bcd2bin(rtc->almdate))
|
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
if (match && (rtc->rtcalm & 0x10)) {
|
|
||||||
if ((tm->tm_mon + 1) != bcd2bin(rtc->almmon))
|
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
if (match && (rtc->rtcalm & 0x20)) {
|
|
||||||
if ((tm->tm_year % 100) != bcd2bin(rtc->almyear))
|
|
||||||
match = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match) {
|
switch ( offset ) {
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
case S3C2410_RTC_BCDSEC:
|
||||||
printf("RTC: assert ALARM interrupt\n");
|
*( reg->datap ) = bin2bcd( tm->tm_sec );
|
||||||
#endif
|
break;
|
||||||
s3c2410_intc_assert(x49gp, INT_RTC, 0);
|
case S3C2410_RTC_BCDMIN:
|
||||||
}
|
*( reg->datap ) = bin2bcd( tm->tm_min );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_BCDHOUR:
|
||||||
|
*( reg->datap ) = bin2bcd( tm->tm_hour );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_BCDDATE:
|
||||||
|
*( reg->datap ) = bin2bcd( tm->tm_mday );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_BCDDAY:
|
||||||
|
*( reg->datap ) = bin2bcd( tm->tm_wday + 1 );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_BCDMON:
|
||||||
|
*( reg->datap ) = bin2bcd( tm->tm_mon + 1 );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_BCDYEAR:
|
||||||
|
*( reg->datap ) = bin2bcd( tm->tm_year % 100 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
printf("RTC: reload ALARM timer (%lld us)\n", (unsigned long long) us);
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-rtc", S3C2410_RTC_BASE, reg->name, ( unsigned long )offset,
|
||||||
|
*( reg->datap ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_mod_timer(rtc->alarm_timer, now + us);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void s3c2410_rtc_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_rtc_set_rtcalm(s3c2410_rtc_t *rtc)
|
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
s3c2410_rtc_t* rtc = opaque;
|
||||||
int64_t now, us;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (!(rtc->rtcalm & 0x40)) {
|
if ( !S3C2410_OFFSET_OK( rtc, offset ) ) {
|
||||||
x49gp_del_timer(rtc->alarm_timer);
|
return;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
reg = S3C2410_OFFSET_ENTRY( rtc, offset );
|
||||||
|
|
||||||
now = x49gp_get_clock();
|
|
||||||
us = 1000000LL - tv.tv_usec;
|
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
printf("RTC: start ALARM timer (%lld us)\n", (unsigned long long) us);
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-rtc", S3C2410_RTC_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_mod_timer(rtc->alarm_timer, now + us);
|
switch ( offset ) {
|
||||||
return 0;
|
case S3C2410_RTC_TICNT:
|
||||||
|
*( reg->datap ) = data;
|
||||||
|
s3c2410_rtc_set_ticnt( rtc );
|
||||||
|
break;
|
||||||
|
case S3C2410_RTC_RTCALM:
|
||||||
|
*( reg->datap ) = data;
|
||||||
|
s3c2410_rtc_set_rtcalm( rtc );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*( reg->datap ) = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static int s3c2410_rtc_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_rtc_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc = opaque;
|
s3c2410_rtc_t* rtc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
int error = 0;
|
||||||
if (! S3C2410_OFFSET_OK(rtc, offset)) {
|
int i;
|
||||||
return ~(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(rtc, offset);
|
|
||||||
|
|
||||||
if (S3C2410_RTC_BCDSEC <= offset && offset <= S3C2410_RTC_BCDYEAR) {
|
|
||||||
struct tm *tm;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
tm = localtime(&tv.tv_sec);
|
|
||||||
|
|
||||||
switch (offset) {
|
|
||||||
case S3C2410_RTC_BCDSEC:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_sec);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDMIN:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_min);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDHOUR:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_hour);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDDATE:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_mday);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDDAY:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_wday + 1);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDMON:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_mon + 1);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_BCDYEAR:
|
|
||||||
*(reg->datap) = bin2bcd(tm->tm_year % 100);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
|
||||||
"s3c2410-rtc", S3C2410_RTC_BASE,
|
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *(reg->datap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
s3c2410_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
|
||||||
s3c2410_rtc_t *rtc = opaque;
|
|
||||||
s3c2410_offset_t *reg;
|
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(rtc, offset)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(rtc, offset);
|
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
|
||||||
"s3c2410-rtc", S3C2410_RTC_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (offset) {
|
|
||||||
case S3C2410_RTC_TICNT:
|
|
||||||
*(reg->datap) = data;
|
|
||||||
s3c2410_rtc_set_ticnt(rtc);
|
|
||||||
break;
|
|
||||||
case S3C2410_RTC_RTCALM:
|
|
||||||
*(reg->datap) = data;
|
|
||||||
s3c2410_rtc_set_rtcalm(rtc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*(reg->datap) = data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
s3c2410_rtc_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
|
||||||
s3c2410_rtc_t *rtc = module->user_data;
|
|
||||||
s3c2410_offset_t *reg;
|
|
||||||
int error = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < rtc->nr_regs; i++) {
|
for ( i = 0; i < rtc->nr_regs; i++ ) {
|
||||||
reg = &rtc->regs[i];
|
reg = &rtc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
s3c2410_rtc_set_ticnt(rtc);
|
s3c2410_rtc_set_ticnt( rtc );
|
||||||
s3c2410_rtc_set_rtcalm(rtc);
|
s3c2410_rtc_set_rtcalm( rtc );
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_rtc_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_rtc_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc = module->user_data;
|
s3c2410_rtc_t* rtc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < rtc->nr_regs; i++) {
|
for ( i = 0; i < rtc->nr_regs; i++ ) {
|
||||||
reg = &rtc->regs[i];
|
reg = &rtc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_rtc_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_rtc_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc = module->user_data;
|
s3c2410_rtc_t* rtc = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < (S3C2410_RTC_RTCALM >> 2); i++) {
|
for ( i = 0; i < ( S3C2410_RTC_RTCALM >> 2 ); i++ ) {
|
||||||
reg = &rtc->regs[i];
|
reg = &rtc->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
s3c2410_rtc_set_ticnt(rtc);
|
s3c2410_rtc_set_ticnt( rtc );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_rtc_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_rtc_readfn[] = { s3c2410_rtc_read, s3c2410_rtc_read, s3c2410_rtc_read };
|
||||||
{
|
|
||||||
s3c2410_rtc_read,
|
|
||||||
s3c2410_rtc_read,
|
|
||||||
s3c2410_rtc_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_rtc_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_rtc_writefn[] = { s3c2410_rtc_write, s3c2410_rtc_write, s3c2410_rtc_write };
|
||||||
{
|
|
||||||
s3c2410_rtc_write,
|
|
||||||
s3c2410_rtc_write,
|
|
||||||
s3c2410_rtc_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_rtc_init( x49gp_module_t* module )
|
||||||
s3c2410_rtc_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc;
|
s3c2410_rtc_t* rtc;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rtc = malloc(sizeof(s3c2410_rtc_t));
|
rtc = malloc( sizeof( s3c2410_rtc_t ) );
|
||||||
if (NULL == rtc) {
|
if ( NULL == rtc ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->x49gp->progname, __FUNCTION__, __LINE__ );
|
||||||
module->x49gp->progname, __FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_rtc_data_init( rtc ) ) {
|
||||||
if (s3c2410_rtc_data_init(rtc)) {
|
free( rtc );
|
||||||
free(rtc);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = rtc;
|
module->user_data = rtc;
|
||||||
rtc->x49gp = module->x49gp;
|
rtc->x49gp = module->x49gp;
|
||||||
|
|
||||||
rtc->tick_timer = x49gp_new_timer(X49GP_TIMER_REALTIME,
|
rtc->tick_timer = x49gp_new_timer( X49GP_TIMER_REALTIME, s3c2410_rtc_timeout, rtc );
|
||||||
s3c2410_rtc_timeout, rtc);
|
rtc->alarm_timer = x49gp_new_timer( X49GP_TIMER_REALTIME, s3c2410_rtc_alarm, rtc );
|
||||||
rtc->alarm_timer = x49gp_new_timer(X49GP_TIMER_REALTIME,
|
|
||||||
s3c2410_rtc_alarm, rtc);
|
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_rtc_readfn,
|
iotype = cpu_register_io_memory( s3c2410_rtc_readfn, s3c2410_rtc_writefn, rtc );
|
||||||
s3c2410_rtc_writefn, rtc);
|
|
||||||
#ifdef DEBUG_S3C2410_RTC
|
#ifdef DEBUG_S3C2410_RTC
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_RTC_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_RTC_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_rtc_exit( x49gp_module_t* module )
|
||||||
s3c2410_rtc_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_rtc_t *rtc;
|
s3c2410_rtc_t* rtc;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
rtc = module->user_data;
|
rtc = module->user_data;
|
||||||
if (rtc->regs)
|
if ( rtc->regs )
|
||||||
free(rtc->regs);
|
free( rtc->regs );
|
||||||
free(rtc);
|
free( rtc );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_rtc_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_rtc_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-rtc",
|
if ( x49gp_module_init( x49gp, "s3c2410-rtc", s3c2410_rtc_init, s3c2410_rtc_exit, s3c2410_rtc_reset, s3c2410_rtc_load, s3c2410_rtc_save,
|
||||||
s3c2410_rtc_init,
|
NULL, &module ) ) {
|
||||||
s3c2410_rtc_exit,
|
return -1;
|
||||||
s3c2410_rtc_reset,
|
}
|
||||||
s3c2410_rtc_load,
|
|
||||||
s3c2410_rtc_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
1282
src/s3c2410_sdi.c
1282
src/s3c2410_sdi.c
File diff suppressed because it is too large
Load diff
|
@ -13,281 +13,242 @@
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
#include "s3c2410_intc.h"
|
#include "s3c2410_intc.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t spicon0;
|
uint32_t spicon0;
|
||||||
uint32_t spista0;
|
uint32_t spista0;
|
||||||
uint32_t sppin0;
|
uint32_t sppin0;
|
||||||
uint32_t sppre0;
|
uint32_t sppre0;
|
||||||
uint32_t sptdat0;
|
uint32_t sptdat0;
|
||||||
uint32_t sprdat0;
|
uint32_t sprdat0;
|
||||||
uint32_t spicon1;
|
uint32_t spicon1;
|
||||||
uint32_t spista1;
|
uint32_t spista1;
|
||||||
uint32_t sppin1;
|
uint32_t sppin1;
|
||||||
uint32_t sppre1;
|
uint32_t sppre1;
|
||||||
uint32_t sptdat1;
|
uint32_t sptdat1;
|
||||||
uint32_t sprdat1;
|
uint32_t sprdat1;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
} s3c2410_spi_t;
|
} s3c2410_spi_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_data_init( s3c2410_spi_t* spi )
|
||||||
s3c2410_spi_data_init(s3c2410_spi_t *spi)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] =
|
s3c2410_offset_t regs[] = {
|
||||||
{
|
S3C2410_OFFSET( SPI, SPICON0, 0x00000000, spi->spicon0 ), S3C2410_OFFSET( SPI, SPISTA0, 0x00000000, spi->spista0 ),
|
||||||
S3C2410_OFFSET(SPI, SPICON0, 0x00000000, spi->spicon0),
|
S3C2410_OFFSET( SPI, SPPIN0, 0x00000000, spi->sppin0 ), S3C2410_OFFSET( SPI, SPPRE0, 0x00000000, spi->sppre0 ),
|
||||||
S3C2410_OFFSET(SPI, SPISTA0, 0x00000000, spi->spista0),
|
S3C2410_OFFSET( SPI, SPTDAT0, 0x00000000, spi->sptdat0 ), S3C2410_OFFSET( SPI, SPRDAT0, 0x00000000, spi->sprdat0 ),
|
||||||
S3C2410_OFFSET(SPI, SPPIN0, 0x00000000, spi->sppin0),
|
S3C2410_OFFSET( SPI, SPICON1, 0x00000000, spi->spicon1 ), S3C2410_OFFSET( SPI, SPISTA1, 0x00000000, spi->spista1 ),
|
||||||
S3C2410_OFFSET(SPI, SPPRE0, 0x00000000, spi->sppre0),
|
S3C2410_OFFSET( SPI, SPPIN1, 0x00000000, spi->sppin1 ), S3C2410_OFFSET( SPI, SPPRE1, 0x00000000, spi->sppre1 ),
|
||||||
S3C2410_OFFSET(SPI, SPTDAT0, 0x00000000, spi->sptdat0),
|
S3C2410_OFFSET( SPI, SPTDAT1, 0x00000000, spi->sptdat1 ), S3C2410_OFFSET( SPI, SPRDAT1, 0x00000000, spi->sprdat1 ),
|
||||||
S3C2410_OFFSET(SPI, SPRDAT0, 0x00000000, spi->sprdat0),
|
};
|
||||||
S3C2410_OFFSET(SPI, SPICON1, 0x00000000, spi->spicon1),
|
|
||||||
S3C2410_OFFSET(SPI, SPISTA1, 0x00000000, spi->spista1),
|
|
||||||
S3C2410_OFFSET(SPI, SPPIN1, 0x00000000, spi->sppin1),
|
|
||||||
S3C2410_OFFSET(SPI, SPPRE1, 0x00000000, spi->sppre1),
|
|
||||||
S3C2410_OFFSET(SPI, SPTDAT1, 0x00000000, spi->sptdat1),
|
|
||||||
S3C2410_OFFSET(SPI, SPRDAT1, 0x00000000, spi->sprdat1),
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(spi, 0, sizeof(s3c2410_spi_t));
|
memset( spi, 0, sizeof( s3c2410_spi_t ) );
|
||||||
|
|
||||||
spi->regs = malloc(sizeof(regs));
|
spi->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == spi->regs) {
|
if ( NULL == spi->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(spi->regs, regs, sizeof(regs));
|
memcpy( spi->regs, regs, sizeof( regs ) );
|
||||||
spi->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
spi->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t s3c2410_spi_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_spi_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi = opaque;
|
s3c2410_spi_t* spi = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(spi, offset)) {
|
if ( !S3C2410_OFFSET_OK( spi, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(spi, offset);
|
reg = S3C2410_OFFSET_ENTRY( spi, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_SPI
|
#ifdef DEBUG_S3C2410_SPI
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-spi", S3C2410_SPI_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-spi", S3C2410_SPI_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_SPI_SPRDAT0:
|
case S3C2410_SPI_SPRDAT0:
|
||||||
spi->spista0 &= ~(1);
|
spi->spista0 &= ~( 1 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S3C2410_SPI_SPRDAT1:
|
case S3C2410_SPI_SPRDAT1:
|
||||||
spi->spista1 &= ~(1);
|
spi->spista1 &= ~( 1 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void s3c2410_spi_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_spi_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi = opaque;
|
s3c2410_spi_t* spi = opaque;
|
||||||
x49gp_t *x49gp = spi->x49gp;
|
x49gp_t* x49gp = spi->x49gp;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(spi, offset)) {
|
if ( !S3C2410_OFFSET_OK( spi, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(spi, offset);
|
reg = S3C2410_OFFSET_ENTRY( spi, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_SPI
|
#ifdef DEBUG_S3C2410_SPI
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-spi", S3C2410_SPI_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-spi", S3C2410_SPI_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_SPI_SPTDAT0:
|
case S3C2410_SPI_SPTDAT0:
|
||||||
spi->spista0 |= 1;
|
spi->spista0 |= 1;
|
||||||
s3c2410_intc_assert(x49gp, INT_SPI0, 0);
|
s3c2410_intc_assert( x49gp, INT_SPI0, 0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S3C2410_SPI_SPTDAT1:
|
case S3C2410_SPI_SPTDAT1:
|
||||||
spi->spista1 |= 1;
|
spi->spista1 |= 1;
|
||||||
s3c2410_intc_assert(x49gp, INT_SPI1, 0);
|
s3c2410_intc_assert( x49gp, INT_SPI1, 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_spi_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi = module->user_data;
|
s3c2410_spi_t* spi = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < spi->nr_regs; i++) {
|
for ( i = 0; i < spi->nr_regs; i++ ) {
|
||||||
reg = &spi->regs[i];
|
reg = &spi->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_spi_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi = module->user_data;
|
s3c2410_spi_t* spi = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < spi->nr_regs; i++) {
|
for ( i = 0; i < spi->nr_regs; i++ ) {
|
||||||
reg = &spi->regs[i];
|
reg = &spi->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_spi_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi = module->user_data;
|
s3c2410_spi_t* spi = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < spi->nr_regs; i++) {
|
for ( i = 0; i < spi->nr_regs; i++ ) {
|
||||||
reg = &spi->regs[i];
|
reg = &spi->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_spi_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_spi_readfn[] = { s3c2410_spi_read, s3c2410_spi_read, s3c2410_spi_read };
|
||||||
{
|
|
||||||
s3c2410_spi_read,
|
|
||||||
s3c2410_spi_read,
|
|
||||||
s3c2410_spi_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_spi_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_spi_writefn[] = { s3c2410_spi_write, s3c2410_spi_write, s3c2410_spi_write };
|
||||||
{
|
|
||||||
s3c2410_spi_write,
|
|
||||||
s3c2410_spi_write,
|
|
||||||
s3c2410_spi_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_init( x49gp_module_t* module )
|
||||||
s3c2410_spi_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi;
|
s3c2410_spi_t* spi;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spi = malloc(sizeof(s3c2410_spi_t));
|
spi = malloc( sizeof( s3c2410_spi_t ) );
|
||||||
if (NULL == spi) {
|
if ( NULL == spi ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_spi_data_init( spi ) ) {
|
||||||
if (s3c2410_spi_data_init(spi)) {
|
free( spi );
|
||||||
free(spi);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = spi;
|
module->user_data = spi;
|
||||||
spi->x49gp = module->x49gp;
|
spi->x49gp = module->x49gp;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_spi_readfn,
|
iotype = cpu_register_io_memory( s3c2410_spi_readfn, s3c2410_spi_writefn, spi );
|
||||||
s3c2410_spi_writefn, spi);
|
|
||||||
#ifdef DEBUG_S3C2410_SPI
|
#ifdef DEBUG_S3C2410_SPI
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_SPI_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_SPI_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_spi_exit( x49gp_module_t* module )
|
||||||
s3c2410_spi_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_spi_t *spi;
|
s3c2410_spi_t* spi;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
spi = module->user_data;
|
spi = module->user_data;
|
||||||
if (spi->regs)
|
if ( spi->regs )
|
||||||
free(spi->regs);
|
free( spi->regs );
|
||||||
free(spi);
|
free( spi );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_spi_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_spi_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-spi",
|
if ( x49gp_module_init( x49gp, "s3c2410-spi", s3c2410_spi_init, s3c2410_spi_exit, s3c2410_spi_reset, s3c2410_spi_load, s3c2410_spi_save,
|
||||||
s3c2410_spi_init,
|
NULL, &module ) ) {
|
||||||
s3c2410_spi_exit,
|
return -1;
|
||||||
s3c2410_spi_reset,
|
}
|
||||||
s3c2410_spi_load,
|
|
||||||
s3c2410_spi_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,182 +14,157 @@
|
||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *data;
|
void* data;
|
||||||
char *filename;
|
char* filename;
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
} filemap_t;
|
} filemap_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_sram_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_sram_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
filemap_t *filemap = module->user_data;
|
filemap_t* filemap = module->user_data;
|
||||||
char *filename;
|
char* filename;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
error = x49gp_module_get_filename(module, key, "filename",
|
error = x49gp_module_get_filename( module, key, "filename", "s3c2410-sram", &( filemap->filename ), &filename );
|
||||||
"s3c2410-sram", &(filemap->filename),
|
|
||||||
&filename);
|
|
||||||
|
|
||||||
filemap->fd = open(filename, O_RDWR | O_CREAT, 0644);
|
filemap->fd = open( filename, O_RDWR | O_CREAT, 0644 );
|
||||||
if (filemap->fd < 0) {
|
if ( filemap->fd < 0 ) {
|
||||||
error = -errno;
|
error = -errno;
|
||||||
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
|
fprintf( stderr, "%s: %s:%u: open %s: %s\n", module->name, __FUNCTION__, __LINE__, filename, strerror( errno ) );
|
||||||
module->name, __FUNCTION__, __LINE__,
|
g_free( filename );
|
||||||
filename, strerror(errno));
|
return error;
|
||||||
g_free(filename);
|
}
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
filemap->size = S3C2410_SRAM_SIZE;
|
filemap->size = S3C2410_SRAM_SIZE;
|
||||||
if (ftruncate(filemap->fd, filemap->size) < 0) {
|
if ( ftruncate( filemap->fd, filemap->size ) < 0 ) {
|
||||||
error = -errno;
|
error = -errno;
|
||||||
fprintf(stderr, "%s: %s:%u: ftruncate %s: %s\n",
|
fprintf( stderr, "%s: %s:%u: ftruncate %s: %s\n", module->name, __FUNCTION__, __LINE__, filename, strerror( errno ) );
|
||||||
module->name, __FUNCTION__, __LINE__,
|
g_free( filename );
|
||||||
filename, strerror(errno));
|
close( filemap->fd );
|
||||||
g_free(filename);
|
filemap->fd = -1;
|
||||||
close(filemap->fd);
|
return error;
|
||||||
filemap->fd = -1;
|
}
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
filemap->data = mmap(phys_ram_base + filemap->offset, filemap->size,
|
filemap->data = mmap( phys_ram_base + filemap->offset, filemap->size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, filemap->fd, 0 );
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
|
if ( filemap->data == ( void* )-1 ) {
|
||||||
filemap->fd, 0);
|
error = -errno;
|
||||||
if (filemap->data == (void *) -1) {
|
fprintf( stderr, "%s: %s:%u: mmap %s: %s\n", module->name, __FUNCTION__, __LINE__, filename, strerror( errno ) );
|
||||||
error = -errno;
|
g_free( filename );
|
||||||
fprintf(stderr, "%s: %s:%u: mmap %s: %s\n",
|
close( filemap->fd );
|
||||||
module->name, __FUNCTION__, __LINE__,
|
filemap->fd = -1;
|
||||||
filename, strerror(errno));
|
return error;
|
||||||
g_free(filename);
|
}
|
||||||
close(filemap->fd);
|
|
||||||
filemap->fd = -1;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(filename);
|
g_free( filename );
|
||||||
|
|
||||||
x49gp_schedule_lcd_update(module->x49gp);
|
x49gp_schedule_lcd_update( module->x49gp );
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_sram_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_sram_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
filemap_t *filemap = module->user_data;
|
filemap_t* filemap = module->user_data;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_module_set_filename(module, key, "filename", filemap->filename);
|
x49gp_module_set_filename( module, key, "filename", filemap->filename );
|
||||||
|
|
||||||
error = msync(filemap->data, filemap->size, MS_ASYNC);
|
error = msync( filemap->data, filemap->size, MS_ASYNC );
|
||||||
if (error) {
|
if ( error ) {
|
||||||
fprintf(stderr, "%s:%u: msync: %s\n",
|
fprintf( stderr, "%s:%u: msync: %s\n", __FUNCTION__, __LINE__, strerror( errno ) );
|
||||||
__FUNCTION__, __LINE__, strerror(errno));
|
return error;
|
||||||
return error;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
error = fsync(filemap->fd);
|
error = fsync( filemap->fd );
|
||||||
if (error) {
|
if ( error ) {
|
||||||
fprintf(stderr, "%s:%u: fsync: %s\n",
|
fprintf( stderr, "%s:%u: fsync: %s\n", __FUNCTION__, __LINE__, strerror( errno ) );
|
||||||
__FUNCTION__, __LINE__, strerror(errno));
|
return error;
|
||||||
return error;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_sram_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_sram_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_sram_init( x49gp_module_t* module )
|
||||||
s3c2410_sram_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
filemap_t *filemap;
|
filemap_t* filemap;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
filemap = malloc(sizeof(filemap_t));
|
filemap = malloc( sizeof( filemap_t ) );
|
||||||
if (NULL == filemap) {
|
if ( NULL == filemap ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
filemap->size = 0;
|
filemap->size = 0;
|
||||||
filemap->fd = -1;
|
filemap->fd = -1;
|
||||||
|
|
||||||
module->user_data = filemap;
|
module->user_data = filemap;
|
||||||
|
|
||||||
filemap->data = (void *) -1;
|
filemap->data = ( void* )-1;
|
||||||
filemap->offset = phys_ram_size;
|
filemap->offset = phys_ram_size;
|
||||||
phys_ram_size += S3C2410_SRAM_SIZE;
|
phys_ram_size += S3C2410_SRAM_SIZE;
|
||||||
|
|
||||||
cpu_register_physical_memory(S3C2410_SRAM_BASE, S3C2410_SRAM_SIZE,
|
cpu_register_physical_memory( S3C2410_SRAM_BASE, S3C2410_SRAM_SIZE, filemap->offset | IO_MEM_RAM );
|
||||||
filemap->offset | IO_MEM_RAM);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_sram_exit( x49gp_module_t* module )
|
||||||
s3c2410_sram_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
filemap_t *filemap;
|
filemap_t* filemap;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
filemap = module->user_data;
|
filemap = module->user_data;
|
||||||
|
|
||||||
if (filemap->data != (void *) -1) {
|
if ( filemap->data != ( void* )-1 ) {
|
||||||
munmap(filemap->data, filemap->size);
|
munmap( filemap->data, filemap->size );
|
||||||
}
|
}
|
||||||
if (filemap->fd >= 0) {
|
if ( filemap->fd >= 0 ) {
|
||||||
close(filemap->fd);
|
close( filemap->fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filemap);
|
free( filemap );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_sram_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_sram_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-sram",
|
if ( x49gp_module_init( x49gp, "s3c2410-sram", s3c2410_sram_init, s3c2410_sram_exit, s3c2410_sram_reset, s3c2410_sram_load,
|
||||||
s3c2410_sram_init,
|
s3c2410_sram_save, NULL, &module ) ) {
|
||||||
s3c2410_sram_exit,
|
return -1;
|
||||||
s3c2410_sram_reset,
|
}
|
||||||
s3c2410_sram_load,
|
|
||||||
s3c2410_sram_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,546 +14,490 @@
|
||||||
#include "s3c2410_timer.h"
|
#include "s3c2410_timer.h"
|
||||||
#include "s3c2410_intc.h"
|
#include "s3c2410_intc.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t reload_bit;
|
uint32_t reload_bit;
|
||||||
uint32_t update_bit;
|
uint32_t update_bit;
|
||||||
uint32_t start_bit;
|
uint32_t start_bit;
|
||||||
unsigned int pre_shift;
|
unsigned int pre_shift;
|
||||||
unsigned int mux_shift;
|
unsigned int mux_shift;
|
||||||
int irq;
|
int irq;
|
||||||
} s3c2410_timer_config_t;
|
} s3c2410_timer_config_t;
|
||||||
|
|
||||||
struct __s3c2410_timer_s__;
|
struct __s3c2410_timer_s__;
|
||||||
typedef struct __s3c2410_timer_s__ s3c2410_timer_t;
|
typedef struct __s3c2410_timer_s__ s3c2410_timer_t;
|
||||||
|
|
||||||
struct __s3c2410_timer_s__ {
|
struct __s3c2410_timer_s__ {
|
||||||
uint32_t tcfg0;
|
uint32_t tcfg0;
|
||||||
uint32_t tcfg1;
|
uint32_t tcfg1;
|
||||||
uint32_t tcon;
|
uint32_t tcon;
|
||||||
uint32_t prev_tcon;
|
uint32_t prev_tcon;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
struct s3c2410_timeout {
|
struct s3c2410_timeout {
|
||||||
uint32_t tcntb;
|
uint32_t tcntb;
|
||||||
uint32_t tcmpb;
|
uint32_t tcmpb;
|
||||||
uint32_t tcnt;
|
uint32_t tcnt;
|
||||||
uint32_t tcmp;
|
uint32_t tcmp;
|
||||||
|
|
||||||
const s3c2410_timer_config_t *tconfig;
|
const s3c2410_timer_config_t* tconfig;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
s3c2410_timer_t *main;
|
s3c2410_timer_t* main;
|
||||||
|
|
||||||
unsigned long interval;
|
unsigned long interval;
|
||||||
x49gp_timer_t *timer;
|
x49gp_timer_t* timer;
|
||||||
} timeout[5];
|
} timeout[ 5 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
static const s3c2410_timer_config_t s3c2410_timer_config[] =
|
static const s3c2410_timer_config_t s3c2410_timer_config[] = {
|
||||||
{
|
{TCON_TIMER0_RELOAD, TCON_TIMER0_UPDATE, TCON_TIMER0_START, TCFG0_PRE0_SHIFT, TCFG1_MUX0_SHIFT, INT_TIMER0},
|
||||||
{
|
{TCON_TIMER1_RELOAD, TCON_TIMER1_UPDATE, TCON_TIMER1_START, TCFG0_PRE0_SHIFT, TCFG1_MUX1_SHIFT, INT_TIMER1},
|
||||||
TCON_TIMER0_RELOAD, TCON_TIMER0_UPDATE, TCON_TIMER0_START,
|
{TCON_TIMER2_RELOAD, TCON_TIMER2_UPDATE, TCON_TIMER2_START, TCFG0_PRE1_SHIFT, TCFG1_MUX2_SHIFT, INT_TIMER2},
|
||||||
TCFG0_PRE0_SHIFT, TCFG1_MUX0_SHIFT, INT_TIMER0
|
{TCON_TIMER3_RELOAD, TCON_TIMER3_UPDATE, TCON_TIMER3_START, TCFG0_PRE1_SHIFT, TCFG1_MUX3_SHIFT, INT_TIMER3},
|
||||||
},
|
{TCON_TIMER4_RELOAD, TCON_TIMER4_UPDATE, TCON_TIMER4_START, TCFG0_PRE1_SHIFT, TCFG1_MUX4_SHIFT, INT_TIMER4},
|
||||||
{
|
|
||||||
TCON_TIMER1_RELOAD, TCON_TIMER1_UPDATE, TCON_TIMER1_START,
|
|
||||||
TCFG0_PRE0_SHIFT, TCFG1_MUX1_SHIFT, INT_TIMER1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
TCON_TIMER2_RELOAD, TCON_TIMER2_UPDATE, TCON_TIMER2_START,
|
|
||||||
TCFG0_PRE1_SHIFT, TCFG1_MUX2_SHIFT, INT_TIMER2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
TCON_TIMER3_RELOAD, TCON_TIMER3_UPDATE, TCON_TIMER3_START,
|
|
||||||
TCFG0_PRE1_SHIFT, TCFG1_MUX3_SHIFT, INT_TIMER3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
TCON_TIMER4_RELOAD, TCON_TIMER4_UPDATE, TCON_TIMER4_START,
|
|
||||||
TCFG0_PRE1_SHIFT, TCFG1_MUX4_SHIFT, INT_TIMER4
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_data_init( s3c2410_timer_t* timer )
|
||||||
s3c2410_timer_data_init(s3c2410_timer_t *timer)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = { S3C2410_OFFSET( TIMER, TCFG0, 0, timer->tcfg0 ),
|
||||||
S3C2410_OFFSET(TIMER, TCFG0, 0, timer->tcfg0),
|
S3C2410_OFFSET( TIMER, TCFG1, 0, timer->tcfg1 ),
|
||||||
S3C2410_OFFSET(TIMER, TCFG1, 0, timer->tcfg1),
|
S3C2410_OFFSET( TIMER, TCON, 0, timer->tcon ),
|
||||||
S3C2410_OFFSET(TIMER, TCON, 0, timer->tcon),
|
S3C2410_OFFSET( TIMER, TCNTB0, 0, timer->timeout[ 0 ].tcntb ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTB0, 0, timer->timeout[0].tcntb),
|
S3C2410_OFFSET( TIMER, TCMPB0, 0, timer->timeout[ 0 ].tcmpb ),
|
||||||
S3C2410_OFFSET(TIMER, TCMPB0, 0, timer->timeout[0].tcmpb),
|
S3C2410_OFFSET( TIMER, TCNTO0, 0, timer->timeout[ 0 ].tcnt ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTO0, 0, timer->timeout[0].tcnt),
|
S3C2410_OFFSET( TIMER, TCNTB1, 0, timer->timeout[ 1 ].tcntb ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTB1, 0, timer->timeout[1].tcntb),
|
S3C2410_OFFSET( TIMER, TCMPB1, 0, timer->timeout[ 1 ].tcmpb ),
|
||||||
S3C2410_OFFSET(TIMER, TCMPB1, 0, timer->timeout[1].tcmpb),
|
S3C2410_OFFSET( TIMER, TCNTO1, 0, timer->timeout[ 1 ].tcnt ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTO1, 0, timer->timeout[1].tcnt),
|
S3C2410_OFFSET( TIMER, TCNTB2, 0, timer->timeout[ 2 ].tcntb ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTB2, 0, timer->timeout[2].tcntb),
|
S3C2410_OFFSET( TIMER, TCMPB2, 0, timer->timeout[ 2 ].tcmpb ),
|
||||||
S3C2410_OFFSET(TIMER, TCMPB2, 0, timer->timeout[2].tcmpb),
|
S3C2410_OFFSET( TIMER, TCNTO2, 0, timer->timeout[ 2 ].tcnt ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTO2, 0, timer->timeout[2].tcnt),
|
S3C2410_OFFSET( TIMER, TCNTB3, 0, timer->timeout[ 3 ].tcntb ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTB3, 0, timer->timeout[3].tcntb),
|
S3C2410_OFFSET( TIMER, TCMPB3, 0, timer->timeout[ 3 ].tcmpb ),
|
||||||
S3C2410_OFFSET(TIMER, TCMPB3, 0, timer->timeout[3].tcmpb),
|
S3C2410_OFFSET( TIMER, TCNTO3, 0, timer->timeout[ 3 ].tcnt ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTO3, 0, timer->timeout[3].tcnt),
|
S3C2410_OFFSET( TIMER, TCNTB4, 0, timer->timeout[ 4 ].tcntb ),
|
||||||
S3C2410_OFFSET(TIMER, TCNTB4, 0, timer->timeout[4].tcntb),
|
S3C2410_OFFSET( TIMER, TCNTO4, 0, timer->timeout[ 4 ].tcnt ) };
|
||||||
S3C2410_OFFSET(TIMER, TCNTO4, 0, timer->timeout[4].tcnt)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(timer, 0, sizeof(s3c2410_timer_t));
|
memset( timer, 0, sizeof( s3c2410_timer_t ) );
|
||||||
|
|
||||||
timer->regs = malloc(sizeof(regs));
|
timer->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == timer->regs) {
|
if ( NULL == timer->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(timer->regs, regs, sizeof(regs));
|
memcpy( timer->regs, regs, sizeof( regs ) );
|
||||||
timer->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
timer->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_timer_timeout( void* data )
|
||||||
s3c2410_timer_timeout(void *data)
|
|
||||||
{
|
{
|
||||||
struct s3c2410_timeout *t = data;
|
struct s3c2410_timeout* t = data;
|
||||||
s3c2410_timer_t *timer = t->main;
|
s3c2410_timer_t* timer = t->main;
|
||||||
x49gp_t *x49gp = timer->x49gp;
|
x49gp_t* x49gp = timer->x49gp;
|
||||||
int64_t timeout;
|
int64_t timeout;
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: assert TIMER%u interrupt\n", t->index);
|
printf( "s3c2410-timer: assert TIMER%u interrupt\n", t->index );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s3c2410_intc_assert(timer->x49gp, t->tconfig->irq, 0);
|
s3c2410_intc_assert( timer->x49gp, t->tconfig->irq, 0 );
|
||||||
|
|
||||||
if (timer->tcon & t->tconfig->reload_bit) {
|
if ( timer->tcon & t->tconfig->reload_bit ) {
|
||||||
t->tcnt = t->tcntb;
|
t->tcnt = t->tcntb;
|
||||||
t->tcmp = t->tcmpb;
|
t->tcmp = t->tcmpb;
|
||||||
} else {
|
} else {
|
||||||
timer->tcon &= ~(t->tconfig->start_bit);
|
timer->tcon &= ~( t->tconfig->start_bit );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: reload TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval, (unsigned long long) timeout);
|
printf( "s3c2410-timer: reload TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval, ( unsigned long long )timeout );
|
||||||
#endif
|
#endif
|
||||||
x49gp_mod_timer(t->timer, x49gp_get_clock() + timeout);
|
x49gp_mod_timer( t->timer, x49gp_get_clock() + timeout );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long s3c2410_timer_next_interrupt( x49gp_t* x49gp )
|
||||||
s3c2410_timer_next_interrupt(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = x49gp->s3c2410_timer;
|
s3c2410_timer_t* timer = x49gp->s3c2410_timer;
|
||||||
struct s3c2410_timeout *t;
|
struct s3c2410_timeout* t;
|
||||||
unsigned long irq, next;
|
unsigned long irq, next;
|
||||||
unsigned long ticks;
|
unsigned long ticks;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ticks = x49gp_get_clock();
|
ticks = x49gp_get_clock();
|
||||||
|
|
||||||
next = ~(0);
|
next = ~( 0 );
|
||||||
for (i = 0; i < 5; i++) {
|
for ( i = 0; i < 5; i++ ) {
|
||||||
t = &timer->timeout[i];
|
t = &timer->timeout[ i ];
|
||||||
|
|
||||||
if (!(timer->tcon & t->tconfig->start_bit))
|
if ( !( timer->tcon & t->tconfig->start_bit ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_timer_pending(t->timer)) {
|
if ( x49gp_timer_pending( t->timer ) ) {
|
||||||
irq = x49gp_timer_expires(t->timer) - ticks;
|
irq = x49gp_timer_expires( t->timer ) - ticks;
|
||||||
} else {
|
} else {
|
||||||
irq = 0;
|
irq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->tcnt) {
|
if ( t->tcnt ) {
|
||||||
irq += (t->tcnt - 1) * t->interval;
|
irq += ( t->tcnt - 1 ) * t->interval;
|
||||||
} else {
|
} else {
|
||||||
if (!(timer->tcon & t->tconfig->reload_bit))
|
if ( !( timer->tcon & t->tconfig->reload_bit ) )
|
||||||
continue;
|
continue;
|
||||||
irq += t->tcntb * t->interval;
|
irq += t->tcntb * t->interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq < next)
|
if ( irq < next )
|
||||||
next = irq;
|
next = irq;
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: TIMER%u: tcnt %u, interval %lu, pending %u, next irq %lu\n",
|
printf( "s3c2410-timer: TIMER%u: tcnt %u, interval %lu, pending %u, next irq %lu\n", t->index, t->tcnt, t->interval,
|
||||||
t->index, t->tcnt, t->interval, x49gp_timer_pending(t->timer), irq);
|
x49gp_timer_pending( t->timer ), irq );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_update_tcfg( s3c2410_timer_t* timer )
|
||||||
s3c2410_update_tcfg(s3c2410_timer_t *timer)
|
|
||||||
{
|
{
|
||||||
struct s3c2410_timeout *t;
|
struct s3c2410_timeout* t;
|
||||||
x49gp_t *x49gp = timer->x49gp;
|
x49gp_t* x49gp = timer->x49gp;
|
||||||
uint32_t pre, mux;
|
uint32_t pre, mux;
|
||||||
int64_t timeout;
|
int64_t timeout;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for ( i = 0; i < 5; i++ ) {
|
||||||
t = &timer->timeout[i];
|
t = &timer->timeout[ i ];
|
||||||
|
|
||||||
pre = (timer->tcfg0 >> t->tconfig->pre_shift) & TCFG0_PREx_MASK;
|
pre = ( timer->tcfg0 >> t->tconfig->pre_shift ) & TCFG0_PREx_MASK;
|
||||||
mux = (timer->tcfg1 >> t->tconfig->mux_shift) & TCFG1_MUXx_MASK;
|
mux = ( timer->tcfg1 >> t->tconfig->mux_shift ) & TCFG1_MUXx_MASK;
|
||||||
|
|
||||||
if (mux > 3) {
|
if ( mux > 3 ) {
|
||||||
printf("s3c2410-timer: can't handle MUX %02x for TIMER%u\n",
|
printf( "s3c2410-timer: can't handle MUX %02x for TIMER%u\n", mux, t->index );
|
||||||
mux, t->index);
|
mux = 3;
|
||||||
mux = 3;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
t->interval = (pre + 1) * (2 << mux);
|
t->interval = ( pre + 1 ) * ( 2 << mux );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: TIMER%u: pre %u, mux %u, tick %lu PCLKs\n",
|
printf( "s3c2410-timer: TIMER%u: pre %u, mux %u, tick %lu PCLKs\n", t->index, pre, mux, t->interval );
|
||||||
t->index, pre, mux, t->interval);
|
|
||||||
#endif
|
#endif
|
||||||
if (x49gp_timer_pending(t->timer)) {
|
if ( x49gp_timer_pending( t->timer ) ) {
|
||||||
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: mod TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval, (unsigned long long) timeout);
|
printf( "s3c2410-timer: mod TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval,
|
||||||
|
( unsigned long long )timeout );
|
||||||
#endif
|
#endif
|
||||||
x49gp_mod_timer(t->timer, x49gp_get_clock() + timeout);
|
x49gp_mod_timer( t->timer, x49gp_get_clock() + timeout );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_update_tcon( s3c2410_timer_t* timer )
|
||||||
s3c2410_update_tcon(s3c2410_timer_t *timer)
|
|
||||||
{
|
{
|
||||||
struct s3c2410_timeout *t;
|
struct s3c2410_timeout* t;
|
||||||
x49gp_t *x49gp = timer->x49gp;
|
x49gp_t* x49gp = timer->x49gp;
|
||||||
int64_t timeout;
|
int64_t timeout;
|
||||||
uint32_t change;
|
uint32_t change;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
change = timer->prev_tcon ^ timer->tcon;
|
change = timer->prev_tcon ^ timer->tcon;
|
||||||
timer->prev_tcon = timer->tcon;
|
timer->prev_tcon = timer->tcon;
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for ( i = 0; i < 5; i++ ) {
|
||||||
t = &timer->timeout[i];
|
t = &timer->timeout[ i ];
|
||||||
|
|
||||||
if (timer->tcon & t->tconfig->update_bit) {
|
if ( timer->tcon & t->tconfig->update_bit ) {
|
||||||
t->tcnt = t->tcntb;
|
t->tcnt = t->tcntb;
|
||||||
t->tcmp = t->tcmpb;
|
t->tcmp = t->tcmpb;
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: update TIMER%u tcnt %u, tcmp %u\n", t->index, t->tcnt, t->tcmp);
|
printf( "s3c2410-timer: update TIMER%u tcnt %u, tcmp %u\n", t->index, t->tcnt, t->tcmp );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change & t->tconfig->start_bit) {
|
if ( change & t->tconfig->start_bit ) {
|
||||||
if (timer->tcon & t->tconfig->start_bit) {
|
if ( timer->tcon & t->tconfig->start_bit ) {
|
||||||
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
timeout = 1000000LL * t->tcnt * t->interval / x49gp->PCLK;
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: start TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval, (unsigned long long) timeout);
|
printf( "s3c2410-timer: start TIMER%u: CNT %u (%lu PCLKs): %llu us\n", t->index, t->tcnt, t->interval,
|
||||||
|
( unsigned long long )timeout );
|
||||||
#endif
|
#endif
|
||||||
x49gp_mod_timer(t->timer, x49gp_get_clock() + timeout);
|
x49gp_mod_timer( t->timer, x49gp_get_clock() + timeout );
|
||||||
} else {
|
} else {
|
||||||
x49gp_del_timer(t->timer);
|
x49gp_del_timer( t->timer );
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("s3c2410-timer: stop TIMER%u\n", t->index);
|
printf( "s3c2410-timer: stop TIMER%u\n", t->index );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_read_tcnt( s3c2410_timer_t* timer, int index )
|
||||||
s3c2410_read_tcnt(s3c2410_timer_t *timer, int index)
|
|
||||||
{
|
{
|
||||||
struct s3c2410_timeout *t = &timer->timeout[index];
|
struct s3c2410_timeout* t = &timer->timeout[ index ];
|
||||||
x49gp_t *x49gp = timer->x49gp;
|
x49gp_t* x49gp = timer->x49gp;
|
||||||
int64_t now, expires, timeout;
|
int64_t now, expires, timeout;
|
||||||
|
|
||||||
if (!(timer->tcon & t->tconfig->start_bit))
|
if ( !( timer->tcon & t->tconfig->start_bit ) )
|
||||||
return t->tcnt;
|
return t->tcnt;
|
||||||
|
|
||||||
if (x49gp_timer_pending(t->timer)) {
|
if ( x49gp_timer_pending( t->timer ) ) {
|
||||||
now = x49gp_get_clock();
|
now = x49gp_get_clock();
|
||||||
expires = x49gp_timer_expires(t->timer);
|
expires = x49gp_timer_expires( t->timer );
|
||||||
|
|
||||||
timeout = expires - now;
|
timeout = expires - now;
|
||||||
if (timeout <= 0)
|
if ( timeout <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
t->tcnt = timeout * x49gp->PCLK / (1000000LL * t->interval);
|
t->tcnt = timeout * x49gp->PCLK / ( 1000000LL * t->interval );
|
||||||
}
|
}
|
||||||
|
|
||||||
return t->tcnt;
|
return t->tcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_timer_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_timer_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = opaque;
|
s3c2410_timer_t* timer = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
uint32_t data;
|
uint32_t data;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(timer, offset)) {
|
if ( !S3C2410_OFFSET_OK( timer, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(timer, offset);
|
reg = S3C2410_OFFSET_ENTRY( timer, offset );
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_TIMER_TCNTO0:
|
case S3C2410_TIMER_TCNTO0:
|
||||||
data = s3c2410_read_tcnt(timer, 0);
|
data = s3c2410_read_tcnt( timer, 0 );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCNTO1:
|
case S3C2410_TIMER_TCNTO1:
|
||||||
data = s3c2410_read_tcnt(timer, 1);
|
data = s3c2410_read_tcnt( timer, 1 );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCNTO2:
|
case S3C2410_TIMER_TCNTO2:
|
||||||
data = s3c2410_read_tcnt(timer, 2);
|
data = s3c2410_read_tcnt( timer, 2 );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCNTO3:
|
case S3C2410_TIMER_TCNTO3:
|
||||||
data = s3c2410_read_tcnt(timer, 3);
|
data = s3c2410_read_tcnt( timer, 3 );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCNTO4:
|
case S3C2410_TIMER_TCNTO4:
|
||||||
data = s3c2410_read_tcnt(timer, 4);
|
data = s3c2410_read_tcnt( timer, 4 );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
data = *(reg->datap);
|
data = *( reg->datap );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-timer", S3C2410_TIMER_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-timer", S3C2410_TIMER_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_timer_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_timer_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = opaque;
|
s3c2410_timer_t* timer = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(timer, offset)) {
|
if ( !S3C2410_OFFSET_OK( timer, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(timer, offset);
|
reg = S3C2410_OFFSET_ENTRY( timer, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-timer", S3C2410_TIMER_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-timer", S3C2410_TIMER_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_TIMER_TCFG0:
|
case S3C2410_TIMER_TCFG0:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
s3c2410_update_tcfg(timer);
|
s3c2410_update_tcfg( timer );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCFG1:
|
case S3C2410_TIMER_TCFG1:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
s3c2410_update_tcfg(timer);
|
s3c2410_update_tcfg( timer );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCON:
|
case S3C2410_TIMER_TCON:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
s3c2410_update_tcon(timer);
|
s3c2410_update_tcon( timer );
|
||||||
break;
|
break;
|
||||||
case S3C2410_TIMER_TCNTO0:
|
case S3C2410_TIMER_TCNTO0:
|
||||||
case S3C2410_TIMER_TCNTO1:
|
case S3C2410_TIMER_TCNTO1:
|
||||||
case S3C2410_TIMER_TCNTO2:
|
case S3C2410_TIMER_TCNTO2:
|
||||||
case S3C2410_TIMER_TCNTO3:
|
case S3C2410_TIMER_TCNTO3:
|
||||||
case S3C2410_TIMER_TCNTO4:
|
case S3C2410_TIMER_TCNTO4:
|
||||||
/* read only */
|
/* read only */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_timer_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = module->user_data;
|
s3c2410_timer_t* timer = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < timer->nr_regs; i++) {
|
for ( i = 0; i < timer->nr_regs; i++ ) {
|
||||||
reg = &timer->regs[i];
|
reg = &timer->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
s3c2410_update_tcon(timer);
|
s3c2410_update_tcon( timer );
|
||||||
s3c2410_update_tcfg(timer);
|
s3c2410_update_tcfg( timer );
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_timer_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = module->user_data;
|
s3c2410_timer_t* timer = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < timer->nr_regs; i++) {
|
for ( i = 0; i < timer->nr_regs; i++ ) {
|
||||||
reg = &timer->regs[i];
|
reg = &timer->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_timer_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer = module->user_data;
|
s3c2410_timer_t* timer = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < timer->nr_regs; i++) {
|
for ( i = 0; i < timer->nr_regs; i++ ) {
|
||||||
reg = &timer->regs[i];
|
reg = &timer->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
s3c2410_update_tcon(timer);
|
s3c2410_update_tcon( timer );
|
||||||
s3c2410_update_tcfg(timer);
|
s3c2410_update_tcfg( timer );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_timer_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_timer_readfn[] = { s3c2410_timer_read, s3c2410_timer_read, s3c2410_timer_read };
|
||||||
{
|
|
||||||
s3c2410_timer_read,
|
|
||||||
s3c2410_timer_read,
|
|
||||||
s3c2410_timer_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_timer_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_timer_writefn[] = { s3c2410_timer_write, s3c2410_timer_write, s3c2410_timer_write };
|
||||||
{
|
|
||||||
s3c2410_timer_write,
|
|
||||||
s3c2410_timer_write,
|
|
||||||
s3c2410_timer_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_init( x49gp_module_t* module )
|
||||||
s3c2410_timer_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer;
|
s3c2410_timer_t* timer;
|
||||||
struct s3c2410_timeout *t;
|
struct s3c2410_timeout* t;
|
||||||
int iotype;
|
int iotype;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
timer = malloc(sizeof(s3c2410_timer_t));
|
timer = malloc( sizeof( s3c2410_timer_t ) );
|
||||||
if (NULL == timer) {
|
if ( NULL == timer ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->x49gp->progname, __FUNCTION__, __LINE__ );
|
||||||
module->x49gp->progname, __FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_timer_data_init( timer ) ) {
|
||||||
if (s3c2410_timer_data_init(timer)) {
|
free( timer );
|
||||||
free(timer);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = timer;
|
module->user_data = timer;
|
||||||
|
|
||||||
timer->x49gp = module->x49gp;
|
timer->x49gp = module->x49gp;
|
||||||
module->x49gp->s3c2410_timer = timer;
|
module->x49gp->s3c2410_timer = timer;
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
for ( i = 0; i < 5; i++ ) {
|
||||||
t = &timer->timeout[i];
|
t = &timer->timeout[ i ];
|
||||||
|
|
||||||
t->tconfig = &s3c2410_timer_config[i];
|
t->tconfig = &s3c2410_timer_config[ i ];
|
||||||
t->index = i;
|
t->index = i;
|
||||||
|
|
||||||
t->main = timer;
|
t->main = timer;
|
||||||
|
|
||||||
t->timer = x49gp_new_timer(X49GP_TIMER_VIRTUAL, s3c2410_timer_timeout, t);
|
t->timer = x49gp_new_timer( X49GP_TIMER_VIRTUAL, s3c2410_timer_timeout, t );
|
||||||
}
|
}
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_timer_readfn,
|
iotype = cpu_register_io_memory( s3c2410_timer_readfn, s3c2410_timer_writefn, timer );
|
||||||
s3c2410_timer_writefn, timer);
|
|
||||||
#ifdef DEBUG_S3C2410_TIMER
|
#ifdef DEBUG_S3C2410_TIMER
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_TIMER_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_TIMER_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_timer_exit( x49gp_module_t* module )
|
||||||
s3c2410_timer_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_timer_t *timer;
|
s3c2410_timer_t* timer;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
timer = module->user_data;
|
timer = module->user_data;
|
||||||
if (timer->regs)
|
if ( timer->regs )
|
||||||
free(timer->regs);
|
free( timer->regs );
|
||||||
free(timer);
|
free( timer );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_timer_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_timer_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-timer",
|
if ( x49gp_module_init( x49gp, "s3c2410-timer", s3c2410_timer_init, s3c2410_timer_exit, s3c2410_timer_reset, s3c2410_timer_load,
|
||||||
s3c2410_timer_init,
|
s3c2410_timer_save, NULL, &module ) ) {
|
||||||
s3c2410_timer_exit,
|
return -1;
|
||||||
s3c2410_timer_reset,
|
}
|
||||||
s3c2410_timer_load,
|
|
||||||
s3c2410_timer_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,43 +6,43 @@
|
||||||
|
|
||||||
#include "x49gp_types.h"
|
#include "x49gp_types.h"
|
||||||
|
|
||||||
#define TCFG0_DEAD_SHIFT 16
|
#define TCFG0_DEAD_SHIFT 16
|
||||||
#define TCFG0_DEAD_MASK 0xff
|
#define TCFG0_DEAD_MASK 0xff
|
||||||
#define TCFG0_PRE1_SHIFT 8
|
#define TCFG0_PRE1_SHIFT 8
|
||||||
#define TCFG0_PRE0_SHIFT 0
|
#define TCFG0_PRE0_SHIFT 0
|
||||||
#define TCFG0_PREx_MASK 0xff
|
#define TCFG0_PREx_MASK 0xff
|
||||||
|
|
||||||
#define TCFG1_DMA_SHIFT 20
|
#define TCFG1_DMA_SHIFT 20
|
||||||
#define TCFG1_DMA_MASK 0x0f
|
#define TCFG1_DMA_MASK 0x0f
|
||||||
#define TCFG1_MUX4_SHIFT 16
|
#define TCFG1_MUX4_SHIFT 16
|
||||||
#define TCFG1_MUX3_SHIFT 12
|
#define TCFG1_MUX3_SHIFT 12
|
||||||
#define TCFG1_MUX2_SHIFT 8
|
#define TCFG1_MUX2_SHIFT 8
|
||||||
#define TCFG1_MUX1_SHIFT 4
|
#define TCFG1_MUX1_SHIFT 4
|
||||||
#define TCFG1_MUX0_SHIFT 0
|
#define TCFG1_MUX0_SHIFT 0
|
||||||
#define TCFG1_MUXx_MASK 0x0f
|
#define TCFG1_MUXx_MASK 0x0f
|
||||||
|
|
||||||
#define TCON_TIMER4_RELOAD 0x00400000
|
#define TCON_TIMER4_RELOAD 0x00400000
|
||||||
#define TCON_TIMER4_UPDATE 0x00200000
|
#define TCON_TIMER4_UPDATE 0x00200000
|
||||||
#define TCON_TIMER4_START 0x00100000
|
#define TCON_TIMER4_START 0x00100000
|
||||||
#define TCON_TIMER3_RELOAD 0x00080000
|
#define TCON_TIMER3_RELOAD 0x00080000
|
||||||
#define TCON_TIMER3_INVERT 0x00040000
|
#define TCON_TIMER3_INVERT 0x00040000
|
||||||
#define TCON_TIMER3_UPDATE 0x00020000
|
#define TCON_TIMER3_UPDATE 0x00020000
|
||||||
#define TCON_TIMER3_START 0x00010000
|
#define TCON_TIMER3_START 0x00010000
|
||||||
#define TCON_TIMER2_RELOAD 0x00008000
|
#define TCON_TIMER2_RELOAD 0x00008000
|
||||||
#define TCON_TIMER2_INVERT 0x00004000
|
#define TCON_TIMER2_INVERT 0x00004000
|
||||||
#define TCON_TIMER2_UPDATE 0x00002000
|
#define TCON_TIMER2_UPDATE 0x00002000
|
||||||
#define TCON_TIMER2_START 0x00001000
|
#define TCON_TIMER2_START 0x00001000
|
||||||
#define TCON_TIMER1_RELOAD 0x00000800
|
#define TCON_TIMER1_RELOAD 0x00000800
|
||||||
#define TCON_TIMER1_INVERT 0x00000400
|
#define TCON_TIMER1_INVERT 0x00000400
|
||||||
#define TCON_TIMER1_UPDATE 0x00000200
|
#define TCON_TIMER1_UPDATE 0x00000200
|
||||||
#define TCON_TIMER1_START 0x00000100
|
#define TCON_TIMER1_START 0x00000100
|
||||||
#define TCON_TIMER0_DEADZONE 0x00000010
|
#define TCON_TIMER0_DEADZONE 0x00000010
|
||||||
#define TCON_TIMER0_RELOAD 0x00000008
|
#define TCON_TIMER0_RELOAD 0x00000008
|
||||||
#define TCON_TIMER0_INVERT 0x00000004
|
#define TCON_TIMER0_INVERT 0x00000004
|
||||||
#define TCON_TIMER0_UPDATE 0x00000002
|
#define TCON_TIMER0_UPDATE 0x00000002
|
||||||
#define TCON_TIMER0_START 0x00000001
|
#define TCON_TIMER0_START 0x00000001
|
||||||
|
|
||||||
void s3c2410_run_timers(x49gp_t *x49gp);
|
void s3c2410_run_timers( x49gp_t* x49gp );
|
||||||
clock_t s3c2410_next_timer(x49gp_t *x49gp);
|
clock_t s3c2410_next_timer( x49gp_t* x49gp );
|
||||||
|
|
||||||
#endif /* !(_S3C2410_TIMER_H) */
|
#endif /* !(_S3C2410_TIMER_H) */
|
||||||
|
|
|
@ -13,466 +13,415 @@
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
#include "s3c2410_intc.h"
|
#include "s3c2410_intc.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ulcon;
|
uint32_t ulcon;
|
||||||
uint32_t ucon;
|
uint32_t ucon;
|
||||||
uint32_t ufcon;
|
uint32_t ufcon;
|
||||||
uint32_t umcon;
|
uint32_t umcon;
|
||||||
uint32_t utrstat;
|
uint32_t utrstat;
|
||||||
uint32_t uerstat;
|
uint32_t uerstat;
|
||||||
uint32_t ufstat;
|
uint32_t ufstat;
|
||||||
uint32_t umstat;
|
uint32_t umstat;
|
||||||
uint32_t utxh;
|
uint32_t utxh;
|
||||||
uint32_t urxh;
|
uint32_t urxh;
|
||||||
uint32_t ubrdiv;
|
uint32_t ubrdiv;
|
||||||
|
|
||||||
int int_err;
|
int int_err;
|
||||||
int int_txd;
|
int int_txd;
|
||||||
int int_rxd;
|
int int_rxd;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
} s3c2410_uart_reg_t;
|
} s3c2410_uart_reg_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
s3c2410_uart_reg_t uart[3];
|
s3c2410_uart_reg_t uart[ 3 ];
|
||||||
} s3c2410_uart_t;
|
} s3c2410_uart_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_data_init( s3c2410_uart_t* uart )
|
||||||
s3c2410_uart_data_init(s3c2410_uart_t *uart)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs0[] = {
|
s3c2410_offset_t regs0[] = { S3C2410_OFFSET( UART0, ULCON, 0x00000000, uart->uart[ 0 ].ulcon ),
|
||||||
S3C2410_OFFSET(UART0, ULCON, 0x00000000, uart->uart[0].ulcon),
|
S3C2410_OFFSET( UART0, UCON, 0x00000000, uart->uart[ 0 ].ucon ),
|
||||||
S3C2410_OFFSET(UART0, UCON, 0x00000000, uart->uart[0].ucon),
|
S3C2410_OFFSET( UART0, UFCON, 0x00000000, uart->uart[ 0 ].ufcon ),
|
||||||
S3C2410_OFFSET(UART0, UFCON, 0x00000000, uart->uart[0].ufcon),
|
S3C2410_OFFSET( UART0, UMCON, 0x00000000, uart->uart[ 0 ].umcon ),
|
||||||
S3C2410_OFFSET(UART0, UMCON, 0x00000000, uart->uart[0].umcon),
|
S3C2410_OFFSET( UART0, UTRSTAT, 0x00000006, uart->uart[ 0 ].utrstat ),
|
||||||
S3C2410_OFFSET(UART0, UTRSTAT, 0x00000006, uart->uart[0].utrstat),
|
S3C2410_OFFSET( UART0, UERSTAT, 0x00000000, uart->uart[ 0 ].uerstat ),
|
||||||
S3C2410_OFFSET(UART0, UERSTAT, 0x00000000, uart->uart[0].uerstat),
|
S3C2410_OFFSET( UART0, UFSTAT, 0x00000000, uart->uart[ 0 ].ufstat ),
|
||||||
S3C2410_OFFSET(UART0, UFSTAT, 0x00000000, uart->uart[0].ufstat),
|
S3C2410_OFFSET( UART0, UMSTAT, 0x00000000, uart->uart[ 0 ].umstat ),
|
||||||
S3C2410_OFFSET(UART0, UMSTAT, 0x00000000, uart->uart[0].umstat),
|
S3C2410_OFFSET( UART0, UTXH, 0, uart->uart[ 0 ].utxh ),
|
||||||
S3C2410_OFFSET(UART0, UTXH, 0, uart->uart[0].utxh),
|
S3C2410_OFFSET( UART0, URXH, 0, uart->uart[ 0 ].urxh ),
|
||||||
S3C2410_OFFSET(UART0, URXH, 0, uart->uart[0].urxh),
|
S3C2410_OFFSET( UART0, UBRDIV, 0, uart->uart[ 0 ].ubrdiv ) };
|
||||||
S3C2410_OFFSET(UART0, UBRDIV, 0, uart->uart[0].ubrdiv)
|
s3c2410_offset_t regs1[] = { S3C2410_OFFSET( UART1, ULCON, 0x00000000, uart->uart[ 1 ].ulcon ),
|
||||||
};
|
S3C2410_OFFSET( UART1, UCON, 0x00000000, uart->uart[ 1 ].ucon ),
|
||||||
s3c2410_offset_t regs1[] = {
|
S3C2410_OFFSET( UART1, UFCON, 0x00000000, uart->uart[ 1 ].ufcon ),
|
||||||
S3C2410_OFFSET(UART1, ULCON, 0x00000000, uart->uart[1].ulcon),
|
S3C2410_OFFSET( UART1, UMCON, 0x00000000, uart->uart[ 1 ].umcon ),
|
||||||
S3C2410_OFFSET(UART1, UCON, 0x00000000, uart->uart[1].ucon),
|
S3C2410_OFFSET( UART1, UTRSTAT, 0x00000006, uart->uart[ 1 ].utrstat ),
|
||||||
S3C2410_OFFSET(UART1, UFCON, 0x00000000, uart->uart[1].ufcon),
|
S3C2410_OFFSET( UART1, UERSTAT, 0x00000000, uart->uart[ 1 ].uerstat ),
|
||||||
S3C2410_OFFSET(UART1, UMCON, 0x00000000, uart->uart[1].umcon),
|
S3C2410_OFFSET( UART1, UFSTAT, 0x00000000, uart->uart[ 1 ].ufstat ),
|
||||||
S3C2410_OFFSET(UART1, UTRSTAT, 0x00000006, uart->uart[1].utrstat),
|
S3C2410_OFFSET( UART1, UMSTAT, 0x00000000, uart->uart[ 1 ].umstat ),
|
||||||
S3C2410_OFFSET(UART1, UERSTAT, 0x00000000, uart->uart[1].uerstat),
|
S3C2410_OFFSET( UART1, UTXH, 0, uart->uart[ 1 ].utxh ),
|
||||||
S3C2410_OFFSET(UART1, UFSTAT, 0x00000000, uart->uart[1].ufstat),
|
S3C2410_OFFSET( UART1, URXH, 0, uart->uart[ 1 ].urxh ),
|
||||||
S3C2410_OFFSET(UART1, UMSTAT, 0x00000000, uart->uart[1].umstat),
|
S3C2410_OFFSET( UART1, UBRDIV, 0, uart->uart[ 1 ].ubrdiv ) };
|
||||||
S3C2410_OFFSET(UART1, UTXH, 0, uart->uart[1].utxh),
|
s3c2410_offset_t regs2[] = { S3C2410_OFFSET( UART2, ULCON, 0x00000000, uart->uart[ 2 ].ulcon ),
|
||||||
S3C2410_OFFSET(UART1, URXH, 0, uart->uart[1].urxh),
|
S3C2410_OFFSET( UART2, UCON, 0x00000000, uart->uart[ 2 ].ucon ),
|
||||||
S3C2410_OFFSET(UART1, UBRDIV, 0, uart->uart[1].ubrdiv)
|
S3C2410_OFFSET( UART2, UFCON, 0x00000000, uart->uart[ 2 ].ufcon ),
|
||||||
};
|
S3C2410_OFFSET( UART2, UTRSTAT, 0x00000006, uart->uart[ 2 ].utrstat ),
|
||||||
s3c2410_offset_t regs2[] = {
|
S3C2410_OFFSET( UART2, UERSTAT, 0x00000000, uart->uart[ 2 ].uerstat ),
|
||||||
S3C2410_OFFSET(UART2, ULCON, 0x00000000, uart->uart[2].ulcon),
|
S3C2410_OFFSET( UART2, UFSTAT, 0x00000000, uart->uart[ 2 ].ufstat ),
|
||||||
S3C2410_OFFSET(UART2, UCON, 0x00000000, uart->uart[2].ucon),
|
S3C2410_OFFSET( UART2, UTXH, 0, uart->uart[ 2 ].utxh ),
|
||||||
S3C2410_OFFSET(UART2, UFCON, 0x00000000, uart->uart[2].ufcon),
|
S3C2410_OFFSET( UART2, URXH, 0, uart->uart[ 2 ].urxh ),
|
||||||
S3C2410_OFFSET(UART2, UTRSTAT, 0x00000006, uart->uart[2].utrstat),
|
S3C2410_OFFSET( UART2, UBRDIV, 0, uart->uart[ 2 ].ubrdiv ) };
|
||||||
S3C2410_OFFSET(UART2, UERSTAT, 0x00000000, uart->uart[2].uerstat),
|
|
||||||
S3C2410_OFFSET(UART2, UFSTAT, 0x00000000, uart->uart[2].ufstat),
|
|
||||||
S3C2410_OFFSET(UART2, UTXH, 0, uart->uart[2].utxh),
|
|
||||||
S3C2410_OFFSET(UART2, URXH, 0, uart->uart[2].urxh),
|
|
||||||
S3C2410_OFFSET(UART2, UBRDIV, 0, uart->uart[2].ubrdiv)
|
|
||||||
};
|
|
||||||
|
|
||||||
uart->uart[0].regs = malloc(sizeof(regs0));
|
uart->uart[ 0 ].regs = malloc( sizeof( regs0 ) );
|
||||||
if (NULL == uart->uart[0].regs) {
|
if ( NULL == uart->uart[ 0 ].regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
uart->uart[ 1 ].regs = malloc( sizeof( regs1 ) );
|
||||||
uart->uart[1].regs = malloc(sizeof(regs1));
|
if ( NULL == uart->uart[ 1 ].regs ) {
|
||||||
if (NULL == uart->uart[1].regs) {
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
free( uart->uart[ 0 ].regs );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
free(uart->uart[0].regs);
|
}
|
||||||
return -ENOMEM;
|
uart->uart[ 2 ].regs = malloc( sizeof( regs2 ) );
|
||||||
}
|
if ( NULL == uart->uart[ 2 ].regs ) {
|
||||||
uart->uart[2].regs = malloc(sizeof(regs2));
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
if (NULL == uart->uart[2].regs) {
|
free( uart->uart[ 0 ].regs );
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
free( uart->uart[ 1 ].regs );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
free(uart->uart[0].regs);
|
}
|
||||||
free(uart->uart[1].regs);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(uart->uart[0].regs, regs0, sizeof(regs0));
|
memcpy( uart->uart[ 0 ].regs, regs0, sizeof( regs0 ) );
|
||||||
uart->uart[0].nr_regs = sizeof(regs0) / sizeof(regs0[0]);
|
uart->uart[ 0 ].nr_regs = sizeof( regs0 ) / sizeof( regs0[ 0 ] );
|
||||||
uart->uart[0].int_err = SUB_INT_ERR0;
|
uart->uart[ 0 ].int_err = SUB_INT_ERR0;
|
||||||
uart->uart[0].int_txd = SUB_INT_TXD0;
|
uart->uart[ 0 ].int_txd = SUB_INT_TXD0;
|
||||||
uart->uart[0].int_rxd = SUB_INT_RXD0;
|
uart->uart[ 0 ].int_rxd = SUB_INT_RXD0;
|
||||||
|
|
||||||
memcpy(uart->uart[1].regs, regs1, sizeof(regs1));
|
memcpy( uart->uart[ 1 ].regs, regs1, sizeof( regs1 ) );
|
||||||
uart->uart[1].nr_regs = sizeof(regs1) / sizeof(regs1[0]);
|
uart->uart[ 1 ].nr_regs = sizeof( regs1 ) / sizeof( regs1[ 0 ] );
|
||||||
uart->uart[1].int_err = SUB_INT_ERR1;
|
uart->uart[ 1 ].int_err = SUB_INT_ERR1;
|
||||||
uart->uart[1].int_txd = SUB_INT_TXD1;
|
uart->uart[ 1 ].int_txd = SUB_INT_TXD1;
|
||||||
uart->uart[1].int_rxd = SUB_INT_RXD1;
|
uart->uart[ 1 ].int_rxd = SUB_INT_RXD1;
|
||||||
|
|
||||||
memcpy(uart->uart[2].regs, regs2, sizeof(regs2));
|
memcpy( uart->uart[ 2 ].regs, regs2, sizeof( regs2 ) );
|
||||||
uart->uart[2].nr_regs = sizeof(regs2) / sizeof(regs2[0]);
|
uart->uart[ 2 ].nr_regs = sizeof( regs2 ) / sizeof( regs2[ 0 ] );
|
||||||
uart->uart[2].int_err = SUB_INT_ERR2;
|
uart->uart[ 2 ].int_err = SUB_INT_ERR2;
|
||||||
uart->uart[2].int_txd = SUB_INT_TXD2;
|
uart->uart[ 2 ].int_txd = SUB_INT_TXD2;
|
||||||
uart->uart[2].int_rxd = SUB_INT_RXD2;
|
uart->uart[ 2 ].int_rxd = SUB_INT_RXD2;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_uart_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_uart_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = opaque;
|
s3c2410_uart_reg_t* uart_regs = opaque;
|
||||||
x49gp_t *x49gp = uart_regs->x49gp;
|
x49gp_t* x49gp = uart_regs->x49gp;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
const char *module;
|
const char* module;
|
||||||
uint32_t mod_offset;
|
uint32_t mod_offset;
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
|
|
||||||
base = (offset & 0x0000c000) >> 14;
|
base = ( offset & 0x0000c000 ) >> 14;
|
||||||
|
|
||||||
switch (base) {
|
switch ( base ) {
|
||||||
case 0:
|
case 0:
|
||||||
module = "s3c2410-uart0";
|
module = "s3c2410-uart0";
|
||||||
mod_offset = S3C2410_UART0_BASE;
|
mod_offset = S3C2410_UART0_BASE;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
module = "s3c2410-uart1";
|
module = "s3c2410-uart1";
|
||||||
mod_offset = S3C2410_UART1_BASE;
|
mod_offset = S3C2410_UART1_BASE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
module = "s3c2410-uart2";
|
module = "s3c2410-uart2";
|
||||||
mod_offset = S3C2410_UART2_BASE;
|
mod_offset = S3C2410_UART2_BASE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
offset &= ~(0xffffc000);
|
offset &= ~( 0xffffc000 );
|
||||||
if (! S3C2410_OFFSET_OK(uart_regs, offset)) {
|
if ( !S3C2410_OFFSET_OK( uart_regs, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(uart_regs, offset);
|
reg = S3C2410_OFFSET_ENTRY( uart_regs, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", module, mod_offset, reg->name, ( unsigned long )offset, *( reg->datap ) );
|
||||||
module, mod_offset, reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_UART0_URXH:
|
case S3C2410_UART0_URXH:
|
||||||
uart_regs->utrstat &= ~(1 << 0);
|
uart_regs->utrstat &= ~( 1 << 0 );
|
||||||
|
|
||||||
if (uart_regs->ucon & (1 << 8)) {
|
if ( uart_regs->ucon & ( 1 << 8 ) ) {
|
||||||
s3c2410_intc_sub_deassert(x49gp, uart_regs->int_rxd);
|
s3c2410_intc_sub_deassert( x49gp, uart_regs->int_rxd );
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_uart_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_uart_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = opaque;
|
s3c2410_uart_reg_t* uart_regs = opaque;
|
||||||
x49gp_t *x49gp = uart_regs->x49gp;
|
x49gp_t* x49gp = uart_regs->x49gp;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
const char *module;
|
const char* module;
|
||||||
uint32_t mod_offset, ubrdivn, baud;
|
uint32_t mod_offset, ubrdivn, baud;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base = (offset & 0x0000c000) >> 14;
|
base = ( offset & 0x0000c000 ) >> 14;
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
switch (base) {
|
switch ( base ) {
|
||||||
case 0:
|
case 0:
|
||||||
module = "s3c2410-uart0";
|
module = "s3c2410-uart0";
|
||||||
mod_offset = S3C2410_UART0_BASE;
|
mod_offset = S3C2410_UART0_BASE;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
module = "s3c2410-uart1";
|
module = "s3c2410-uart1";
|
||||||
mod_offset = S3C2410_UART1_BASE;
|
mod_offset = S3C2410_UART1_BASE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
module = "s3c2410-uart2";
|
module = "s3c2410-uart2";
|
||||||
mod_offset = S3C2410_UART2_BASE;
|
mod_offset = S3C2410_UART2_BASE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
offset &= ~(0xffffc000);
|
offset &= ~( 0xffffc000 );
|
||||||
if (! S3C2410_OFFSET_OK(uart_regs, offset)) {
|
if ( !S3C2410_OFFSET_OK( uart_regs, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(uart_regs, offset);
|
reg = S3C2410_OFFSET_ENTRY( uart_regs, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", module, mod_offset, reg->name, ( unsigned long )offset, data );
|
||||||
module, mod_offset, reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_UART0_UCON:
|
case S3C2410_UART0_UCON:
|
||||||
if (*(reg->datap) & (1 << 9))
|
if ( *( reg->datap ) & ( 1 << 9 ) )
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_txd, 1);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_txd, 1 );
|
||||||
if (*(reg->datap) & (1 << 8))
|
if ( *( reg->datap ) & ( 1 << 8 ) )
|
||||||
s3c2410_intc_sub_deassert(x49gp, uart_regs->int_rxd);
|
s3c2410_intc_sub_deassert( x49gp, uart_regs->int_rxd );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S3C2410_UART0_UBRDIV:
|
case S3C2410_UART0_UBRDIV:
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
ubrdivn = (data >> 0) & 0xffff;
|
ubrdivn = ( data >> 0 ) & 0xffff;
|
||||||
if (uart_regs->ucon & (1 << 10)) {
|
if ( uart_regs->ucon & ( 1 << 10 ) ) {
|
||||||
baud = x49gp->UCLK / 16 / (ubrdivn + 1);
|
baud = x49gp->UCLK / 16 / ( ubrdivn + 1 );
|
||||||
printf("%s: UEXTCLK %u, ubrdivn %u, baud %u\n",
|
printf( "%s: UEXTCLK %u, ubrdivn %u, baud %u\n", module, x49gp->UCLK, ubrdivn, baud );
|
||||||
module, x49gp->UCLK, ubrdivn, baud);
|
} else {
|
||||||
} else {
|
baud = x49gp->PCLK / 16 / ( ubrdivn + 1 );
|
||||||
baud = x49gp->PCLK / 16 / (ubrdivn + 1);
|
printf( "%s: PCLK %u, ubrdivn %u, baud %u\n", module, x49gp->PCLK, ubrdivn, baud );
|
||||||
printf("%s: PCLK %u, ubrdivn %u, baud %u\n",
|
}
|
||||||
module, x49gp->PCLK, ubrdivn, baud);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S3C2410_UART0_UTXH:
|
case S3C2410_UART0_UTXH:
|
||||||
if (uart_regs->ucon & (1 << 9))
|
if ( uart_regs->ucon & ( 1 << 9 ) )
|
||||||
s3c2410_intc_sub_deassert(x49gp, uart_regs->int_txd);
|
s3c2410_intc_sub_deassert( x49gp, uart_regs->int_txd );
|
||||||
|
|
||||||
uart_regs->utrstat |= (1 << 2) | (1 << 1);
|
uart_regs->utrstat |= ( 1 << 2 ) | ( 1 << 1 );
|
||||||
|
|
||||||
if (uart_regs->ucon & (1 << 9))
|
if ( uart_regs->ucon & ( 1 << 9 ) )
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_txd, 1);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_txd, 1 );
|
||||||
else
|
else
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_txd, 0);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_txd, 0 );
|
||||||
|
|
||||||
if (uart_regs->ucon & (1 << 5)) {
|
if ( uart_regs->ucon & ( 1 << 5 ) ) {
|
||||||
uart_regs->urxh = data;
|
uart_regs->urxh = data;
|
||||||
uart_regs->utrstat |= (1 << 0);
|
uart_regs->utrstat |= ( 1 << 0 );
|
||||||
|
|
||||||
if (uart_regs->ucon & (1 << 8))
|
if ( uart_regs->ucon & ( 1 << 8 ) )
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_rxd, 1);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_rxd, 1 );
|
||||||
else
|
else
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_rxd, 0);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_rxd, 0 );
|
||||||
} else if (base == 2) {
|
} else if ( base == 2 ) {
|
||||||
uart_regs->urxh = data;
|
uart_regs->urxh = data;
|
||||||
uart_regs->utrstat |= (1 << 0);
|
uart_regs->utrstat |= ( 1 << 0 );
|
||||||
|
|
||||||
if (uart_regs->ucon & (1 << 8))
|
if ( uart_regs->ucon & ( 1 << 8 ) )
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_rxd, 1);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_rxd, 1 );
|
||||||
else
|
else
|
||||||
s3c2410_intc_sub_assert(x49gp, uart_regs->int_rxd, 0);
|
s3c2410_intc_sub_assert( x49gp, uart_regs->int_rxd, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_uart_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = module->user_data;
|
s3c2410_uart_reg_t* uart_regs = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < uart_regs->nr_regs; i++) {
|
for ( i = 0; i < uart_regs->nr_regs; i++ ) {
|
||||||
reg = &uart_regs->regs[i];
|
reg = &uart_regs->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_uart_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = module->user_data;
|
s3c2410_uart_reg_t* uart_regs = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < uart_regs->nr_regs; i++) {
|
for ( i = 0; i < uart_regs->nr_regs; i++ ) {
|
||||||
reg = &uart_regs->regs[i];
|
reg = &uart_regs->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_uart_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = module->user_data;
|
s3c2410_uart_reg_t* uart_regs = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < uart_regs->nr_regs; i++) {
|
for ( i = 0; i < uart_regs->nr_regs; i++ ) {
|
||||||
reg = &uart_regs->regs[i];
|
reg = &uart_regs->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_uart_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_uart_readfn[] = { s3c2410_uart_read, s3c2410_uart_read, s3c2410_uart_read };
|
||||||
{
|
|
||||||
s3c2410_uart_read,
|
|
||||||
s3c2410_uart_read,
|
|
||||||
s3c2410_uart_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_uart_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_uart_writefn[] = { s3c2410_uart_write, s3c2410_uart_write, s3c2410_uart_write };
|
||||||
{
|
|
||||||
s3c2410_uart_write,
|
|
||||||
s3c2410_uart_write,
|
|
||||||
s3c2410_uart_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_init( x49gp_module_t* module )
|
||||||
s3c2410_uart_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs = module->user_data;
|
s3c2410_uart_reg_t* uart_regs = module->user_data;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_uart_readfn,
|
iotype = cpu_register_io_memory( s3c2410_uart_readfn, s3c2410_uart_writefn, uart_regs );
|
||||||
s3c2410_uart_writefn, uart_regs);
|
|
||||||
#ifdef DEBUG_S3C2410_UART
|
#ifdef DEBUG_S3C2410_UART
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_UART0_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_UART0_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_uart_exit( x49gp_module_t* module )
|
||||||
s3c2410_uart_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_reg_t *uart_regs;
|
s3c2410_uart_reg_t* uart_regs;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
uart_regs = module->user_data;
|
uart_regs = module->user_data;
|
||||||
if (uart_regs->regs)
|
if ( uart_regs->regs )
|
||||||
free(uart_regs->regs);
|
free( uart_regs->regs );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_uart_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_uart_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
s3c2410_uart_t *uart;
|
s3c2410_uart_t* uart;
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
uart = malloc(sizeof(s3c2410_uart_t));
|
uart = malloc( sizeof( s3c2410_uart_t ) );
|
||||||
if (NULL == uart) {
|
if ( NULL == uart ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
memset( uart, 0, sizeof( s3c2410_uart_t ) );
|
||||||
memset(uart, 0, sizeof(s3c2410_uart_t));
|
|
||||||
|
|
||||||
if (s3c2410_uart_data_init(uart)) {
|
if ( s3c2410_uart_data_init( uart ) ) {
|
||||||
free(uart);
|
free( uart );
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart->uart[0].x49gp = x49gp;
|
uart->uart[ 0 ].x49gp = x49gp;
|
||||||
uart->uart[1].x49gp = x49gp;
|
uart->uart[ 1 ].x49gp = x49gp;
|
||||||
uart->uart[2].x49gp = x49gp;
|
uart->uart[ 2 ].x49gp = x49gp;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-uart0",
|
if ( x49gp_module_init( x49gp, "s3c2410-uart0", s3c2410_uart_init, s3c2410_uart_exit, s3c2410_uart_reset, s3c2410_uart_load,
|
||||||
s3c2410_uart_init,
|
s3c2410_uart_save, &uart->uart[ 0 ], &module ) ) {
|
||||||
s3c2410_uart_exit,
|
return -1;
|
||||||
s3c2410_uart_reset,
|
}
|
||||||
s3c2410_uart_load,
|
if ( x49gp_module_register( module ) ) {
|
||||||
s3c2410_uart_save,
|
return -1;
|
||||||
&uart->uart[0], &module)) {
|
}
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (x49gp_module_register(module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-uart1",
|
if ( x49gp_module_init( x49gp, "s3c2410-uart1", s3c2410_uart_init, s3c2410_uart_exit, s3c2410_uart_reset, s3c2410_uart_load,
|
||||||
s3c2410_uart_init,
|
s3c2410_uart_save, &uart->uart[ 1 ], &module ) ) {
|
||||||
s3c2410_uart_exit,
|
return -1;
|
||||||
s3c2410_uart_reset,
|
}
|
||||||
s3c2410_uart_load,
|
if ( x49gp_module_register( module ) ) {
|
||||||
s3c2410_uart_save,
|
return -1;
|
||||||
&uart->uart[1], &module)) {
|
}
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (x49gp_module_register(module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-uart2",
|
if ( x49gp_module_init( x49gp, "s3c2410-uart2", s3c2410_uart_init, s3c2410_uart_exit, s3c2410_uart_reset, s3c2410_uart_load,
|
||||||
s3c2410_uart_init,
|
s3c2410_uart_save, &uart->uart[ 2 ], &module ) ) {
|
||||||
s3c2410_uart_exit,
|
return -1;
|
||||||
s3c2410_uart_reset,
|
}
|
||||||
s3c2410_uart_load,
|
if ( x49gp_module_register( module ) ) {
|
||||||
s3c2410_uart_save,
|
return -1;
|
||||||
&uart->uart[2], &module)) {
|
}
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (x49gp_module_register(module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,322 +12,288 @@
|
||||||
#include "x49gp.h"
|
#include "x49gp.h"
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t func_addr_reg;
|
uint32_t func_addr_reg;
|
||||||
uint32_t pwr_reg;
|
uint32_t pwr_reg;
|
||||||
uint32_t ep_int_reg;
|
uint32_t ep_int_reg;
|
||||||
uint32_t usb_int_reg;
|
uint32_t usb_int_reg;
|
||||||
uint32_t ep_int_en_reg;
|
uint32_t ep_int_en_reg;
|
||||||
uint32_t usb_int_en_reg;
|
uint32_t usb_int_en_reg;
|
||||||
uint32_t frame_num1_reg;
|
uint32_t frame_num1_reg;
|
||||||
uint32_t frame_num2_reg;
|
uint32_t frame_num2_reg;
|
||||||
uint32_t index_reg;
|
uint32_t index_reg;
|
||||||
uint32_t ep0_fifo_reg;
|
uint32_t ep0_fifo_reg;
|
||||||
uint32_t ep1_fifo_reg;
|
uint32_t ep1_fifo_reg;
|
||||||
uint32_t ep2_fifo_reg;
|
uint32_t ep2_fifo_reg;
|
||||||
uint32_t ep3_fifo_reg;
|
uint32_t ep3_fifo_reg;
|
||||||
uint32_t ep4_fifo_reg;
|
uint32_t ep4_fifo_reg;
|
||||||
uint32_t ep1_dma_con;
|
uint32_t ep1_dma_con;
|
||||||
uint32_t ep1_dma_unit;
|
uint32_t ep1_dma_unit;
|
||||||
uint32_t ep1_dma_fifo;
|
uint32_t ep1_dma_fifo;
|
||||||
uint32_t ep1_dma_ttc_l;
|
uint32_t ep1_dma_ttc_l;
|
||||||
uint32_t ep1_dma_ttc_m;
|
uint32_t ep1_dma_ttc_m;
|
||||||
uint32_t ep1_dma_ttc_h;
|
uint32_t ep1_dma_ttc_h;
|
||||||
uint32_t ep2_dma_con;
|
uint32_t ep2_dma_con;
|
||||||
uint32_t ep2_dma_unit;
|
uint32_t ep2_dma_unit;
|
||||||
uint32_t ep2_dma_fifo;
|
uint32_t ep2_dma_fifo;
|
||||||
uint32_t ep2_dma_ttc_l;
|
uint32_t ep2_dma_ttc_l;
|
||||||
uint32_t ep2_dma_ttc_m;
|
uint32_t ep2_dma_ttc_m;
|
||||||
uint32_t ep2_dma_ttc_h;
|
uint32_t ep2_dma_ttc_h;
|
||||||
uint32_t ep3_dma_con;
|
uint32_t ep3_dma_con;
|
||||||
uint32_t ep3_dma_unit;
|
uint32_t ep3_dma_unit;
|
||||||
uint32_t ep3_dma_fifo;
|
uint32_t ep3_dma_fifo;
|
||||||
uint32_t ep3_dma_ttc_l;
|
uint32_t ep3_dma_ttc_l;
|
||||||
uint32_t ep3_dma_ttc_m;
|
uint32_t ep3_dma_ttc_m;
|
||||||
uint32_t ep3_dma_ttc_h;
|
uint32_t ep3_dma_ttc_h;
|
||||||
uint32_t ep4_dma_con;
|
uint32_t ep4_dma_con;
|
||||||
uint32_t ep4_dma_unit;
|
uint32_t ep4_dma_unit;
|
||||||
uint32_t ep4_dma_fifo;
|
uint32_t ep4_dma_fifo;
|
||||||
uint32_t ep4_dma_ttc_l;
|
uint32_t ep4_dma_ttc_l;
|
||||||
uint32_t ep4_dma_ttc_m;
|
uint32_t ep4_dma_ttc_m;
|
||||||
uint32_t ep4_dma_ttc_h;
|
uint32_t ep4_dma_ttc_h;
|
||||||
uint32_t __wrong_maxp_reg;
|
uint32_t __wrong_maxp_reg;
|
||||||
uint32_t in_csr1_reg_ep0_csr;
|
uint32_t in_csr1_reg_ep0_csr;
|
||||||
uint32_t in_csr2_reg;
|
uint32_t in_csr2_reg;
|
||||||
uint32_t maxp_reg;
|
uint32_t maxp_reg;
|
||||||
uint32_t out_csr1_reg;
|
uint32_t out_csr1_reg;
|
||||||
uint32_t out_csr2_reg;
|
uint32_t out_csr2_reg;
|
||||||
uint32_t out_fifo_cnt1_reg;
|
uint32_t out_fifo_cnt1_reg;
|
||||||
uint32_t out_fifo_cnt2_reg;
|
uint32_t out_fifo_cnt2_reg;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
} s3c2410_usbdev_t;
|
} s3c2410_usbdev_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_data_init( s3c2410_usbdev_t* usbdev )
|
||||||
s3c2410_usbdev_data_init(s3c2410_usbdev_t *usbdev)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = { S3C2410_OFFSET( USBDEV, FUNC_ADDR_REG, 0x00, usbdev->func_addr_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, FUNC_ADDR_REG, 0x00, usbdev->func_addr_reg),
|
S3C2410_OFFSET( USBDEV, PWR_REG, 0x00, usbdev->pwr_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, PWR_REG, 0x00, usbdev->pwr_reg),
|
S3C2410_OFFSET( USBDEV, EP_INT_REG, 0x00, usbdev->ep_int_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP_INT_REG, 0x00, usbdev->ep_int_reg),
|
S3C2410_OFFSET( USBDEV, USB_INT_REG, 0x00, usbdev->usb_int_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, USB_INT_REG, 0x00, usbdev->usb_int_reg),
|
S3C2410_OFFSET( USBDEV, EP_INT_EN_REG, 0xff, usbdev->ep_int_en_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP_INT_EN_REG, 0xff, usbdev->ep_int_en_reg),
|
S3C2410_OFFSET( USBDEV, USB_INT_EN_REG, 0x04, usbdev->usb_int_en_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, USB_INT_EN_REG, 0x04, usbdev->usb_int_en_reg),
|
S3C2410_OFFSET( USBDEV, FRAME_NUM1_REG, 0x00, usbdev->frame_num1_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, FRAME_NUM1_REG, 0x00, usbdev->frame_num1_reg),
|
S3C2410_OFFSET( USBDEV, FRAME_NUM2_REG, 0x00, usbdev->frame_num2_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, FRAME_NUM2_REG, 0x00, usbdev->frame_num2_reg),
|
S3C2410_OFFSET( USBDEV, INDEX_REG, 0x00, usbdev->index_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, INDEX_REG, 0x00, usbdev->index_reg),
|
S3C2410_OFFSET( USBDEV, EP0_FIFO_REG, 0, usbdev->ep0_fifo_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP0_FIFO_REG, 0, usbdev->ep0_fifo_reg),
|
S3C2410_OFFSET( USBDEV, EP1_FIFO_REG, 0, usbdev->ep1_fifo_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_FIFO_REG, 0, usbdev->ep1_fifo_reg),
|
S3C2410_OFFSET( USBDEV, EP2_FIFO_REG, 0, usbdev->ep2_fifo_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_FIFO_REG, 0, usbdev->ep2_fifo_reg),
|
S3C2410_OFFSET( USBDEV, EP3_FIFO_REG, 0, usbdev->ep3_fifo_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_FIFO_REG, 0, usbdev->ep3_fifo_reg),
|
S3C2410_OFFSET( USBDEV, EP4_FIFO_REG, 0, usbdev->ep4_fifo_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_FIFO_REG, 0, usbdev->ep4_fifo_reg),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_CON, 0x00, usbdev->ep1_dma_con ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_CON, 0x00, usbdev->ep1_dma_con),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_UNIT, 0x00, usbdev->ep1_dma_unit ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_UNIT, 0x00, usbdev->ep1_dma_unit),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_FIFO, 0x00, usbdev->ep1_dma_fifo ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_FIFO, 0x00, usbdev->ep1_dma_fifo),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_TTC_L, 0x00, usbdev->ep1_dma_ttc_l ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_TTC_L, 0x00, usbdev->ep1_dma_ttc_l),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_TTC_M, 0x00, usbdev->ep1_dma_ttc_m ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_TTC_M, 0x00, usbdev->ep1_dma_ttc_m),
|
S3C2410_OFFSET( USBDEV, EP1_DMA_TTC_H, 0x00, usbdev->ep1_dma_ttc_h ),
|
||||||
S3C2410_OFFSET(USBDEV, EP1_DMA_TTC_H, 0x00, usbdev->ep1_dma_ttc_h),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_CON, 0x00, usbdev->ep2_dma_con ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_CON, 0x00, usbdev->ep2_dma_con),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_UNIT, 0x00, usbdev->ep2_dma_unit ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_UNIT, 0x00, usbdev->ep2_dma_unit),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_FIFO, 0x00, usbdev->ep2_dma_fifo ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_FIFO, 0x00, usbdev->ep2_dma_fifo),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_TTC_L, 0x00, usbdev->ep2_dma_ttc_l ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_TTC_L, 0x00, usbdev->ep2_dma_ttc_l),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_TTC_M, 0x00, usbdev->ep2_dma_ttc_m ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_TTC_M, 0x00, usbdev->ep2_dma_ttc_m),
|
S3C2410_OFFSET( USBDEV, EP2_DMA_TTC_H, 0x00, usbdev->ep2_dma_ttc_h ),
|
||||||
S3C2410_OFFSET(USBDEV, EP2_DMA_TTC_H, 0x00, usbdev->ep2_dma_ttc_h),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_CON, 0x00, usbdev->ep3_dma_con ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_CON, 0x00, usbdev->ep3_dma_con),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_UNIT, 0x00, usbdev->ep3_dma_unit ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_UNIT, 0x00, usbdev->ep3_dma_unit),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_FIFO, 0x00, usbdev->ep3_dma_fifo ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_FIFO, 0x00, usbdev->ep3_dma_fifo),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_TTC_L, 0x00, usbdev->ep3_dma_ttc_l ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_TTC_L, 0x00, usbdev->ep3_dma_ttc_l),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_TTC_M, 0x00, usbdev->ep3_dma_ttc_m ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_TTC_M, 0x00, usbdev->ep3_dma_ttc_m),
|
S3C2410_OFFSET( USBDEV, EP3_DMA_TTC_H, 0x00, usbdev->ep3_dma_ttc_h ),
|
||||||
S3C2410_OFFSET(USBDEV, EP3_DMA_TTC_H, 0x00, usbdev->ep3_dma_ttc_h),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_CON, 0x00, usbdev->ep4_dma_con ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_CON, 0x00, usbdev->ep4_dma_con),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_UNIT, 0x00, usbdev->ep4_dma_unit ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_UNIT, 0x00, usbdev->ep4_dma_unit),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_FIFO, 0x00, usbdev->ep4_dma_fifo ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_FIFO, 0x00, usbdev->ep4_dma_fifo),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_TTC_L, 0x00, usbdev->ep4_dma_ttc_l ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_TTC_L, 0x00, usbdev->ep4_dma_ttc_l),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_TTC_M, 0x00, usbdev->ep4_dma_ttc_m ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_TTC_M, 0x00, usbdev->ep4_dma_ttc_m),
|
S3C2410_OFFSET( USBDEV, EP4_DMA_TTC_H, 0x00, usbdev->ep4_dma_ttc_h ),
|
||||||
S3C2410_OFFSET(USBDEV, EP4_DMA_TTC_H, 0x00, usbdev->ep4_dma_ttc_h),
|
S3C2410_OFFSET( USBDEV, MAXP_REG_WRONG, 0x01, usbdev->__wrong_maxp_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, MAXP_REG_WRONG, 0x01, usbdev->__wrong_maxp_reg),
|
S3C2410_OFFSET( USBDEV, IN_CSR1_REG_EP0_CSR, 0x00, usbdev->in_csr1_reg_ep0_csr ),
|
||||||
S3C2410_OFFSET(USBDEV, IN_CSR1_REG_EP0_CSR, 0x00, usbdev->in_csr1_reg_ep0_csr),
|
S3C2410_OFFSET( USBDEV, IN_CSR2_REG, 0x20, usbdev->in_csr2_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, IN_CSR2_REG, 0x20, usbdev->in_csr2_reg),
|
S3C2410_OFFSET( USBDEV, MAXP_REG, 0x01, usbdev->maxp_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, MAXP_REG, 0x01, usbdev->maxp_reg),
|
S3C2410_OFFSET( USBDEV, OUT_CSR1_REG, 0x00, usbdev->out_csr1_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, OUT_CSR1_REG, 0x00, usbdev->out_csr1_reg),
|
S3C2410_OFFSET( USBDEV, OUT_CSR2_REG, 0x00, usbdev->out_csr2_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, OUT_CSR2_REG, 0x00, usbdev->out_csr2_reg),
|
S3C2410_OFFSET( USBDEV, OUT_FIFO_CNT1_REG, 0x00, usbdev->out_fifo_cnt1_reg ),
|
||||||
S3C2410_OFFSET(USBDEV, OUT_FIFO_CNT1_REG, 0x00, usbdev->out_fifo_cnt1_reg),
|
S3C2410_OFFSET( USBDEV, OUT_FIFO_CNT2_REG, 0x00, usbdev->out_fifo_cnt2_reg ) };
|
||||||
S3C2410_OFFSET(USBDEV, OUT_FIFO_CNT2_REG, 0x00, usbdev->out_fifo_cnt2_reg)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(usbdev, 0, sizeof(s3c2410_usbdev_t));
|
memset( usbdev, 0, sizeof( s3c2410_usbdev_t ) );
|
||||||
|
|
||||||
usbdev->regs = malloc(sizeof(regs));
|
usbdev->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == usbdev->regs) {
|
if ( NULL == usbdev->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(usbdev->regs, regs, sizeof(regs));
|
memcpy( usbdev->regs, regs, sizeof( regs ) );
|
||||||
usbdev->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
usbdev->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_usbdev_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_usbdev_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev = opaque;
|
s3c2410_usbdev_t* usbdev = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(usbdev, offset)) {
|
if ( !S3C2410_OFFSET_OK( usbdev, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(usbdev, offset);
|
reg = S3C2410_OFFSET_ENTRY( usbdev, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_USBDEV
|
#ifdef DEBUG_S3C2410_USBDEV
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-usbdev", S3C2410_USBDEV_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-usbdev", S3C2410_USBDEV_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_usbdev_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_usbdev_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev = opaque;
|
s3c2410_usbdev_t* usbdev = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(usbdev, offset)) {
|
if ( !S3C2410_OFFSET_OK( usbdev, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(usbdev, offset);
|
reg = S3C2410_OFFSET_ENTRY( usbdev, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_USBDEV
|
#ifdef DEBUG_S3C2410_USBDEV
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-usbdev", S3C2410_USBDEV_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-usbdev", S3C2410_USBDEV_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_usbdev_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev = module->user_data;
|
s3c2410_usbdev_t* usbdev = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < usbdev->nr_regs; i++) {
|
for ( i = 0; i < usbdev->nr_regs; i++ ) {
|
||||||
reg = &usbdev->regs[i];
|
reg = &usbdev->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_usbdev_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev = module->user_data;
|
s3c2410_usbdev_t* usbdev = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < usbdev->nr_regs; i++) {
|
for ( i = 0; i < usbdev->nr_regs; i++ ) {
|
||||||
reg = &usbdev->regs[i];
|
reg = &usbdev->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_usbdev_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev = module->user_data;
|
s3c2410_usbdev_t* usbdev = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < usbdev->nr_regs; i++) {
|
for ( i = 0; i < usbdev->nr_regs; i++ ) {
|
||||||
reg = &usbdev->regs[i];
|
reg = &usbdev->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_usbdev_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_usbdev_readfn[] = { s3c2410_usbdev_read, s3c2410_usbdev_read, s3c2410_usbdev_read };
|
||||||
{
|
|
||||||
s3c2410_usbdev_read,
|
|
||||||
s3c2410_usbdev_read,
|
|
||||||
s3c2410_usbdev_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_usbdev_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_usbdev_writefn[] = { s3c2410_usbdev_write, s3c2410_usbdev_write, s3c2410_usbdev_write };
|
||||||
{
|
|
||||||
s3c2410_usbdev_write,
|
|
||||||
s3c2410_usbdev_write,
|
|
||||||
s3c2410_usbdev_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_init( x49gp_module_t* module )
|
||||||
s3c2410_usbdev_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev;
|
s3c2410_usbdev_t* usbdev;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usbdev = malloc(sizeof(s3c2410_usbdev_t));
|
usbdev = malloc( sizeof( s3c2410_usbdev_t ) );
|
||||||
if (NULL == usbdev) {
|
if ( NULL == usbdev ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_usbdev_data_init( usbdev ) ) {
|
||||||
if (s3c2410_usbdev_data_init(usbdev)) {
|
free( usbdev );
|
||||||
free(usbdev);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = usbdev;
|
module->user_data = usbdev;
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_usbdev_readfn,
|
iotype = cpu_register_io_memory( s3c2410_usbdev_readfn, s3c2410_usbdev_writefn, usbdev );
|
||||||
s3c2410_usbdev_writefn, usbdev);
|
|
||||||
#ifdef DEBUG_S3C2410_USBDEV
|
#ifdef DEBUG_S3C2410_USBDEV
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_USBDEV_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_USBDEV_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_usbdev_exit( x49gp_module_t* module )
|
||||||
s3c2410_usbdev_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_usbdev_t *usbdev;
|
s3c2410_usbdev_t* usbdev;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
usbdev = module->user_data;
|
usbdev = module->user_data;
|
||||||
if (usbdev->regs)
|
if ( usbdev->regs )
|
||||||
free(usbdev->regs);
|
free( usbdev->regs );
|
||||||
free(usbdev);
|
free( usbdev );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_usbdev_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_usbdev_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-usbdev",
|
if ( x49gp_module_init( x49gp, "s3c2410-usbdev", s3c2410_usbdev_init, s3c2410_usbdev_exit, s3c2410_usbdev_reset, s3c2410_usbdev_load,
|
||||||
s3c2410_usbdev_init,
|
s3c2410_usbdev_save, NULL, &module ) ) {
|
||||||
s3c2410_usbdev_exit,
|
return -1;
|
||||||
s3c2410_usbdev_reset,
|
}
|
||||||
s3c2410_usbdev_load,
|
|
||||||
s3c2410_usbdev_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,367 +13,328 @@
|
||||||
#include "s3c2410.h"
|
#include "s3c2410.h"
|
||||||
#include "s3c2410_intc.h"
|
#include "s3c2410_intc.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t wtcon;
|
uint32_t wtcon;
|
||||||
uint32_t wtdat;
|
uint32_t wtdat;
|
||||||
uint32_t wtcnt;
|
uint32_t wtcnt;
|
||||||
|
|
||||||
unsigned int nr_regs;
|
unsigned int nr_regs;
|
||||||
s3c2410_offset_t *regs;
|
s3c2410_offset_t* regs;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
|
|
||||||
unsigned long interval;
|
unsigned long interval;
|
||||||
x49gp_timer_t *timer;
|
x49gp_timer_t* timer;
|
||||||
} s3c2410_watchdog_t;
|
} s3c2410_watchdog_t;
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_data_init( s3c2410_watchdog_t* watchdog )
|
||||||
s3c2410_watchdog_data_init(s3c2410_watchdog_t *watchdog)
|
|
||||||
{
|
{
|
||||||
s3c2410_offset_t regs[] = {
|
s3c2410_offset_t regs[] = { S3C2410_OFFSET( WATCHDOG, WTCON, 0x8021, watchdog->wtcon ),
|
||||||
S3C2410_OFFSET(WATCHDOG, WTCON, 0x8021, watchdog->wtcon),
|
S3C2410_OFFSET( WATCHDOG, WTDAT, 0x8000, watchdog->wtdat ),
|
||||||
S3C2410_OFFSET(WATCHDOG, WTDAT, 0x8000, watchdog->wtdat),
|
S3C2410_OFFSET( WATCHDOG, WTCNT, 0x8000, watchdog->wtcnt ) };
|
||||||
S3C2410_OFFSET(WATCHDOG, WTCNT, 0x8000, watchdog->wtcnt)
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(watchdog, 0, sizeof(s3c2410_watchdog_t));
|
memset( watchdog, 0, sizeof( s3c2410_watchdog_t ) );
|
||||||
|
|
||||||
watchdog->regs = malloc(sizeof(regs));
|
watchdog->regs = malloc( sizeof( regs ) );
|
||||||
if (NULL == watchdog->regs) {
|
if ( NULL == watchdog->regs ) {
|
||||||
fprintf(stderr, "%s:%u: Out of memory\n",
|
fprintf( stderr, "%s:%u: Out of memory\n", __FUNCTION__, __LINE__ );
|
||||||
__FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(watchdog->regs, regs, sizeof(regs));
|
memcpy( watchdog->regs, regs, sizeof( regs ) );
|
||||||
watchdog->nr_regs = sizeof(regs) / sizeof(regs[0]);
|
watchdog->nr_regs = sizeof( regs ) / sizeof( regs[ 0 ] );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_watchdog_tick( void* data )
|
||||||
s3c2410_watchdog_tick(void *data)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = data;
|
s3c2410_watchdog_t* watchdog = data;
|
||||||
x49gp_t *x49gp = watchdog->x49gp;
|
x49gp_t* x49gp = watchdog->x49gp;
|
||||||
|
|
||||||
if (watchdog->wtcnt > 0) {
|
if ( watchdog->wtcnt > 0 ) {
|
||||||
watchdog->wtcnt--;
|
watchdog->wtcnt--;
|
||||||
} else {
|
} else {
|
||||||
watchdog->wtcnt = watchdog->wtdat;
|
watchdog->wtcnt = watchdog->wtdat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchdog->wtcnt > 0) {
|
if ( watchdog->wtcnt > 0 ) {
|
||||||
// watchdog->timer.expires += watchdog->interval;
|
// watchdog->timer.expires += watchdog->interval;
|
||||||
x49gp_mod_timer(watchdog->timer, x49gp_get_clock() + watchdog->interval);
|
x49gp_mod_timer( watchdog->timer, x49gp_get_clock() + watchdog->interval );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchdog->wtcon & 0x0004) {
|
if ( watchdog->wtcon & 0x0004 ) {
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("WATCHDOG: assert WDT interrupt\n");
|
printf( "WATCHDOG: assert WDT interrupt\n" );
|
||||||
#endif
|
#endif
|
||||||
// g_mutex_lock(x49gp->memlock);
|
// g_mutex_lock(x49gp->memlock);
|
||||||
|
|
||||||
s3c2410_intc_assert(x49gp, INT_WDT, 0);
|
s3c2410_intc_assert( x49gp, INT_WDT, 0 );
|
||||||
|
|
||||||
// g_mutex_unlock(x49gp->memlock);
|
// g_mutex_unlock(x49gp->memlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchdog->wtcon & 0x0001) {
|
if ( watchdog->wtcon & 0x0001 ) {
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("WATCHDOG: assert internal RESET\n");
|
printf( "WATCHDOG: assert internal RESET\n" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x49gp_modules_reset(x49gp, X49GP_RESET_WATCHDOG);
|
x49gp_modules_reset( x49gp, X49GP_RESET_WATCHDOG );
|
||||||
cpu_reset(x49gp->env);
|
cpu_reset( x49gp->env );
|
||||||
|
|
||||||
// if (x49gp->arm->NresetSig != LOW) {
|
// if (x49gp->arm->NresetSig != LOW) {
|
||||||
// x49gp->arm->NresetSig = LOW;
|
// x49gp->arm->NresetSig = LOW;
|
||||||
// x49gp->arm->Exception++;
|
// x49gp->arm->Exception++;
|
||||||
// }
|
// }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchdog->timer.expires += watchdog->interval;
|
// watchdog->timer.expires += watchdog->interval;
|
||||||
x49gp_mod_timer(watchdog->timer, x49gp_get_clock() + watchdog->interval);
|
x49gp_mod_timer( watchdog->timer, x49gp_get_clock() + watchdog->interval );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long s3c2410_watchdog_next_interrupt( x49gp_t* x49gp )
|
||||||
s3c2410_watchdog_next_interrupt(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = x49gp->s3c2410_watchdog;
|
s3c2410_watchdog_t* watchdog = x49gp->s3c2410_watchdog;
|
||||||
unsigned long irq;
|
unsigned long irq;
|
||||||
unsigned long ticks;
|
unsigned long ticks;
|
||||||
|
|
||||||
ticks = x49gp_get_clock();
|
ticks = x49gp_get_clock();
|
||||||
|
|
||||||
if (!(watchdog->wtcon & 0x0020)) {
|
if ( !( watchdog->wtcon & 0x0020 ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x49gp_timer_pending(watchdog->timer)) {
|
if ( x49gp_timer_pending( watchdog->timer ) ) {
|
||||||
irq = x49gp_timer_expires(watchdog->timer) - ticks;
|
irq = x49gp_timer_expires( watchdog->timer ) - ticks;
|
||||||
} else {
|
} else {
|
||||||
irq = 0;
|
irq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watchdog->wtcnt) {
|
if ( watchdog->wtcnt ) {
|
||||||
irq += (watchdog->wtcnt - 1) * watchdog->interval;
|
irq += ( watchdog->wtcnt - 1 ) * watchdog->interval;
|
||||||
} else {
|
} else {
|
||||||
irq += watchdog->wtdat * watchdog->interval;
|
irq += watchdog->wtdat * watchdog->interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("WATCHDOG: wtcnt %u, interval %lu, expires %llu, next irq %lu\n",
|
printf( "WATCHDOG: wtcnt %u, interval %lu, expires %llu, next irq %lu\n", watchdog->wtcnt, watchdog->interval,
|
||||||
watchdog->wtcnt, watchdog->interval, (unsigned long long) (x49gp_timer_pending(watchdog->timer) ? x49gp_timer_expires(watchdog->timer) : 0), irq);
|
( unsigned long long )( x49gp_timer_pending( watchdog->timer ) ? x49gp_timer_expires( watchdog->timer ) : 0 ), irq );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return irq;
|
return irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_update( s3c2410_watchdog_t* watchdog )
|
||||||
s3c2410_watchdog_update(s3c2410_watchdog_t *watchdog)
|
|
||||||
{
|
{
|
||||||
uint32_t pre, mux;
|
uint32_t pre, mux;
|
||||||
|
|
||||||
if (!(watchdog->wtcon & 0x0020)) {
|
if ( !( watchdog->wtcon & 0x0020 ) ) {
|
||||||
x49gp_del_timer(watchdog->timer);
|
x49gp_del_timer( watchdog->timer );
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("WATCHDOG: stop timer\n");
|
printf( "WATCHDOG: stop timer\n" );
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre = (watchdog->wtcon >> 8) & 0xff;
|
pre = ( watchdog->wtcon >> 8 ) & 0xff;
|
||||||
mux = (watchdog->wtcon >> 3) & 3;
|
mux = ( watchdog->wtcon >> 3 ) & 3;
|
||||||
|
|
||||||
watchdog->interval = (pre + 1) * (16 << mux);
|
watchdog->interval = ( pre + 1 ) * ( 16 << mux );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("WATCHDOG: start tick (%lu PCLKs)\n", watchdog->interval);
|
printf( "WATCHDOG: start tick (%lu PCLKs)\n", watchdog->interval );
|
||||||
#endif
|
#endif
|
||||||
x49gp_mod_timer(watchdog->timer, x49gp_get_clock() + watchdog->interval);
|
x49gp_mod_timer( watchdog->timer, x49gp_get_clock() + watchdog->interval );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t s3c2410_watchdog_read( void* opaque, target_phys_addr_t offset )
|
||||||
s3c2410_watchdog_read(void *opaque, target_phys_addr_t offset)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = opaque;
|
s3c2410_watchdog_t* watchdog = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(watchdog, offset)) {
|
if ( !S3C2410_OFFSET_OK( watchdog, offset ) ) {
|
||||||
return ~(0);
|
return ~( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(watchdog, offset);
|
|
||||||
|
|
||||||
|
reg = S3C2410_OFFSET_ENTRY( watchdog, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("read %s [%08x] %s [%08lx] data %08x\n",
|
printf( "read %s [%08x] %s [%08lx] data %08x\n", "s3c2410-watchdog", S3C2410_WATCHDOG_BASE, reg->name, ( unsigned long )offset,
|
||||||
"s3c2410-watchdog", S3C2410_WATCHDOG_BASE,
|
*( reg->datap ) );
|
||||||
reg->name, (unsigned long) offset, *(reg->datap));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(reg->datap);
|
return *( reg->datap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void s3c2410_watchdog_write( void* opaque, target_phys_addr_t offset, uint32_t data )
|
||||||
s3c2410_watchdog_write(void *opaque, target_phys_addr_t offset, uint32_t data)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = opaque;
|
s3c2410_watchdog_t* watchdog = opaque;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
|
|
||||||
if (! S3C2410_OFFSET_OK(watchdog, offset)) {
|
if ( !S3C2410_OFFSET_OK( watchdog, offset ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = S3C2410_OFFSET_ENTRY(watchdog, offset);
|
reg = S3C2410_OFFSET_ENTRY( watchdog, offset );
|
||||||
|
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("write %s [%08x] %s [%08lx] data %08x\n",
|
printf( "write %s [%08x] %s [%08lx] data %08x\n", "s3c2410-watchdog", S3C2410_WATCHDOG_BASE, reg->name, ( unsigned long )offset, data );
|
||||||
"s3c2410-watchdog", S3C2410_WATCHDOG_BASE,
|
|
||||||
reg->name, (unsigned long) offset, data);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*(reg->datap) = data;
|
*( reg->datap ) = data;
|
||||||
|
|
||||||
switch (offset) {
|
switch ( offset ) {
|
||||||
case S3C2410_WATCHDOG_WTCON:
|
case S3C2410_WATCHDOG_WTCON:
|
||||||
case S3C2410_WATCHDOG_WTCNT:
|
case S3C2410_WATCHDOG_WTCNT:
|
||||||
s3c2410_watchdog_update(watchdog);
|
s3c2410_watchdog_update( watchdog );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_load( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_watchdog_load(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = module->user_data;
|
s3c2410_watchdog_t* watchdog = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < watchdog->nr_regs; i++) {
|
for ( i = 0; i < watchdog->nr_regs; i++ ) {
|
||||||
reg = &watchdog->regs[i];
|
reg = &watchdog->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (x49gp_module_get_u32(module, key, reg->name,
|
if ( x49gp_module_get_u32( module, key, reg->name, reg->reset, reg->datap ) )
|
||||||
reg->reset, reg->datap))
|
error = -EAGAIN;
|
||||||
error = -EAGAIN;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
s3c2410_watchdog_update(watchdog);
|
s3c2410_watchdog_update( watchdog );
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_save( x49gp_module_t* module, GKeyFile* key )
|
||||||
s3c2410_watchdog_save(x49gp_module_t *module, GKeyFile *key)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = module->user_data;
|
s3c2410_watchdog_t* watchdog = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < watchdog->nr_regs; i++) {
|
for ( i = 0; i < watchdog->nr_regs; i++ ) {
|
||||||
reg = &watchdog->regs[i];
|
reg = &watchdog->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
x49gp_module_set_u32(module, key, reg->name, *(reg->datap));
|
x49gp_module_set_u32( module, key, reg->name, *( reg->datap ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_reset( x49gp_module_t* module, x49gp_reset_t reset )
|
||||||
s3c2410_watchdog_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog = module->user_data;
|
s3c2410_watchdog_t* watchdog = module->user_data;
|
||||||
s3c2410_offset_t *reg;
|
s3c2410_offset_t* reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < watchdog->nr_regs; i++) {
|
for ( i = 0; i < watchdog->nr_regs; i++ ) {
|
||||||
reg = &watchdog->regs[i];
|
reg = &watchdog->regs[ i ];
|
||||||
|
|
||||||
if (NULL == reg->name)
|
if ( NULL == reg->name )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(reg->datap) = reg->reset;
|
*( reg->datap ) = reg->reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
s3c2410_watchdog_update(watchdog);
|
s3c2410_watchdog_update( watchdog );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUReadMemoryFunc *s3c2410_watchdog_readfn[] =
|
static CPUReadMemoryFunc* s3c2410_watchdog_readfn[] = { s3c2410_watchdog_read, s3c2410_watchdog_read, s3c2410_watchdog_read };
|
||||||
{
|
|
||||||
s3c2410_watchdog_read,
|
|
||||||
s3c2410_watchdog_read,
|
|
||||||
s3c2410_watchdog_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static CPUWriteMemoryFunc *s3c2410_watchdog_writefn[] =
|
static CPUWriteMemoryFunc* s3c2410_watchdog_writefn[] = { s3c2410_watchdog_write, s3c2410_watchdog_write, s3c2410_watchdog_write };
|
||||||
{
|
|
||||||
s3c2410_watchdog_write,
|
|
||||||
s3c2410_watchdog_write,
|
|
||||||
s3c2410_watchdog_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_init( x49gp_module_t* module )
|
||||||
s3c2410_watchdog_init(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog;
|
s3c2410_watchdog_t* watchdog;
|
||||||
int iotype;
|
int iotype;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
watchdog = malloc(sizeof(s3c2410_watchdog_t));
|
watchdog = malloc( sizeof( s3c2410_watchdog_t ) );
|
||||||
if (NULL == watchdog) {
|
if ( NULL == watchdog ) {
|
||||||
fprintf(stderr, "%s: %s:%u: Out of memory\n",
|
fprintf( stderr, "%s: %s:%u: Out of memory\n", module->x49gp->progname, __FUNCTION__, __LINE__ );
|
||||||
module->x49gp->progname, __FUNCTION__, __LINE__);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
if ( s3c2410_watchdog_data_init( watchdog ) ) {
|
||||||
if (s3c2410_watchdog_data_init(watchdog)) {
|
free( watchdog );
|
||||||
free(watchdog);
|
return -ENOMEM;
|
||||||
return -ENOMEM;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module->user_data = watchdog;
|
module->user_data = watchdog;
|
||||||
|
|
||||||
watchdog->x49gp = module->x49gp;
|
watchdog->x49gp = module->x49gp;
|
||||||
module->x49gp->s3c2410_watchdog = watchdog;
|
module->x49gp->s3c2410_watchdog = watchdog;
|
||||||
|
|
||||||
watchdog->timer = x49gp_new_timer(X49GP_TIMER_VIRTUAL,
|
watchdog->timer = x49gp_new_timer( X49GP_TIMER_VIRTUAL, s3c2410_watchdog_tick, watchdog );
|
||||||
s3c2410_watchdog_tick, watchdog);
|
|
||||||
|
|
||||||
iotype = cpu_register_io_memory(s3c2410_watchdog_readfn,
|
iotype = cpu_register_io_memory( s3c2410_watchdog_readfn, s3c2410_watchdog_writefn, watchdog );
|
||||||
s3c2410_watchdog_writefn, watchdog);
|
|
||||||
#ifdef DEBUG_S3C2410_WATCHDOG
|
#ifdef DEBUG_S3C2410_WATCHDOG
|
||||||
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
|
printf( "%s: iotype %08x\n", __FUNCTION__, iotype );
|
||||||
#endif
|
#endif
|
||||||
cpu_register_physical_memory(S3C2410_WATCHDOG_BASE, S3C2410_MAP_SIZE, iotype);
|
cpu_register_physical_memory( S3C2410_WATCHDOG_BASE, S3C2410_MAP_SIZE, iotype );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int s3c2410_watchdog_exit( x49gp_module_t* module )
|
||||||
s3c2410_watchdog_exit(x49gp_module_t *module)
|
|
||||||
{
|
{
|
||||||
s3c2410_watchdog_t *watchdog;
|
s3c2410_watchdog_t* watchdog;
|
||||||
|
|
||||||
#ifdef DEBUG_X49GP_MODULES
|
#ifdef DEBUG_X49GP_MODULES
|
||||||
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
printf( "%s: %s:%u\n", module->name, __FUNCTION__, __LINE__ );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (module->user_data) {
|
if ( module->user_data ) {
|
||||||
watchdog = module->user_data;
|
watchdog = module->user_data;
|
||||||
if (watchdog->regs)
|
if ( watchdog->regs )
|
||||||
free(watchdog->regs);
|
free( watchdog->regs );
|
||||||
free(watchdog);
|
free( watchdog );
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_module_unregister(module);
|
x49gp_module_unregister( module );
|
||||||
free(module);
|
free( module );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_s3c2410_watchdog_init( x49gp_t* x49gp )
|
||||||
x49gp_s3c2410_watchdog_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
x49gp_module_t *module;
|
x49gp_module_t* module;
|
||||||
|
|
||||||
if (x49gp_module_init(x49gp, "s3c2410-watchdog",
|
if ( x49gp_module_init( x49gp, "s3c2410-watchdog", s3c2410_watchdog_init, s3c2410_watchdog_exit, s3c2410_watchdog_reset,
|
||||||
s3c2410_watchdog_init,
|
s3c2410_watchdog_load, s3c2410_watchdog_save, NULL, &module ) ) {
|
||||||
s3c2410_watchdog_exit,
|
return -1;
|
||||||
s3c2410_watchdog_reset,
|
}
|
||||||
s3c2410_watchdog_load,
|
|
||||||
s3c2410_watchdog_save,
|
|
||||||
NULL, &module)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x49gp_module_register(module);
|
return x49gp_module_register( module );
|
||||||
}
|
}
|
||||||
|
|
60
src/saturn.h
60
src/saturn.h
|
@ -4,40 +4,40 @@
|
||||||
#ifndef SATURN_H
|
#ifndef SATURN_H
|
||||||
#define SATURN_H 1
|
#define SATURN_H 1
|
||||||
|
|
||||||
#define NB_RSTK 8
|
#define NB_RSTK 8
|
||||||
|
|
||||||
typedef uint64_t saturn_reg_t;
|
typedef uint64_t saturn_reg_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t read_map[256 + 1];
|
uint32_t read_map[ 256 + 1 ];
|
||||||
uint32_t write_map[256 + 1];
|
uint32_t write_map[ 256 + 1 ];
|
||||||
uint8_t top_map[256 + 1 + 3];
|
uint8_t top_map[ 256 + 1 + 3 ];
|
||||||
saturn_reg_t A;
|
saturn_reg_t A;
|
||||||
saturn_reg_t B;
|
saturn_reg_t B;
|
||||||
saturn_reg_t C;
|
saturn_reg_t C;
|
||||||
saturn_reg_t D;
|
saturn_reg_t D;
|
||||||
saturn_reg_t R0;
|
saturn_reg_t R0;
|
||||||
saturn_reg_t R1;
|
saturn_reg_t R1;
|
||||||
saturn_reg_t R2;
|
saturn_reg_t R2;
|
||||||
saturn_reg_t R3;
|
saturn_reg_t R3;
|
||||||
saturn_reg_t R4;
|
saturn_reg_t R4;
|
||||||
uint32_t D0;
|
uint32_t D0;
|
||||||
uint32_t D1;
|
uint32_t D1;
|
||||||
uint32_t P, P4, P4_32;
|
uint32_t P, P4, P4_32;
|
||||||
uint32_t ST;
|
uint32_t ST;
|
||||||
uint32_t HST;
|
uint32_t HST;
|
||||||
uint32_t carry;
|
uint32_t carry;
|
||||||
int dec;
|
int dec;
|
||||||
uint32_t RSTK[NB_RSTK];
|
uint32_t RSTK[ NB_RSTK ];
|
||||||
uint32_t RSTK_i;
|
uint32_t RSTK_i;
|
||||||
uint32_t REG_FIELD[32];
|
uint32_t REG_FIELD[ 32 ];
|
||||||
uint32_t FIELD_START[32];
|
uint32_t FIELD_START[ 32 ];
|
||||||
uint32_t FIELD_LENGTH[32];
|
uint32_t FIELD_LENGTH[ 32 ];
|
||||||
} saturn_cpu_t;
|
} saturn_cpu_t;
|
||||||
|
|
||||||
#define SAT_RPLTOP 0x8076b
|
#define SAT_RPLTOP 0x8076b
|
||||||
#define SAT_RSKTOP 0x806f3 /* RETTOP */
|
#define SAT_RSKTOP 0x806f3 /* RETTOP */
|
||||||
#define SAT_DSKTOP 0x806f8
|
#define SAT_DSKTOP 0x806f8
|
||||||
#define SAT_EDITLINE 0x806fd
|
#define SAT_EDITLINE 0x806fd
|
||||||
|
|
||||||
#endif /* !(SATURN_H) */
|
#endif /* !(SATURN_H) */
|
||||||
|
|
1121
src/sram.c
1121
src/sram.c
File diff suppressed because it is too large
Load diff
355
src/symbol.c
355
src/symbol.c
|
@ -9,271 +9,184 @@
|
||||||
|
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_square_path_data[] =
|
static const cairo_path_data_t symbol_square_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.100 ), SYMBOL_LINE_TO( 0.500, 0.000 ),
|
||||||
{
|
SYMBOL_LINE_TO( 0.000, 0.500 ), SYMBOL_LINE_TO( -0.500, 0.000 ),
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.100 ),
|
SYMBOL_CLOSE_PATH() };
|
||||||
SYMBOL_LINE_TO( 0.500, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.500 ),
|
|
||||||
SYMBOL_LINE_TO( -0.500, 0.000 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(square, 0.7, 0.0, 0.1, 0.1, 0.6, 0.6);
|
SYMBOL( square, 0.7, 0.0, 0.1, 0.1, 0.6, 0.6 );
|
||||||
|
|
||||||
|
static const cairo_path_data_t symbol_triangleup_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.000 ), SYMBOL_LINE_TO( 0.800, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( -0.400, 0.693 ), SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_triangleup_path_data[] =
|
SYMBOL( triangleup, 1.0, 0.0, 0.1, 0.0, 0.9, 0.693 );
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.800, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( -0.400, 0.693 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(triangleup, 1.0, 0.0, 0.1, 0.0, 0.9, 0.693);
|
static const cairo_path_data_t symbol_triangleright_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.000 ), SYMBOL_LINE_TO( 0.000, 0.800 ),
|
||||||
|
SYMBOL_LINE_TO( 0.693, -0.400 ), SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
|
SYMBOL( triangleright, 0.893, 0.0, 0.1, 0.0, 0.793, 0.8 );
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_triangleright_path_data[] =
|
static const cairo_path_data_t symbol_arrowleftdblfull_path_data[] = {
|
||||||
{
|
SYMBOL_MOVE_TO( 0.100, 0.370 ), SYMBOL_LINE_TO( 0.652, 0.500 ), SYMBOL_LINE_TO( 0.000, -0.250 ), SYMBOL_LINE_TO( 1.000, 0.000 ),
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.000 ),
|
SYMBOL_LINE_TO( 0.000, -0.500 ), SYMBOL_LINE_TO( -1.000, 0.000 ), SYMBOL_LINE_TO( 0.000, -0.250 ), SYMBOL_CLOSE_PATH() };
|
||||||
SYMBOL_LINE_TO( 0.000, 0.800 ),
|
|
||||||
SYMBOL_LINE_TO( 0.693, -0.400 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(triangleright, 0.893, 0.0, 0.1, 0.0, 0.793, 0.8);
|
SYMBOL( arrowleftdblfull, 1.852, 0.0, 0.1, -0.13, 1.752, 0.87 );
|
||||||
|
|
||||||
|
static const cairo_path_data_t symbol_uparrowleft_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.500 ), SYMBOL_LINE_TO( 0.600, 0.200 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.150 ), SYMBOL_LINE_TO( 0.500, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.550 ), SYMBOL_LINE_TO( -0.100, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, 0.450 ), SYMBOL_LINE_TO( -0.400, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.150 ), SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_arrowleftdblfull_path_data[] =
|
SYMBOL( uparrowleft, 1.3, 0.0, 0.1, 0.0, 1.2, 0.7 );
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.370 ),
|
|
||||||
SYMBOL_LINE_TO( 0.652, 0.500 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.250 ),
|
|
||||||
SYMBOL_LINE_TO( 1.000, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.500 ),
|
|
||||||
SYMBOL_LINE_TO( -1.000, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.250 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(arrowleftdblfull, 1.852, 0.0, 0.1, -0.13, 1.752, 0.87);
|
static const cairo_path_data_t symbol_uparrowright_path_data[] = { SYMBOL_MOVE_TO( 1.200, 0.500 ), SYMBOL_LINE_TO( -0.600, 0.200 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.150 ), SYMBOL_LINE_TO( -0.500, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.550 ), SYMBOL_LINE_TO( 0.100, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, 0.450 ), SYMBOL_LINE_TO( 0.400, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.150 ), SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_uparrowleft_path_data[] =
|
SYMBOL( uparrowright, 1.3, 0.0, 0.1, 0.0, 1.2, 0.7 );
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.500 ),
|
|
||||||
SYMBOL_LINE_TO( 0.600, 0.200 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.150 ),
|
|
||||||
SYMBOL_LINE_TO( 0.500, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.550 ),
|
|
||||||
SYMBOL_LINE_TO( -0.100, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.450 ),
|
|
||||||
SYMBOL_LINE_TO( -0.400, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.150 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(uparrowleft, 1.3, 0.0, 0.1, 0.0, 1.2, 0.7);
|
static const cairo_path_data_t symbol_tick_path_data[] = { SYMBOL_MOVE_TO( 0.100, 0.400 ), SYMBOL_LINE_TO( 0.000, 0.450 ),
|
||||||
|
SYMBOL_LINE_TO( 0.150, 0.000 ), SYMBOL_LINE_TO( 0.000, -0.450 ),
|
||||||
|
SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
|
SYMBOL( tick, 0.35, 0.0, 0.1, 0.4, 0.25, 0.85 );
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_uparrowright_path_data[] =
|
static const cairo_path_data_t symbol_radical_path_data[] = { SYMBOL_MOVE_TO( 0.000, 0.500 ), SYMBOL_LINE_TO( 0.214, 0.100 ),
|
||||||
{
|
SYMBOL_LINE_TO( 0.213, -0.456 ), SYMBOL_LINE_TO( 0.229, 0.856 ),
|
||||||
SYMBOL_MOVE_TO( 1.200, 0.500 ),
|
SYMBOL_LINE_TO( 0.077, 0.000 ), SYMBOL_LINE_TO( 0.000, -0.100 ),
|
||||||
SYMBOL_LINE_TO( -0.600, 0.200 ),
|
SYMBOL_LINE_TO( -0.281, -1.050 ), SYMBOL_LINE_TO( -0.287, 0.616 ),
|
||||||
SYMBOL_LINE_TO( 0.000, -0.150 ),
|
SYMBOL_LINE_TO( -0.123, -0.057 ), SYMBOL_CLOSE_PATH() };
|
||||||
SYMBOL_LINE_TO( -0.500, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.550 ),
|
|
||||||
SYMBOL_LINE_TO( 0.100, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.450 ),
|
|
||||||
SYMBOL_LINE_TO( 0.400, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.150 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(uparrowright, 1.3, 0.0, 0.1, 0.0, 1.2, 0.7);
|
SYMBOL( radical, 0.733, 0.0, 0.0, -0.15, 0.733, 1.0 );
|
||||||
|
|
||||||
|
static const cairo_path_data_t symbol_overscore_path_data[] = { SYMBOL_MOVE_TO( 0.000, 1.000 ), SYMBOL_LINE_TO( 0.900, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.100 ), SYMBOL_LINE_TO( -0.900, 0.000 ),
|
||||||
|
SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_tick_path_data[] =
|
SYMBOL( overscore, 0.8, 0.0, 0.0, 0.9, 0.9, 1.0 );
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.100, 0.400 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.450 ),
|
|
||||||
SYMBOL_LINE_TO( 0.150, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.450 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(tick, 0.35, 0.0, 0.1, 0.4, 0.25, 0.85);
|
static const cairo_path_data_t symbol_minus_path_data[] = { SYMBOL_MOVE_TO( 0.050, 0.312 ), SYMBOL_LINE_TO( 0.000, 0.118 ),
|
||||||
|
SYMBOL_LINE_TO( 0.500, 0.000 ), SYMBOL_LINE_TO( 0.000, -0.118 ),
|
||||||
|
SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
|
SYMBOL( minus, 0.6, 0.0, 0.05, 0.312, 0.55, 0.430 );
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_radical_path_data[] =
|
static const cairo_path_data_t symbol_divide_path_data[] = { SYMBOL_MOVE_TO( 0.050, 0.312 ),
|
||||||
{
|
SYMBOL_LINE_TO( 0.000, 0.118 ),
|
||||||
SYMBOL_MOVE_TO( 0.000, 0.500 ),
|
SYMBOL_LINE_TO( 0.500, 0.000 ),
|
||||||
SYMBOL_LINE_TO( 0.214, 0.100 ),
|
SYMBOL_LINE_TO( 0.000, -0.118 ),
|
||||||
SYMBOL_LINE_TO( 0.213, -0.456 ),
|
SYMBOL_CLOSE_PATH(),
|
||||||
SYMBOL_LINE_TO( 0.229, 0.856 ),
|
SYMBOL_MOVE_TO( 0.180, -0.108 ),
|
||||||
SYMBOL_LINE_TO( 0.077, 0.000 ),
|
SYMBOL_LINE_TO( 0.135, 0.000 ),
|
||||||
SYMBOL_LINE_TO( 0.000, -0.100 ),
|
SYMBOL_LINE_TO( 0.000, -0.135 ),
|
||||||
SYMBOL_LINE_TO( -0.281, -1.050 ),
|
SYMBOL_LINE_TO( -0.135, 0.000 ),
|
||||||
SYMBOL_LINE_TO( -0.287, 0.616 ),
|
SYMBOL_CLOSE_PATH(),
|
||||||
SYMBOL_LINE_TO( -0.123, -0.057 ),
|
SYMBOL_MOVE_TO( 0.000, 0.334 ),
|
||||||
SYMBOL_CLOSE_PATH()
|
SYMBOL_LINE_TO( 0.000, 0.135 ),
|
||||||
};
|
SYMBOL_LINE_TO( 0.135, 0.000 ),
|
||||||
|
SYMBOL_LINE_TO( 0.000, -0.135 ),
|
||||||
|
SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
SYMBOL(radical, 0.733, 0.0, 0.0, -0.15, 0.733, 1.0);
|
SYMBOL( divide, 0.6, 0.0, 0.05, 0.069, 0.55, 0.673 );
|
||||||
|
|
||||||
|
static const cairo_path_data_t symbol_divisionslash_path_data[] = { SYMBOL_MOVE_TO( 0.050, 0.000 ), SYMBOL_LINE_TO( 0.345, 0.739 ),
|
||||||
|
SYMBOL_LINE_TO( 0.130, 0.000 ), SYMBOL_LINE_TO( -0.345, -0.739 ),
|
||||||
|
SYMBOL_CLOSE_PATH() };
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_overscore_path_data[] =
|
SYMBOL( divisionslash, 0.575, 0.000, 0.050, 0.000, 0.525, 0.739 );
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.000, 1.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.900, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.100 ),
|
|
||||||
SYMBOL_LINE_TO( -0.900, 0.000 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(overscore, 0.8, 0.0, 0.0, 0.9, 0.9, 1.0);
|
CONTROL( beginsuperscript, 0.0, 0.5, 1.0, 0.8 );
|
||||||
|
CONTROL( endsuperscript, 0.0, 0.5, 1.25, 1.0 );
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_minus_path_data[] =
|
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.050, 0.312 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.118 ),
|
|
||||||
SYMBOL_LINE_TO( 0.500, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.118 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(minus, 0.6, 0.0, 0.05, 0.312, 0.55, 0.430);
|
|
||||||
|
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_divide_path_data[] =
|
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.050, 0.312 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.118 ),
|
|
||||||
SYMBOL_LINE_TO( 0.500, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.118 ),
|
|
||||||
SYMBOL_CLOSE_PATH(),
|
|
||||||
SYMBOL_MOVE_TO( 0.180, -0.108 ),
|
|
||||||
SYMBOL_LINE_TO( 0.135, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.135 ),
|
|
||||||
SYMBOL_LINE_TO( -0.135, 0.000 ),
|
|
||||||
SYMBOL_CLOSE_PATH(),
|
|
||||||
SYMBOL_MOVE_TO( 0.000, 0.334 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, 0.135 ),
|
|
||||||
SYMBOL_LINE_TO( 0.135, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.000, -0.135 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(divide, 0.6, 0.0, 0.05, 0.069, 0.55, 0.673);
|
|
||||||
|
|
||||||
|
|
||||||
static const cairo_path_data_t symbol_divisionslash_path_data[] =
|
|
||||||
{
|
|
||||||
SYMBOL_MOVE_TO( 0.050, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( 0.345, 0.739 ),
|
|
||||||
SYMBOL_LINE_TO( 0.130, 0.000 ),
|
|
||||||
SYMBOL_LINE_TO( -0.345, -0.739 ),
|
|
||||||
SYMBOL_CLOSE_PATH()
|
|
||||||
};
|
|
||||||
|
|
||||||
SYMBOL(divisionslash, 0.575, 0.000, 0.050, 0.000, 0.525, 0.739);
|
|
||||||
|
|
||||||
|
|
||||||
CONTROL(beginsuperscript, 0.0, 0.5, 1.0, 0.8);
|
|
||||||
CONTROL(endsuperscript, 0.0, 0.5, 1.25, 1.0);
|
|
||||||
|
|
||||||
CONTROL(kern_m1, -0.1, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m2, -0.2, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m3, -0.3, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m4, -0.4, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m5, -0.5, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m6, -0.6, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m7, -0.7, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m8, -0.8, 0.0, 1.0, 1.0);
|
|
||||||
CONTROL(kern_m9, -0.9, 0.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
|
CONTROL( kern_m1, -0.1, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m2, -0.2, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m3, -0.3, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m4, -0.4, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m5, -0.5, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m6, -0.6, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m7, -0.7, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m8, -0.8, 0.0, 1.0, 1.0 );
|
||||||
|
CONTROL( kern_m9, -0.9, 0.0, 1.0, 1.0 );
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char* name;
|
||||||
const x49gp_symbol_t *symbol;
|
const x49gp_symbol_t* symbol;
|
||||||
} symbol_name_t;
|
} symbol_name_t;
|
||||||
|
|
||||||
static const symbol_name_t symbol_names[] =
|
static const symbol_name_t symbol_names[] = {
|
||||||
{
|
{".notdef", &symbol_square },
|
||||||
{ ".notdef", &symbol_square },
|
{"arrowleftdblfull", &symbol_arrowleftdblfull},
|
||||||
{ "arrowleftdblfull", &symbol_arrowleftdblfull },
|
{"divide", &symbol_divide },
|
||||||
{ "divide", &symbol_divide },
|
{"divisionslash", &symbol_divisionslash },
|
||||||
{ "divisionslash", &symbol_divisionslash },
|
{"minus", &symbol_minus },
|
||||||
{ "minus", &symbol_minus },
|
{"overscore", &symbol_overscore },
|
||||||
{ "overscore", &symbol_overscore },
|
{"radical", &symbol_radical },
|
||||||
{ "radical", &symbol_radical },
|
{"square", &symbol_square },
|
||||||
{ "square", &symbol_square },
|
{"tick", &symbol_tick },
|
||||||
{ "tick", &symbol_tick },
|
{"triangleright", &symbol_triangleright },
|
||||||
{ "triangleright", &symbol_triangleright },
|
{"triangleup", &symbol_triangleup },
|
||||||
{ "triangleup", &symbol_triangleup },
|
{"uparrowleft", &symbol_uparrowleft },
|
||||||
{ "uparrowleft", &symbol_uparrowleft },
|
{"uparrowright", &symbol_uparrowright },
|
||||||
{ "uparrowright", &symbol_uparrowright },
|
{"super", &symbol_beginsuperscript},
|
||||||
{ "super", &symbol_beginsuperscript },
|
{"/super", &symbol_endsuperscript },
|
||||||
{ "/super", &symbol_endsuperscript },
|
{"kern-1", &symbol_kern_m1 },
|
||||||
{ "kern-1", &symbol_kern_m1 },
|
{"kern-2", &symbol_kern_m2 },
|
||||||
{ "kern-2", &symbol_kern_m2 },
|
{"kern-3", &symbol_kern_m3 },
|
||||||
{ "kern-3", &symbol_kern_m3 },
|
{"kern-4", &symbol_kern_m4 },
|
||||||
{ "kern-4", &symbol_kern_m4 },
|
{"kern-5", &symbol_kern_m5 },
|
||||||
{ "kern-5", &symbol_kern_m5 },
|
{"kern-6", &symbol_kern_m6 },
|
||||||
{ "kern-6", &symbol_kern_m6 },
|
{"kern-7", &symbol_kern_m7 },
|
||||||
{ "kern-7", &symbol_kern_m7 },
|
{"kern-8", &symbol_kern_m8 },
|
||||||
{ "kern-8", &symbol_kern_m8 },
|
{"kern-9", &symbol_kern_m9 },
|
||||||
{ "kern-9", &symbol_kern_m9 },
|
{NULL, NULL }
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
};
|
||||||
#define NR_SYMBOLS (sizeof(symbol_names) / sizeof(symbol_names[0]) - 1)
|
#define NR_SYMBOLS ( sizeof( symbol_names ) / sizeof( symbol_names[ 0 ] ) - 1 )
|
||||||
|
|
||||||
int
|
int symbol_lookup_glyph_by_name( const char* name, int namelen, gunichar* glyph )
|
||||||
symbol_lookup_glyph_by_name(const char *name, int namelen, gunichar *glyph)
|
|
||||||
{
|
{
|
||||||
const symbol_name_t *symname;
|
const symbol_name_t* symname;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code symbols as Unicode Private Use from U+E000 on...
|
* Code symbols as Unicode Private Use from U+E000 on...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
symname = symbol_names;
|
symname = symbol_names;
|
||||||
while (symname->name) {
|
while ( symname->name ) {
|
||||||
if ((strlen(symname->name) == namelen) &&
|
if ( ( strlen( symname->name ) == namelen ) && !strncmp( symname->name, name, namelen ) ) {
|
||||||
!strncmp(symname->name, name, namelen)) {
|
if ( glyph ) {
|
||||||
if (glyph) {
|
*glyph = 0xe000 + i;
|
||||||
*glyph = 0xe000 + i;
|
}
|
||||||
}
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
symname++;
|
symname++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const x49gp_symbol_t *
|
const x49gp_symbol_t* symbol_get_by_glyph( gunichar glyph )
|
||||||
symbol_get_by_glyph(gunichar glyph)
|
|
||||||
{
|
{
|
||||||
int index = glyph - 0xe000;
|
int index = glyph - 0xe000;
|
||||||
|
|
||||||
if ((index >= 0) && (index < NR_SYMBOLS)) {
|
if ( ( index >= 0 ) && ( index < NR_SYMBOLS ) ) {
|
||||||
return symbol_names[index].symbol;
|
return symbol_names[ index ].symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const x49gp_symbol_t *
|
const x49gp_symbol_t* symbol_get_by_name( const char* name )
|
||||||
symbol_get_by_name(const char *name)
|
|
||||||
{
|
{
|
||||||
gunichar glyph;
|
gunichar glyph;
|
||||||
|
|
||||||
if (symbol_lookup_glyph_by_name(name, strlen(name), &glyph)) {
|
if ( symbol_lookup_glyph_by_name( name, strlen( name ), &glyph ) ) {
|
||||||
return symbol_get_by_glyph(glyph);
|
return symbol_get_by_glyph( glyph );
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
101
src/symbol.h
101
src/symbol.h
|
@ -7,62 +7,73 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const cairo_path_data_t *data;
|
const cairo_path_data_t* data;
|
||||||
int num_data;
|
int num_data;
|
||||||
} symbol_path_t;
|
} symbol_path_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double x_advance;
|
double x_advance;
|
||||||
double y_advance;
|
double y_advance;
|
||||||
double llx;
|
double llx;
|
||||||
double lly;
|
double lly;
|
||||||
double urx;
|
double urx;
|
||||||
double ury;
|
double ury;
|
||||||
double prescale;
|
double prescale;
|
||||||
double postscale;
|
double postscale;
|
||||||
const symbol_path_t *path;
|
const symbol_path_t* path;
|
||||||
} x49gp_symbol_t;
|
} x49gp_symbol_t;
|
||||||
|
|
||||||
#define SYMBOL_MOVE_TO(x, y) \
|
#define SYMBOL_MOVE_TO( x, y ) \
|
||||||
{ header: { CAIRO_PATH_MOVE_TO, 2 } }, \
|
{ \
|
||||||
{ point: { x, y } }
|
header : { CAIRO_PATH_MOVE_TO, 2 } \
|
||||||
|
}, \
|
||||||
|
{ \
|
||||||
|
point: \
|
||||||
|
{ \
|
||||||
|
x, y \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define SYMBOL_LINE_TO(x, y) \
|
#define SYMBOL_LINE_TO( x, y ) \
|
||||||
{ header: { CAIRO_PATH_LINE_TO, 2 } }, \
|
{ \
|
||||||
{ point: { x, y } }
|
header : { CAIRO_PATH_LINE_TO, 2 } \
|
||||||
|
}, \
|
||||||
|
{ \
|
||||||
|
point: \
|
||||||
|
{ \
|
||||||
|
x, y \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define SYMBOL_CURVE_TO(x1, y1, x2, y2, x3, y3) \
|
#define SYMBOL_CURVE_TO( x1, y1, x2, y2, x3, y3 ) \
|
||||||
{ header: { CAIRO_PATH_CURVE_TO, 4 } }, \
|
{ \
|
||||||
{ point: { x1, y1 } }, \
|
header : { CAIRO_PATH_CURVE_TO, 4 } \
|
||||||
{ point: { x2, y2 } }, \
|
}, \
|
||||||
{ point: { x3, y3 } }
|
{ point : { x1, y1 } }, { point : { x2, y2 } }, \
|
||||||
|
{ \
|
||||||
|
point: \
|
||||||
|
{ \
|
||||||
|
x3, y3 \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define SYMBOL_CLOSE_PATH() \
|
#define SYMBOL_CLOSE_PATH() \
|
||||||
{ header: { CAIRO_PATH_CLOSE_PATH, 1 } }
|
{ \
|
||||||
|
header : { CAIRO_PATH_CLOSE_PATH, 1 } \
|
||||||
|
}
|
||||||
|
|
||||||
#define SYMBOL(name, x_advance, y_advance, llx, lly, urx, ury) \
|
#define SYMBOL( name, x_advance, y_advance, llx, lly, urx, ury ) \
|
||||||
static const symbol_path_t symbol_##name##_path = \
|
static const symbol_path_t symbol_##name##_path = { symbol_##name##_path_data, \
|
||||||
{ \
|
sizeof( symbol_##name##_path_data ) / sizeof( cairo_path_data_t ) }; \
|
||||||
symbol_##name##_path_data, \
|
\
|
||||||
sizeof(symbol_##name##_path_data) / sizeof(cairo_path_data_t) \
|
static const x49gp_symbol_t symbol_##name = { x_advance, y_advance, llx, lly, urx, ury, 1.0, 1.0, &symbol_##name##_path }
|
||||||
}; \
|
|
||||||
\
|
|
||||||
static const x49gp_symbol_t symbol_##name = \
|
|
||||||
{ \
|
|
||||||
x_advance, y_advance, llx, lly, urx, ury, 1.0, 1.0, \
|
|
||||||
&symbol_##name##_path \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONTROL(name, x_advance, y_advance, prescale, postscale) \
|
#define CONTROL( name, x_advance, y_advance, prescale, postscale ) \
|
||||||
static const x49gp_symbol_t symbol_##name = \
|
static const x49gp_symbol_t symbol_##name = { x_advance, y_advance, 0.0, 0.0, 0.0, 0.0, prescale, postscale, NULL }
|
||||||
{ \
|
|
||||||
x_advance, y_advance, 0.0, 0.0, 0.0, 0.0, \
|
|
||||||
prescale, postscale, NULL \
|
|
||||||
}
|
|
||||||
|
|
||||||
int symbol_lookup_glyph_by_name(const char *name, int namelen, gunichar *);
|
int symbol_lookup_glyph_by_name( const char* name, int namelen, gunichar* );
|
||||||
|
|
||||||
const x49gp_symbol_t *symbol_get_by_name(const char *name);
|
const x49gp_symbol_t* symbol_get_by_name( const char* name );
|
||||||
const x49gp_symbol_t *symbol_get_by_glyph(gunichar glyph);
|
const x49gp_symbol_t* symbol_get_by_glyph( gunichar glyph );
|
||||||
|
|
||||||
#endif /* !(_X49GP_SYMBOL_H) */
|
#endif /* !(_X49GP_SYMBOL_H) */
|
||||||
|
|
419
src/timer.c
419
src/timer.c
|
@ -23,299 +23,254 @@
|
||||||
#include "gdbstub.h"
|
#include "gdbstub.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long type;
|
long type;
|
||||||
} x49gp_clock_t;
|
} x49gp_clock_t;
|
||||||
|
|
||||||
struct x49gp_timer_s {
|
struct x49gp_timer_s {
|
||||||
long type;
|
long type;
|
||||||
int64_t expires;
|
int64_t expires;
|
||||||
x49gp_timer_cb_t cb;
|
x49gp_timer_cb_t cb;
|
||||||
void *user_data;
|
void* user_data;
|
||||||
x49gp_timer_t *next;
|
x49gp_timer_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef x49gp_timer_cb_t QEMUTimerCB;
|
typedef x49gp_timer_cb_t QEMUTimerCB;
|
||||||
typedef void * QEMUClock;
|
typedef void* QEMUClock;
|
||||||
QEMUClock *rt_clock = (void *) X49GP_TIMER_REALTIME;
|
QEMUClock* rt_clock = ( void* )X49GP_TIMER_REALTIME;
|
||||||
QEMUClock *vm_clock = (void *) X49GP_TIMER_VIRTUAL;
|
QEMUClock* vm_clock = ( void* )X49GP_TIMER_VIRTUAL;
|
||||||
int64_t ticks_per_sec = 1000000;
|
int64_t ticks_per_sec = 1000000;
|
||||||
|
|
||||||
static x49gp_timer_t *x49gp_timer_lists[2];
|
static x49gp_timer_t* x49gp_timer_lists[ 2 ];
|
||||||
|
|
||||||
int64_t
|
int64_t x49gp_get_clock( void )
|
||||||
x49gp_get_clock(void)
|
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int64_t us;
|
int64_t us;
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday( &tv, NULL );
|
||||||
|
|
||||||
us = tv.tv_sec * 1000000LL + tv.tv_usec;
|
us = tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||||
|
|
||||||
return us;
|
return us;
|
||||||
}
|
}
|
||||||
|
|
||||||
x49gp_timer_t *
|
x49gp_timer_t* x49gp_new_timer( long type, x49gp_timer_cb_t cb, void* user_data )
|
||||||
x49gp_new_timer(long type, x49gp_timer_cb_t cb, void *user_data)
|
|
||||||
{
|
{
|
||||||
x49gp_timer_t *ts;
|
x49gp_timer_t* ts;
|
||||||
|
|
||||||
ts = malloc(sizeof(x49gp_timer_t));
|
ts = malloc( sizeof( x49gp_timer_t ) );
|
||||||
if (NULL == ts) {
|
if ( NULL == ts ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(ts, 0, sizeof(x49gp_timer_t));
|
memset( ts, 0, sizeof( x49gp_timer_t ) );
|
||||||
|
|
||||||
ts->type = type;
|
ts->type = type;
|
||||||
ts->cb = cb;
|
ts->cb = cb;
|
||||||
ts->user_data = user_data;
|
ts->user_data = user_data;
|
||||||
|
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void x49gp_free_timer( x49gp_timer_t* ts ) { free( ts ); }
|
||||||
x49gp_free_timer(x49gp_timer_t *ts)
|
|
||||||
|
void x49gp_del_timer( x49gp_timer_t* ts )
|
||||||
{
|
{
|
||||||
free(ts);
|
x49gp_timer_t **pt, *t;
|
||||||
|
|
||||||
|
// printf("%s: ts %p\n", __FUNCTION__, ts);
|
||||||
|
pt = &x49gp_timer_lists[ ts->type ];
|
||||||
|
while ( 1 ) {
|
||||||
|
t = *pt;
|
||||||
|
if ( NULL == t )
|
||||||
|
break;
|
||||||
|
if ( t == ts ) {
|
||||||
|
*pt = t->next;
|
||||||
|
ts->next = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pt = &t->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void x49gp_mod_timer( x49gp_timer_t* ts, int64_t expires )
|
||||||
x49gp_del_timer(x49gp_timer_t *ts)
|
|
||||||
{
|
{
|
||||||
x49gp_timer_t **pt, *t;
|
x49gp_timer_t **pt, *t;
|
||||||
|
|
||||||
// printf("%s: ts %p\n", __FUNCTION__, ts);
|
x49gp_del_timer( ts );
|
||||||
pt = &x49gp_timer_lists[ts->type];
|
|
||||||
while (1) {
|
// printf("%s: ts %p, expires %lld\n", __FUNCTION__, ts, expires);
|
||||||
t = *pt;
|
pt = &x49gp_timer_lists[ ts->type ];
|
||||||
if (NULL == t)
|
while ( 1 ) {
|
||||||
break;
|
t = *pt;
|
||||||
if (t == ts) {
|
if ( NULL == t )
|
||||||
*pt = t->next;
|
break;
|
||||||
ts->next = NULL;
|
if ( t->expires > expires )
|
||||||
break;
|
break;
|
||||||
}
|
pt = &t->next;
|
||||||
pt = &t->next;
|
}
|
||||||
}
|
|
||||||
|
ts->expires = expires;
|
||||||
|
ts->next = *pt;
|
||||||
|
*pt = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int x49gp_timer_pending( x49gp_timer_t* ts )
|
||||||
x49gp_mod_timer(x49gp_timer_t *ts, int64_t expires)
|
|
||||||
{
|
{
|
||||||
x49gp_timer_t **pt, *t;
|
x49gp_timer_t* t;
|
||||||
|
|
||||||
x49gp_del_timer(ts);
|
for ( t = x49gp_timer_lists[ ts->type ]; t; t = t->next ) {
|
||||||
|
if ( t == ts )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// printf("%s: ts %p, expires %lld\n", __FUNCTION__, ts, expires);
|
return 0;
|
||||||
pt = &x49gp_timer_lists[ts->type];
|
|
||||||
while (1) {
|
|
||||||
t = *pt;
|
|
||||||
if (NULL == t)
|
|
||||||
break;
|
|
||||||
if (t->expires > expires)
|
|
||||||
break;
|
|
||||||
pt = &t->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
ts->expires = expires;
|
|
||||||
ts->next = *pt;
|
|
||||||
*pt = ts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int64_t x49gp_timer_expires( x49gp_timer_t* ts ) { return ts->expires; }
|
||||||
x49gp_timer_pending(x49gp_timer_t *ts)
|
|
||||||
|
static int x49gp_timer_expired( x49gp_timer_t* timer_head, int64_t current_time )
|
||||||
{
|
{
|
||||||
x49gp_timer_t *t;
|
if ( NULL == timer_head )
|
||||||
|
return 0;
|
||||||
for (t = x49gp_timer_lists[ts->type]; t; t = t->next) {
|
return ( timer_head->expires <= current_time );
|
||||||
if (t == ts)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t
|
|
||||||
x49gp_timer_expires(x49gp_timer_t *ts)
|
|
||||||
{
|
|
||||||
return ts->expires;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
x49gp_timer_expired(x49gp_timer_t *timer_head, int64_t current_time)
|
|
||||||
{
|
|
||||||
if (NULL == timer_head)
|
|
||||||
return 0;
|
|
||||||
return (timer_head->expires <= current_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LD TEMPO HACK */
|
/* LD TEMPO HACK */
|
||||||
|
|
||||||
QEMUTimer *
|
QEMUTimer* qemu_new_timer( QEMUClock* clock, QEMUTimerCB cb, void* opaque )
|
||||||
qemu_new_timer(QEMUClock *clock, QEMUTimerCB cb, void *opaque)
|
|
||||||
{
|
{
|
||||||
return (void *) x49gp_new_timer((long) clock, cb, opaque);
|
return ( void* )x49gp_new_timer( ( long )clock, cb, opaque );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void qemu_free_timer( QEMUTimer* ts ) { return x49gp_free_timer( ( void* )ts ); }
|
||||||
qemu_free_timer(QEMUTimer *ts)
|
|
||||||
|
void qemu_mod_timer( QEMUTimer* ts, int64_t expire_time ) { return x49gp_mod_timer( ( void* )ts, expire_time ); }
|
||||||
|
|
||||||
|
void qemu_del_timer( QEMUTimer* ts ) { return x49gp_del_timer( ( void* )ts ); }
|
||||||
|
|
||||||
|
int qemu_timer_pending( QEMUTimer* ts ) { return x49gp_timer_pending( ( void* )ts ); }
|
||||||
|
|
||||||
|
int64_t qemu_get_clock( QEMUClock* clock ) { return x49gp_get_clock(); }
|
||||||
|
|
||||||
|
static void x49gp_run_timers( x49gp_timer_t** ptimer_head, int64_t current_time )
|
||||||
{
|
{
|
||||||
return x49gp_free_timer((void *) ts);
|
x49gp_timer_t* ts;
|
||||||
|
|
||||||
|
// printf("%s: now %lld\n", __FUNCTION__, current_time);
|
||||||
|
while ( 1 ) {
|
||||||
|
ts = *ptimer_head;
|
||||||
|
if ( NULL == ts || ts->expires > current_time )
|
||||||
|
break;
|
||||||
|
|
||||||
|
*ptimer_head = ts->next;
|
||||||
|
ts->next = NULL;
|
||||||
|
|
||||||
|
// printf("%s: call ts %p\n", __FUNCTION__, ts);
|
||||||
|
ts->cb( ts->user_data );
|
||||||
|
// printf("%s: ts %p done\n", __FUNCTION__, ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("%s: timers done\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void x49gp_alarm_handler( int sig )
|
||||||
qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
|
|
||||||
{
|
{
|
||||||
return x49gp_mod_timer((void *) ts, expire_time);
|
if ( x49gp_timer_expired( x49gp_timer_lists[ X49GP_TIMER_VIRTUAL ], x49gp_get_clock() ) ||
|
||||||
|
x49gp_timer_expired( x49gp_timer_lists[ X49GP_TIMER_REALTIME ], x49gp_get_clock() ) ) {
|
||||||
|
if ( cpu_single_env && !cpu_single_env->exit_request ) {
|
||||||
|
cpu_exit( cpu_single_env );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void x49gp_main_loop_wait( x49gp_t* x49gp, int timeout )
|
||||||
qemu_del_timer(QEMUTimer *ts)
|
|
||||||
{
|
{
|
||||||
return x49gp_del_timer((void *) ts);
|
// printf("%s: timeout: %d\n", __FUNCTION__, timeout);
|
||||||
|
|
||||||
|
if ( gdb_poll( x49gp->env ) ) {
|
||||||
|
gdb_handlesig( x49gp->env, 0 );
|
||||||
|
} else
|
||||||
|
poll( NULL, 0, timeout );
|
||||||
|
|
||||||
|
if ( x49gp->arm_idle != X49GP_ARM_OFF ) {
|
||||||
|
x49gp_run_timers( &x49gp_timer_lists[ X49GP_TIMER_VIRTUAL ], x49gp_get_clock() );
|
||||||
|
}
|
||||||
|
|
||||||
|
x49gp_run_timers( &x49gp_timer_lists[ X49GP_TIMER_REALTIME ], x49gp_get_clock() );
|
||||||
|
|
||||||
|
// printf("%s: done\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int x49gp_main_loop( x49gp_t* x49gp )
|
||||||
qemu_timer_pending(QEMUTimer *ts)
|
|
||||||
{
|
{
|
||||||
return x49gp_timer_pending((void *) ts);
|
int prev_idle;
|
||||||
}
|
int ret, timeout;
|
||||||
|
|
||||||
int64_t
|
while ( !x49gp->arm_exit ) {
|
||||||
qemu_get_clock(QEMUClock *clock)
|
prev_idle = x49gp->arm_idle;
|
||||||
{
|
|
||||||
return x49gp_get_clock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
if ( x49gp->arm_idle == X49GP_ARM_RUN ) {
|
||||||
x49gp_run_timers(x49gp_timer_t **ptimer_head, int64_t current_time)
|
|
||||||
{
|
|
||||||
x49gp_timer_t *ts;
|
|
||||||
|
|
||||||
// printf("%s: now %lld\n", __FUNCTION__, current_time);
|
|
||||||
while (1) {
|
|
||||||
ts = *ptimer_head;
|
|
||||||
if (NULL == ts || ts->expires > current_time)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*ptimer_head = ts->next;
|
|
||||||
ts->next = NULL;
|
|
||||||
|
|
||||||
// printf("%s: call ts %p\n", __FUNCTION__, ts);
|
|
||||||
ts->cb(ts->user_data);
|
|
||||||
// printf("%s: ts %p done\n", __FUNCTION__, ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("%s: timers done\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
x49gp_alarm_handler(int sig)
|
|
||||||
{
|
|
||||||
if (x49gp_timer_expired(x49gp_timer_lists[X49GP_TIMER_VIRTUAL],
|
|
||||||
x49gp_get_clock()) ||
|
|
||||||
x49gp_timer_expired(x49gp_timer_lists[X49GP_TIMER_REALTIME],
|
|
||||||
x49gp_get_clock())) {
|
|
||||||
if (cpu_single_env && ! cpu_single_env->exit_request) {
|
|
||||||
cpu_exit(cpu_single_env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
x49gp_main_loop_wait(x49gp_t *x49gp, int timeout)
|
|
||||||
{
|
|
||||||
// printf("%s: timeout: %d\n", __FUNCTION__, timeout);
|
|
||||||
|
|
||||||
if (gdb_poll(x49gp->env)) {
|
|
||||||
gdb_handlesig(x49gp->env, 0);
|
|
||||||
} else
|
|
||||||
poll(NULL, 0, timeout);
|
|
||||||
|
|
||||||
if (x49gp->arm_idle != X49GP_ARM_OFF) {
|
|
||||||
x49gp_run_timers(&x49gp_timer_lists[X49GP_TIMER_VIRTUAL],
|
|
||||||
x49gp_get_clock());
|
|
||||||
}
|
|
||||||
|
|
||||||
x49gp_run_timers(&x49gp_timer_lists[X49GP_TIMER_REALTIME],
|
|
||||||
x49gp_get_clock());
|
|
||||||
|
|
||||||
// printf("%s: done\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
x49gp_main_loop(x49gp_t *x49gp)
|
|
||||||
{
|
|
||||||
int prev_idle;
|
|
||||||
int ret, timeout;
|
|
||||||
|
|
||||||
while (! x49gp->arm_exit) {
|
|
||||||
prev_idle = x49gp->arm_idle;
|
|
||||||
|
|
||||||
if (x49gp->arm_idle == X49GP_ARM_RUN) {
|
|
||||||
#ifdef DEBUG_X49GP_TIMER_IDLE
|
#ifdef DEBUG_X49GP_TIMER_IDLE
|
||||||
printf("%lld: %s: call cpu_exec(%p)\n", (unsigned long long) x49gp_get_clock(), __FUNCTION__, x49gp->env);
|
printf( "%lld: %s: call cpu_exec(%p)\n", ( unsigned long long )x49gp_get_clock(), __FUNCTION__, x49gp->env );
|
||||||
#endif
|
#endif
|
||||||
ret = cpu_exec(x49gp->env);
|
ret = cpu_exec( x49gp->env );
|
||||||
#ifdef DEBUG_X49GP_TIMER_IDLE
|
#ifdef DEBUG_X49GP_TIMER_IDLE
|
||||||
printf("%lld: %s: cpu_exec(): %d, PC %08x\n", (unsigned long long) x49gp_get_clock(), __FUNCTION__, ret, x49gp->env->regs[15]);
|
printf( "%lld: %s: cpu_exec(): %d, PC %08x\n", ( unsigned long long )x49gp_get_clock(), __FUNCTION__, ret,
|
||||||
|
x49gp->env->regs[ 15 ] );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (x49gp->env->regs[15] == 0x8620) {
|
if ( x49gp->env->regs[ 15 ] == 0x8620 ) {
|
||||||
printf("PC %08x: SRAM %08x: %08x %08x %08x <%08x>\n", x49gp->env->regs[15], 0x08000a0c,
|
printf( "PC %08x: SRAM %08x: %08x %08x %08x <%08x>\n", x49gp->env->regs[ 15 ], 0x08000a0c,
|
||||||
* ((uint32_t *) &x49gp->sram[0x0a00]),
|
*( ( uint32_t* )&x49gp->sram[ 0x0a00 ] ), *( ( uint32_t* )&x49gp->sram[ 0x0a04 ] ),
|
||||||
* ((uint32_t *) &x49gp->sram[0x0a04]),
|
*( ( uint32_t* )&x49gp->sram[ 0x0a08 ] ), *( ( uint32_t* )&x49gp->sram[ 0x0a0c ] ) );
|
||||||
* ((uint32_t *) &x49gp->sram[0x0a08]),
|
*( ( uint32_t* )&x49gp->sram[ 0x0a0c ] ) = 0x00000000;
|
||||||
* ((uint32_t *) &x49gp->sram[0x0a0c]));
|
}
|
||||||
* ((uint32_t *) &x49gp->sram[0x0a0c]) = 0x00000000;
|
|
||||||
|
if ( ret == EXCP_DEBUG ) {
|
||||||
|
gdb_handlesig( x49gp->env, SIGTRAP );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x49gp->arm_idle != prev_idle ) {
|
||||||
|
if ( x49gp->arm_idle == X49GP_ARM_OFF ) {
|
||||||
|
x49gp_lcd_update( x49gp );
|
||||||
|
cpu_reset( x49gp->env );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ret == EXCP_HALTED ) {
|
||||||
|
timeout = 10;
|
||||||
|
} else {
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeout = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
x49gp_main_loop_wait( x49gp, timeout );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == EXCP_DEBUG) {
|
int x49gp_timer_init( x49gp_t* x49gp )
|
||||||
gdb_handlesig(x49gp->env, SIGTRAP);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x49gp->arm_idle != prev_idle) {
|
|
||||||
if (x49gp->arm_idle == X49GP_ARM_OFF) {
|
|
||||||
x49gp_lcd_update(x49gp);
|
|
||||||
cpu_reset(x49gp->env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == EXCP_HALTED) {
|
|
||||||
timeout = 10;
|
|
||||||
} else {
|
|
||||||
timeout = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timeout = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
x49gp_main_loop_wait(x49gp, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
x49gp_timer_init(x49gp_t *x49gp)
|
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
struct itimerval it;
|
struct itimerval it;
|
||||||
|
|
||||||
x49gp_timer_lists[X49GP_TIMER_VIRTUAL] = NULL;
|
x49gp_timer_lists[ X49GP_TIMER_VIRTUAL ] = NULL;
|
||||||
x49gp_timer_lists[X49GP_TIMER_REALTIME] = NULL;
|
x49gp_timer_lists[ X49GP_TIMER_REALTIME ] = NULL;
|
||||||
|
|
||||||
sigfillset(&sa.sa_mask);
|
sigfillset( &sa.sa_mask );
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
sa.sa_handler = x49gp_alarm_handler;
|
sa.sa_handler = x49gp_alarm_handler;
|
||||||
sigaction(SIGALRM, &sa, NULL);
|
sigaction( SIGALRM, &sa, NULL );
|
||||||
|
|
||||||
it.it_interval.tv_sec = 0;
|
it.it_interval.tv_sec = 0;
|
||||||
it.it_interval.tv_usec = 1000;
|
it.it_interval.tv_usec = 1000;
|
||||||
it.it_value.tv_sec = 0;
|
it.it_value.tv_sec = 0;
|
||||||
it.it_value.tv_usec = 1000;
|
it.it_value.tv_usec = 1000;
|
||||||
|
|
||||||
setitimer(ITIMER_REAL, &it, NULL);
|
setitimer( ITIMER_REAL, &it, NULL );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
183
src/tiny_font.c
183
src/tiny_font.c
|
@ -94,113 +94,110 @@
|
||||||
|
|
||||||
#include "bitmaps/tiny__i.xbm"
|
#include "bitmaps/tiny__i.xbm"
|
||||||
|
|
||||||
const bitmap_font_t tiny_font =
|
const bitmap_font_t tiny_font = {
|
||||||
{
|
7,
|
||||||
7,
|
-3,
|
||||||
-3,
|
{ GLYPH( tiny, notdef ),
|
||||||
{
|
|
||||||
GLYPH(tiny, notdef),
|
|
||||||
|
|
||||||
SPACE("space", 4, 0),
|
SPACE( "space", 4, 0 ),
|
||||||
GLYPH(tiny, quotedbl),
|
GLYPH( tiny, quotedbl ),
|
||||||
GLYPH(tiny, numbersign),
|
GLYPH( tiny, numbersign ),
|
||||||
GLYPH(tiny, ampersand),
|
GLYPH( tiny, ampersand ),
|
||||||
GLYPH(tiny, parenleft),
|
GLYPH( tiny, parenleft ),
|
||||||
GLYPH(tiny, parenright),
|
GLYPH( tiny, parenright ),
|
||||||
GLYPH(tiny, comma),
|
GLYPH( tiny, comma ),
|
||||||
GLYPH(tiny, hyphen),
|
GLYPH( tiny, hyphen ),
|
||||||
GLYPH(tiny, period),
|
GLYPH( tiny, period ),
|
||||||
GLYPH(tiny, slash),
|
GLYPH( tiny, slash ),
|
||||||
|
|
||||||
GLYPH(tiny, zero),
|
GLYPH( tiny, zero ),
|
||||||
GLYPH(tiny, one),
|
GLYPH( tiny, one ),
|
||||||
GLYPH(tiny, two),
|
GLYPH( tiny, two ),
|
||||||
GLYPH(tiny, three),
|
GLYPH( tiny, three ),
|
||||||
|
|
||||||
GLYPH(tiny, colon),
|
GLYPH( tiny, colon ),
|
||||||
|
|
||||||
GLYPH(tiny, less),
|
GLYPH( tiny, less ),
|
||||||
GLYPH(tiny, equal),
|
GLYPH( tiny, equal ),
|
||||||
GLYPH(tiny, greater),
|
GLYPH( tiny, greater ),
|
||||||
|
|
||||||
GLYPH(tiny, A),
|
GLYPH( tiny, A ),
|
||||||
GLYPH(tiny, B),
|
GLYPH( tiny, B ),
|
||||||
GLYPH(tiny, C),
|
GLYPH( tiny, C ),
|
||||||
GLYPH(tiny, D),
|
GLYPH( tiny, D ),
|
||||||
GLYPH(tiny, E),
|
GLYPH( tiny, E ),
|
||||||
GLYPH(tiny, F),
|
GLYPH( tiny, F ),
|
||||||
GLYPH(tiny, G),
|
GLYPH( tiny, G ),
|
||||||
GLYPH(tiny, H),
|
GLYPH( tiny, H ),
|
||||||
GLYPH(tiny, I),
|
GLYPH( tiny, I ),
|
||||||
GLYPH(tiny, J),
|
GLYPH( tiny, J ),
|
||||||
GLYPH(tiny, K),
|
GLYPH( tiny, K ),
|
||||||
GLYPH(tiny, L),
|
GLYPH( tiny, L ),
|
||||||
GLYPH(tiny, M),
|
GLYPH( tiny, M ),
|
||||||
GLYPH(tiny, N),
|
GLYPH( tiny, N ),
|
||||||
GLYPH(tiny, O),
|
GLYPH( tiny, O ),
|
||||||
GLYPH(tiny, P),
|
GLYPH( tiny, P ),
|
||||||
GLYPH(tiny, Q),
|
GLYPH( tiny, Q ),
|
||||||
GLYPH(tiny, R),
|
GLYPH( tiny, R ),
|
||||||
GLYPH(tiny, S),
|
GLYPH( tiny, S ),
|
||||||
GLYPH(tiny, T),
|
GLYPH( tiny, T ),
|
||||||
GLYPH(tiny, U),
|
GLYPH( tiny, U ),
|
||||||
GLYPH(tiny, V),
|
GLYPH( tiny, V ),
|
||||||
GLYPH(tiny, W),
|
GLYPH( tiny, W ),
|
||||||
GLYPH(tiny, X),
|
GLYPH( tiny, X ),
|
||||||
GLYPH(tiny, Y),
|
GLYPH( tiny, Y ),
|
||||||
GLYPH(tiny, Z),
|
GLYPH( tiny, Z ),
|
||||||
|
|
||||||
GLYPH(tiny, bracketleft),
|
GLYPH( tiny, bracketleft ),
|
||||||
GLYPH(tiny, bracketright),
|
GLYPH( tiny, bracketright ),
|
||||||
GLYPH(tiny, underscore),
|
GLYPH( tiny, underscore ),
|
||||||
|
|
||||||
GLYPH(tiny, i),
|
GLYPH( tiny, i ),
|
||||||
|
|
||||||
GLYPH(tiny, overscore),
|
GLYPH( tiny, overscore ),
|
||||||
GLYPH(tiny, arrowleft),
|
GLYPH( tiny, arrowleft ),
|
||||||
GLYPH(tiny, arrowright),
|
GLYPH( tiny, arrowright ),
|
||||||
GLYPH(tiny, guillemotleft),
|
GLYPH( tiny, guillemotleft ),
|
||||||
GLYPH(tiny, guillemotright),
|
GLYPH( tiny, guillemotright ),
|
||||||
|
|
||||||
GLYPH(tiny, braceleft),
|
GLYPH( tiny, braceleft ),
|
||||||
GLYPH(tiny, braceright),
|
GLYPH( tiny, braceright ),
|
||||||
|
|
||||||
GLYPH(tiny, large_comma),
|
GLYPH( tiny, large_comma ),
|
||||||
|
|
||||||
GLYPH(tiny, xsuperior),
|
GLYPH( tiny, xsuperior ),
|
||||||
GLYPH(tiny, twosuperior),
|
GLYPH( tiny, twosuperior ),
|
||||||
|
|
||||||
GLYPH(tiny, math_e),
|
GLYPH( tiny, math_e ),
|
||||||
GLYPH(tiny, math_x),
|
GLYPH( tiny, math_x ),
|
||||||
GLYPH(tiny, math_y),
|
GLYPH( tiny, math_y ),
|
||||||
GLYPH(tiny, math_pi),
|
GLYPH( tiny, math_pi ),
|
||||||
GLYPH(tiny, math_summation),
|
GLYPH( tiny, math_summation ),
|
||||||
GLYPH(tiny, math_radical),
|
GLYPH( tiny, math_radical ),
|
||||||
GLYPH(tiny, math_partialdiff),
|
GLYPH( tiny, math_partialdiff ),
|
||||||
GLYPH(tiny, math_integral),
|
GLYPH( tiny, math_integral ),
|
||||||
GLYPH(tiny, math_infinity),
|
GLYPH( tiny, math_infinity ),
|
||||||
|
|
||||||
GLYPH(tiny, math_numbersign),
|
GLYPH( tiny, math_numbersign ),
|
||||||
GLYPH(tiny, math_less),
|
GLYPH( tiny, math_less ),
|
||||||
GLYPH(tiny, math_greater),
|
GLYPH( tiny, math_greater ),
|
||||||
GLYPH(tiny, math_lessequal),
|
GLYPH( tiny, math_lessequal ),
|
||||||
GLYPH(tiny, math_greaterequal),
|
GLYPH( tiny, math_greaterequal ),
|
||||||
GLYPH(tiny, math_equal),
|
GLYPH( tiny, math_equal ),
|
||||||
GLYPH(tiny, math_notequal),
|
GLYPH( tiny, math_notequal ),
|
||||||
|
|
||||||
GLYPH(tiny, math_arrowleft),
|
GLYPH( tiny, math_arrowleft ),
|
||||||
GLYPH(tiny, math_arrowright),
|
GLYPH( tiny, math_arrowright ),
|
||||||
GLYPH(tiny, math_downarrowleft),
|
GLYPH( tiny, math_downarrowleft ),
|
||||||
GLYPH(tiny, math_downarrowright),
|
GLYPH( tiny, math_downarrowright ),
|
||||||
|
|
||||||
SPACE("kern-1", -1, -1),
|
SPACE( "kern-1", -1, -1 ),
|
||||||
SPACE("kern-2", -2, -2),
|
SPACE( "kern-2", -2, -2 ),
|
||||||
SPACE("kern-3", -3, -3),
|
SPACE( "kern-3", -3, -3 ),
|
||||||
SPACE("kern-4", -4, -4),
|
SPACE( "kern-4", -4, -4 ),
|
||||||
SPACE("kern-5", -5, -5),
|
SPACE( "kern-5", -5, -5 ),
|
||||||
SPACE("kern-6", -6, -6),
|
SPACE( "kern-6", -6, -6 ),
|
||||||
SPACE("kern-7", -7, -7),
|
SPACE( "kern-7", -7, -7 ),
|
||||||
|
|
||||||
{ NULL }
|
{ NULL } }
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
181
src/x49gp.h
181
src/x49gp.h
|
@ -20,148 +20,115 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
/* LD TEMPO HACK */
|
/* LD TEMPO HACK */
|
||||||
extern uint8_t *phys_ram_base;
|
extern uint8_t* phys_ram_base;
|
||||||
extern int phys_ram_size;
|
extern int phys_ram_size;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { X49GP_ARM_RUN = 0, X49GP_ARM_SLEEP, X49GP_ARM_OFF } x49gp_arm_idle_t;
|
||||||
X49GP_ARM_RUN = 0,
|
|
||||||
X49GP_ARM_SLEEP,
|
|
||||||
X49GP_ARM_OFF
|
|
||||||
} x49gp_arm_idle_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { X49GP_RESET_POWER_ON = 0, X49GP_RESET_POWER_OFF, X49GP_RESET_WATCHDOG } x49gp_reset_t;
|
||||||
X49GP_RESET_POWER_ON = 0,
|
|
||||||
X49GP_RESET_POWER_OFF,
|
|
||||||
X49GP_RESET_WATCHDOG
|
|
||||||
} x49gp_reset_t;
|
|
||||||
|
|
||||||
struct __x49gp_module_s__;
|
struct __x49gp_module_s__;
|
||||||
typedef struct __x49gp_module_s__ x49gp_module_t;
|
typedef struct __x49gp_module_s__ x49gp_module_t;
|
||||||
|
|
||||||
struct __x49gp_module_s__ {
|
struct __x49gp_module_s__ {
|
||||||
const char *name;
|
const char* name;
|
||||||
|
|
||||||
int (*init) (x49gp_module_t *);
|
int ( *init )( x49gp_module_t* );
|
||||||
int (*exit) (x49gp_module_t *);
|
int ( *exit )( x49gp_module_t* );
|
||||||
|
|
||||||
int (*reset) (x49gp_module_t *, x49gp_reset_t);
|
int ( *reset )( x49gp_module_t*, x49gp_reset_t );
|
||||||
|
|
||||||
int (*load) (x49gp_module_t *, GKeyFile *);
|
int ( *load )( x49gp_module_t*, GKeyFile* );
|
||||||
int (*save) (x49gp_module_t *, GKeyFile *);
|
int ( *save )( x49gp_module_t*, GKeyFile* );
|
||||||
|
|
||||||
void *user_data;
|
void* user_data;
|
||||||
|
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { X49GP_REINIT_NONE = 0, X49GP_REINIT_REBOOT_ONLY, X49GP_REINIT_FLASH, X49GP_REINIT_FLASH_FULL } x49gp_reinit_t;
|
||||||
X49GP_REINIT_NONE = 0,
|
|
||||||
X49GP_REINIT_REBOOT_ONLY,
|
|
||||||
X49GP_REINIT_FLASH,
|
|
||||||
X49GP_REINIT_FLASH_FULL
|
|
||||||
} x49gp_reinit_t;
|
|
||||||
|
|
||||||
struct __x49gp_s__ {
|
struct __x49gp_s__ {
|
||||||
CPUARMState *env;
|
CPUARMState* env;
|
||||||
|
|
||||||
struct list_head modules;
|
struct list_head modules;
|
||||||
|
|
||||||
void *s3c2410_lcd;
|
void* s3c2410_lcd;
|
||||||
void *s3c2410_timer;
|
void* s3c2410_timer;
|
||||||
void *s3c2410_watchdog;
|
void* s3c2410_watchdog;
|
||||||
void *s3c2410_intc;
|
void* s3c2410_intc;
|
||||||
void *s3c2410_io_port;
|
void* s3c2410_io_port;
|
||||||
void *s3c2410_sdi;
|
void* s3c2410_sdi;
|
||||||
|
|
||||||
void *timer;
|
void* timer;
|
||||||
uint8_t *sram;
|
uint8_t* sram;
|
||||||
|
|
||||||
uint32_t MCLK;
|
uint32_t MCLK;
|
||||||
uint32_t UCLK;
|
uint32_t UCLK;
|
||||||
|
|
||||||
uint32_t FCLK;
|
uint32_t FCLK;
|
||||||
uint32_t HCLK;
|
uint32_t HCLK;
|
||||||
uint32_t PCLK;
|
uint32_t PCLK;
|
||||||
int PCLK_ratio;
|
int PCLK_ratio;
|
||||||
|
|
||||||
clock_t clk_tck;
|
clock_t clk_tck;
|
||||||
unsigned long emulator_fclk;
|
unsigned long emulator_fclk;
|
||||||
|
|
||||||
unsigned char keybycol[8];
|
unsigned char keybycol[ 8 ];
|
||||||
unsigned char keybyrow[8];
|
unsigned char keybyrow[ 8 ];
|
||||||
|
|
||||||
x49gp_timer_t *gtk_timer;
|
x49gp_timer_t* gtk_timer;
|
||||||
x49gp_timer_t *lcd_timer;
|
x49gp_timer_t* lcd_timer;
|
||||||
|
|
||||||
x49gp_arm_idle_t arm_idle;
|
x49gp_arm_idle_t arm_idle;
|
||||||
int arm_exit;
|
int arm_exit;
|
||||||
|
|
||||||
x49gp_ui_t *ui;
|
x49gp_ui_t* ui;
|
||||||
|
|
||||||
GKeyFile *config;
|
GKeyFile* config;
|
||||||
const char *progname;
|
const char* progname;
|
||||||
const char *progpath;
|
const char* progpath;
|
||||||
const char *basename;
|
const char* basename;
|
||||||
int debug_port;
|
int debug_port;
|
||||||
x49gp_reinit_t startup_reinit;
|
x49gp_reinit_t startup_reinit;
|
||||||
char *firmware;
|
char* firmware;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void x49gp_set_idle(x49gp_t *, x49gp_arm_idle_t idle);
|
extern void x49gp_set_idle( x49gp_t*, x49gp_arm_idle_t idle );
|
||||||
|
|
||||||
extern int x49gp_module_init(x49gp_t *x49gp, const char *name,
|
extern int x49gp_module_init( x49gp_t* x49gp, const char* name, int ( *init )( x49gp_module_t* ), int ( *exit )( x49gp_module_t* ),
|
||||||
int (*init)(x49gp_module_t *),
|
int ( *reset )( x49gp_module_t*, x49gp_reset_t ), int ( *load )( x49gp_module_t*, GKeyFile* ),
|
||||||
int (*exit)(x49gp_module_t *),
|
int ( *save )( x49gp_module_t*, GKeyFile* ), void* user_data, x49gp_module_t** module );
|
||||||
int (*reset)(x49gp_module_t *, x49gp_reset_t),
|
|
||||||
int (*load)(x49gp_module_t *, GKeyFile *),
|
|
||||||
int (*save)(x49gp_module_t *, GKeyFile *),
|
|
||||||
void *user_data, x49gp_module_t **module);
|
|
||||||
|
|
||||||
extern int x49gp_module_register(x49gp_module_t *module);
|
extern int x49gp_module_register( x49gp_module_t* module );
|
||||||
extern int x49gp_module_unregister(x49gp_module_t *module);
|
extern int x49gp_module_unregister( x49gp_module_t* module );
|
||||||
|
|
||||||
extern int x49gp_module_get_filename(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_get_filename( x49gp_module_t* module, GKeyFile*, const char*, char*, char**, char** );
|
||||||
const char *, char *, char **,
|
extern int x49gp_module_set_filename( x49gp_module_t* module, GKeyFile*, const char*, const char* );
|
||||||
char **);
|
extern int x49gp_module_get_int( x49gp_module_t* module, GKeyFile*, const char*, int, int* );
|
||||||
extern int x49gp_module_set_filename(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_set_int( x49gp_module_t* module, GKeyFile*, const char*, int );
|
||||||
const char *, const char *);
|
extern int x49gp_module_get_uint( x49gp_module_t* module, GKeyFile*, const char*, unsigned int, unsigned int* );
|
||||||
extern int x49gp_module_get_int(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_set_uint( x49gp_module_t* module, GKeyFile*, const char*, unsigned int );
|
||||||
const char *, int, int *);
|
extern int x49gp_module_get_u32( x49gp_module_t* module, GKeyFile*, const char*, uint32_t, uint32_t* );
|
||||||
extern int x49gp_module_set_int(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_set_u32( x49gp_module_t* module, GKeyFile*, const char*, uint32_t );
|
||||||
const char *, int);
|
extern int x49gp_module_get_u64( x49gp_module_t* module, GKeyFile*, const char*, uint64_t, uint64_t* );
|
||||||
extern int x49gp_module_get_uint(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_set_u64( x49gp_module_t* module, GKeyFile*, const char*, uint64_t );
|
||||||
const char *,
|
extern int x49gp_module_get_string( x49gp_module_t* module, GKeyFile*, const char*, char*, char** );
|
||||||
unsigned int, unsigned int *);
|
extern int x49gp_module_set_string( x49gp_module_t* module, GKeyFile*, const char*, const char* );
|
||||||
extern int x49gp_module_set_uint(x49gp_module_t *module, GKeyFile *,
|
extern int x49gp_module_open_rodata( x49gp_module_t* module, const char* name, char** path );
|
||||||
const char *, unsigned int);
|
|
||||||
extern int x49gp_module_get_u32(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, uint32_t, uint32_t *);
|
|
||||||
extern int x49gp_module_set_u32(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, uint32_t);
|
|
||||||
extern int x49gp_module_get_u64(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, uint64_t, uint64_t *);
|
|
||||||
extern int x49gp_module_set_u64(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, uint64_t);
|
|
||||||
extern int x49gp_module_get_string(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, char *, char **);
|
|
||||||
extern int x49gp_module_set_string(x49gp_module_t *module, GKeyFile *,
|
|
||||||
const char *, const char *);
|
|
||||||
extern int x49gp_module_open_rodata(x49gp_module_t *module,
|
|
||||||
const char *name,
|
|
||||||
char **path);
|
|
||||||
|
|
||||||
extern void s3c2410_sdi_unmount(x49gp_t *x49gp);
|
extern void s3c2410_sdi_unmount( x49gp_t* x49gp );
|
||||||
extern int s3c2410_sdi_mount(x49gp_t *x49gp, char *filename);
|
extern int s3c2410_sdi_mount( x49gp_t* x49gp, char* filename );
|
||||||
extern int s3c2410_sdi_is_mounted(x49gp_t *x49gp);
|
extern int s3c2410_sdi_is_mounted( x49gp_t* x49gp );
|
||||||
|
|
||||||
extern int x49gp_modules_init(x49gp_t *);
|
extern int x49gp_modules_init( x49gp_t* );
|
||||||
extern int x49gp_modules_exit(x49gp_t *);
|
extern int x49gp_modules_exit( x49gp_t* );
|
||||||
extern int x49gp_modules_reset(x49gp_t *, x49gp_reset_t);
|
extern int x49gp_modules_reset( x49gp_t*, x49gp_reset_t );
|
||||||
extern int x49gp_modules_load(x49gp_t *, const char *);
|
extern int x49gp_modules_load( x49gp_t*, const char* );
|
||||||
extern int x49gp_modules_save(x49gp_t *, const char *);
|
extern int x49gp_modules_save( x49gp_t*, const char* );
|
||||||
|
|
||||||
extern int x49gp_flash_init(x49gp_t *);
|
extern int x49gp_flash_init( x49gp_t* );
|
||||||
extern int x49gp_sram_init(x49gp_t *);
|
extern int x49gp_sram_init( x49gp_t* );
|
||||||
|
|
||||||
#endif /* !(_X49GP_H) */
|
#endif /* !(_X49GP_H) */
|
||||||
|
|
|
@ -8,26 +8,26 @@
|
||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
#define X49GP_TIMER_VIRTUAL 0
|
#define X49GP_TIMER_VIRTUAL 0
|
||||||
#define X49GP_TIMER_REALTIME 1
|
#define X49GP_TIMER_REALTIME 1
|
||||||
|
|
||||||
int64_t x49gp_get_clock(void);
|
int64_t x49gp_get_clock( void );
|
||||||
|
|
||||||
typedef void (*x49gp_timer_cb_t) (void *);
|
typedef void ( *x49gp_timer_cb_t )( void* );
|
||||||
typedef struct x49gp_timer_s x49gp_timer_t;
|
typedef struct x49gp_timer_s x49gp_timer_t;
|
||||||
|
|
||||||
x49gp_timer_t *x49gp_new_timer(long type, x49gp_timer_cb_t, void *user_data);
|
x49gp_timer_t* x49gp_new_timer( long type, x49gp_timer_cb_t, void* user_data );
|
||||||
void x49gp_free_timer(x49gp_timer_t *);
|
void x49gp_free_timer( x49gp_timer_t* );
|
||||||
|
|
||||||
void x49gp_mod_timer(x49gp_timer_t *, int64_t expires);
|
void x49gp_mod_timer( x49gp_timer_t*, int64_t expires );
|
||||||
void x49gp_del_timer(x49gp_timer_t *);
|
void x49gp_del_timer( x49gp_timer_t* );
|
||||||
int x49gp_timer_pending(x49gp_timer_t *);
|
int x49gp_timer_pending( x49gp_timer_t* );
|
||||||
int64_t x49gp_timer_expires(x49gp_timer_t *);
|
int64_t x49gp_timer_expires( x49gp_timer_t* );
|
||||||
|
|
||||||
#define X49GP_GTK_REFRESH_INTERVAL 30000LL
|
#define X49GP_GTK_REFRESH_INTERVAL 30000LL
|
||||||
#define X49GP_LCD_REFRESH_INTERVAL 50000LL
|
#define X49GP_LCD_REFRESH_INTERVAL 50000LL
|
||||||
|
|
||||||
int x49gp_main_loop(x49gp_t *);
|
int x49gp_main_loop( x49gp_t* );
|
||||||
int x49gp_timer_init(x49gp_t *);
|
int x49gp_timer_init( x49gp_t* );
|
||||||
|
|
||||||
#endif /* !(_X49GP_TIMER_H) */
|
#endif /* !(_X49GP_TIMER_H) */
|
||||||
|
|
|
@ -15,9 +15,9 @@ typedef unsigned int u32;
|
||||||
typedef unsigned long long u64;
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
struct __x49gp_s__;
|
struct __x49gp_s__;
|
||||||
typedef struct __x49gp_s__ x49gp_t;
|
typedef struct __x49gp_s__ x49gp_t;
|
||||||
|
|
||||||
struct __x49gp_ui_s__;
|
struct __x49gp_ui_s__;
|
||||||
typedef struct __x49gp_ui_s__ x49gp_ui_t;
|
typedef struct __x49gp_ui_s__ x49gp_ui_t;
|
||||||
|
|
||||||
#endif /* !(_X49GP_TYPES_H) */
|
#endif /* !(_X49GP_TYPES_H) */
|
||||||
|
|
216
src/x49gp_ui.h
216
src/x49gp_ui.h
|
@ -7,145 +7,139 @@
|
||||||
#include "x49gp_types.h"
|
#include "x49gp_types.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UI_COLOR_BLACK = 0,
|
UI_COLOR_BLACK = 0,
|
||||||
UI_COLOR_WHITE,
|
UI_COLOR_WHITE,
|
||||||
UI_COLOR_YELLOW,
|
UI_COLOR_YELLOW,
|
||||||
UI_COLOR_RED,
|
UI_COLOR_RED,
|
||||||
UI_COLOR_GREEN,
|
UI_COLOR_GREEN,
|
||||||
UI_COLOR_SILVER,
|
UI_COLOR_SILVER,
|
||||||
UI_COLOR_ORANGE,
|
UI_COLOR_ORANGE,
|
||||||
UI_COLOR_BLUE,
|
UI_COLOR_BLUE,
|
||||||
UI_COLOR_GRAYSCALE_0,
|
UI_COLOR_GRAYSCALE_0,
|
||||||
UI_COLOR_GRAYSCALE_1,
|
UI_COLOR_GRAYSCALE_1,
|
||||||
UI_COLOR_GRAYSCALE_2,
|
UI_COLOR_GRAYSCALE_2,
|
||||||
UI_COLOR_GRAYSCALE_3,
|
UI_COLOR_GRAYSCALE_3,
|
||||||
UI_COLOR_GRAYSCALE_4,
|
UI_COLOR_GRAYSCALE_4,
|
||||||
UI_COLOR_GRAYSCALE_5,
|
UI_COLOR_GRAYSCALE_5,
|
||||||
UI_COLOR_GRAYSCALE_6,
|
UI_COLOR_GRAYSCALE_6,
|
||||||
UI_COLOR_GRAYSCALE_7,
|
UI_COLOR_GRAYSCALE_7,
|
||||||
UI_COLOR_GRAYSCALE_8,
|
UI_COLOR_GRAYSCALE_8,
|
||||||
UI_COLOR_GRAYSCALE_9,
|
UI_COLOR_GRAYSCALE_9,
|
||||||
UI_COLOR_GRAYSCALE_10,
|
UI_COLOR_GRAYSCALE_10,
|
||||||
UI_COLOR_GRAYSCALE_11,
|
UI_COLOR_GRAYSCALE_11,
|
||||||
UI_COLOR_GRAYSCALE_12,
|
UI_COLOR_GRAYSCALE_12,
|
||||||
UI_COLOR_GRAYSCALE_13,
|
UI_COLOR_GRAYSCALE_13,
|
||||||
UI_COLOR_GRAYSCALE_14,
|
UI_COLOR_GRAYSCALE_14,
|
||||||
UI_COLOR_GRAYSCALE_15,
|
UI_COLOR_GRAYSCALE_15,
|
||||||
UI_COLOR_MAX
|
UI_COLOR_MAX
|
||||||
} x49gp_ui_color_t;
|
} x49gp_ui_color_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UI_SHAPE_BUTTON_TINY = 0,
|
UI_SHAPE_BUTTON_TINY = 0,
|
||||||
UI_SHAPE_BUTTON_SMALL,
|
UI_SHAPE_BUTTON_SMALL,
|
||||||
UI_SHAPE_BUTTON_NORMAL,
|
UI_SHAPE_BUTTON_NORMAL,
|
||||||
UI_SHAPE_BUTTON_LARGE,
|
UI_SHAPE_BUTTON_LARGE,
|
||||||
UI_SHAPE_BUTTON_ROUND,
|
UI_SHAPE_BUTTON_ROUND,
|
||||||
UI_SHAPE_MAX
|
UI_SHAPE_MAX
|
||||||
} x49gp_ui_shape_t;
|
} x49gp_ui_shape_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { UI_LAYOUT_LEFT = 0, UI_LAYOUT_LEFT_NO_SPACE, UI_LAYOUT_BELOW, UI_LAYOUT_MAX } x49gp_ui_layout_t;
|
||||||
UI_LAYOUT_LEFT = 0,
|
|
||||||
UI_LAYOUT_LEFT_NO_SPACE,
|
|
||||||
UI_LAYOUT_BELOW,
|
|
||||||
UI_LAYOUT_MAX
|
|
||||||
} x49gp_ui_layout_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UI_CALCULATOR_HP49GP = 0,
|
UI_CALCULATOR_HP49GP = 0,
|
||||||
UI_CALCULATOR_HP49GP_NEWRPL,
|
UI_CALCULATOR_HP49GP_NEWRPL,
|
||||||
UI_CALCULATOR_HP50G,
|
UI_CALCULATOR_HP50G,
|
||||||
UI_CALCULATOR_HP50G_NEWRPL
|
UI_CALCULATOR_HP50G_NEWRPL
|
||||||
} x49gp_ui_calculator_t;
|
} x49gp_ui_calculator_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *label;
|
const char* label;
|
||||||
const char *letter;
|
const char* letter;
|
||||||
const char *left;
|
const char* left;
|
||||||
const char *right;
|
const char* right;
|
||||||
const char *below;
|
const char* below;
|
||||||
x49gp_ui_color_t color;
|
x49gp_ui_color_t color;
|
||||||
double font_size;
|
double font_size;
|
||||||
cairo_font_weight_t font_weight;
|
cairo_font_weight_t font_weight;
|
||||||
x49gp_ui_shape_t shape;
|
x49gp_ui_shape_t shape;
|
||||||
double letter_size;
|
double letter_size;
|
||||||
x49gp_ui_layout_t layout;
|
x49gp_ui_layout_t layout;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int column;
|
int column;
|
||||||
int row;
|
int row;
|
||||||
unsigned char columnbit;
|
unsigned char columnbit;
|
||||||
unsigned char rowbit;
|
unsigned char rowbit;
|
||||||
int eint;
|
int eint;
|
||||||
} x49gp_ui_key_t;
|
} x49gp_ui_key_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
x49gp_t *x49gp;
|
x49gp_t* x49gp;
|
||||||
const x49gp_ui_key_t *key;
|
const x49gp_ui_key_t* key;
|
||||||
GtkWidget *button;
|
GtkWidget* button;
|
||||||
GtkWidget *label;
|
GtkWidget* label;
|
||||||
GtkWidget *box;
|
GtkWidget* box;
|
||||||
GdkPixmap *pixmap;
|
GdkPixmap* pixmap;
|
||||||
gboolean down;
|
gboolean down;
|
||||||
gboolean hold;
|
gboolean hold;
|
||||||
} x49gp_ui_button_t;
|
} x49gp_ui_button_t;
|
||||||
|
|
||||||
struct __x49gp_ui_s__ {
|
struct __x49gp_ui_s__ {
|
||||||
GtkWidget *window;
|
GtkWidget* window;
|
||||||
GtkWidget *fixed;
|
GtkWidget* fixed;
|
||||||
GtkWidget *menu;
|
GtkWidget* menu;
|
||||||
GtkWidget *menu_unmount;
|
GtkWidget* menu_unmount;
|
||||||
GtkWidget *menu_debug;
|
GtkWidget* menu_debug;
|
||||||
|
|
||||||
GdkPixbuf *bg_pixbuf;
|
GdkPixbuf* bg_pixbuf;
|
||||||
GdkPixmap *bg_pixmap;
|
GdkPixmap* bg_pixmap;
|
||||||
GtkWidget *background;
|
GtkWidget* background;
|
||||||
|
|
||||||
GdkColor colors[UI_COLOR_MAX];
|
GdkColor colors[ UI_COLOR_MAX ];
|
||||||
GdkBitmap *shapes[UI_SHAPE_MAX];
|
GdkBitmap* shapes[ UI_SHAPE_MAX ];
|
||||||
|
|
||||||
x49gp_ui_calculator_t calculator;
|
x49gp_ui_calculator_t calculator;
|
||||||
|
|
||||||
x49gp_ui_button_t *buttons;
|
x49gp_ui_button_t* buttons;
|
||||||
unsigned int nr_buttons;
|
unsigned int nr_buttons;
|
||||||
unsigned int buttons_down;
|
unsigned int buttons_down;
|
||||||
|
|
||||||
char *name;
|
char* name;
|
||||||
|
|
||||||
GtkWidget *lcd_canvas;
|
GtkWidget* lcd_canvas;
|
||||||
GdkPixmap *lcd_pixmap;
|
GdkPixmap* lcd_pixmap;
|
||||||
|
|
||||||
GdkGC *ann_left_gc;
|
GdkGC* ann_left_gc;
|
||||||
GdkGC *ann_right_gc;
|
GdkGC* ann_right_gc;
|
||||||
GdkGC *ann_alpha_gc;
|
GdkGC* ann_alpha_gc;
|
||||||
GdkGC *ann_battery_gc;
|
GdkGC* ann_battery_gc;
|
||||||
GdkGC *ann_busy_gc;
|
GdkGC* ann_busy_gc;
|
||||||
GdkGC *ann_io_gc;
|
GdkGC* ann_io_gc;
|
||||||
|
|
||||||
GdkBitmap *ann_left;
|
GdkBitmap* ann_left;
|
||||||
GdkBitmap *ann_right;
|
GdkBitmap* ann_right;
|
||||||
GdkBitmap *ann_alpha;
|
GdkBitmap* ann_alpha;
|
||||||
GdkBitmap *ann_battery;
|
GdkBitmap* ann_battery;
|
||||||
GdkBitmap *ann_busy;
|
GdkBitmap* ann_busy;
|
||||||
GdkBitmap *ann_io;
|
GdkBitmap* ann_io;
|
||||||
|
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
|
|
||||||
gint kb_x_offset;
|
gint kb_x_offset;
|
||||||
gint kb_y_offset;
|
gint kb_y_offset;
|
||||||
|
|
||||||
gint lcd_x_offset;
|
gint lcd_x_offset;
|
||||||
gint lcd_y_offset;
|
gint lcd_y_offset;
|
||||||
gint lcd_width;
|
gint lcd_width;
|
||||||
gint lcd_height;
|
gint lcd_height;
|
||||||
gint lcd_top_margin;
|
gint lcd_top_margin;
|
||||||
};
|
};
|
||||||
|
|
||||||
int x49gp_ui_init(x49gp_t *x49gp);
|
int x49gp_ui_init( x49gp_t* x49gp );
|
||||||
void x49gp_ui_show_error(x49gp_t *x49gp, const char *text);
|
void x49gp_ui_show_error( x49gp_t* x49gp, const char* text );
|
||||||
void x49gp_ui_open_firmware(x49gp_t *x49gp, char **filename);
|
void x49gp_ui_open_firmware( x49gp_t* x49gp, char** filename );
|
||||||
|
|
||||||
#endif /* !(_X49GP_UI_H) */
|
#endif /* !(_X49GP_UI_H) */
|
||||||
|
|
Loading…
Reference in a new issue