OpenCores
no use no use 1/1 no use no use
[or1ksim #29] Cleanup gpio peripheral
by Unknown on Feb 9, 2005
Not available!
Hi, This Cleans up the last of the peripherals, gpio. I couldn't find anything to test this with. There is the acv_gpio test, but I don't understand what I'm ment to connect to the VAPI. Can anyone help with this? With the new all-callbacks scheme we could actually implement the memory section useing peripherals. Is this desired? I also realised that I basically broke FAST_SIM. Is this still a wanted feature? It appears to have been bit rotting for quite some time anyway. About the recompiler, I have now got it to the stage were it's generating code (I haven't run it yet, though). I kind of hit a rather hard brick wall with how I'm going to implement the scheduler. I could do a call out to do_scheduler but then more than half the cpu time would be taken up by executeing the scheduler. I also tought about inlineing it after every instruction, but do_scheduler is 444 bytes long. I got it down to ~60 bytes but that would still constitute ~120 KILO bytes of the recompiled data, so this is not an option. I also had the brainy idea of useing the host cpu's hardware debug unit, but the debug unit in the x86 is a piece of crap, which can't set conditional watchpoints. So do you (or anyone else) have a good idea about how this may be implemented? ChangeLog: * Cleanup the gpio peripheral useing the new callbacks. nog. -------------- next part -------------- --- peripheral/gpio.c 2005-02-05 11:26:14.000000000 +0100 +++ ../or1ksim-ac/peripheral/gpio.c 2005-02-09 11:08:47.000000000 +0100 @@ -34,124 +34,55 @@ #include "pic.h" #include "vapi.h" #include "debug.h" - -static struct gpio_device gpios[MAX_GPIOS]; +#include "sched.h" static void gpio_vapi_read( unsigned long id, unsigned long data, void *dat ); static uint32_t gpio_read32( oraddr_t addr, void *dat ); static void gpio_write32( oraddr_t addr, uint32_t value, void *dat ); -static void gpio_external_clock( unsigned long value ); +static void gpio_external_clock( unsigned long value, struct gpio_device *gpio ); static void gpio_device_clock( struct gpio_device *gpio ); -static int gpio_find_device( oraddr_t addr, struct gpio_device **gpio, oraddr_t *reladdr ); -static struct gpio_device *gpio_find_vapi_device( unsigned long id, unsigned *which_vapi ); /* Initialize all parameters and state */ -void gpio_reset( void ) +void gpio_reset( void *dat ) { - static int first_time = 1; - unsigned i; + struct gpio_device *gpio = dat; - if ( first_time ) { - memset( gpios, 0, sizeof(gpios) ); - first_time = 0; - } - - for ( i = 0; i gpio_number = i; - gpio->baseaddr = config.gpios.baseaddr; - - if ( gpio->baseaddr != 0 ) { - /* Get IRQ */ - gpio->irq = config.gpios.irq; - - /* Register memory range */ - register_memoryarea( gpio->baseaddr, GPIO_ADDR_SPACE, 4, 0, gpio_read32, gpio_write32, NULL ); - - /* Possibly connect to VAPI */ - if ( config.gpios.base_vapi_id ) { - gpio->base_vapi_id = config.gpios.base_vapi_id; - vapi_install_multi_handler( gpio->base_vapi_id, GPIO_NUM_VAPI_IDS, gpio_vapi_read, NULL ); - } + if ( gpio->baseaddr != 0 ) { + /* Possibly connect to VAPI */ + if ( gpio->base_vapi_id ) { + vapi_install_multi_handler( gpio->base_vapi_id, GPIO_NUM_VAPI_IDS, gpio_vapi_read, dat ); } } } /* Dump status */ -void gpio_status( void ) +void gpio_status( void *dat ) { - unsigned i; + struct gpio_device *gpio = dat; - for ( i = 0; i baseaddr == 0 ) - continue; - - PRINTF( "\nGPIO %u at 0x%"PRIxADDR":\n", i, gpio->baseaddr ); - PRINTF( "RGPIO_IN : 0x%08lX\n", gpio->curr.in ); - PRINTF( "RGPIO_OUT : 0x%08lX\n", gpio->curr.out ); - PRINTF( "RGPIO_OE : 0x%08lX\n", gpio->curr.oe ); - PRINTF( "RGPIO_INTE : 0x%08lX\n", gpio->curr.inte ); - PRINTF( "RGPIO_PTRIG : 0x%08lX\n", gpio->curr.ptrig ); - PRINTF( "RGPIO_AUX : 0x%08lX\n", gpio->curr.aux ); - PRINTF( "RGPIO_CTRL : 0x%08lX\n", gpio->curr.ctrl ); - PRINTF( "RGPIO_INTS : 0x%08lX\n", gpio->curr.ints ); - } -} - - -/* Convert a memory address to a device struct and relative address. - * Return nonzero on success */ -int gpio_find_device( oraddr_t addr, struct gpio_device **gpio, oraddr_t *reladdr ) -{ - unsigned i; - *gpio = NULL; - - for ( i = 0; i = gpios.baseaddr) && (addr baseaddr) % 4 != 0 ) - return 0; - - *reladdr = addr - (*gpio)->baseaddr; - return 1; -} - - -/* Find device by vapi id */ -struct gpio_device *gpio_find_vapi_device( unsigned long id, unsigned *which ) -{ - unsigned i; - - for ( i = 0; i = gpios.base_vapi_id) && (id baseaddr == 0 ) + return; - return NULL; + PRINTF( "\nGPIO at 0x%"PRIxADDR":\n", gpio->baseaddr ); + PRINTF( "RGPIO_IN : 0x%08lX\n", gpio->curr.in ); + PRINTF( "RGPIO_OUT : 0x%08lX\n", gpio->curr.out ); + PRINTF( "RGPIO_OE : 0x%08lX\n", gpio->curr.oe ); + PRINTF( "RGPIO_INTE : 0x%08lX\n", gpio->curr.inte ); + PRINTF( "RGPIO_PTRIG : 0x%08lX\n", gpio->curr.ptrig ); + PRINTF( "RGPIO_AUX : 0x%08lX\n", gpio->curr.aux ); + PRINTF( "RGPIO_CTRL : 0x%08lX\n", gpio->curr.ctrl ); + PRINTF( "RGPIO_INTS : 0x%08lX\n", gpio->curr.ints ); } /* Wishbone read */ uint32_t gpio_read32( oraddr_t addr, void *dat ) { - struct gpio_device *gpio; - if ( !gpio_find_device( addr, &gpio, &addr ) ) { - debug( 2, "gpio_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr ); - return 0; - } + struct gpio_device *gpio = dat; + + addr -= gpio->baseaddr; switch( addr ) { case RGPIO_IN: return gpio->curr.in | gpio->curr.out; @@ -163,17 +94,17 @@ case RGPIO_CTRL: return gpio->curr.ctrl; case RGPIO_INTS: return gpio->curr.ints; } + + return 0; } /* Wishbone write */ void gpio_write32( oraddr_t addr, uint32_t value, void *dat ) { - struct gpio_device *gpio; - if ( !gpio_find_device( addr, &gpio, &addr ) ) { - debug( 2, "gpio_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr ); - return; - } + struct gpio_device *gpio = dat; + + addr -= gpio->baseaddr; switch( addr ) { case RGPIO_IN: debug( 5, "GPIO: Cannot write to RGPIO_IN\n" ); break; @@ -192,14 +123,11 @@ void gpio_vapi_read( unsigned long id, unsigned long data, void *dat ) { unsigned which; - struct gpio_device *gpio = gpio_find_vapi_device( id, &which ); + struct gpio_device *gpio = dat; debug( 5, "GPIO: id %08lx, data %08lx\n", id, data ); - if ( !gpio ) { - debug( 1, "GPIO: VAPI ID %08lx is not ours!\n", id ); - return; - } + which = id - gpio->base_vapi_id; switch( which ) { case GPIO_VAPI_DATA: @@ -226,45 +154,42 @@ gpio->next.ctrl = data; break; case GPIO_VAPI_CLOCK: - gpio_external_clock( data ); + gpio_external_clock( data, gpio ); break; } -} - -/* System Clock. */ -void gpio_clock( void ) -{ - unsigned i; - for ( i = 0; i curr.ctrl & RGPIO_CTRL_ECLK) ) + gpio_device_clock( gpio ); } /* External Clock. */ -void gpio_external_clock( unsigned long value ) +static void gpio_external_clock( unsigned long value, struct gpio_device *gpio ) { - unsigned i; + int use_external_clock = ((gpio->curr.ctrl & RGPIO_CTRL_ECLK) == RGPIO_CTRL_ECLK); + int negative_edge = ((gpio->curr.ctrl & RGPIO_CTRL_NEC) == RGPIO_CTRL_NEC); /* "Normalize" clock value */ value = (value != 0); - for ( i = 0; i next.external_clock = value; - int use_external_clock = ((gpio->curr.ctrl & RGPIO_CTRL_ECLK) == RGPIO_CTRL_ECLK); - int negative_edge = ((gpio->curr.ctrl & RGPIO_CTRL_NEC) == RGPIO_CTRL_NEC); - - gpio->next.external_clock = value; - - if ( use_external_clock && (gpio->next.external_clock != gpio->curr.external_clock) && (value != negative_edge) ) + if ( use_external_clock && (gpio->next.external_clock != gpio->curr.external_clock) && (value != negative_edge) ) + /* Make sure that in vapi_read, we don't clock the device */ + if ( gpio->curr.ctrl & RGPIO_CTRL_ECLK ) gpio_device_clock( gpio ); - } } +/* Report an interrupt to the sim */ +void gpio_do_int( void *dat ) +{ + struct gpio_device *gpio = dat; + + report_interrupt( gpio->irq ); +} /* Clock as handld by one device. */ -void gpio_device_clock( struct gpio_device *gpio ) +static void gpio_device_clock( struct gpio_device *gpio ) { /* Calculate new inputs and outputs */ gpio->next.in &= ~gpio->next.oe; /* Only input bits */ @@ -292,9 +217,12 @@ if ( relevant_bits & gpio->next.inte ) { debug( 3, "GPIO: Reporting interrupt %d\n", gpio->irq ); - report_interrupt( gpio->irq ); gpio->next.ctrl |= RGPIO_CTRL_INTS; gpio->next.ints |= relevant_bits & gpio->next.inte; + /* Since we can't report an interrupt during a readmem/writemem + * schedule the scheduler to do it. Read the comment above + * report_interrupt in pic/pic.c */ + SCHED_ADD( gpio_do_int, gpio, runtime.sim.cycles + 1 ); } } } @@ -304,46 +232,56 @@ } /*---------------------------------------------------[ GPIO configuration ]---*/ -void gpio_ngpios(union param_val val, void *dat) -{ - if (val.int_val >= 0 && val.int_val = 0 && current_device baseaddr = val.addr_val; } void gpio_irq(union param_val val, void *dat) { - if (current_device >= 0 && current_device irq = val.int_val; } void gpio_base_vapi_id(union param_val val, void *dat) { - if (current_device >= 0 && current_device base_vapi_id = val.int_val; +} + +void *gpio_sec_start(void) +{ + struct gpio_device *new = malloc(sizeof(struct gpio_device)); + + if(!new) { + fprintf(stderr, "Peripheral Test: Run out of memory\n"); + exit(-1); + } + + new->auxiliary_inputs = 0; + memset(&new->curr, 0, sizeof(new->curr)); + memset(&new->next, 0, sizeof(new->next)); + + return new; +} + +void gpio_sec_end(void *dat) +{ + struct gpio_device *gpio = dat; + + /* Register memory range */ + register_memoryarea( gpio->baseaddr, GPIO_ADDR_SPACE, 4, 0, gpio_read32, gpio_write32, dat ); + + reg_sim_reset(gpio_reset, dat); + reg_sim_stat(gpio_status, dat); } void reg_gpio_sec(void) { struct config_section *sec = reg_config_sec("gpio", NULL, NULL); - reg_config_param(sec, "ngpios", paramt_int, gpio_ngpios); - reg_config_param(sec, "device", paramt_int, change_device); reg_config_param(sec, "baseaddr", paramt_addr, gpio_baseaddr); reg_config_param(sec, "irq", paramt_int, gpio_irq); reg_config_param(sec, "base_vapi_id", paramt_int, gpio_base_vapi_id); - reg_config_param(sec, "enddevice", paramt_none, end_device); } --- peripheral/gpio.h 2002-01-02 11:38:36.000000000 +0100 +++ ../or1ksim-ac/peripheral/gpio.h 2005-02-09 10:30:12.000000000 +0100 @@ -21,13 +21,7 @@ #ifndef __OR1KSIM_PERIPHERAL_GPIO_H #define __OR1KSIM_PERIPHERAL_GPIO_H -/* Exported function prototypes */ -void gpio_reset( void ); -void gpio_clock( void ); -void gpio_status( void ); - - -/* Address space required by one Ethernet MAC */ +/* Address space required by one GPIO */ #define GPIO_ADDR_SPACE 0x20 /* Relative Register Addresses */ --- sim-config.c 2005-02-05 15:55:00.000000000 +0100 +++ ../or1ksim-ac/sim-config.c 2005-02-09 11:07:48.000000000 +0100 @@ -144,9 +143,6 @@ config.vapi.enabled = 0; strcpy (config.vapi.vapi_fn, "vapi.log"); - /* GPIO */ - config.ngpios = 0; - /* PM */ config.pm.enabled = 0; @@ -892,16 +893,6 @@ fprintf (f, " tick:{enabled:%i},\n", config.tick.enabled); - fprintf (f, " ngpios:%i, gpios:{", config.ngpios); - comma = 0; - for (i = 0; i - make specified number of instances, configure each - instance within device - enddevice construct. - - instance specific: baseaddr = address of first GPIO register for this device @@ -728,13 +723,9 @@ */ section gpio - ngpios = 1 - - device 0 - baseaddr = 0x91000000 - irq = 3 - base_vapi_id = 0x0200 - enddevice + baseaddr = 0x91000000 + irq = 3 + base_vapi_id = 0x0200 end /* VGA SECTION --- sim-cmd.c 2005-02-09 14:23:10.000000000 +0100 +++ ../or1ksim-ac/sim-cmd.c 2005-02-09 11:08:05.000000000 +0100 @@ -59,7 +59,6 @@ #include "icache_model.h" #include "dcache_model.h" #include "branch_predict.h" -#include "gpio.h" struct sim_stat { void (*stat_func)(void *dat); @@ -418,8 +427,6 @@ if (config.bpb.enabled) bpb_info(); if (config.bpb.btic) btic_info(); - if (config.ngpios) gpio_status(); - while(cur_stat) { cur_stat->stat_func(cur_stat->dat); cur_stat = cur_stat->next; --- toplevel.c 2005-02-09 14:23:10.000000000 +0100 +++ ../or1ksim-ac/toplevel.c 2005-02-09 11:07:33.000000000 +0100 @@ -54,7 +54,6 @@ #include "sched.h" #include "profiler.h" #include "mprofiler.h" -#include "gpio.h" #include "pm.h" #include "pic.h" #include "opcode/or32.h" @@ -165,7 +164,6 @@ cur_reset = cur_reset->next; } - gpio_reset(); tick_reset(); pm_reset(); pic_reset(); @@ -438,7 +436,6 @@ if (config.ic.enabled) ic_clock(); } - if (config.ngpios) gpio_clock(); if (config.vapi.enabled && runtime.vapi.enabled) vapi_check(); if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */ IFF(config.debug.enabled)
no use no use 1/1 no use no use
© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.